/* Sistema de Gestión CEHOSAM — hoja de estilo única.
   La paleta de series (--serie-1..8) es la misma que usa graficos.js: si se
   cambia aquí, hay que cambiarla allá. */

:root {
  color-scheme: light;

  /* Superficies e tinta */
  /* El plano y la tarjeta se separan por luminosidad, no por sombra: entre
     #f9f9f7 y #fcfcfb había 0,009 de L en OKLCH —invisible— y la tarjeta se
     confundía con la página. Ahora son 0,046. Se hundió el plano en vez de
     aclarar la tarjeta para no gastar el contraste que le queda a la tinta. */
  --plano:        #ededea;   /* el fondo de la página */
  --superficie:   #fcfcfb;   /* tarjetas y fichas, por encima del plano */
  --superficie-2: #ffffff;   /* campos y botones: la capa que se pulsa */
  --cabecera-tabla: #fbfbf9;
  --realce:       #fafaf7;   /* fila de tabla bajo el ratón */
  --realce-2:     #f4f4f1;   /* botón bajo el ratón, distintivo de estado */
  --gris-suave:   #eeeeea;   /* pastilla gris, contador de pestaña */
  --bloque-suave: #f5f5f2;   /* el recuadro de «qué es» sobre un gráfico */
  --tinta:        #0b0b0b;
  --tinta-2:      #52514e;
  --tenue:        #898781;
  --rejilla:      #e1e0d9;
  --linea-base:   #c3c2b7;
  --borde:        rgba(11, 11, 11, 0.10);
  /* Texto que va encima de un fondo de acento (azul lleno): no es --tinta. */
  --sobre-acento: #ffffff;
  /* El azul RELLENO que lleva texto blanco encima (botón principal, avatar).
     Va aparte de --azul-450 porque tiene que cumplir dos cosas a la vez: que
     el blanco se lea sobre él y que él se distinga del fondo. Los acentos que
     no llevan texto encima —el borde de una ficha, la barra de avance— no
     tienen esa atadura y siguen con --azul-450. */
  /* #2a78d6 dejaba el blanco en 4,42:1, por debajo del 4,5:1 que pide
     texto normal. Dos puntos más abajo y se lee: 4,81:1. */
  --acento-solido: #2872cc;

  /* Azul institucional (rampa secuencial) */
  --azul-100: #cde2fb;
  --azul-250: #86b6ef;
  --azul-450: #2a78d6;
  --azul-550: #1c5cab;
  --azul-650: #104281;
  --azul-700: #0d366b;

  /* Estados */
  --bien:     #0ca30c;
  --aviso:    #fab219;
  --serio:    #ec835a;
  --critico:  #d03b3b;
  --prioridad-alta: #c2571f;
  /* Fondo tenue para marcar un bloque entero sin gritar. */
  --critico-suave: #fdf0ee;
  --fondo-alerta:  #fdf3f3;
  --borde-alerta:  #e7c3c3;
  /* Pistas del semáforo: el canal por el que corre la barra de avance. */
  --pista-bajo:  #f6dfdf;
  --pista-medio: #fbeed2;
  --pista-alto:  #dcefdc;

  /* Menú lateral. Va aparte de la rampa azul porque en oscuro deja de ser
     azul: el azul se reserva para el acento y el lateral se hunde en gris. */
  --lateral-fondo:   #0d366b;
  --lateral-tinta:   #dbe7f6;
  --lateral-tinta-2: #b9d0ec;   /* sub-oficinas, un nivel más abajo */
  --lateral-fuerte:  #ffffff;
  --lateral-sub:     #9dbde4;
  --lateral-rotulo:  #7fa4d4;
  --lateral-linea:   rgba(255, 255, 255, .12);
  --lateral-realce:  rgba(255, 255, 255, .07);
  --lateral-activo:  rgba(255, 255, 255, .13);

  /* Series categóricas (orden fijo, nunca ciclado) */
  --serie-1: #2a78d6;  --serie-2: #eb6834;  --serie-3: #1baf7a;  --serie-4: #eda100;
  --serie-5: #e87ba4;  --serie-6: #008300;  --serie-7: #4a3aa7;  --serie-8: #e34948;

  --radio: 8px;
  --sombra: 0 1px 2px rgba(11, 11, 11, .05), 0 1px 3px rgba(11, 11, 11, .04);
  --sombra-flotante: 0 4px 14px rgba(11, 11, 11, .12);
  --sombra-barrido: rgba(11, 11, 11, .16);
  --sombra-modal: 0 20px 50px rgba(0, 0, 0, .25);
  --sombra-ingreso: 0 18px 40px rgba(0, 0, 0, .28);
  --velo: rgba(11, 11, 11, .42);
  --ingreso-fondo: linear-gradient(160deg, #0d366b, #1c5cab);
  --lateral: 264px;
}

/* ------------------------------------------------------------- Tema oscuro */
/* Aquí NO se escribe ninguna regla: solo se redefinen los tokens de arriba.
   Esa es la única forma de que un tema nuevo no se olvide de una pantalla —
   si un color viviera dentro de una regla, esa pantalla se quedaría en claro.

   El atributo lo pone el servidor con la cookie `tema` (ver base.html), y el
   guion del <head> lo completa cuando la preferencia es «seguir al sistema».
   Por eso basta un bloque y no hace falta duplicarlo dentro de un
   @media (prefers-color-scheme: dark), que habría que mantener a la par.

   El fondo es gris —no negro— a pedido: #1e2024 de plano y #26282d en las
   tarjetas. En oscuro la elevación se dice con una superficie más clara, no
   con sombra: sobre negro una sombra no se ve. */
:root[data-tema="oscuro"] {
  color-scheme: dark;

  /* La misma separación que en claro (0,065 de L): el plano baja y con él
     sube toda la escalera de superficies, para que la tarjeta siga siendo la
     más clara y el campo que se pulsa siga por encima de la tarjeta. Se movió
     el plano y no la tarjeta porque las ocho series y el acento se validaron
     contra la tarjeta: aclararla les come el contraste. */
  --plano:        #191b1f;
  --superficie:   #282b30;
  --superficie-2: #2e3138;
  --cabecera-tabla: #2c2f35;
  --realce:       #30333a;
  --realce-2:     #363941;
  --gris-suave:   #36393f;
  --bloque-suave: #212429;
  /* Blanco roto, no blanco puro: sobre gris oscuro el blanco puro deslumbra
     y engorda la letra. */
  --tinta:        #eceef1;
  --tinta-2:      #b8bcc3;
  --tenue:        #9aa0a8;
  --rejilla:      #3a3e45;
  --linea-base:   #4d525a;
  --borde:        rgba(255, 255, 255, 0.10);
  --sobre-acento: #ffffff;

  /* La rampa azul se invierte de papel: --azul-100 deja de ser un tinte claro
     de fondo para ser un tinte OSCURO de fondo, y --azul-550/--azul-650, que
     en claro son texto oscuro, pasan a ser texto claro. Los sitios que los
     usan (enlaces, pastillas, pista de avance) siguen funcionando igual. */
  --azul-100: #1c3350;
  --azul-250: #7fb4f2;
  --azul-450: #3081de;
  --acento-solido: #2c74cd;   /* blanco encima 4,7:1; contra la tarjeta 3,2:1 */
  --azul-550: #8cbcf5;
  --azul-650: #a9cdf7;
  --azul-700: #0d366b;

  --bien:     #3fc23f;
  --aviso:    #f5bb3c;
  --serio:    #f2946d;
  --critico:  #f5716e;
  --prioridad-alta: #e08a4e;
  --critico-suave: #3a2422;
  --fondo-alerta:  #3a2523;
  --borde-alerta:  #6b3d3a;
  --pista-bajo:  #3d2626;
  --pista-medio: #3d3320;
  --pista-alto:  #233523;

  /* El lateral deja de ser azul institucional y se hunde en gris: con el
     cuerpo en gris oscuro, un panel azul intenso al lado se lee como un
     error de tema. El azul sigue estando, como acento del enlace activo. */
  --lateral-fondo:   #121417;
  --lateral-tinta:   #d5d8dd;
  --lateral-tinta-2: #a9aeb6;
  --lateral-fuerte:  #f2f3f5;
  --lateral-sub:     #969ba3;
  --lateral-rotulo:  #7c828c;
  --lateral-linea:   rgba(255, 255, 255, .08);
  --lateral-realce:  rgba(255, 255, 255, .05);
  --lateral-activo:  rgba(255, 255, 255, .09);

  /* Mismos tonos que en claro (una serie no cambia de identidad al cambiar de
     tema), re-escalados en luminosidad para la banda oscura: las ocho pasan
     las seis comprobaciones de paleta categórica sobre #26282d — banda de
     luminosidad, chroma mínimo, separación para daltonismo (ΔE 9,3 el peor
     par adyacente), separación a vista normal y contraste ≥ 3:1. */
  --serie-1: #418eee;  --serie-2: #e76530;  --serie-3: #0fab76;  --serie-4: #c78600;
  --serie-5: #d66b94;  --serie-6: #2b9927;  --serie-7: #736adc;  --serie-8: #e64c4a;

  --sombra: 0 1px 2px rgba(0, 0, 0, .45), 0 1px 3px rgba(0, 0, 0, .30);
  --sombra-flotante: 0 6px 18px rgba(0, 0, 0, .55);
  --sombra-barrido: rgba(0, 0, 0, .55);
  --sombra-modal: 0 20px 50px rgba(0, 0, 0, .60);
  --sombra-ingreso: 0 18px 40px rgba(0, 0, 0, .60);
  --velo: rgba(0, 0, 0, .62);
  --ingreso-fondo: linear-gradient(160deg, #14161a, #242931);
}

/* El selector de tema de la barra superior. Va con etiqueta, no solo con
   icono: un símbolo suelto no dice qué va a pasar al pulsarlo. */
.selector-tema { min-width: 0; }
.selector-tema .glifo { font-size: 13px; line-height: 1; }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--plano);
  color: var(--tinta);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}

a { color: var(--azul-550); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- Estructura */
.disposicion { display: flex; min-height: 100vh; }

.lateral {
  width: var(--lateral);
  flex: 0 0 var(--lateral);
  background: var(--lateral-fondo);
  color: var(--lateral-tinta);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
/* La marca es un ENLACE al panel general (pulsar el logo de un sistema es lo
   que todo el mundo intenta), así que apaga la decoración del enlace y hereda
   los colores del lateral en vez de los del acento. */
.lateral .marca {
  display: block;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--lateral-linea);
  text-decoration: none;
  color: inherit;
}
.lateral .marca:hover strong { color: var(--lateral-tinta); }
/* El logo se sirve al triple del tamaño en que se ve, para que no salga
   borroso en un teléfono. Manda el ALTO: lo que cambia de un logo a otro es lo
   apaisado que sea, y fijando el ancho se aplastarían los cuadrados. */
.lateral .marca-logo {
  display: block; height: 36px; width: auto;
  max-width: 100%; object-fit: contain;
}
.lateral .marca-logo + strong { margin-top: 8px; }

/* El pie de todas las pantallas. Va dentro del contenido, no fijo abajo: una
   franja pegada al borde le come alto a un teléfono en todas las pantallas, y
   esto es un crédito, no un control. */
.pie-sistema {
  margin-top: 28px; padding-top: 14px;
  border-top: 1px solid var(--linea-base);
  color: var(--tinta-2); font-size: 11.5px; text-align: center;
}
/* En el ingreso el pie va al fondo de la página, FUERA de la caja: dentro
   parecía un renglón más del formulario. Ahí abajo el fondo es el degradado
   azul o una foto —los dos oscuros en los dos temas—, así que el texto va
   claro y con sombra, que es lo único que se lee encima de cualquier imagen.
   Sin raya arriba: separa el borde de la caja, no una línea. */
.pie-portada {
  border: 0; margin: 18px 0 0; padding: 0;
  max-width: 380px; color: rgba(255, 255, 255, .78);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .55);
}
.lateral .marca strong { color: var(--lateral-fuerte); display: block; font-size: 15px; letter-spacing: .2px; }
.lateral .marca span { color: var(--lateral-sub); font-size: 11.5px; text-transform: uppercase; letter-spacing: .8px; }

.lateral nav { padding: 10px 0 20px; }
.lateral .rotulo {
  padding: 14px 20px 6px; font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--lateral-rotulo);
}

/* --- Secciones plegables del menú ----------------------------------------
   El rótulo de cada sección es un BOTÓN, no un div: se puede alcanzar con el
   tabulador y anuncia su estado con `aria-expanded`. Conserva exactamente el
   aspecto del rótulo de antes —mismas medidas, mismo color— y solo añade el
   galón a la derecha; plegar el menú no debía cambiar cómo se ve abierto. */
.lateral button.rotulo {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: left;
  font: inherit; font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--lateral-rotulo);
}
.lateral button.rotulo:hover { color: var(--lateral-sub); }
.lateral button.rotulo .galon {
  margin-left: auto; font-size: 9px; line-height: 1;
  transition: transform .15s ease;
}
/* Cerrado apunta a la derecha, abierto hacia abajo. Un solo glifo girado, no
   dos caracteres distintos: así no salta de ancho al cambiar. */
.lateral button.rotulo[aria-expanded="true"] .galon { transform: rotate(90deg); }
.lateral .seccion[hidden] { display: none; }

/* La rama del árbol de oficinas que tiene hijas. La palanca va aparte del
   enlace —y no dentro— porque el enlace tiene que seguir abriendo la oficina:
   si plegar y entrar fueran el mismo clic, no habría forma de hacer una sin la
   otra. Se posiciona encima del enlace para no tocar la sangría de
   `.arbol-menu ul a.enlace`, de la que dependen los tres niveles. */
.arbol-menu li { position: relative; }
.arbol-menu li.con-hijas > a.enlace { padding-right: 34px; }
.palanca-rama {
  position: absolute; top: 3px; right: 8px;
  width: 22px; height: 22px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 5px; cursor: pointer;
  color: var(--lateral-rotulo); font-size: 9px; line-height: 1;
}
.palanca-rama:hover { background: var(--lateral-realce); color: var(--lateral-fuerte); }
.palanca-rama[aria-expanded="true"] { transform: rotate(90deg); }
.arbol-menu ul[hidden] { display: none; }
/* Estaba escrito a mano en la plantilla. Aquí, como todo lo demás: en las
   plantillas no queda ni un color, ni siquiera como token. */
.lateral .sin-oficinas {
  padding: 6px 20px; font-size: 12px; color: var(--lateral-rotulo);
}
.lateral a.enlace {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 20px; color: var(--lateral-tinta); font-size: 13.5px;
}
.lateral a.enlace:hover { background: var(--lateral-realce); text-decoration: none; }
.lateral a.enlace.activo { background: var(--lateral-activo); color: var(--lateral-fuerte); box-shadow: inset 3px 0 0 var(--azul-250); }
.lateral .icono { width: 18px; text-align: center; opacity: .9; }

.arbol-menu { list-style: none; margin: 0; padding: 0; }
.arbol-menu ul { list-style: none; margin: 0; padding: 0; }
.arbol-menu ul a.enlace { padding-left: 40px; font-size: 12.5px; color: var(--lateral-tinta-2); }
.arbol-menu ul ul a.enlace { padding-left: 56px; }

.disposicion > .principal { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.barra-superior {
  background: var(--superficie);
  border-bottom: 1px solid var(--rejilla);
  padding: 12px 28px;
  display: flex; align-items: center; gap: 16px;
  position: sticky; top: 0; z-index: 20;
}
.barra-superior h1 { font-size: 17px; margin: 0; font-weight: 600; }
.barra-superior .migas { color: var(--tenue); font-size: 12px; margin-top: 2px; }
.barra-superior .migas a { color: var(--tinta-2); }
.espaciador { flex: 1; }

.usuario-chip {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; color: var(--tinta-2);
}
.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--acento-solido); color: var(--sobre-acento);
  display: grid; place-items: center; font-size: 12px; font-weight: 600;
}

.contenido { padding: 22px 28px 48px; }
/* El marco de la vista previa del fondo es apaisado, como una pantalla. */
.imagen-firma .marco.marco-fondo { width: 220px; height: 124px; }
.imagen-firma .marco.marco-logo { width: 220px; height: 80px; }
.imagen-firma .marco.marco-fondo img { width: 100%; height: 100%; object-fit: cover; }
/* El logo de la marca se previsualiza sobre el fondo del MENÚ, no sobre el
   damero: ahí es donde va a vivir, y un logo de letra oscura desaparece sobre
   el azul sin que nadie se entere hasta verlo puesto. */
.imagen-firma .marco.marco-menu {
  width: 220px; height: 80px;
  background-color: var(--lateral-fondo); background-image: none;
}

/* ---------------------------------------------------------------- Tarjetas */
.tarjeta {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  margin-bottom: 18px;
}
.tarjeta > header {
  padding: 13px 18px;
  border-bottom: 1px solid var(--rejilla);
  display: flex; align-items: center; gap: 12px;
}
.tarjeta > header h2 { margin: 0; font-size: 14px; font-weight: 600; }
.tarjeta > header .sub { color: var(--tenue); font-size: 12px; }
.tarjeta .cuerpo { padding: 16px 18px; }
.tarjeta .cuerpo.sin-relleno { padding: 0; }

.rejilla { display: grid; gap: 16px; }
/* col-1 existe porque el número de fichas del resumen depende de los módulos
   encendidos en la oficina: puede quedar una sola. */
.col-1 { grid-template-columns: minmax(0, 1fr); }
.col-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.col-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.col-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.col-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1100px) { .col-3, .col-4, .col-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 720px)  { .rejilla { grid-template-columns: minmax(0, 1fr); } }

/* Fichas de indicador (stat tiles) */
.ficha {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  padding: 15px 17px;
  box-shadow: var(--sombra);
}
.ficha .rotulo { color: var(--tinta-2); font-size: 12.5px; margin-bottom: 6px; }
/* Rótulo a la izquierda y descarga a la derecha, en la misma línea. Con
   `align-items: start` el botón no se estira a lo alto del rótulo cuando este
   ocupa dos renglones. */
.ficha .linea-rotulo { display: flex; align-items: start; gap: 10px; }
.ficha .linea-rotulo .rotulo { flex: 1; }
.ficha .excel-ficha { padding: 2px 7px; font-size: 11px; line-height: 1.5; }
.ficha .valor { font-size: 27px; font-weight: 600; letter-spacing: -.4px; line-height: 1.15; }
.ficha .pie { color: var(--tenue); font-size: 11.5px; margin-top: 5px; }
.ficha.acento { border-left: 3px solid var(--azul-450); }
.ficha.alerta { border-left: 3px solid var(--critico); }
.ficha.atencion { border-left: 3px solid var(--aviso); }
.ficha.ok { border-left: 3px solid var(--bien); }

/* «Qué es»: la línea que impide que la cifra se lea al revés. Va siempre
   visible, no detrás de un ratón que en una tablet no existe. */
.ficha .que-es {
  color: var(--tinta-2); font-size: 11.5px; line-height: 1.35;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--rejilla);
}
/* Una ficha que lleva a su desglose. La cifra es el enlace; el borde y la
   sombra al pasar por encima dicen que la tarjeta entera es un destino. */
.ficha.enlazable:hover { border-color: var(--azul-450); box-shadow: var(--sombra-flotante); }
.ficha .valor a { color: inherit; text-decoration: none; }
.ficha.enlazable:hover .valor a { color: var(--azul-550); }
/* No se llama «ficha-accion»: una clase que empieza por «ficha» se cuela en
   cualquier búsqueda de fichas — le pasó a prueba_sistema.py, que contaba
   siete fichas donde había cinco. */
.ficha .accion { margin-top: 7px; font-size: 12px; }
.ficha .accion a { font-weight: 500; }

/* Una ficha cuya cifra sale de otras: al pasar por encima cuenta de dónde
   salió, con el MISMO globo que los gráficos (`.sugerencia-grafico`) y no con
   el del navegador, que no se puede vestir. El cursor de ayuda es el que avisa
   en `.termino`; sin él, una explicación detrás del ratón no la encuentra
   nadie. */
.ficha.con-detalle { cursor: help; }
.ficha.con-detalle:hover { border-color: var(--linea-base); }

/* Un periodo sin capturar no es un cero: se dice con palabras. */
.ficha .valor .sin-dato {
  font-size: 15px; font-weight: 400; color: var(--tenue); letter-spacing: 0;
}

/* Término del glosario: el punteado avisa de que hay una explicación. */
.termino { border-bottom: 1px dotted var(--linea-base); cursor: help; }

/* Quién factura: el nombre a la izquierda y cuántas facturas a la derecha, en
   columnas para poder comparar de un vistazo entre aseguradoras. */
.facturador {
  display: flex; gap: 10px; align-items: baseline;
  line-height: 1.5;
}
.facturador > :first-child { flex: 1; }
.facturador > :last-child { font-variant-numeric: tabular-nums; }

/* Nombres que no caben: ADRES se llama «Administradora de los Recursos del
   Sistema General de Seguridad Social en Salud», 79 caracteres que estiran la
   columna y aplastan a las demás. Se acota y el nombre completo va en el
   `title` — no se recorta con puntos suspensivos, que esconden información. */
td.nombre-largo { max-width: 26ch; }

/* Explicación de un bloque entero, encima del gráfico: dice qué se está
   mirando antes de que la persona intente deducirlo del dibujo. */
.que-es-bloque {
  background: var(--bloque-suave); border-left: 2px solid var(--linea-base);
  border-radius: 0 4px 4px 0;
  padding: 9px 12px; margin: 4px 0 14px;
  color: var(--tinta-2); font-size: 12.5px; line-height: 1.5; max-width: 92ch;
}

/* Paginación. Los botones de los extremos no se ocultan al llegar al primero
   o al último: se atenúan. Que un control desaparezca mueve los de al lado y
   se acaba pulsando otro sin querer. */
.paginacion {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 18px; border-top: 1px solid var(--rejilla);
}
.boton.apagado {
  opacity: .4; pointer-events: none;
}

/* Cómo se lee un gráfico. Va debajo del dibujo, no en la leyenda: explica la
   convención (qué es una columna, qué significa un hueco), no los datos. */
.pie-grafico {
  color: var(--tenue); font-size: 11.5px; line-height: 1.5;
  margin-top: 10px; max-width: 78ch;
}

/* ------------------------------------------------- Procedencia de una cifra */
/* Sin esto nadie distingue un dato traído de la base de uno escrito a mano, y
   esa diferencia decide si la cifra se puede reportar. */
.procedencia {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--rejilla);
  color: var(--tenue); font-size: 11px; line-height: 1.4;
}
.procedencia .icono { font-size: 11px; flex: none; }
.procedencia .cuando { font-variant-numeric: tabular-nums; }
.tarjeta .cuerpo > .procedencia:first-child,
.tarjeta > .procedencia {
  margin: 0; padding: 9px 18px; border-top: 1px solid var(--rejilla);
}
.proc-vivo .icono { color: var(--bien); }
.proc-sql .icono { color: var(--azul-450); }
.proc-manual .icono { color: var(--serio); }
.proc-propio .icono { color: var(--tenue); }
/* El dato de ejemplo se marca fuerte a propósito: mientras esté en pantalla
   alguien puede reportarlo como si fuera real. */
.proc-demo {
  color: var(--critico); font-weight: 500;
  background: var(--critico-suave);
  margin-left: -17px; margin-right: -17px; padding: 7px 17px 0;
}

.heroe { font-size: 48px; font-weight: 600; letter-spacing: -1.4px; line-height: 1.05; }

/* ---------------------------------------------------------------- Tablas */
table.datos { width: 100%; border-collapse: collapse; font-size: 13px; }
table.datos th {
  text-align: left; font-weight: 600; color: var(--tinta-2);
  padding: 9px 12px; border-bottom: 1px solid var(--rejilla);
  background: var(--cabecera-tabla); font-size: 12px; white-space: nowrap;
}
table.datos td { padding: 9px 12px; border-bottom: 1px solid var(--rejilla); vertical-align: top; }
table.datos tr:last-child td { border-bottom: 0; }
table.datos tbody tr:hover { background: var(--realce); }
table.datos td.num, table.datos th.num { text-align: right; font-variant-numeric: tabular-nums; }
/* La columna del mes elegido en el filtro. Se tiñe, no se aísla: la gracia de
   verla es poder compararla con los otros once meses, que siguen ahí. */
table.datos th.mes-elegido, table.datos td.mes-elegido { background: var(--azul-100); }
table.datos tbody tr:hover td.mes-elegido { background: var(--azul-100); }
.envoltorio-tabla { overflow-x: auto; }
/* Un bloque vacío tiene que enseñar: qué falta, por qué, y qué hacer. Un
   «sin datos» a secas deja a la persona sin saber si el sistema falló o si
   todavía nadie ha cargado nada. */
.vacio { padding: 26px 18px; text-align: center; color: var(--tenue); font-size: 13px; }
.vacio .vacio-titulo { color: var(--tinta-2); font-size: 13.5px; font-weight: 500; }
.vacio .vacio-razon {
  margin: 6px auto 0; max-width: 52ch; font-size: 12.5px; line-height: 1.5;
}
.vacio .vacio-accion { margin-top: 12px; }

/* ---------------------------------------------------------------- Distintivos */
.marca-estado {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11.5px; font-weight: 500; white-space: nowrap;
  border: 1px solid var(--borde); background: var(--realce-2); color: var(--tinta-2);
}
.marca-estado::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--tenue); flex: none;
}
.e-PENDIENTE::before, .e-PLANEADO::before, .e-SOLICITADA::before { background: var(--azul-450); }
.e-EN_PROCESO::before, .e-EN_EJECUCION::before, .e-EN_ESTUDIO::before { background: var(--aviso); }
.e-EN_ESPERA::before, .e-SUSPENDIDO::before, .e-RECIBIDA::before { background: var(--serio); }
.e-FINALIZADA::before, .e-FINALIZADO::before, .e-APROBADA::before,
.e-ADJUDICADA::before, .e-ACTIVO::before { background: var(--bien); }
.e-CANCELADA::before, .e-CANCELADO::before, .e-RECHAZADA::before,
.e-VENCIDA::before { background: var(--critico); }

.prioridad { font-size: 11.5px; font-weight: 600; }
.p-URGENTE { color: var(--critico); }
.p-ALTA { color: var(--prioridad-alta); }
.p-MEDIA { color: var(--tinta-2); }
.p-BAJA { color: var(--tenue); }

.pastilla {
  display: inline-block; padding: 1px 7px; border-radius: 4px;
  background: var(--azul-100); color: var(--azul-650);
  font-size: 11px; font-weight: 500;
}
.pastilla.gris { background: var(--gris-suave); color: var(--tinta-2); }
.aviso-vencido { color: var(--critico); font-weight: 600; }

/* Barra de avance, teñida por el semáforo (punto 13) */
.avance { display: flex; align-items: center; gap: 8px; min-width: 110px; }
.avance .pista {
  flex: 1; height: 6px; border-radius: 3px;
  background: var(--azul-100); overflow: hidden;
}
.avance .relleno { height: 100%; background: var(--azul-450); border-radius: 3px; }
.avance .cifra { font-size: 11.5px; color: var(--tinta-2); font-variant-numeric: tabular-nums; }

.avance.s-bajo  .pista { background: var(--pista-bajo); }
.avance.s-bajo  .relleno { background: var(--critico); }
.avance.s-medio .pista { background: var(--pista-medio); }
.avance.s-medio .relleno { background: var(--aviso); }
.avance.s-alto  .pista { background: var(--pista-alto); }
.avance.s-alto  .relleno { background: var(--bien); }

/* Semáforo de avance, al lado del estado (puntos 13 y 15).
   El punto de color nunca va solo: siempre lo acompaña su etiqueta. */
.estado-semaforo { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.semaforo {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 500; color: var(--tinta-2);
  white-space: nowrap;
}
.semaforo .luz {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  box-shadow: 0 0 0 2px var(--superficie);
}
.semaforo.s-bajo  .luz { background: var(--critico); }
.semaforo.s-medio .luz { background: var(--aviso); }
.semaforo.s-alto  .luz { background: var(--bien); }

/* Contacto (punto 5) */
.contacto { display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: 12px; color: var(--tinta-2); }
.contacto .dato { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.contacto .icono { color: var(--tenue); font-size: 11px; }

/* ---------------------------------------------------------------- Formularios */
label { display: block; font-size: 12px; color: var(--tinta-2); margin-bottom: 4px; font-weight: 500; }
input[type=text], input[type=password], input[type=number], input[type=date],
input[type=email], select, textarea {
  width: 100%; padding: 7px 10px;
  border: 1px solid var(--linea-base); border-radius: 6px;
  background: var(--superficie-2); color: var(--tinta);
  font: inherit; font-size: 13px;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--azul-250); outline-offset: -1px; border-color: var(--azul-450);
}
textarea { min-height: 76px; resize: vertical; }
.campo { margin-bottom: 12px; }
.fila-campos { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.casilla { display: flex; align-items: center; gap: 7px; font-size: 13px; }
.casilla input { width: auto; }
.ayuda { color: var(--tenue); font-size: 11.5px; margin-top: 4px; }

.boton {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 6px; border: 1px solid var(--linea-base);
  background: var(--superficie-2); color: var(--tinta); font: inherit; font-size: 13px;
  font-weight: 500; cursor: pointer;
}
.boton:hover { background: var(--realce-2); text-decoration: none; }
.boton.principal { background: var(--acento-solido); border-color: var(--acento-solido); color: var(--sobre-acento); }
.boton.principal:hover { background: var(--azul-550); }
.boton.peligro { color: var(--critico); border-color: var(--borde-alerta); }
.boton.chico { padding: 4px 9px; font-size: 12px; }

/* ---------------------------------------------------------------- Avisos */
.avisos { margin-bottom: 16px; display: grid; gap: 8px; }
/* Un párrafo, no una fila de cajas. Era `display: flex`, y en flex **cada
   trozo suelto de texto y cada `<strong>` se vuelve un elemento de la fila**:
   en cuanto el aviso se estrecha —un teléfono, o una ventana a media
   pantalla— la frase se parte en columnas y se lee a saltos. Se vio el
   2026-09-17 en «Además hay N atenciones sin ningún cargo registrado», que
   salía en cinco columnitas. Si algún día un aviso necesita un icono al lado,
   se le pone al icono `float` o se envuelve el texto; no se hace flex el
   párrafo entero. */
.aviso-msg {
  padding: 10px 14px; border-radius: 6px; font-size: 13px;
  border: 1px solid var(--borde); background: var(--superficie);
  line-height: 1.45;
}
.aviso-msg.ok { border-left: 3px solid var(--bien); }
.aviso-msg.error { border-left: 3px solid var(--critico); }
.aviso-msg.aviso { border-left: 3px solid var(--aviso); }

/* ---------------------------------------------------------------- Pestañas */
.pestanas { display: flex; gap: 2px; border-bottom: 1px solid var(--rejilla); margin-bottom: 18px; flex-wrap: wrap; }
.pestanas button {
  border: 0; background: none; padding: 9px 15px; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--tinta-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.pestanas button:hover { color: var(--tinta); }
.pestanas button.activa { color: var(--azul-550); border-bottom-color: var(--azul-450); font-weight: 600; }
.pestanas .cuenta {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  border-radius: 999px; background: var(--gris-suave); font-size: 11px; color: var(--tinta-2);
}
.panel-pestana[hidden] { display: none; }

/* ---------------------------------------------------------------- Árbol de oficinas */
.arbol { list-style: none; margin: 0; padding: 0; }
.arbol ul { list-style: none; margin: 0; padding-left: 26px; border-left: 1px solid var(--rejilla); }
.arbol li { margin: 3px 0; }
.nodo {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-radius: 6px;
  border: 1px solid var(--borde); background: var(--superficie);
}
.nodo .nombre { font-weight: 500; }
.nodo .meta { color: var(--tenue); font-size: 11.5px; }
.nodo .acciones { margin-left: auto; display: flex; gap: 6px; }
.nodo.inactiva { opacity: .55; }

/* ---------------------------------------------------------------- Gráficos */
.grafico { width: 100%; }
.grafico svg { display: block; width: 100%; }
.leyenda { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 10px 2px 0; }
.leyenda .item { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--tinta-2); }
.leyenda .muestra { width: 10px; height: 10px; border-radius: 3px; flex: none; }

.sugerencia-grafico {
  position: absolute; z-index: 60; pointer-events: none;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: 6px; padding: 8px 10px; font-size: 12px;
  box-shadow: var(--sombra-flotante);
  min-width: 130px; opacity: 0; transition: opacity .1s;
}
.sugerencia-grafico .titulo { font-weight: 600; margin-bottom: 5px; }
.sugerencia-grafico .linea { display: flex; align-items: center; gap: 7px; margin-top: 2px; }
.sugerencia-grafico .linea .punto { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.sugerencia-grafico .linea .cifra { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
/* El renglón del total, separado como en una cuenta: la raya es lo que dice
   que las líneas de arriba suman esta. */
.sugerencia-grafico .linea.suma {
  border-top: 1px solid var(--rejilla); margin-top: 7px; padding-top: 7px;
}
/* Y lo que NO entra en ese total, en su propio grupo. Si fuera un renglón más
   se leería como un sumando, que es justo lo contrario de lo que es. */
.sugerencia-grafico .linea.aparte {
  border-top: 1px solid var(--rejilla); margin-top: 10px; padding-top: 9px;
  color: var(--tinta-2);
}
.sugerencia-grafico .nota {
  margin-top: 6px; font-size: 11px; line-height: 1.35; color: var(--tenue);
  max-width: 250px;
}

details.tabla-alterna { margin-top: 12px; }
details.tabla-alterna summary {
  cursor: pointer; font-size: 12.5px; color: var(--azul-550); padding: 4px 0;
}

/* ---------------------------------------------------------------- Ingreso */
/* Dos filas: la caja centrada en lo que sobre y el pie abajo del todo. Sin
   pie la segunda fila mide cero y la caja queda centrada igual que siempre. */
.pantalla-ingreso {
  min-height: 100vh; display: grid; grid-template-rows: 1fr auto;
  justify-items: center; align-items: center;
  background: var(--ingreso-fondo);
  padding: 20px;
}
/* Imagen de fondo del ingreso (migración 017). La URL llega de la vista en
   `--imagen-fondo`; el encuadre es de aquí. Reemplaza al degradado azul solo
   cuando hay imagen. Sin velo encima, a pedido: la imagen se ve tal cual y la
   caja de ingreso, que es opaca, se lee igual. */
.pantalla-ingreso.con-fondo {
  background-image: var(--imagen-fondo);
  background-size: cover;
  background-position: center;
}
.caja-ingreso {
  width: 100%; max-width: 380px; background: var(--superficie);
  border-radius: 12px; padding: 30px 28px;
  box-shadow: var(--sombra-ingreso);
}
/* El logo se guarda al doble (480×160) y se muestra a la mitad: nítido en
   pantallas de alta densidad. */
.caja-ingreso .logo-ingreso {
  display: block; margin: 0 auto 14px; max-width: 100%; max-height: 72px;
}
.caja-ingreso h1 { margin: 0 0 4px; font-size: 19px; text-align: center; }
.caja-ingreso .sub { color: var(--tenue); font-size: 12.5px; margin-bottom: 22px; text-align: center; }
/* El eslogan de la portada. Debajo del botón y en letra pequeña: es una frase
   larga —hasta 160 caracteres— y arriba, entre la marca y el formulario,
   empujaba el botón fuera de la pantalla en un teléfono. `text-wrap: balance`
   reparte los renglones en vez de dejar una palabra suelta al final. */
.caja-ingreso .eslogan-ingreso {
  margin: 14px 0 0; color: var(--tenue); font-size: 11.5px;
  line-height: 1.4; text-align: center; text-wrap: balance;
}

/* ---------------------------------------------------------------- Utilidades */
.filtros { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: 16px; }
.filtros .campo { margin: 0; min-width: 150px; }
.oculto { display: none !important; }
.dialogo { border: 1px solid var(--borde); border-radius: var(--radio); padding: 0; width: min(640px, 94vw); box-shadow: var(--sombra-modal); }
.dialogo::backdrop { background: var(--velo); }
.dialogo header { padding: 14px 18px; border-bottom: 1px solid var(--rejilla); font-weight: 600; }
.dialogo .cuerpo { padding: 16px 18px; max-height: 68vh; overflow-y: auto; }
.dialogo footer { padding: 12px 18px; border-top: 1px solid var(--rejilla); display: flex; gap: 8px; justify-content: flex-end; }

/* Qué hacer con el Excel: dos opciones del mismo tamaño, no un botón grande y
   un enlace pequeño. Las dos son destinos legítimos del mismo archivo y
   jerarquizar una empujaría a pulsarla sin leer la otra. */
.excel-que { margin: 0 0 14px; }
/* El nombre del informe, que es también el asunto del correo: se ve tal cual
   antes de mandarlo, no escondido dentro de un campo. */
.excel-que .titulo { font-weight: 600; font-size: 14px; }
.excel-que .desc {
  margin-top: 3px; color: var(--tinta-2); font-size: 12.5px; line-height: 1.4;
}
.opciones-excel { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 560px) { .opciones-excel { grid-template-columns: 1fr; } }
.opciones-excel .opcion {
  display: block; text-align: left; text-decoration: none; cursor: pointer;
  font: inherit; color: var(--tinta);
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); padding: 12px 14px;
}
.opciones-excel .opcion:hover {
  border-color: var(--azul-450); background: var(--realce); text-decoration: none;
}
.opciones-excel .opcion .icono { font-size: 17px; color: var(--acento-solido); }
.opciones-excel .opcion .titulo {
  display: block; font-weight: 600; margin-top: 2px;
}
.opciones-excel .opcion .ayuda {
  display: block; margin-top: 3px; font-size: 11.5px; color: var(--tenue);
  line-height: 1.35;
}
/* Firma de correo: la vista previa muestra el correo entero, no solo el pie.
   Lo que hay que entender de un vistazo es que el «De» es el sistema y que
   quien responda le responde a la persona — sin el encabezado, la firma
   parece un adorno. */
.vista-correo {
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie); overflow: hidden;
}
.cabecera-correo {
  padding: 10px 12px; border-bottom: 1px solid var(--rejilla);
  background: var(--cabecera-tabla); font-size: 12px;
}
.cabecera-correo > div { display: flex; gap: 8px; padding: 1px 0; }
.cabecera-correo span { color: var(--tenue); width: 88px; flex: none; }
.cabecera-correo strong { font-weight: 500; word-break: break-word; }
.cabecera-correo .adjunto { color: var(--acento-solido); }
.cuerpo-correo { padding: 12px; font-size: 12.5px; }
.cuerpo-correo p { margin: 0 0 10px; }
.cuerpo-correo hr { border: 0; border-top: 1px solid var(--rejilla); margin: 10px 0; }
/* La vista previa reproduce la maqueta del correo de verdad: el logo a la
   izquierda con el texto al lado, y la rúbrica debajo. Lo que se promete aquí
   es lo que tiene que llegar. */
.firma-previa .fila { display: flex; gap: 14px; align-items: flex-start; }
.firma-previa .logo { flex: none; max-width: 130px; height: auto; }
.firma-previa .rubrica { display: block; margin-top: 8px; max-width: 160px; height: auto; }
/* El texto se pinta tal cual se escribió: en un correo los saltos de línea
   son la firma. Por eso es un <pre> y no un <p>. */
.firma-previa .texto {
  margin: 0; font: inherit; color: var(--tinta-2);
  white-space: pre-wrap; word-break: break-word; min-height: 1.4em;
}

/* Cada imagen de la firma: el marco a la izquierda y sus datos al lado. El
   marco tiene alto fijo para que la pantalla no salte al subir o quitar una
   — y el fondo a cuadros es lo que deja ver si el logo tiene transparencia,
   que es lo que decide si se verá bien sobre el fondo del correo. */
.imagen-firma {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 12px 0; border-top: 1px solid var(--rejilla);
}
.imagen-firma .marco {
  flex: none; width: 140px; height: 76px; display: flex;
  align-items: center; justify-content: center; overflow: hidden;
  border: 1px solid var(--rejilla); border-radius: var(--radio);
  background-color: var(--superficie-2);
  background-image:
    linear-gradient(45deg, var(--rejilla) 25%, transparent 25%),
    linear-gradient(-45deg, var(--rejilla) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--rejilla) 75%),
    linear-gradient(-45deg, transparent 75%, var(--rejilla) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}
.imagen-firma .marco img { max-width: 100%; max-height: 100%; }
.imagen-firma .marco .sin-imagen { font-size: 11px; color: var(--tenue); }
.imagen-firma .datos { flex: 1; min-width: 0; }
.imagen-firma .datos .ayuda { margin-top: 2px; }
.subida-firma { display: flex; gap: 6px; align-items: center; }
.subida-firma input[type=file] { font-size: 11.5px; max-width: 190px; }
.acciones-firma { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Qué se enseña como marca: tres opciones que se ven todas a la vez, no un
   desplegable. Con tres valores un desplegable esconde dos de ellos y obliga a
   abrirlo para saber qué hay.

   La pastilla entera es el `label`, así que el blanco de pulsación es todo el
   recuadro y no el círculo de 13 px del radio — que es lo que se falla con el
   dedo. El radio se deja a la vista, no se esconde con `appearance: none`: es
   lo que dice cuál está elegido cuando el color no basta (impresión, visión
   de color reducida). */
.formulario-marca .campo { max-width: 460px; margin-bottom: 14px; }
.grupo-modo {
  border: 1px solid var(--rejilla); border-radius: var(--radio);
  padding: 12px 14px; margin: 0 0 14px; min-width: 0;
}
.grupo-modo legend { font-size: 12.5px; font-weight: 600; padding: 0 6px; }
.grupo-modo .fila-casillas { margin-top: 10px; }
.opcion-modo {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; border: 1px solid var(--borde); border-radius: 999px;
  background: var(--superficie-2); cursor: pointer; font-size: 13px;
}
.opcion-modo:hover { border-color: var(--acento-solido); }
.opcion-modo:has(input:checked) {
  border-color: var(--acento-solido);
  background: var(--azul-100);
  font-weight: 600;
}
/* Sin imagen subida no hay nada que enseñar: la opción se deja a la vista,
   apagada y explicada debajo, en vez de desaparecer — una opción que no está
   no se puede preguntar por qué no está. */
.opcion-modo.apagada { opacity: .55; cursor: not-allowed; }
.opcion-modo input { margin: 0; }
/* Pasarse del tope se avisa mientras se escribe, pero no se recorta: quien
   escribió doce renglones tiene que saber que sobran cuatro. */
.ayuda.pasado { color: var(--critico); font-weight: 600; }

/* Lo que todavía no funciona se dice, no se disimula: es la misma regla del
   pie de procedencia en rojo de los datos de ejemplo. */
.aviso-pendiente {
  margin: 16px 0 14px; padding: 10px 12px; font-size: 12px; line-height: 1.45;
  background: var(--fondo-alerta); border: 1px solid var(--borde-alerta);
  border-radius: var(--radio); color: var(--tinta-2);
}
/* El mismo bloque sirve para decir que algo salió bien: cambia el color, no
   el sitio — quien acaba de pulsar mira ahí, salga como salga. */
.aviso-pendiente.bien {
  background: var(--fondo-bien, var(--realce)); border-color: var(--bien);
}
.tenue { color: var(--tenue); }
.chico { font-size: 12px; }
.derecha { text-align: right; }
.centro { text-align: center; }
.nowrap { white-space: nowrap; }

/* Hallazgos de la validación de cuentas: se apilan varios por fila, así que
   van compactos y sin margen lateral. */
.pastilla.alerta-hallazgo {
  display: block; margin: 2px 0; background: var(--fondo-alerta); color: var(--critico);
  border: 1px solid var(--borde-alerta); font-size: 11px;
}

/* ------------------------------------- Módulos por oficina y baja (fase 4) */
.grupo-modulos {
  border: 1px solid var(--borde); border-radius: var(--radio);
  padding: 14px 16px; margin: 18px 0;
}
.grupo-modulos legend { padding: 0 6px; font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--tinta-2); }
.fila-casillas { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.fila-casillas .campo { margin: 0; }

/* La zona de baja se distingue del resto: quien llega aquí debe notar que no
   es un formulario más. */
.peligro-zona { border-color: var(--borde-alerta); }
.peligro-zona > header h2 { color: var(--critico); }

/* ------------------------------------------- Apariencia personal (colores)
   El selector de color nativo es un cuadro pequeño y sin borde propio: se le
   pone el mismo marco que a los demás campos para que se lea como un campo y
   no como un adorno. */
.fila-color {
  display: grid; grid-template-columns: 44px 1fr 118px; gap: 12px;
  align-items: start; padding: 12px 0; border-top: 1px solid var(--borde);
}
.fila-color:first-of-type { border-top: 0; }
.fila-color input[type="color"] {
  width: 44px; height: 40px; padding: 2px; cursor: pointer;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie-2);
}
.fila-color input[type="text"] { text-transform: lowercase; }
.fila-color .nombre { font-weight: 500; }
.fila-color .ayuda { margin-top: 2px; }
.fila-color .campo { margin: 0; }
/* El valor de casa se dice con su propio color al lado: un código
   hexadecimal no le dice a nadie de qué color está hablando. */
.fila-color .de-casa { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.fila-color .de-casa .gota {
  width: 11px; height: 11px; border-radius: 3px; border: 1px solid var(--borde);
}

/* ================================================================ Pantallas
   estrechas — teléfono y tableta (2026-09-17)

   Hasta hoy la hoja tenía tres `@media` en 864 líneas y la maqueta era una
   sola: menú lateral fijo de 264 px más el contenido al lado. En un teléfono
   de 320 px eso deja **56 px de contenido**: el menú se comía el 82 % del
   ancho, la página se iba de lado y el texto caía a una palabra por renglón.
   Comprobado con un recorrido automático de las 31 pantallas en 9
   resoluciones.

   Tres decisiones de esta capa:

   - **El menú se convierte en cajón, no se esconde.** Sin él no hay
     navegación: el sistema es un árbol de oficinas. Se abre con el botón de
     la barra superior, se cierra con el velo, con Escape y al pulsar
     cualquier enlace — en un cajón que se queda abierto encima del contenido
     nadie entiende que ya cambió de pantalla.
   - **Nada se oculta por ser pequeño.** Lo único que desaparece en teléfono
     es lo que se repite (el nombre al lado del avatar, el rótulo del botón
     de tema); ninguna cifra, ningún filtro, ninguna columna. Una pantalla que
     esconde datos según el aparato obliga a volver al computador justo cuando
     no se tiene delante.
   - **Lo ancho se desplaza dentro de su caja**, nunca la página entera. Las
     tablas y los gráficos van en `.envoltorio-tabla`; el barrido horizontal
     del documento es siempre un defecto.  */

/* Nada se sale por una imagen o un lienzo más ancho que su sitio. */
img, svg, canvas, video { max-width: 100%; }
.envoltorio-tabla { -webkit-overflow-scrolling: touch; }

/* Texto solo para lectores de pantalla: el botón del menú es un glifo. */
.oculto-visual {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* El botón del cajón no existe en escritorio: ahí el menú está siempre. */
.palanca-menu { display: none; }
.velo-menu { display: none; }

@media (max-width: 1023.98px) {
  .palanca-menu {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 34px; height: 34px; padding: 0; font-size: 16px;
    line-height: 1;
  }
  /* El lateral sale del flujo: así `.principal` ocupa el ancho entero y no
     queda una franja azul empujando el contenido.

     Va condicionado a que EXISTA el botón del menú (`:has`). El servidor puede
     estar sirviendo la hoja nueva con una plantilla vieja —los estáticos se
     leen del disco y las plantillas se quedan en memoria hasta que se
     reinicia, y en el VPS los archivos suben de a uno—: sin esta condición,
     durante ese rato el menú quedaría fuera de la pantalla y sin nada que lo
     abriera. Con ella, lo peor que pasa es que se vea como antes. */
  .disposicion:has(.palanca-menu) .lateral {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
    width: min(300px, 86vw); flex-basis: auto; height: 100dvh;
    transform: translateX(-100%);
    transition: transform .18s ease-out;
    box-shadow: 0 0 0 100vmax transparent;
  }
  .disposicion:has(.palanca-menu) .velo-menu {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: var(--velo); opacity: 0; pointer-events: none;
    transition: opacity .18s ease-out;
  }
  /* Abierto. Lleva el MISMO `:has(.palanca-menu)` que la regla de arriba, y no
     es por gusto: `body.menu-abierto .lateral` pesa menos —dos clases y un
     elemento contra tres clases—, así que el navegador se quedaba con el
     `translateX(-100%)`. El botón se pulsaba, la clase entraba en el `<body>`,
     el velo aparecía… y el cajón no se movía (reportado desde un teléfono el
     2026-09-19). Toda regla que dependa de `.menu-abierto` para mover el
     lateral tiene que repetir esta condición. */
  body.menu-abierto .disposicion:has(.palanca-menu) .lateral {
    transform: none; box-shadow: var(--sombra-modal);
  }
  body.menu-abierto .disposicion:has(.palanca-menu) .velo-menu {
    opacity: 1; pointer-events: auto;
  }
  /* Con el cajón abierto, el fondo no se desplaza: se perdería el sitio. */
  body.menu-abierto { overflow: hidden; }

  .barra-superior { padding: 10px 14px; gap: 10px; }
  .contenido { padding: 16px 14px 40px; }

  /* Una tabla de datos se DESPLAZA, no se aplasta. Sin esto, «Administradora
     de los Recursos del Sistema General de Seguridad Social en Salud» caía en
     una columna de 60px, una o dos letras por renglón, y la pantalla de
     validación de cuentas no se podía leer en un teléfono. Con `max-content`
     cada columna toma el ancho que necesita y la tabla se corre de lado
     dentro de su envoltorio; el tope de 70vw es para que una celda de texto
     libre —una observación, un detalle de bitácora— siga partiéndose en
     renglones en vez de irse a mil píxeles de ancho. */
  .envoltorio-tabla table.datos { width: max-content; min-width: 100%; }
  .envoltorio-tabla table.datos th,
  .envoltorio-tabla table.datos td { max-width: 70vw; }
  /* Un encabezado va en un renglón mientras quepa —es lo que le da el ancho a
     su columna—, pero si es largo tiene que poder partirse: con `nowrap` fijo,
     «Qué cuelga hoy de Facturación y su sub-árbol» pedía 257px dentro de un
     tope de 224 y se salía de su celda. */
  .envoltorio-tabla table.datos th { white-space: normal; }
  /* La columna de la acción se queda pegada al borde derecho mientras el
     resto de la tabla se corre por debajo. Es para la pantalla de dosis: el
     botón de confirmar es a lo que se vino, y quedaba detrás del barrido. */
  .envoltorio-tabla table.datos th.accion-fija,
  .envoltorio-tabla table.datos td.accion-fija {
    position: sticky; right: 0; background: var(--superficie);
    box-shadow: -9px 0 9px -9px var(--sombra-barrido);
  }
  .envoltorio-tabla table.datos th.accion-fija { background: var(--cabecera-tabla); }

  /* Una tabla ancha se desplaza de lado, pero eso no se ve: en un teléfono no
     hay barra de desplazamiento hasta que se toca. Estas dos sombras aparecen
     en el borde por el que queda tabla sin ver y desaparecen al llegar al
     final; es el aviso de que ahí sigue habiendo columnas. */
  .envoltorio-tabla {
    background:
      linear-gradient(90deg, var(--superficie) 30%, transparent) left / 26px 100% no-repeat,
      linear-gradient(270deg, var(--superficie) 30%, transparent) right / 26px 100% no-repeat,
      radial-gradient(farthest-side at 0 50%, var(--sombra-barrido), transparent) left / 11px 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%, var(--sombra-barrido), transparent) right / 11px 100% no-repeat;
    background-attachment: local, local, scroll, scroll;
  }
}

/* Quien no quiera animación no la tiene. */
@media (prefers-reduced-motion: reduce) {
  .lateral, .velo-menu { transition: none; }
}

@media (max-width: 720px) {
  /* La barra superior se queda con lo que identifica la pantalla: título,
     migas y los tres controles. El nombre repetido al lado del avatar se va;
     el avatar y «Salir» no. */
  /* El título y las migas bajan a su propio renglón. Entre el botón del menú
     y los tres de la derecha les quedaban 73px: el título salía cortado y las
     migas no se leían. Ahora tienen el ancho entero y no hace falta recortar
     nada. */
  .barra-superior { gap: 8px 10px; padding: 9px 12px; flex-wrap: wrap; }
  .titulo-pantalla { order: 9; flex: 1 0 100%; min-width: 0; }
  .barra-superior h1 { font-size: 15.5px; }
  .usuario-chip > div:not(.avatar) { display: none; }
  .selector-tema .rotulo-tema { display: none; }
  #boton-atras { padding: 4px 9px; }

  .palanca-menu { width: 38px; height: 38px; }

  .contenido { padding: 14px 12px 36px; }
  .tarjeta { margin-bottom: 14px; }
  .tarjeta > header { padding: 11px 12px; flex-wrap: wrap; gap: 8px; }
  .tarjeta .cuerpo { padding: 12px; }
  .rejilla { gap: 12px; }

  /* Los filtros dejan de ser una fila que se parte en escalera. */
  .filtros { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .filtros .campo { min-width: 0; }
  .filtros .boton, .filtros button { width: 100%; }

  /* Las pestañas se desplazan de lado en vez de apilarse en tres renglones. */
  .pestanas {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  }
  .pestanas::-webkit-scrollbar { display: none; }
  .pestanas button { white-space: nowrap; flex: none; }

  .heroe { font-size: 34px; letter-spacing: -.8px; }
  .ficha .valor { font-size: 23px; }

  /* El diálogo pasa a ser una hoja a pantalla completa: un recuadro con
     márgenes deja el formulario de correo en una rendija. */
  .dialogo {
    width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
    border-radius: 0; border: 0; margin: 0;
  }
  /* `[open]` no es adorno: un `dialog` cerrado es `display: none`, y poner
     `display: flex` a secas lo dejaría visible siempre. */
  .dialogo[open] { display: flex; flex-direction: column; }
  .dialogo .cuerpo { flex: 1; max-height: none; }
  .dialogo footer { background: var(--superficie); }

  .nodo { flex-wrap: wrap; }
  .nodo .acciones { margin-left: 0; width: 100%; }
  .arbol ul { padding-left: 14px; }

  .firma-previa .fila { flex-direction: column; }
  .imagen-firma { flex-direction: column; }
  .subida-firma { flex-wrap: wrap; }
  .subida-firma input[type=file] { max-width: 100%; }
  .cabecera-correo span { width: 68px; }
  .fila-color { grid-template-columns: 44px 1fr; }
  .fila-color .campo { grid-column: 1 / -1; }
}

@media (max-width: 400px) {
  /* En un teléfono la barra del navegador aparece y desaparece: con `100vh`
     la caja de ingreso queda partida por la mitad al aparecer. */
  .pantalla-ingreso { min-height: 100dvh; padding: 14px; }
  .caja-ingreso { padding: 24px 18px; }
  .contenido { padding: 12px 10px 32px; }
  .tarjeta .cuerpo { padding: 11px 10px; }
  .ficha { padding: 12px 11px; }
  .heroe { font-size: 29px; }
  table.datos th, table.datos td { padding: 8px 9px; }
}

/* ---------------------------------------------- Lo que se pulsa con el dedo
   Esto NO va por ancho de pantalla, va por aparato. Un iPad vertical mide
   768px —más que un portátil pequeño de hace diez años— y aun así se toca con
   el dedo: colgarlo de un `max-width` dejaba media tableta con botones de
   28px. `pointer: coarse` pregunta lo que de verdad importa.

   36px de alto es el suelo; la referencia de accesibilidad son 44 y estos
   botones van pegados unos a otros. */
@media (pointer: coarse) {
  .boton { min-height: 38px; }
  .boton.chico { min-height: 36px; padding: 6px 10px; }
  .selector-tema { min-width: 36px; }
  /* 16px en los campos: por debajo, Safari de iPhone acerca la pantalla al
     tocarlos y deja la página descuadrada. */
  input, select, textarea { font-size: 16px; }
  input[type=checkbox], input[type=radio] { width: 20px; height: 20px; }
  /* Se pulsa el rótulo entero, no el cuadradito. */
  .casilla { min-height: 36px; }
  /* Una casilla dentro de una tabla: el blanco es la celda. */
  table.datos td.centro { padding: 11px 12px; }
  details.tabla-alterna summary { padding-top: 10px; padding-bottom: 10px; }
  input[type=file] { min-height: 34px; }
  /* Las palancas del árbol del menú, que eran de 22px. */
  .palanca-rama { width: 32px; height: 32px; }
  .arbol-menu li.con-hijas > a.enlace { padding-right: 40px; }
  .lateral a.enlace { padding-top: 10px; padding-bottom: 10px; }
  .pestanas button { padding-top: 10px; padding-bottom: 10px; }
}

/* El botón de un filtro no se encoge: «Consultar» salía cortado a «Consul» en
   una tableta apaisada, donde la fila de filtros llega justa. */
.filtros .boton, .filtros button { flex: none; white-space: nowrap; }
/* Una celda con un dato largo sin espacios —una ruta, un identificador— parte
   por donde sea antes que salirse de su columna. */
table.datos td { overflow-wrap: anywhere; }

/* La franja del servidor de respaldo (`config.SISTEMA_AVISO`). Roja y arriba
   del todo: es la misma regla que el pie de procedencia de los datos de
   ejemplo — lo que no sirve para trabajar tiene que decirlo donde se ve, no en
   un documento. No se puede cerrar y no lleva botón: no es una notificación.
   Va en flujo, no fija, para no comerse alto de pantalla en un teléfono; la
   barra superior es `sticky` y se queda pegada al desplazar, el aviso no. */
.aviso-servidor {
  background: var(--critico); color: #fff;
  padding: 7px 14px; font-size: 12.5px; font-weight: 600;
  text-align: center; letter-spacing: .2px;
}
