/* estilo.css · la hoja COMÚN de LEGAJO (§4, §10.3): tokens, letra, carcasa y piezas que usan todas las vistas.
   Sin nada en línea: la CSP lleva style-src 'self' (§8.6).

   Cómo está repartido (rediseño visual del 28/09, servicios/legajo/DISENO-VISUAL.md):
   - Aquí: los tokens (claro y oscuro), la letra, la base, la carcasa (barra lateral ≥ 1024 px, carril de iconos
     721-1023 px, barra de abajo ≤ 720 px), los controles y las piezas comunes (botones, campos, chapas, semáforo,
     avisos, diálogos, panel lateral, desplegables, avatares, KPI, progreso, estados vacíos, esqueletos,
     control segmentado, gráficas, leyendas), la impresión común y prefers-reduced-motion.
   - Lo de UNA vista va en css/<vista>.css (tablero, mias, tarea, agenda, plazos, expedientes, informes, actividad,
     acceso, ajustes, inicio), enlazado desde index.html detrás de este, cada uno con ?v=<8 del sha256>
     (despliegue/versiones_web.py lo pone y lo comprueba: Caddy solo manda no-cache a /js/* y /estilo.css).
     Una vista que necesita algo común lo pide aquí; no lo copia.

   Por qué así:
   - Colores por tokens en :root y otra vez en el tema oscuro (prefers-color-scheme; no hay interruptor): un solo
     sitio decide cada color. El contraste de cada par de TEXTO está MEDIDO con la luminancia relativa de WCAG
     (no a ojo) y apuntado aquí; el peor par es ≥ 4,5:1 en los dos temas:
       claro   texto #0F172A sobre fondo 16,68 · superficie 17,85 · superficie-2 16,09 · acento-suave 15,97
               texto-suave #475569 sobre fondo 7,08 · superficie 7,58 · superficie-2 6,83 · superficie-3 6,24
               acento #3451D1 sobre superficie 6,47 · superficie-2 5,84 · acento-suave 5,79 (la sección marcada)
               blanco sobre acento 6,47 · sobre acento-hover 8,38 · sobre peligro #C81E1E 5,74
               peligro sobre superficie 5,74 · sobre peligro-suave 5,24 · bien #15803D sobre superficie 5,02 ·
               sobre bien-suave 4,76 · aviso #B45309 sobre superficie 5,02 · sobre aviso-suave 4,71
               chapa-texto #334155 sobre chapa-fondo 9,15 · muestra (texto #0F172A sobre #F3B61F 9,80; sobre la
               raya más oscura 8,44)
               texto sobre el suave de cada semáforo ≥ 14,39; texto-suave sobre él ≥ 6,11
       oscuro  texto #E6EAF2 sobre fondo 15,70 · superficie 14,36 · superficie-2 13,11 · lateral 14,92
               texto-suave #A3AEC4 sobre fondo 8,48 · superficie 7,76 · superficie-2 7,08 · lateral 8,06
               acento #8EA2FF sobre superficie 7,22 · acento-suave 6,07 · texto #0B1020 sobre acento 7,90
               peligro #F87171 sobre superficie 6,26 · sobre peligro-suave 5,83 · bien 9,94 · aviso 10,37
               texto sobre el suave de cada semáforo ≥ 9,71; texto-suave sobre él ≥ 5,24
       avatares (iniciales en blanco, los dos temas) #3451D1 6,47 · #6D28D9 7,10 · #BE185D 6,04 · #0E7490 5,36 ·
               #15803D 5,02 · #B45309 5,02 · #475569 7,58 · #A21CAF 6,32
     Los colores de columna, de semáforo y de serie (--col-*, --s-*, --serie-*) son para PUNTOS, franjas, iconos y
     gráficas, no para texto: sobre blanco, ámbar, cian y verde no llegan a 4,5 (van con texto del color de la
     página al lado).
   - NINGÚN fondo de algo con texto se calcula con color-mix(): Chromium lo devuelve como «color(srgb …)» y las
     varas de contraste (prueba_base.mjs, ensayo_pantallas.mjs) no lo leen. Los suaves van precalculados en los
     tokens; el tinte del color de una materia (que llega de Ajustes) va en un ::before encima de un fondo sólido.
   - El color de una materia llega por `--color-materia` con style.setProperty desde JS (§10.3) y solo pinta un
     punto, un tinte o un borde: el texto va siempre con el color de la página.
   - Letra: Inter Variable autoalojada (fuentes/, OFL; LICENCIAS.txt al lado), con system-ui detrás. Cero
     recursos externos.

   Clases comunes (quién las usa):
   Carcasa         body.fuera · body.dentro · body.con-muestra · body.con-panel · .cabecera · .cabecera-marca ·
                   .marca/.marca-logo/.marca-texto/.marca-casa/.marca-sep/.marca-nombre · .despacho · .boton-buscar/
                   .buscador-texto/.buscador-atajo · .pestanas/.pestana/.pestana-nombre/.pestana-cuenta ·
                   .cabecera-acciones · .cuenta-resumen · .avatar (el botón de la cuenta) · .contador ·
                   .franja-muestra/.franja-icono/.franja-texto · .vista · .barra-movil/.barra-boton ·
                   .desplegable-cabecera · .menu-cuenta · .menu-movil · .menu-opcion · .menu-quien · .campana-* ·
                   .vista-mensaje · .cargando · .cabecera-vista/.vista-cabeza · .vista-titulo
   Controles       .boton · .boton-principal (= .boton-primario) · .boton-secundario · .boton-peligro · .boton-texto ·
                   .boton-icono · .boton-pequeno · .boton-ancho · .acciones · .botones · .segmentado/
                   .segmentado-opcion · .interruptor (una casilla que se ve como interruptor)
   Formularios     .campo · .campo-etiqueta · .campo-ayuda · .campo-error · .campo-obligatorio · .control-campo ·
                   .con-error · .campo-mal · .casilla · .error-formulario · .formulario-campos · .lista-fechas*
   Piezas          .icono · .chapa (+ -materia -etiqueta -contrato -orientativa -confirmada -confidencial -aviso
                   -estado -muestra -calendario -suprimido) · .chapa-punto · .semaforo (+ -vencido -hoy -tres_dias
                   -semana -lejos -falta) · .semaforo-punto · .aviso (+ -info -bien -error -aviso) · .aviso-icono ·
                   .avisos · .dialogo* · .panel-lateral · .panel-velo · .panel-* · .desplegable/.desplegable-opcion ·
                   .avatar-persona (+ -xs -s -m -l -xl, -c0…-c7, -mas) · .pila-avatares · .progreso* · .kpi* ·
                   .fila-kpi · .estado-vacio* · .esqueleto* · .seccion-tarjeta* · .rejilla-tarjetas · .fila-graficas ·
                   .grafica* · .leyenda* ·
                   .barras-* · .chispa* · .serie-* · .solo-lectores
   Filtros y listas .tablero-filtros/.barra-filtros/.filtros/.agenda-filtros · .tabla-desliza · .tabla ·
                   .tabla-detalle · .bloque · .dato · .gris · .paginacion · .buscador/.buscar-* (el buscador
                   global) · .od-* (OneDrive, en la ficha de tarea y en la de expediente) · .zona-* · .nota-apoyo
*/

/* ─────────────────────────────────────────────── letra (Inter Variable, OFL: fuentes/LICENCIAS.txt) */

/* Los unicode-range son los del paquete de Inter (fontsource, wght.css), copiados tal cual: el navegador baja
   solo el trozo que la página usa (casi siempre, el latino). */
@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fuentes/inter-latin-ext-wght-normal.woff2") format("woff2-variations"), url("/fuentes/inter-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fuentes/inter-latin-wght-normal.woff2") format("woff2-variations"), url("/fuentes/inter-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ─────────────────────────────────────────────── tokens */

:root {
  color-scheme: light;
  /* superficies y texto */
  --fondo: #f6f7fb;
  --superficie: #ffffff;
  --superficie-2: #f1f3f9;
  --superficie-3: #e6e9f2;
  --lateral: #ffffff;
  --cristal: rgba(255, 255, 255, 0.86);
  --borde: #e3e7f0;
  --borde-fuerte: #c5ccdb;
  --borde-control: #97a1b5;
  --texto: #0f172a;
  --texto-suave: #475569;
  /* la tinta del despacho */
  --acento: #3451d1;
  --acento-hover: #2a42b0;
  --acento-texto: #ffffff;
  --acento-suave: #eef2ff;
  --acento-grafico: #3451d1;
  --degradado-tinta: linear-gradient(135deg, #4f6bf0 0%, #3451d1 45%, #243aa6 100%);
  --oro: #b8892b;
  /* estados */
  --peligro: #c81e1e;
  --peligro-texto: #ffffff;
  --peligro-suave: #fef2f2;
  --bien: #15803d;
  --bien-suave: #ecfdf3;
  --aviso: #b45309;
  --aviso-suave: #fff7e6;
  --muestra-fondo: #f3b61f;
  --muestra-raya: rgba(0, 0, 0, 0.07);
  --muestra-texto: #0f172a;
  --chapa-fondo: #eef1f6;
  --chapa-texto: #334155;
  --foco: #3451d1;
  /* semáforo (puntos y franjas) y su suave precalculado (14 % sobre la superficie) */
  --s-vencido: #dc2626;
  --s-hoy: #ea580c;
  --s-tres: #d97706;
  --s-semana: #16a34a;
  --s-lejos: #94a3b8;
  --s-vencido-suave: #fae1e1;
  --s-hoy-suave: #fce8dd;
  --s-tres-suave: #faecdc;
  --s-semana-suave: #def2e6;
  --s-lejos-suave: #f0f2f5;
  /* prioridad (borde izquierdo de la tarjeta) */
  --p-urgente: #dc2626;
  --p-alta: #ea580c;
  --p-normal: #c5ccdb;
  --p-baja: #e3e7f0;
  /* columnas del tablero (claves de servidor/consultas.py) y su fondo tintado (7 % sobre superficie-2) */
  --col-bandeja: #7c3aed;
  --col-por-hacer: #2563eb;
  --col-en-curso: #d97706;
  --col-en-espera: #db2777;
  --col-para-revisar: #0891b2;
  --col-hecho: #16a34a;
  --col-neutra: #64748b;
  --col-bandeja-suave: #e9e6f8;
  --col-por-hacer-suave: #e3e9f8;
  --col-en-curso-suave: #efeae8;
  --col-en-espera-suave: #efe5f0;
  --col-para-revisar-suave: #e1ecf4;
  --col-hecho-suave: #e2eded;
  --col-neutra-suave: #e7eaf1;
  /* series de las gráficas (las 8 por defecto y las de tono) */
  --serie-0: #3451d1;
  --serie-1: #7c3aed;
  --serie-2: #0891b2;
  --serie-3: #db2777;
  --serie-4: #d97706;
  --serie-5: #16a34a;
  --serie-6: #64748b;
  --serie-7: #ea580c;
  --grafico-bien: #16a34a;
  /* avatares: iniciales en blanco, ≥ 4,5:1 en los dos temas (medido arriba) */
  --av-0: #3451d1;
  --av-1: #6d28d9;
  --av-2: #be185d;
  --av-3: #0e7490;
  --av-4: #15803d;
  --av-5: #b45309;
  /* El 6 era gris pizarra (#475569): se leía como «desactivado» y es el tono del sistema (crítica visual, 28/09).
     Naranja tostado, 5,18:1 con el blanco; el gris se queda para quien no es una persona (--av-neutro). */
  --av-6: #c2410c;
  --av-neutro: #475569;
  --av-7: #a21caf;
  /* el color de una materia (lo pone JS con setProperty; este es el de reserva) */
  --color-materia: #7a8291;
  /* formas, sombras y tiempos */
  --radio: 12px;
  --radio-control: 10px;
  --radio-pequeno: 8px;
  --radio-pildora: 999px;
  --sombra-suave: 0 1px 2px rgba(15, 23, 42, 0.06);
  --sombra: 0 1px 2px rgba(15, 23, 42, 0.06), 0 8px 24px -12px rgba(15, 23, 42, 0.18);
  --sombra-alta: 0 2px 4px rgba(15, 23, 42, 0.07), 0 14px 32px -12px rgba(15, 23, 42, 0.26);
  --sombra-grande: 0 4px 8px rgba(15, 23, 42, 0.08), 0 24px 48px -16px rgba(15, 23, 42, 0.32);
  --velo: rgba(15, 23, 42, 0.42);
  --t-rapido: 150ms;
  --curva: cubic-bezier(0.2, 0.8, 0.2, 1);
  /* medidas de la carcasa */
  --ancho-lateral: 248px;
  --ancho-carril: 64px;
  --alto-cabecera: 56px;
  --alto-barra: 64px;
  --letra: "Inter Variable", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --letra-fija: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
}

/* El tema oscuro va DOS veces con los mismos valores (por prefers-color-scheme y por data-theme="dark"): así se
   puede forzar para una captura sin tocar el sistema. Si se cambia uno, se cambia el otro. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --fondo: #0b1020;
    --superficie: #121a2e;
    --superficie-2: #18223a;
    --superficie-3: #223052;
    --lateral: #0f1629;
    --cristal: rgba(15, 22, 41, 0.86);
    --borde: #26324d;
    --borde-fuerte: #3a4867;
    --borde-control: #52618a;
    --texto: #e6eaf2;
    --texto-suave: #a3aec4;
    --acento: #8ea2ff;
    --acento-hover: #a9b8ff;
    --acento-texto: #0b1020;
    --acento-suave: #1c2650;
    --acento-grafico: #8ea2ff;
    --degradado-tinta: linear-gradient(135deg, #5b75f5 0%, #3f5bdc 50%, #2b41ad 100%);
    --peligro: #f87171;
    --peligro-texto: #1c0706;
    --peligro-suave: #3a1519;
    --bien: #4ade80;
    --bien-suave: #0f2a1c;
    --aviso: #fbbf24;
    --aviso-suave: #2e230c;
    --chapa-fondo: #22304d;
    --chapa-texto: #d5dbe8;
    --foco: #8ea2ff;
    --s-vencido: #f87171;
    --s-hoy: #fb923c;
    --s-tres: #fbbf24;
    --s-semana: #4ade80;
    --s-lejos: #7b8aa5;
    --s-vencido-suave: #3b2a3a;
    --s-hoy-suave: #3c3031;
    --s-tres-suave: #3c382c;
    --s-semana-suave: #1c3d3d;
    --s-lejos-suave: #252e43;
    --p-urgente: #f87171;
    --p-alta: #fb923c;
    --p-normal: #3a4867;
    --p-baja: #26324d;
    --col-bandeja: #a78bfa;
    --col-por-hacer: #60a5fa;
    --col-en-curso: #fbbf24;
    --col-en-espera: #f472b6;
    --col-para-revisar: #22d3ee;
    --col-hecho: #4ade80;
    --col-neutra: #94a3b8;
    --col-bandeja-suave: #232a49;
    --col-por-hacer-suave: #1e2c49;
    --col-en-curso-suave: #2a2f38;
    --col-en-espera-suave: #2a2844;
    --col-para-revisar-suave: #193048;
    --col-hecho-suave: #1c3140;
    --col-neutra-suave: #222c44;
    --serie-0: #8ea2ff;
    --serie-1: #a78bfa;
    --serie-2: #22d3ee;
    --serie-3: #f472b6;
    --serie-4: #fbbf24;
    --serie-5: #4ade80;
    --serie-6: #94a3b8;
    --serie-7: #fb923c;
    --grafico-bien: #4ade80;
    --sombra-suave: 0 1px 2px rgba(0, 0, 0, 0.4);
    --sombra: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
    --sombra-alta: 0 2px 4px rgba(0, 0, 0, 0.45), 0 14px 32px -12px rgba(0, 0, 0, 0.7);
    --sombra-grande: 0 4px 8px rgba(0, 0, 0, 0.5), 0 24px 48px -16px rgba(0, 0, 0, 0.75);
    --velo: rgba(3, 6, 14, 0.62);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --fondo: #0b1020;
  --superficie: #121a2e;
  --superficie-2: #18223a;
  --superficie-3: #223052;
  --lateral: #0f1629;
  --cristal: rgba(15, 22, 41, 0.86);
  --borde: #26324d;
  --borde-fuerte: #3a4867;
  --borde-control: #52618a;
  --texto: #e6eaf2;
  --texto-suave: #a3aec4;
  --acento: #8ea2ff;
  --acento-hover: #a9b8ff;
  --acento-texto: #0b1020;
  --acento-suave: #1c2650;
  --acento-grafico: #8ea2ff;
  --degradado-tinta: linear-gradient(135deg, #5b75f5 0%, #3f5bdc 50%, #2b41ad 100%);
  --peligro: #f87171;
  --peligro-texto: #1c0706;
  --peligro-suave: #3a1519;
  --bien: #4ade80;
  --bien-suave: #0f2a1c;
  --aviso: #fbbf24;
  --aviso-suave: #2e230c;
  --chapa-fondo: #22304d;
  --chapa-texto: #d5dbe8;
  --foco: #8ea2ff;
  --s-vencido: #f87171;
  --s-hoy: #fb923c;
  --s-tres: #fbbf24;
  --s-semana: #4ade80;
  --s-lejos: #7b8aa5;
  --s-vencido-suave: #3b2a3a;
  --s-hoy-suave: #3c3031;
  --s-tres-suave: #3c382c;
  --s-semana-suave: #1c3d3d;
  --s-lejos-suave: #252e43;
  --p-urgente: #f87171;
  --p-alta: #fb923c;
  --p-normal: #3a4867;
  --p-baja: #26324d;
  --col-bandeja: #a78bfa;
  --col-por-hacer: #60a5fa;
  --col-en-curso: #fbbf24;
  --col-en-espera: #f472b6;
  --col-para-revisar: #22d3ee;
  --col-hecho: #4ade80;
  --col-neutra: #94a3b8;
  --col-bandeja-suave: #232a49;
  --col-por-hacer-suave: #1e2c49;
  --col-en-curso-suave: #2a2f38;
  --col-en-espera-suave: #2a2844;
  --col-para-revisar-suave: #193048;
  --col-hecho-suave: #1c3140;
  --col-neutra-suave: #222c44;
  --serie-0: #8ea2ff;
  --serie-1: #a78bfa;
  --serie-2: #22d3ee;
  --serie-3: #f472b6;
  --serie-4: #fbbf24;
  --serie-5: #4ade80;
  --serie-6: #94a3b8;
  --serie-7: #fb923c;
  --grafico-bien: #4ade80;
  --sombra-suave: 0 1px 2px rgba(0, 0, 0, 0.4);
  --sombra: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
  --sombra-alta: 0 2px 4px rgba(0, 0, 0, 0.45), 0 14px 32px -12px rgba(0, 0, 0, 0.7);
  --sombra-grande: 0 4px 8px rgba(0, 0, 0, 0.5), 0 24px 48px -16px rgba(0, 0, 0, 0.75);
  --velo: rgba(3, 6, 14, 0.62);
}

/* ─────────────────────────────────────────────── base */

*, *::before, *::after { box-sizing: border-box; }

/* Una hoja del autor gana a la del navegador: sin esto, cualquier clase con `display` dejaría de esconder lo
   que lleva `hidden` (§12 02/09: las dos ventanas abiertas encima del tablero). */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--letra);
  font-size: 14px;
  line-height: 1.5;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* break-word y no anywhere: los dos parten una palabra que no cabe en su línea, pero anywhere además rebaja el
     ancho mínimo de cada caja a una letra, y en una tabla la celda se encoge hasta partir «Toled|o» y
     «Responsab|le» (medido en la captura de Expedientes). */
  overflow-wrap: break-word;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 0.5em; letter-spacing: -0.015em; }
h1 { font-size: 1.6rem; font-weight: 700; }
h2 { font-size: 1.15rem; font-weight: 650; }
h3 { font-size: 1rem; font-weight: 600; }
p { margin: 0 0 0.6em; }
a { color: var(--acento); text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }
code, .secreto, .codigos code { font-family: var(--letra-fija); }
img, svg { max-width: 100%; }
table { border-collapse: collapse; }
::selection { background: var(--acento-suave); color: var(--texto); }

/* Barras de desplazamiento finas (Chromium y Firefox leen las dos propiedades estándar). */
* { scrollbar-width: thin; scrollbar-color: var(--borde-fuerte) transparent; }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--foco);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Iconos (ui.icono): 20 px salvo que la pieza diga otra cosa con --icono (o ui.icono(n, {tam})). */
.icono { width: var(--icono, 20px); height: var(--icono, 20px); display: block; flex: none; }

/* Lo que solo es para el lector de pantalla (un nombre que no cabe en el carril de iconos, un pie de gráfica). */
.solo-lectores {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.sin-js { padding: 24px; text-align: center; }

/* ─────────────────────────────────────────────── carcasa: barra lateral (≥ 1024 px) */

/* La barra lateral es #cabecera (los id de siempre: #marca, #despacho, #chapa-contrato, #buscador, #pestanas,
   #avatar, #campana, #menu-movil). En escritorio va fija a la izquierda y el cuerpo se aparta su ancho; entre 721
   y 1023 px se queda en carril de iconos; en el móvil (≤ 720 px) vuelve a ser una barra fina arriba, con la
   barra de abajo (#barra-movil) para lo de cada día. Todas las secciones se ven en todos los anchos de escritorio:
   no hay pestañas escondidas en un menú. */
body.dentro { padding-left: var(--ancho-lateral); }

.cabecera {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: var(--ancho-lateral);
  padding: 16px 12px 12px;
  background: var(--lateral);
  border-right: 1px solid var(--borde);
}

.cabecera-marca {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  flex: none;
  padding: 0 6px 12px;
  border-bottom: 1px solid var(--borde);
}
.marca {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  max-width: 100%;
  color: var(--texto);
  text-decoration: none;
  border-radius: 10px;
}
/* El monograma: una «L» blanca sobre el degradado de la tinta, con el filo de oro de la casa. La letra va en el
   ::before (no es texto de la página: el nombre ya lo dice #marca). */
.marca-logo {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--degradado-tinta);
  box-shadow: inset 0 -3px 0 var(--oro), 0 4px 10px -4px rgba(52, 81, 209, 0.6);
}
.marca-logo::before {
  content: "L";
  color: #ffffff;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  transform: translateY(-1px);
}
.marca-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
/* «LEGAJO» en mayúsculas con algo de aire (en mayúsculas, el -0,02em de antes las apretaba) y debajo «by SAYKIN
   Consulting» tal cual se escribe: sin tracking ancho, que en minúsculas separa las letras. */
.marca-nombre { font-size: 1.12rem; font-weight: 750; letter-spacing: 0.05em; white-space: nowrap; }
.marca-casa { color: var(--texto-suave); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.01em; white-space: nowrap; }
/* El espacio entre el nombre y la casa: en la lateral van en dos renglones y no se ve, pero sigue en el texto
   (#marca dice «LEGAJO by SAYKIN Consulting», literal). En el móvil también van en dos. */
.marca-sep { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: pre; }
.despacho {
  max-width: 100%;
  margin-left: 44px;
  color: var(--texto-suave);
  font-size: 0.76rem;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chapa-contrato { margin: 6px 0 0 44px; cursor: help; }
/* La chapa «Demo» de una instalación de demostración (js/perfil.js → DEMO), con los colores de la muestra. */
.chapa-demo { margin: 6px 0 0 44px; cursor: help; background: var(--muestra-fondo); color: var(--muestra-texto); }
/* Novedades (29/09, js/novedades.js): «v1.1 · Novedades» bajo la marca, con un punto la semana de una versión nueva;
   abre el panel con todas las versiones. En el carril de iconos, plegada y en el móvil no cabe: está en el menú de la
   cuenta y en el ☰. */
.novedades-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 6px 0 0 44px;
  padding: 2px 8px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-pildora);
  background: transparent;
  color: var(--texto-suave);
  font: inherit;
  font-size: 0.72rem;
  line-height: 1.5;
  cursor: pointer;
}
.novedades-chip:hover { border-color: var(--borde-fuerte); color: var(--texto); }
.novedades-version { font-weight: 700; color: var(--texto); }
.novedades-punto { width: 7px; height: 7px; border-radius: 50%; background: var(--acento); box-shadow: 0 0 0 2px var(--acento-suave); }
/* El panel: versión, fecha y la chapa «Nueva»; debajo, su título y lo que cambió. */
.novedades-intro { margin: 0 0 12px; color: var(--texto-suave); }
.novedades-bloque { padding: 14px 0; border-top: 1px solid var(--borde); }
.novedades-cabeza { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin: 0; font-size: 1rem; }
.novedades-numero { font-weight: 800; }
.novedades-fecha { color: var(--texto-suave); font-size: 0.85rem; font-weight: 500; }
.novedades-titulo { margin: 6px 0 8px; font-weight: 650; }
.novedades-lista { display: flex; flex-direction: column; gap: 6px; margin: 0; padding-left: 18px; }
.novedades-lista li { line-height: 1.45; }
/* Plegar / desplegar la lateral (app.js, alternaPliegue): arriba a la derecha de la marca; plegada, debajo del
   monograma. Solo en ≥ 1024 px: entre 721 y 1023 el carril es obligado y en el móvil no hay lateral. */
.boton-plegar.boton-icono { position: absolute; top: 2px; right: -2px; width: 30px; height: 30px; color: var(--texto-suave); }
.boton-plegar .icono { --icono: 18px; }
.boton-plegar:hover { color: var(--texto); }

/* El buscador, como píldora: «Buscar…» y su atajo (Ctrl K, o ⌘ K en un Mac). El nombre para el lector de
   pantalla lo lleva su aria-label («Buscar (Ctrl+K o /)»). */
.boton-buscar.boton-icono {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  flex: none;
  width: 100%;
  height: 38px;
  padding: 0 8px 0 10px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-control);
  background: var(--superficie-2);
  color: var(--texto-suave);
  font: inherit;
  font-size: 0.88rem;
}
.boton-buscar .icono { --icono: 17px; }
.boton-buscar:hover { background: var(--superficie); border-color: var(--borde-fuerte); color: var(--texto); }
.buscador-texto { flex: 1 1 auto; text-align: left; }
.buscador-atajo {
  flex: none;
  padding: 1px 6px;
  border: 1px solid var(--borde);
  border-radius: 6px;
  background: var(--superficie);
  color: var(--texto-suave);
  font-family: var(--letra);
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 18px;
}

/* La navegación: icono + nombre (+ contador donde tiene sentido). Se desliza DENTRO si la ventana es muy baja. */
.pestanas {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0 -4px;
  padding: 3px 4px;
  overflow-y: auto;
}
.pestana {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  min-height: 38px;
  padding: 0 10px;
  border-radius: var(--radio-control);
  color: var(--texto-suave);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--t-rapido) var(--curva), color var(--t-rapido) var(--curva);
}
.pestana .icono { --icono: 18px; }
.pestana-nombre { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pestana:hover { background: var(--superficie-2); color: var(--texto); }
.pestana[aria-current="page"] { background: var(--acento-suave); color: var(--acento); font-weight: 600; }
/* La papelera, abajo del todo de la navegación y separada de las secciones por una línea fina. */
.pestanas-pie { display: flex; flex-direction: column; margin-top: auto; padding-top: 6px; border-top: 1px solid var(--borde); }
.pestana-cuenta {
  margin-left: auto;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radio-pildora);
  background: var(--peligro);
  color: var(--peligro-texto);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Abajo: la cuenta (avatar, nombre y rol) y la campana. */
.cabecera-acciones {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 10px 2px 0;
  border-top: 1px solid var(--borde);
}
.cuenta-resumen { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; line-height: 1.25; cursor: pointer; }
.cuenta-nombre { font-size: 0.86rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cuenta-rol { color: var(--texto-suave); font-size: 0.76rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.boton-icono {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radio-control);
  background: transparent;
  color: var(--texto);
  cursor: pointer;
  transition: background var(--t-rapido) var(--curva);
}
.boton-icono:hover { background: var(--superficie-2); }
.boton-menu { display: none; }

.contador {
  position: absolute;
  top: 1px;
  right: -1px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--peligro);
  color: var(--peligro-texto);
  box-shadow: 0 0 0 2px var(--lateral);
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

/* El botón de la cuenta: las iniciales sobre el color de la persona (app.js le pone .avatar-cN). */
.avatar {
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: var(--av-0);
  color: #ffffff;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 0 0 2px var(--lateral), 0 0 0 3px var(--borde);
}

/* La franja de DATOS DE MUESTRA: ámbar, rayada, pegada arriba y con su icono. Imposible de no ver (§4.6). */
.franja-muestra {
  position: sticky;
  top: 0;
  z-index: 35;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 16px;
  background-color: var(--muestra-fondo);
  background-image: repeating-linear-gradient(-45deg, transparent 0 14px, var(--muestra-raya) 14px 28px);
  color: var(--muestra-texto);
  font-weight: 700;
  font-size: 0.86rem;
  text-align: center;
  letter-spacing: 0.01em;
  border-bottom: 1px solid rgba(0, 0, 0, 0.18);
  box-shadow: 0 2px 8px -4px rgba(0, 0, 0, 0.35);
}
.franja-icono { --icono: 18px; }

.desplegable-cabecera {
  position: absolute;
  left: calc(100% + 18px);
  bottom: 0;
  z-index: 60;
  width: min(380px, calc(100vw - 32px));
  max-height: min(70vh, 560px);
  overflow: auto;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra-grande);
}
.menu-cuenta, .menu-movil { display: flex; flex-direction: column; padding: 6px; }
.menu-quien { display: flex; flex-direction: column; padding: 8px 10px; margin: 0 0 4px; border-bottom: 1px solid var(--borde); }
.menu-quien span { color: var(--texto-suave); font-size: 0.85rem; }
.menu-opcion {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--radio-pequeno);
  background: transparent;
  color: var(--texto);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.menu-opcion .icono { --icono: 18px; color: var(--texto-suave); }
.menu-opcion:hover, .menu-opcion[aria-current="page"] { background: var(--superficie-2); }
.menu-titulo { padding: 8px 10px 4px; margin: 0; color: var(--texto-suave); font-size: 0.85rem; }

.campana-caja { padding: 12px; }
.campana-cabecera { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.campana-cabecera h2 { margin: 0; font-size: 1rem; }
.campana-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.campana-vacia { padding: 12px 6px; color: var(--texto-suave); }
.campana-aviso {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 10px 10px 10px 12px;
  border: 0;
  border-radius: var(--radio-pequeno);
  background: transparent;
  color: var(--texto);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.campana-aviso:hover { background: var(--superficie-2); }
.campana-aviso.sin-leer { font-weight: 600; box-shadow: inset 3px 0 0 var(--acento); }
.campana-cuando { color: var(--texto-suave); font-size: 0.8rem; font-weight: 400; }
/* Cada aviso con el icono de su tipo en un círculo del tono (app.js, ICONO_AVISO); negrita y raya azul, solo los no
   leídos. El texto va con el color de la página: el tono pinta el círculo, nunca la letra. */
.campana-cuerpo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.campana-icono { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--superficie-2); color: var(--texto-suave); }
.campana-icono .icono { --icono: 15px; }
.campana-tono-violeta { background: var(--col-bandeja-suave); color: var(--col-bandeja); }
.campana-tono-cian { background: var(--col-para-revisar-suave); color: var(--col-para-revisar); }
.campana-tono-aviso { background: var(--s-tres-suave); color: var(--s-tres); }
.campana-tono-hoy { background: var(--s-hoy-suave); color: var(--s-hoy); }
.campana-tono-peligro { background: var(--s-vencido-suave); color: var(--s-vencido); }
.campana-tono-acento { background: var(--acento-suave); color: var(--acento); }
.campana-aviso.leido .campana-texto { font-weight: 400; }

/* ─────────────────────────────────────────────── vista */

.vista {
  display: block;
  width: 100%;
  max-width: 1480px;
  margin: 0 auto;
  padding: 28px 32px 48px;
  min-height: 60vh;
}
.vista:focus { outline: none; }
.vista-mensaje { max-width: 560px; margin: 40px auto; text-align: center; }
.vista-mensaje .boton { margin-top: 10px; }
.cargando { color: var(--texto-suave); padding: 24px 0; text-align: center; }
.cabecera-vista, .vista-cabeza { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 20px; }
.vista-titulo { display: flex; align-items: center; gap: 10px; margin: 0; font-size: 1.6rem; }
/* El icono del título de una vista en un cuadrado con el degradado de la tinta. Vivía cinco veces con cinco
   nombres y cuatro tamaños (38, 44, 44, 44 y 48 px): .vista-titulo-icono (tablero, Mis tareas, papelera, Informes,
   Actividad), .agenda-sello, .plazos-sello, .baldosa-icono (Expedientes, Clientes) y .ajustes-insignia. Los
   nombres se quedan (los pintan sus vistas); la forma es UNA, aquí (integración, 28/09). */
.vista-titulo-icono, .agenda-sello, .plazos-sello, .baldosa-icono, .ajustes-insignia {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--radio);
  background: var(--degradado-tinta);
  color: #ffffff;
  box-shadow: 0 6px 16px -8px rgba(52, 81, 209, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
:is(.vista-titulo-icono, .agenda-sello, .plazos-sello, .baldosa-icono, .ajustes-insignia) .icono { --icono: 22px; }
.mensaje, .vacio { color: var(--texto-suave); padding: 12px 0; }
.mensaje.error { color: var(--peligro); }
.mensaje.bien { color: var(--bien); }

.barra-movil { display: none; }

/* ─────────────────────────────────────────────── botones */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 40px;
  padding: 8px 14px;
  border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-control);
  background: var(--superficie);
  color: var(--texto);
  box-shadow: var(--sombra-suave);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 20px;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--t-rapido) var(--curva), border-color var(--t-rapido) var(--curva), box-shadow var(--t-rapido) var(--curva);
}
.boton .icono { --icono: 17px; }
.boton:hover { background: var(--superficie-2); border-color: var(--borde-control); }
.boton:active { box-shadow: none; }
.boton:disabled, .boton[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.boton-principal, .boton-primario {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-texto);
  box-shadow: 0 1px 2px rgba(52, 81, 209, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
.boton-principal:hover, .boton-primario:hover { background: var(--acento-hover); border-color: var(--acento-hover); }
.boton-secundario, .secundario { background: var(--superficie-2); }
.boton-peligro, .peligro { background: var(--peligro); border-color: var(--peligro); color: var(--peligro-texto); }
.boton-peligro:hover { background: var(--peligro); filter: brightness(1.08); }
.boton-aviso { background: var(--aviso-suave); border-color: var(--aviso); color: var(--texto); }
.boton-texto {
  min-height: 36px;
  padding: 6px 8px;
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  color: var(--acento);
  font-weight: 600;
}
.boton-texto:hover { background: var(--acento-suave); border-color: transparent; }
.boton-pequeno { min-height: 32px; padding: 4px 10px; font-size: 0.85rem; }
/* Un botón que es solo un icono y además lleva .boton (el ✕ de ui.panel, las flechas de página de Clientes y del
   Inicio): el relleno de .boton (8px 14px) le ganaba al padding: 0 de .boton-icono (declarado antes) y a un botón de
   38 px le dejaba 8 px para el icono — un aspa aplastada de 8×17, medido el 28/09. Con las dos clases, ninguno. */
.boton.boton-icono { padding: 0; }
.boton.boton-icono .icono { --icono: 18px; }
.boton-ancho { width: 100%; }
.boton-quitar { color: var(--peligro); }
.acciones, .botones { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0; }
/* Un botón que es un interruptor (Semana/Mes, Lista/Ver como tablero) dice cuál está puesto. */
.boton[aria-pressed="true"] { background: var(--acento-suave); border-color: var(--acento); color: var(--texto); }

/* Control segmentado (ui.segmentado): las opciones en una cápsula, la puesta en blanco con sombra. */
.segmentado {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-control);
  background: var(--superficie-2);
}
.segmentado-opcion {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 4px 12px;
  border: 0;
  border-radius: var(--radio-pequeno);
  background: transparent;
  color: var(--texto-suave);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t-rapido) var(--curva), color var(--t-rapido) var(--curva);
}
.segmentado-opcion .icono { --icono: 16px; }
.segmentado-opcion:hover { color: var(--texto); }
.segmentado-opcion[aria-pressed="true"] { background: var(--superficie); color: var(--texto); box-shadow: var(--sombra-suave), 0 0 0 1px var(--borde); }

/* ─────────────────────────────────────────────── formularios */

.campo { display: flex; flex-direction: column; gap: 5px; margin-bottom: 14px; min-width: 0; }
.campo-etiqueta { font-weight: 600; font-size: 0.86rem; }
.campo-obligatorio { color: var(--texto-suave); font-weight: 400; }
.campo-ayuda, .ayuda { color: var(--texto-suave); font-size: 0.82rem; }
.campo-error, .error-formulario { color: var(--peligro); font-size: 0.86rem; font-weight: 600; margin: 2px 0 0; }
.error-formulario { padding: 9px 12px; border-radius: var(--radio-pequeno); background: var(--peligro-suave); margin-bottom: 12px; }

input[type="text"], input[type="email"], input[type="password"], input[type="url"], input[type="search"],
input[type="number"], input[type="date"], input[type="datetime-local"], input[type="time"], input[type="tel"],
select, textarea, .control-campo {
  width: 100%;
  max-width: 100%;
  min-height: 40px;
  padding: 8px 11px;
  border: 1px solid var(--borde-control);
  border-radius: var(--radio-control);
  background-color: var(--superficie);
  color: var(--texto);
  font: inherit;
  transition: border-color var(--t-rapido) var(--curva), box-shadow var(--t-rapido) var(--curva);
}
input:hover, select:hover, textarea:hover { border-color: var(--texto-suave); }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--acento); box-shadow: 0 0 0 3px var(--acento-suave); }
/* El desplegable con su flecha propia (dos triángulos en degradado: sin imagen y del color del tema). */
select:not([multiple]) {
  appearance: none;
  padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, var(--texto-suave) 50%), linear-gradient(135deg, var(--texto-suave) 50%, transparent 50%);
  background-position: calc(100% - 18px) 52%, calc(100% - 13px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
textarea { min-height: 80px; resize: vertical; }
input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; min-height: 0; margin: 0; flex: none; accent-color: var(--acento); }
/* Una casilla que se ve como interruptor (Ajustes, módulos): sigue siendo un checkbox, con su foco y su teclado. */
input[type="checkbox"].interruptor {
  appearance: none;
  position: relative;
  width: 38px;
  height: 22px;
  border-radius: var(--radio-pildora);
  background: var(--borde-fuerte);
  cursor: pointer;
  transition: background var(--t-rapido) var(--curva);
}
input[type="checkbox"].interruptor::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.3);
  transition: transform var(--t-rapido) var(--curva);
}
input[type="checkbox"].interruptor:checked { background: var(--acento); }
input[type="checkbox"].interruptor:checked::before { transform: translateX(16px); }
input[type="checkbox"].interruptor:disabled { opacity: 0.5; cursor: not-allowed; }
/* Un campo cuyo rótulo va ANTES de la casilla (el formulario de plazos) se da la vuelta: casilla y rótulo en la
   misma línea. Las casillas que ya van delante de su texto (.campo-casilla) no se tocan. */
.campo:not(.campo-casilla):has(> input[type="checkbox"]) { flex-direction: row-reverse; justify-content: flex-end; align-items: center; gap: 10px; }
.campo:not(.campo-casilla):has(> input[type="checkbox"]) .campo-etiqueta { font-weight: 500; }
.campo-casilla { flex-direction: row; align-items: center; }
select[multiple] { min-height: 100px; }
fieldset.control-campo { padding: 8px; }
input::placeholder, textarea::placeholder { color: var(--texto-suave); opacity: 1; }
.con-error .control-campo, .con-error input, .con-error select, .con-error textarea, .campo-mal,
[aria-invalid="true"] { border-color: var(--peligro); box-shadow: 0 0 0 1px var(--peligro); }

.casilla, .campo-casilla { display: flex; align-items: center; gap: 8px; margin: 10px 0; cursor: pointer; }
.casilla input, .campo-casilla input { width: 18px; height: 18px; min-height: 0; margin: 0; accent-color: var(--acento); }

.formulario, .formulario-campos { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); gap: 0 16px; }
.formulario > .boton, .formulario-campos > .boton, .formulario > .botones, .formulario-campos > .botones { align-self: end; justify-self: start; margin-bottom: 14px; }
.lista-fechas { border-radius: var(--radio-control); }
.lista-fechas-filas { display: flex; flex-direction: column; gap: 6px; }
.lista-fechas-fila { display: grid; grid-template-columns: minmax(0, 11em) minmax(0, 1fr) auto; gap: 6px; align-items: center; }

.desplegable {
  position: relative;
  z-index: 30;
  list-style: none;
  margin: 4px 0 0;
  padding: 4px;
  max-height: 260px;
  overflow: auto;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio-control);
  box-shadow: var(--sombra-alta);
}
.desplegable-opcion { padding: 8px 10px; border-radius: 6px; cursor: pointer; }
.desplegable-opcion.activa, .desplegable-opcion:hover { background: var(--acento-suave); }

/* El buscador global (la lupa y «Buscar» del móvil, buscar.js), como paleta de órdenes (crítica visual, 28/09): la
   caja arriba con la lupa y «Esc», grupos (Clientes, Expedientes, Tareas) con una fila por resultado —el icono de
   su tipo en un cuadrado, el código en chapa monoespaciada, el título con lo tecleado en <mark> y lo demás debajo en
   gris— y un pie con las teclas. El título del diálogo queda para el lector de pantalla y el botón «Cerrar»,
   escondido: buscar.js lo pulsa para cerrar (Esc, Intro sobre un resultado). */
.dialogo.dialogo-buscar { width: min(640px, calc(100vw - 32px)); margin-top: min(14vh, 120px); padding: 0; overflow: hidden; }
.buscar-titulo { min-width: 0; }
.dialogo-buscar .dialogo-titulo { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.dialogo-buscar .dialogo-cuerpo { margin: 0; }
.dialogo-buscar .dialogo-pie { display: none; }
.buscador { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.buscar-caja { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--borde); }
.buscar-caja .buscar-lupa { --icono: 18px; flex: none; color: var(--texto-suave); }
.buscar-caja input[type="search"] { flex: 1 1 auto; min-width: 0; min-height: 32px; padding: 0; border: 0; background: transparent; color: var(--texto); font: inherit; font-size: 1rem; box-shadow: none; }
.buscar-caja input[type="search"]:focus, .buscar-caja input[type="search"]:focus-visible { outline: none; box-shadow: none; }
.buscar-caja:focus-within { box-shadow: inset 0 -2px 0 var(--acento); }
.buscar-caja input[type="search"]::-webkit-search-cancel-button { display: none; }
.buscador kbd {
  display: inline-grid; place-items: center; min-width: 22px; height: 20px; padding: 0 5px;
  border: 1px solid var(--borde-fuerte); border-bottom-width: 2px; border-radius: 5px;
  background: var(--superficie-2); color: var(--texto-suave); font: inherit; font-size: 0.7rem; font-weight: 600;
}
.buscar-esc { flex: none; }
.buscar-estado { margin: 0; padding: 10px 16px 0; color: var(--texto-suave); font-size: 0.82rem; }
.buscar-resultados { display: flex; flex-direction: column; gap: 10px; min-width: 0; max-height: min(60vh, 520px); overflow-y: auto; padding: 6px 8px 10px; }
.buscar-resultados:empty { display: none; }
.buscar-grupo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.buscar-grupo > h3 { margin: 6px 8px 4px; font-size: 0.72rem; font-weight: 650; letter-spacing: 0.04em; font-variant-caps: all-small-caps; color: var(--texto-suave); }
.buscar-opcion {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; padding: 8px 10px; border: 1px solid transparent; border-radius: var(--radio-control);
  background: transparent; color: var(--texto); font: inherit; cursor: pointer;
}
.buscar-opcion[aria-selected="true"], .buscar-opcion:hover { background: var(--acento-suave); border-color: transparent; }
.buscar-icono { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 8px; background: var(--superficie-2); color: var(--texto-suave); }
.buscar-icono .icono { --icono: 16px; }
.buscar-tipo-cliente .buscar-icono { color: var(--col-bandeja); }
.buscar-tipo-expediente .buscar-icono { color: var(--acento); }
.buscar-tipo-tarea .buscar-icono { color: var(--col-hecho); }
.buscar-opcion[aria-selected="true"] .buscar-icono { background: var(--superficie); }
.buscar-textos { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.buscar-principal { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-width: 0; overflow-wrap: anywhere; font-weight: 550; }
.buscar-codigo {
  flex: none; padding: 0 6px; border-radius: 5px; background: var(--superficie-2); box-shadow: inset 0 0 0 1px var(--borde);
  color: var(--texto); font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 0.76rem; font-weight: 600; line-height: 20px;
}
.buscar-secundario { color: var(--texto-suave); font-size: 0.8rem; overflow-wrap: anywhere; }
.buscar-opcion mark { padding: 0 1px; border-radius: 3px; background: var(--s-hoy-suave); color: var(--texto); box-shadow: inset 0 -2px 0 var(--s-hoy); }
.buscar-ir { flex: none; color: var(--texto-suave); opacity: 0; }
.buscar-ir .icono { --icono: 15px; }
.buscar-opcion[aria-selected="true"] .buscar-ir { opacity: 1; color: var(--acento); }
.buscar-pie { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 10px 16px; border-top: 1px solid var(--borde); background: var(--superficie-2); color: var(--texto-suave); font-size: 0.76rem; }
.buscar-pista { display: inline-flex; align-items: center; gap: 6px; }
.buscar-pie kbd { background: var(--superficie); }

/* ─────────────────────────────────────────────── chapas y semáforo */

.chapa {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 2px 9px;
  border-radius: var(--radio-pildora);
  background: var(--chapa-fondo);
  color: var(--chapa-texto);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
.chapa-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--color-materia); flex: none; }
.chapa-texto { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La materia: fondo pastel de su color (un ::before del 14 % encima de la superficie: el fondo que mide el
   contraste es el sólido de debajo), punto del color puro y el texto con el color de la página. */
.chapa-materia {
  position: relative;
  isolation: isolate;
  background: var(--superficie);
  color: var(--texto);
  box-shadow: inset 0 0 0 1px var(--borde);
}
.chapa-materia::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--color-materia);
  opacity: 0.14;
}
/* Una etiqueta: solo el contorno fino. */
.chapa-etiqueta { background: transparent; color: var(--texto-suave); box-shadow: inset 0 0 0 1px var(--borde-fuerte); }
.chapa-orientativa, .chapa-aviso, .chapa-calendario { background: var(--aviso-suave); color: var(--texto); border: 1px dashed var(--aviso); }
.chapa-confirmada { background: var(--bien-suave); color: var(--texto); }
.chapa-confidencial, .chapa-suprimido { background: var(--peligro-suave); color: var(--texto); }
.chapa-muestra { background: var(--muestra-fondo); color: var(--muestra-texto); }
.chapa-contrato { background: var(--aviso-suave); color: var(--texto); box-shadow: inset 0 0 0 1px var(--aviso); }
.chapas, .agenda-chapas { display: flex; flex-wrap: wrap; gap: 6px; }

/* El semáforo de un vencimiento: una píldora con el punto de su color y un fondo suave del mismo tono. */
.semaforo {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 1px 9px 1px 7px;
  border-radius: 12px;
  background: var(--s-lejos-suave);
  color: var(--texto);
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 20px;
  /* Parte en dos renglones si no cabe (una tarjeta estrecha, 320 px): una píldora que no parte ensancha la página. */
  overflow-wrap: anywhere;
}
.semaforo-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--s-lejos); flex: none; }
.semaforo-vencido { background: var(--s-vencido-suave); font-weight: 700; }
.semaforo-vencido .semaforo-punto { background: var(--s-vencido); box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18); }
.semaforo-hoy { background: var(--s-hoy-suave); font-weight: 600; }
.semaforo-hoy .semaforo-punto { background: var(--s-hoy); }
.semaforo-tres_dias { background: var(--s-tres-suave); }
.semaforo-tres_dias .semaforo-punto { background: var(--s-tres); }
.semaforo-semana { background: var(--s-semana-suave); }
.semaforo-semana .semaforo-punto { background: var(--s-semana); }
.semaforo-falta { background: transparent; box-shadow: inset 0 0 0 1px var(--borde-fuerte); }
/* Sin fecha: un punto HUECO de trazo continuo. Discontinuo, a 8 px se leía como un «cargando» que no acaba. Va con
   --borde-control y no con --borde-fuerte: sobre la píldora (que ya lleva --borde-fuerte de contorno) el hueco
   tiene que distinguirse de su propio borde. */
.semaforo-falta .semaforo-punto { background: transparent; border: 2px solid var(--borde-control); }

/* ─────────────────────────────────────────────── avisos (toasts) y zonas de aviso */

.avisos {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(420px, calc(100vw - 32px));
  pointer-events: none;
}
.aviso {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 8px 12px 14px;
  border-radius: var(--radio);
  border: 1px solid var(--borde);
  border-left: 4px solid var(--acento);
  background: var(--superficie);
  color: var(--texto);
  box-shadow: var(--sombra-grande);
  pointer-events: auto;
  animation: aparece 180ms var(--curva);
}
.aviso-icono { --icono: 20px; margin-top: 1px; color: var(--acento); }
.aviso-texto { flex: 1 1 auto; margin: 1px 0; font-weight: 500; }
.aviso-bien, .aviso-ok { border-left-color: var(--bien); }
.aviso-bien .aviso-icono { color: var(--bien); }
.aviso-error { border-left-color: var(--peligro); }
.aviso-error .aviso-icono { color: var(--peligro); }
.aviso-aviso { border-left-color: var(--aviso); background: var(--aviso-suave); }
.aviso-aviso .aviso-icono { color: var(--aviso); }
.aviso-cerrar {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 5px;
  border: 0;
  border-radius: var(--radio-pequeno);
  background: transparent;
  color: var(--texto-suave);
  cursor: pointer;
}
.aviso-cerrar .icono { width: 20px; height: 20px; }
.aviso-cerrar:hover { background: var(--superficie-2); color: var(--texto); }
.zona-aviso, .aviso-arts910, .aviso-arts, .aviso-campos, .aviso-borrador, .aviso-juzgado, .conflicto-incompleto, .od-mientras {
  padding: 10px 12px 10px 14px;
  border-radius: var(--radio-pequeno);
  background: var(--aviso-suave);
  border: 1px solid var(--aviso);
  border-left-width: 4px;
  color: var(--texto);
  margin: 8px 0;
}
/* Las vistas dejan su zona de avisos puesta y vacía hasta que hay algo que decir: vacía no se pinta. */
.zona-alta:empty, .zona-edicion:empty, .zona-invitar:empty, .zona-estado:empty, .resultados-clientes:empty,
.zona-aviso:empty, .aviso-arts910:empty, .aviso-arts:empty, .aviso-campos:empty, .aviso-borrador:empty,
.aviso-juzgado:empty, .conflicto-incompleto:empty, .od-mientras:empty, .error-formulario:empty { display: none; }
.nota-apoyo { color: var(--texto-suave); font-size: 0.85rem; font-style: italic; }

/* ─────────────────────────────────────────────── diálogo y panel lateral */

.dialogo {
  width: min(540px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 24px;
  border: 1px solid var(--borde);
  border-radius: 16px;
  background: var(--superficie);
  color: var(--texto);
  box-shadow: var(--sombra-grande);
}
.dialogo[open] { animation: aparece 160ms var(--curva); }
/* El velo, con cristal: la página se ve detrás, desenfocada. */
.dialogo::backdrop { background: var(--velo); backdrop-filter: blur(4px); }
.dialogo-titulo { font-size: 1.2rem; }
.dialogo-cuerpo { margin: 12px 0 20px; }
.dialogo-pie { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }

/* El velo del panel lateral, sin desenfoque: el tablero de detrás se sigue leyendo, como en Linear (el cristal es solo
   de la barra de arriba y de los diálogos, DISENO-VISUAL.md; crítica visual, 28/09). */
.panel-velo { position: fixed; inset: 0; z-index: 70; background: var(--velo); animation: aparece 160ms var(--curva); }
.panel-lateral {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  display: flex;
  flex-direction: column;
  width: min(600px, 100vw);
  background: var(--superficie);
  border-left: 1px solid var(--borde);
  box-shadow: var(--sombra-grande);
  animation: aparece 160ms var(--curva);
}
.panel-cabecera {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--alto-cabecera);
  padding: 0 10px 0 16px;
  border-bottom: 1px solid var(--borde);
  background: var(--superficie);
}
.panel-titulo { flex: 1 1 auto; margin: 0; font-size: 1.05rem; min-width: 0; }
.panel-volver { display: none; }
.panel-cuerpo { flex: 1 1 auto; overflow: auto; padding: 20px; }
/* La ficha de tarea, en una ventana centrada del 88 % de ancho y el 90 % de alto (v1.7, Rubén 30/09, dos veces: en la
   columna de 600 px «tienes que bajar muchas veces con el ratón»; «entre un 80 % o 90 % de la pantalla»). Solo en escritorio: en el móvil sigue siendo la pantalla entera
   (la regla de 720 px de abajo). Sin transform, como el panel: la caja no se mueve mientras aparece. */
@media (min-width: 721px) {
  .panel-lateral.panel-ventana {
    top: 5vh;
    bottom: 5vh;
    left: 0;
    right: 0;
    width: min(88vw, 2000px);
    margin: 0 auto;
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    overflow: hidden;
  }
}

/* Aparecer: la opacidad; lo que sale de un botón, además, crece desde él (ui.brota, DISENO-VISUAL.md «El movimiento»). */
@keyframes aparece { from { opacity: 0; } to { opacity: 1; } }

/* ─────────────────────────────────────────────── filtros (tablero, expedientes, agenda, actividad…) */

.tablero-filtros, .barra-filtros, .filtros, .agenda-filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-bottom: 16px;
}
/* Una fila de controles del mismo alto: la búsqueda se estira, los desplegables llevan un rótulo corto
   («Persona», «Materia»…) y un ancho fijo para que el texto no se corte (a 1440 px se cortaba «Todas las
   personas»), y lo que no cabe baja a la línea siguiente en vez de apilarse uno por renglón. */
.tablero-filtros > *, .filtros > *, .agenda-filtros > * { flex: 0 1 10.5rem; min-width: 8rem; width: auto; margin: 0; }
.filtros > select { flex-basis: 10rem; min-width: 9.75rem; }
.filtros > input[type="search"] { min-width: 11rem; }
.barra-filtros > * { flex: 0 1 11rem; min-width: 8rem; margin: 0; }
.barra-filtros > .boton, .agenda-filtros > .boton { flex: 0 0 auto; min-width: 0; }
/* Los desplegables de la agenda, a su ancho propio: con 10,5rem se cortaban «De quién» y «Festivos de» con su sede. */
.agenda-filtros > select { flex: 0 1 auto; min-width: 11rem; }
.barra-filtros .campo { margin-bottom: 0; }
.barra-filtros { align-items: flex-end; }
.tablero-filtros > input[type="search"], .filtros > input[type="search"] { flex: 1 1 14rem; min-width: 12rem; }
.tablero-filtros > select, .filtros > select { padding-right: 34px; text-overflow: ellipsis; }
.tablero-filtros select.con-valor, .filtros select.con-valor { border-color: var(--acento); box-shadow: inset 0 0 0 1px var(--acento); background-color: var(--acento-suave); }
.tablero-filtros > .boton, .filtros > .boton, .filtros > .campo-casilla { flex: 0 0 auto; min-width: 0; }
.filtros > .campo-casilla { margin: 0; white-space: nowrap; }
.filtros-mas { display: contents; }
.filtros-mas[hidden] { display: none !important; }

/* ─────────────────────────────────────────────── tablas, bloques y listas */

/* La tabla lleva su propio desplazamiento horizontal si no cabe (la página no se desplaza de lado), y cada columna
   su ancho mínimo: el código en una línea, las palabras enteras. */
.tabla-desliza { width: 100%; overflow-x: auto; }
.tabla, .tabla-expedientes, .tabla-detalle { width: 100%; border-collapse: collapse; }
.tabla-expedientes td.numero, .tabla td.numero { text-align: right; font-variant-numeric: tabular-nums; }
.tabla th, .tabla td, .tabla-expedientes th, .tabla-expedientes td, .tabla-detalle th, .tabla-detalle td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--borde);
  text-align: left;
  vertical-align: top;
}
.tabla th, .tabla-expedientes th, .tabla-detalle th {
  background: var(--superficie-2);
  color: var(--texto-suave);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.tabla tbody tr, .tabla-expedientes tbody tr { transition: background var(--t-rapido) var(--curva); }
.tabla tbody tr:hover, .tabla-expedientes tbody tr:hover { background: var(--superficie-2); }
.bloque, .bloque-ficha, .tarjeta-informe, .tarjeta-ajustes, .zona-alta, .zona-edicion, .zona-invitar, .zona-estado {
  padding: 18px;
  margin-bottom: 16px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  box-shadow: var(--sombra-suave);
}
.dato { display: flex; flex-direction: column; margin-bottom: 8px; }
.gris { color: var(--texto-suave); }
.paginacion { display: flex; gap: 8px; align-items: center; justify-content: center; margin: 12px 0; }

/* Una tarjeta de sección (Inicio, Informes, fichas): cabeza con icono, título y una acción a la derecha. */
.seccion-tarjeta {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  padding: 18px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  box-shadow: var(--sombra-suave);
}
.seccion-tarjeta-cabeza { display: flex; align-items: center; gap: 10px; min-width: 0; }
.seccion-tarjeta-cabeza > .icono { --icono: 18px; color: var(--acento); }
/* Rejilla de tarjetas de sección (Inicio, Informes) y una fila de gráficas pequeñas (dos anillos, un donut…). */
.rejilla-tarjetas { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: 16px; align-items: start; }
.fila-graficas { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px; }
.seccion-tarjeta-titulo { flex: 1 1 auto; min-width: 0; margin: 0; font-size: 1rem; font-weight: 650; }

/* OneDrive: un resultado por fila, el nombre arriba, carpeta y fecha debajo en pequeño, el botón a la derecha. */
.od-buscar { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.od-buscar > .boton { align-self: flex-start; }
.od-panel .campo { margin-bottom: 6px; }
.od-resultados { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.od-resultado {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "nombre boton" "datos boton";
  gap: 2px 10px;
  align-items: center;
  padding: 8px 10px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-pequeno);
  background: var(--superficie);
}
.od-resultado .od-nombre { grid-area: nombre; font-weight: 600; overflow-wrap: anywhere; }
.od-resultado .od-datos { grid-area: datos; color: var(--texto-suave); font-size: 0.82rem; overflow-wrap: anywhere; }
.od-resultado .boton { grid-area: boton; }
.od-estado:empty { display: none; }
.od-faltas { margin: 0 0 6px; padding-left: 1.2em; color: var(--texto-suave); font-size: 0.9rem; }

/* ─────────────────────────────────────────────── página de vuelta de OneDrive (od-vuelta.html, solo esta hoja) */

body.od-vuelta { display: flex; justify-content: center; padding: 10vh 16px; }
.od-vuelta-caja {
  width: min(480px, 100%);
  padding: 24px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  box-shadow: var(--sombra);
}

/* ─────────────────────────────────────────────── avatares (ui.avatar, ui.pilaAvatares) */

.avatar-persona {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background-color: var(--av-neutro);
  color: #ffffff;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  user-select: none;
}
.avatar-xs { width: 20px; height: 20px; font-size: 0.56rem; }
.avatar-s { width: 24px; height: 24px; font-size: 0.62rem; }
.avatar-m { width: 28px; height: 28px; font-size: 0.68rem; }
.avatar-l { width: 36px; height: 36px; font-size: 0.8rem; }
.avatar-xl { width: 48px; height: 48px; font-size: 1.02rem; }
.avatar-c0 { background-color: var(--av-0); }
.avatar-c1 { background-color: var(--av-1); }
.avatar-c2 { background-color: var(--av-2); }
.avatar-c3 { background-color: var(--av-3); }
.avatar-c4 { background-color: var(--av-4); }
.avatar-c5 { background-color: var(--av-5); }
.avatar-c6 { background-color: var(--av-6); }
.avatar-c7 { background-color: var(--av-7); }
.avatar-mas { background-color: var(--superficie-2); color: var(--texto-suave); box-shadow: inset 0 0 0 1px var(--borde-fuerte); }
.pila-avatares { display: inline-flex; align-items: center; flex: none; }
.pila-avatares > .avatar-persona { box-shadow: 0 0 0 2px var(--superficie); }
.pila-avatares > .avatar-persona + .avatar-persona { margin-left: -5px; }
.pila-avatares > .avatar-mas { box-shadow: 0 0 0 2px var(--superficie), inset 0 0 0 1px var(--borde-fuerte); }

/* ─────────────────────────────────────────────── progreso, KPI, estado vacío y esqueleto */

.progreso { display: inline-flex; align-items: center; gap: 6px; color: var(--texto-suave); font-size: 0.75rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.progreso-barra { display: block; width: 44px; height: 6px; border-radius: var(--radio-pildora); background: var(--superficie-3); overflow: hidden; }
.progreso-relleno { display: block; width: var(--progreso, 0%); height: 100%; border-radius: inherit; background: var(--acento-grafico); transition: width 300ms var(--curva); }
.progreso-completo .progreso-relleno { background: var(--grafico-bien); }

/* Una fila de KPI (Inicio, Informes): se reparten el ancho y bajan de línea solas. */
.fila-kpi { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr)); gap: 12px; margin-bottom: 20px; }
.kpi {
  --kpi-color: var(--acento);
  --kpi-suave: var(--acento-suave);
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-width: 0;
  padding: 16px;
  overflow: hidden;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--superficie);
  color: var(--texto);
  box-shadow: var(--sombra-suave);
  text-decoration: none;
  transition: box-shadow var(--t-rapido) var(--curva), border-color var(--t-rapido) var(--curva), transform var(--t-rapido) var(--curva);
}
.kpi::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--kpi-color); }
a.kpi:hover { border-color: var(--borde-fuerte); box-shadow: var(--sombra-alta); transform: translateY(-1px); }
.kpi-icono { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: 12px; background: var(--kpi-suave); color: var(--kpi-color); }
.kpi-icono .icono { --icono: 20px; }
.kpi-cuerpo { display: flex; flex-direction: column; min-width: 0; }
.kpi-valor { font-size: 1.85rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.kpi-etiqueta { margin-top: 2px; color: var(--texto-suave); font-size: 0.84rem; font-weight: 500; }
.kpi-detalle { margin-top: 2px; color: var(--texto-suave); font-size: 0.76rem; }
.kpi-peligro { --kpi-color: var(--s-vencido); --kpi-suave: var(--s-vencido-suave); }
.kpi-hoy { --kpi-color: var(--s-hoy); --kpi-suave: var(--s-hoy-suave); }
.kpi-aviso { --kpi-color: var(--s-tres); --kpi-suave: var(--s-tres-suave); }
.kpi-bien { --kpi-color: var(--s-semana); --kpi-suave: var(--s-semana-suave); }
.kpi-violeta { --kpi-color: var(--col-bandeja); --kpi-suave: var(--col-bandeja-suave); }
.kpi-cian { --kpi-color: var(--col-para-revisar); --kpi-suave: var(--col-para-revisar-suave); }
.kpi-rosa { --kpi-color: var(--col-en-espera); --kpi-suave: var(--col-en-espera-suave); }
.kpi-neutro { --kpi-color: var(--col-neutra); --kpi-suave: var(--col-neutra-suave); }

.estado-vacio { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 28px 16px; color: var(--texto-suave); text-align: center; }
.estado-vacio-icono { display: grid; place-items: center; width: 52px; height: 52px; margin-bottom: 6px; border-radius: 50%; background: var(--acento-suave); color: var(--acento); }
.estado-vacio-icono .icono { --icono: 24px; }
.estado-vacio-titulo { margin: 0; color: var(--texto); font-size: 1rem; font-weight: 600; }
.estado-vacio-texto { max-width: 46ch; margin: 0; font-size: 0.88rem; }
.estado-vacio .boton { margin-top: 10px; }

.esqueleto.cargando { display: flex; flex-direction: column; gap: 10px; padding: 4px 0; text-align: left; }
.esqueleto-linea, .esqueleto-bloque {
  display: block;
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--superficie-2) 25%, var(--superficie-3) 45%, var(--superficie-2) 65%);
  background-size: 400% 100%;
  animation: brillo 1.4s ease-in-out infinite;
}
.esqueleto-bloque { height: var(--esqueleto-alto, 120px); border-radius: var(--radio-control); }
.esqueleto-l1 { width: 92%; }
.esqueleto-l2 { width: 76%; }
.esqueleto-l3 { width: 84%; }
.esqueleto-l4 { width: 52%; }
@keyframes brillo { from { background-position: 100% 50%; } to { background-position: 0 50%; } }

/* ─────────────────────────────────────────────── gráficas (ui.donut, anillo, barras, barrasApiladas, chispa) */

/* Los números van en texto de la página (leyenda, totales) o en <text> con el color del texto: nunca en el
   color de la serie. Una serie coloreada por atributo (el color de una materia) no lleva regla aquí: por eso
   los :not([stroke]) / :not([fill]), que dejan ganar al atributo. */
.grafica { display: flex; align-items: center; gap: 18px; min-width: 0; margin: 0; }
.grafica-svg { display: block; width: 100%; height: auto; overflow: visible; }
.grafica-pista { stroke: var(--superficie-3); }
.grafica-fondo { fill: var(--superficie-3); }
.grafica-arco:not([stroke]) { stroke: var(--serie, var(--acento-grafico)); }
.grafica-barra:not([fill]) { fill: var(--serie, var(--acento-grafico)); }
.grafica-texto { fill: currentColor; color: var(--texto); font-family: var(--letra); font-weight: 700; font-variant-numeric: tabular-nums; }
.grafica-centro { font-size: 20px; letter-spacing: -0.02em; }
.grafica-sin-datos { margin: 0; color: var(--texto-suave); font-size: 0.88rem; }
.grafica-pie { margin-top: 6px; color: var(--texto-suave); font-size: 0.84rem; text-align: center; }
.grafica-donut { flex-wrap: wrap; }
.grafica-donut-dibujo { flex: none; width: 148px; }
.grafica-anillo { flex-direction: column; gap: 0; width: 132px; }
.grafica-barras { flex-direction: column; align-items: stretch; gap: 14px; }

.leyenda { display: flex; flex-direction: column; gap: 7px; flex: 1 1 10rem; min-width: 0; max-width: 24rem; margin: 0; padding: 0; list-style: none; font-size: 0.85rem; }
.grafica-barras .leyenda { flex-direction: row; flex-wrap: wrap; gap: 6px 16px; flex: none; }
.leyenda-item { display: flex; align-items: center; gap: 8px; min-width: 0; }
.leyenda-punto { flex: none; width: 10px; height: 10px; border-radius: 3px; background: var(--c, var(--serie, var(--texto-suave))); }
.leyenda-texto { min-width: 0; color: var(--texto); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.leyenda-valor { margin-left: auto; padding-left: 8px; color: var(--texto-suave); font-weight: 600; font-variant-numeric: tabular-nums; }

.barras-filas { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.barras-fila { display: grid; grid-template-columns: minmax(0, 10rem) minmax(0, 1fr) auto; align-items: center; gap: 12px; font-size: 0.85rem; }
.barras-etiqueta { min-width: 0; color: var(--texto); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.barras-pista { display: block; height: 12px; min-width: 0; overflow: hidden; border-radius: var(--radio-pildora); }
.barras-pista .grafica-svg { height: 100%; }
.barras-total { color: var(--texto); font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
/* Cada fila es su propia rejilla, así que la columna del total medía lo que su cifra: «42» o «1,5 h» acortaban su
   carril frente a «1» y el borde derecho salía dentado (crítica visual, 28/09). Con un ancho mínimo común, los
   carriles acaban en la misma x (una cifra más larga que eso, que no sale en estos informes, solo empujaría la suya). */
.barras-total { min-width: 4.5rem; white-space: nowrap; }

.chispa { display: block; width: 100%; height: 28px; overflow: visible; }
.chispa-area { fill: var(--serie, var(--acento-grafico)); fill-opacity: 0.14; }
.chispa-linea { stroke: var(--serie, var(--acento-grafico)); }

/* Las series: la variable --serie la leen los arcos, las barras, la chispa y el punto de la leyenda. */
.serie-0 { --serie: var(--serie-0); }
.serie-1 { --serie: var(--serie-1); }
.serie-2 { --serie: var(--serie-2); }
.serie-3 { --serie: var(--serie-3); }
.serie-4 { --serie: var(--serie-4); }
.serie-5 { --serie: var(--serie-5); }
.serie-6 { --serie: var(--serie-6); }
.serie-7 { --serie: var(--serie-7); }
.serie-acento { --serie: var(--acento-grafico); }
.serie-peligro { --serie: var(--s-vencido); }
.serie-hoy { --serie: var(--s-hoy); }
.serie-aviso { --serie: var(--s-tres); }
.serie-bien { --serie: var(--grafico-bien); }
.serie-violeta { --serie: var(--col-bandeja); }
.serie-cian { --serie: var(--col-para-revisar); }
.serie-rosa { --serie: var(--col-en-espera); }
.serie-neutro { --serie: var(--col-neutra); }
/* «Sin expediente» en el anillo de «Por materia» (inicio.js): el gris claro de los bordes, para no pegarse al gris de
   «Otras» (crítica visual, 28/09: salían del mismo color y juntos no se distinguían). */
.serie-sin { --serie: var(--borde-fuerte); }
.serie-bandeja { --serie: var(--col-bandeja); }
.serie-por-hacer { --serie: var(--col-por-hacer); }
.serie-en-curso { --serie: var(--col-en-curso); }
.serie-en-espera { --serie: var(--col-en-espera); }
.serie-para-revisar { --serie: var(--col-para-revisar); }
.serie-hecho { --serie: var(--col-hecho); }

/* ─────────────────────────────────────────────── carril de iconos (721-1023 px) */

@media (min-width: 721px) and (max-width: 1023px) {
  body.dentro { padding-left: var(--ancho-carril); }
  .cabecera { width: var(--ancho-carril); align-items: center; padding: 12px 8px; gap: 8px; }
  .cabecera-marca { align-items: center; padding: 0 0 10px; }
  .marca-texto, .despacho, .chapa-contrato, .chapa-demo {
    position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .boton-buscar.boton-icono { justify-content: center; width: 44px; height: 40px; padding: 0; }
  .novedades-chip { display: none; }
  .buscador-texto, .buscador-atajo { display: none; }
  .pestanas { align-items: center; margin: 0; padding: 3px; }
  .pestanas-pie { align-items: center; align-self: stretch; }
  .pestana { position: relative; justify-content: center; width: 44px; min-height: 40px; padding: 0; }
  .pestana .icono { --icono: 20px; }
  .pestana-nombre {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .pestana-cuenta { position: absolute; top: 2px; right: 1px; min-width: 16px; height: 16px; padding: 0 4px; font-size: 0.62rem; line-height: 16px; box-shadow: 0 0 0 2px var(--lateral); }
  .cabecera-acciones { flex-direction: column; gap: 8px; padding: 10px 0 0; }
  .cuenta-resumen { display: none; }
  .desplegable-cabecera { left: calc(100% + 16px); }
  .vista { padding: 22px 22px 40px; }
}

/* ─────────────────────────────────────────────── la lateral plegada (≥ 1024 px, app.js: body.lateral-plegada)

   El mismo carril de iconos de arriba, puesto a mano con el botón de la lateral o solo en el tablero y la agenda por
   debajo de 1440 px (app.js lo decide). Son las MISMAS reglas que el carril de 721-1023 px con el prefijo de la
   clase: si se cambia una, se cambia la otra (prueba_base.mjs mide las dos: anchos, nombres escondidos, que cabe). */
@media (max-width: 1023px) {
  .boton-plegar.boton-icono { display: none; }
}
@media (min-width: 1024px) {
  body.dentro.lateral-plegada { padding-left: var(--ancho-carril); }
  .lateral-plegada .cabecera { width: var(--ancho-carril); align-items: center; padding: 12px 8px; gap: 8px; }
  .lateral-plegada .cabecera-marca { align-items: center; gap: 6px; padding: 0 0 10px; }
  .lateral-plegada .marca-texto, .lateral-plegada .despacho, .lateral-plegada .chapa-contrato, .lateral-plegada .chapa-demo {
    position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .lateral-plegada .boton-plegar.boton-icono { position: static; width: 34px; height: 30px; }
  .lateral-plegada .novedades-chip { display: none; }
  .lateral-plegada .boton-buscar.boton-icono { justify-content: center; width: 44px; height: 40px; padding: 0; }
  .lateral-plegada .buscador-texto, .lateral-plegada .buscador-atajo { display: none; }
  .lateral-plegada .pestanas { align-items: center; margin: 0; padding: 3px; }
  .lateral-plegada .pestanas-pie { align-items: center; align-self: stretch; }
  .lateral-plegada .pestana { position: relative; justify-content: center; width: 44px; min-height: 40px; padding: 0; }
  .lateral-plegada .pestana .icono { --icono: 20px; }
  .lateral-plegada .pestana-nombre {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .lateral-plegada .pestana-cuenta { position: absolute; top: 2px; right: 1px; min-width: 16px; height: 16px; padding: 0 4px; font-size: 0.62rem; line-height: 16px; box-shadow: 0 0 0 2px var(--lateral); }
  .lateral-plegada .cabecera-acciones { flex-direction: column; gap: 8px; padding: 10px 0 0; }
  .lateral-plegada .cuenta-resumen { display: none; }
  .lateral-plegada .desplegable-cabecera { left: calc(100% + 16px); }
}
/* Plegada, la lateral lleva debajo del monograma el botón de desplegarla (el carril de 721-1023 no): en una ventana
   baja (un portátil de 1280×700) eso dejaba la navegación 35 px corta, con la papelera fuera. Medido el 28/09. */
@media (min-width: 1024px) and (max-height: 760px) {
  .lateral-plegada .cabecera { gap: 6px; }
  .lateral-plegada .pestana { min-height: 36px; }
}

/* ─────────────────────────────────────────────── móvil (§4.1: ≤ 720 px) */

@media (max-width: 720px) {
  body { font-size: 15px; }
  body.dentro { padding-left: 0; }
  /* iOS agranda la página al enfocar un campo con la letra por debajo de 16 px. */
  input, select, textarea { font-size: 16px; }
  .cabecera {
    position: sticky;
    top: 0;
    bottom: auto;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    width: auto;
    height: var(--alto-cabecera);
    padding: 0 8px 0 12px;
    border-right: 0;
    border-bottom: 1px solid var(--borde);
    background: var(--cristal);
    backdrop-filter: saturate(1.6) blur(14px);
  }
  .cabecera-marca { flex-direction: row; align-items: center; padding: 0; border-bottom: 0; }
  .marca-logo { width: 30px; height: 30px; border-radius: 9px; }
  .marca-logo::before { font-size: 16px; }
  /* En dos renglones, como en la lateral: «LEGAJO by SAYKIN Consulting» en uno solo mide 200 px y a 320 empujaba
     la campana y el menú fuera de la pantalla (medido el 28/09: 20 px de desplazamiento horizontal). */
  .marca-casa { font-size: 0.64rem; }
  .marca-nombre { font-size: 1.02rem; }
  .despacho, .chapa-contrato, .chapa-demo, .pestanas, .boton-buscar.boton-icono, .avatar, .cuenta-resumen { display: none; }
  .cabecera-acciones { margin-left: auto; padding: 0; border-top: 0; gap: 4px; }
  .boton-menu { display: inline-flex; }
  .contador { box-shadow: none; }
  .vista { padding: 16px 12px calc(var(--alto-barra) + 28px); }
  body.fuera .vista { padding-bottom: 24px; }
  .franja-muestra { top: var(--alto-cabecera); font-size: 0.72rem; line-height: 1.3; padding: 5px 10px; gap: 6px; }
  .franja-icono { --icono: 15px; }

  .barra-movil {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 45;
    display: grid;
    /* Una columna igual por cada acceso A LA VISTA (antes, cuatro fijas): al soporte «Mis tareas» no se le pinta
       (app.js, puedeAbrir) y sus tres accesos ocupan la barra entera, sin un hueco a la derecha. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    min-height: var(--alto-barra);
    padding: 4px 6px env(safe-area-inset-bottom);
    background: var(--cristal);
    backdrop-filter: saturate(1.6) blur(14px);
    border-top: 1px solid var(--borde);
  }
  .barra-movil[hidden] { display: none !important; }
  .barra-boton {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    padding: 6px 2px;
    border: 0;
    border-radius: var(--radio-control);
    background: transparent;
    color: var(--texto-suave);
    font: inherit;
    font-size: 0.7rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
  }
  .barra-boton .icono { --icono: 22px; padding: 3px 12px; box-sizing: content-box; border-radius: var(--radio-pildora); transition: background var(--t-rapido) var(--curva); }
  .barra-boton span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .barra-boton[aria-current="page"] { color: var(--acento); font-weight: 700; }
  .barra-boton[aria-current="page"] .icono { background: var(--acento-suave); }

  .desplegable-cabecera { position: fixed; top: calc(var(--alto-cabecera) + 4px); bottom: auto; right: 8px; left: 8px; width: auto; }
  /* A 16 px del borde, como el resto de la pantalla (a 8 se pegaban; crítica visual, 28/09). */
  .avisos { right: 16px; left: 16px; bottom: calc(var(--alto-barra) + 10px); width: auto; }
  /* Con el menú ☰ (o la cuenta, o la campana) abierto, los avisos pasan por debajo: el menú es lo que se está usando. */
  body:has(.desplegable-cabecera) .avisos { z-index: 30; }

  .panel-lateral { width: 100vw; border-left: 0; }
  .panel-volver { display: inline-flex; }
  .panel-velo { display: none; }
  .panel-cuerpo { padding: 16px; }

  .tablero-filtros > *, .barra-filtros > * { max-width: none; flex-basis: 45%; }

  .dialogo { padding: 18px; }
  .dialogo-pie .boton { flex: 1 1 auto; }
  .lista-fechas-fila { grid-template-columns: minmax(0, 1fr) auto; }
  .lista-fechas-etiqueta { grid-column: 1 / -1; grid-row: 2; }
  /* Las tablas se deslizan dentro de su caja (.tabla-desliza) con un ancho mínimo, en vez de apretar cada columna
     hasta una palabra por renglón. Las que en el móvil son TARJETAS (Expedientes, Clientes: expedientes.css) no. */
  .tabla-desliza > .tabla:not(.tabla-expedientes):not(.tabla-clientes) { min-width: 34rem; }
  .tabla-desliza > .tabla:not(.tabla-expedientes):not(.tabla-clientes) th,
  .tabla-desliza > .tabla:not(.tabla-expedientes):not(.tabla-clientes) td { white-space: nowrap; }
  .barras-fila { grid-template-columns: minmax(0, 7rem) minmax(0, 1fr) auto; gap: 8px; }
  .kpi-valor { font-size: 1.55rem; }
  .vista-titulo-icono, .agenda-sello, .plazos-sello, .baldosa-icono, .ajustes-insignia { width: 38px; height: 38px; border-radius: 10px; }
  :is(.vista-titulo-icono, .agenda-sello, .plazos-sello, .baldosa-icono, .ajustes-insignia) .icono { --icono: 20px; }
}

/* ─────────────────────────────────────────────── impresión (§4.2: la semana de la agenda en una hoja apaisada) */

@page { size: A4 landscape; margin: 10mm; }

@media print {
  :root { color-scheme: light; }
  /* min-height: 100vh en papel es «una hoja entera» más los márgenes: sacaba una segunda hoja en blanco. */
  body { background: #ffffff; color: #000000; font-size: 9pt; min-height: 0; }
  /* En papel no hay barra lateral: el cuerpo no se aparta. */
  body.dentro { padding-left: 0; }
  .vista { min-height: 0; }
  h1, h2 { font-size: 11pt; }
  /* La barra de la agenda sí: lleva el título de la semana; sus botones y desplegables no. */
  .cabecera, .franja-muestra, .barra-movil, .avisos, .panel-lateral, .panel-velo, .agenda-filtros,
  .agenda-nav, .agenda-modos, .agenda-nueva, .boton, button, .tablero-filtros, .dialogo { display: none !important; }
  .vista { max-width: none; padding: 0; }
  .chapa { border: 1px solid #999999; background: #ffffff; color: #000000; box-shadow: none; }
  .chapa-materia::before { display: none; }
  .semaforo { background: #ffffff; padding: 0; }
  a { color: #000000; text-decoration: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* Novedades en el móvil: la chapa no cabe en la barra de arriba; va en el ☰ y en el menú de la cuenta. */
@media (max-width: 720px) {
  .novedades-chip { display: none; }
}

/* ─────────────────────────────────────────────── modo básico / completo (29/09, app.js: body.modo-basico)
   Lo marcado .solo-completo no se ve en Básico (con !important: gana a cualquier display de su vista, como [hidden]).
   El selector va arriba a la derecha, fijo; la vista baja 24 px para que no pise el botón de su cabecera. Con un
   panel lateral abierto y fuera (la entrada) no se ve; en el móvil no cabe y el cambio está en el ☰. */
body.modo-basico .solo-completo { display: none !important; }
.modo-selector {
  position: fixed;
  top: 12px;
  right: 22px;
  z-index: 30;
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-pildora);
  background: var(--superficie);
  box-shadow: var(--sombra-suave);
}
.modo-selector[hidden], body.fuera .modo-selector, body.con-panel .modo-selector { display: none; }
.modo-selector button {
  min-height: 28px;
  padding: 3px 12px;
  border: 0;
  border-radius: var(--radio-pildora);
  background: transparent;
  color: var(--texto-suave);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 650;
  cursor: pointer;
}
.modo-selector button:hover { color: var(--texto); }
.modo-selector button[aria-pressed="true"] { background: var(--acento); color: var(--acento-texto); }
/* La franja de muestra está en el flujo (sticky): la vista ya empieza debajo de ella, y el selector se coloca a 12 px
   bajo la franja (app.js, colocaModo): con 52 px arriba, el selector (34 px) cabe sin pisar la cabecera de la vista. */
@media (min-width: 721px) {
  body.dentro .vista { padding-top: 52px; }
}
@media (max-width: 720px) {
  .modo-selector { display: none; }
}
@media print {
  .modo-selector { display: none !important; }
}

/* ── el movimiento (02/10, apple-design) ──────────────────────────────────────────────────────────────────────────────
   Respuesta al pulsar: el botón se hunde al bajar el dedo o el ratón, no al soltar (Apple: «respond on pointer-down»).
   100 ms de ida; la vuelta es la transición normal del botón. */
.boton:not(:disabled):active, .elige-opcion:not(:disabled):active, .menu-tarjeta button:active,
.barra-boton:active, .modo-selector button:active, .ficha-cabeza-plazo:active {
  transform: scale(0.97);
  transition: transform 100ms ease-out;
}
/* La copia que hace el viaje de vuelta al cerrar una lista o una ventana (ui.recoge): no se toca ni se lee. */
.fantasma { pointer-events: none !important; }
/* Quien pide menos transparencia: el velo y las barras con cristal, macizos. */
@media (prefers-reduced-transparency: reduce) {
  .dialogo::backdrop { backdrop-filter: none; }
  .cabecera, .barra-movil { backdrop-filter: none !important; background: var(--superficie) !important; }
}
/* Quien pide más contraste: los bordes de tarjetas, listas y ventanas, con el borde fuerte. */
@media (prefers-contrast: more) {
  .tarjeta, .elige-caja, .menu-tarjeta, .dialogo, .panel-lateral { border-color: var(--borde-fuerte); }
}
.escenario-fantasmas { position: fixed; inset: 0; z-index: 90; pointer-events: none; }
