/* =====================================================================
   TABLERO DE VIGILANCIA · BIALAB S.A.S.

   PALETA CORPORATIVA, en orden de protagonismo (manual de marca biaLab):
     1. Gris corporativo  #575556   87, 85, 86
     2. Verde lima        #A2C418   162, 196, 24

   El gris lleva las acciones: es el primero de la marca y el único de los
   dos que alcanza contraste de texto sobre blanco (6,9:1 frente al 4,5:1
   que exige WCAG AA). El verde lima no llega (1,9:1): va de relleno, de
   distintivo y de subrayado, nunca de texto sobre fondo claro; para texto
   se usa su versión oscurecida --verde-texto.

   El naranja y el rojo NO son de marca: son señales. El naranja marca lo
   provisional —el mes en curso, un aviso— y el rojo el incumplimiento.
   Se mantienen acotados a eso para que no compitan con la identidad.

   DOS TEMAS. Los mismos nombres de token, dos juegos de valores:
     :root                → claro
     [data-tema="oscuro"] → oscuro
   Ninguna regla de más abajo sabe en qué tema está: todas leen tokens.
   Quien quiera cambiar un color lo cambia aquí y en ningún otro lado.

   Los colores de las GRÁFICAS son un juego aparte, derivado de la marca
   pero corrido en luminosidad hasta pasar las pruebas de daltonismo sobre
   cada fondo. El verde y el naranja NUNCA van en series contiguas: son el
   par que un ojo deuteranope confunde primero. Entre ellos va el azul de
   apoyo, que no es de marca y por eso solo aparece dentro de las gráficas.
   ===================================================================== */

:root{
  color-scheme:light;

  /* marca */
  --gris:#575556;        --gris-fuerte:#3F3D3E;   --gris-suave:#ECEBEB;
  --verde:#A2C418;       --verde-texto:#4C5E0B;   --verde-suave:#EEF5D9;

  /* acciones · el gris corporativo */
  --accion:#575556;      --accion-fuerte:#3F3D3E; --accion-suave:#E8E7E7;
  /* enlace · el gris de acción no se distingue del texto corriente, así que
     lo que se puede oprimir lleva el verde oscurecido, que sí pasa AA */
  --enlace:#4C5E0B;      --enlace-fuerte:#3A480A;

  /* señales */
  --naranja:#D57828;     --naranja-texto:#8A4A10; --naranja-suave:#FBEEE0;
  --rojo:#A63A2E;        --rojo-suave:#F7E3E0;
  --amarillo-texto:#6E5200; --amarillo-suave:#FBF0C2;

  /* superficies y tinta · neutros derivados del gris corporativo */
  --tinta:#2A2828;       --tinta-2:#575556;       --tinta-3:#8A8786;
  --fondo:#F4F4F3;       --superficie:#FFFFFF;    --superficie-2:#EEEEED;
  --linea:#DEDDDC;       --linea-2:#C6C4C3;
  --sombra:rgba(42,40,40,.35);
  --radio:6px;

  /* barra lateral · el gris corporativo a plena carta, que es donde la
     marca se ve. En claro es la única superficie oscura de la pantalla. */
  --lat-fondo:#575556;   --lat-linea:#6B6869;     --lat-hover:#666364;
  --lat-activo:#6E6B6C;  --lat-tinta:#D8D6D5;     --lat-tinta-fuerte:#FFFFFF;
  --lat-tinta-3:#A6A3A2;

  /* series de las gráficas · orden fijo, verde → azul → naranja */
  --s1:#7A9412;  --s2:#2F6BAD;  --s3:#C4661A;
  /* Con «Vigilancia de patógenos» una serie dejó de ser un par: pueden
     ir siete líneas en la misma gráfica. El orden alterna familia de
     tinta para que dos vecinas nunca sean el par verde/naranja que un
     ojo deuteranope confunde, y las cuatro nuevas bajan en luminosidad
     para que sigan separándose en escala de grises al imprimir. */
  --s4:#7B4E9E;  --s5:#1F7A6B;  --s6:#A6322F;  --s7:#5A6470;
  /* rampa secuencial de una sola tinta, la del verde de marca */
  /* Mapa de calor. La rampa anterior era de una sola tinta —del verde
     claro al verde oscuro— y decía exactamente lo contrario de lo que
     significaba: el punto con más incumplimiento quedaba del verde más
     intenso, que todo el mundo lee como «bien». Ahora va de verde a rojo,
     que es la convención que nadie tiene que aprender.
     El tramo sin muestreo se sale de la rampa a propósito: no es «poco
     incumplimiento», es ausencia de dato, y no puede parecerse al extremo
     bueno. */
  --c0:#7FA64A; --c1:#A8BF52; --c2:#D2CF5A; --c3:#E8B84E;
  --c4:#E0913F; --c5:#D06437; --c6:#B8352F;
  --calor-tinta-clara:#FFFFFF; --calor-tinta-oscura:#241F1C;
  /* El tramo SIN MUESTREO no es «poco incumplimiento»: es ausencia de
     dato, y tiene que salirse de la rampa sin parecerse al extremo
     bueno. En fondo claro eso es un gris muy pálido, casi el papel; en
     fondo oscuro, casi la tinta. Estaba en #3A3838 en los dos temas, y
     en modo claro se leía como una celda negra. */
  --calor-sin:#F1EFED;   --calor-sin-tinta:#8A8785;
  --calor-alta:#FFFFFF;
}

/* ---- tema oscuro ----------------------------------------------------
   No es el claro con los colores invertidos. Sobre fondo oscuro el verde
   lima SÍ alcanza contraste de texto, así que --verde-texto se aclara en
   vez de oscurecerse; y las superficies suben de luminosidad en lugar de
   bajar, que es como el ojo lee profundidad en un fondo oscuro.
   -------------------------------------------------------------------- */
[data-tema="oscuro"]{
  color-scheme:dark;

  --gris:#8A8786;        --gris-fuerte:#A5A2A1;   --gris-suave:#454240;
  --verde:#A2C418;       --verde-texto:#BCD94A;   --verde-suave:#3B4520;

  --accion:#A2C418;      --accion-fuerte:#B6D633; --accion-suave:#45423F;

  --naranja:#D57828;     --naranja-texto:#EDA163; --naranja-suave:#45331F;
  --rojo:#E4796B;        --rojo-suave:#472C27;
  --amarillo-texto:#E9CB6A; --amarillo-suave:#443A1C;

  --tinta:#F3F2F0;       --tinta-2:#C3C0BD;       --tinta-3:#95918E;
  --fondo:#252322;       --superficie:#2F2D2C;    --superficie-2:#3C3A38;
  --linea:#454240;       --linea-2:#5D5A57;
  --sombra:rgba(0,0,0,.6);

  --lat-fondo:#1F1E1D;   --lat-linea:#3A3836;     --lat-hover:#33312F;
  --lat-activo:#3A3836;  --lat-tinta:#C3C0BD;     --lat-tinta-fuerte:#F7F6F4;
  --lat-tinta-3:#8B8784;

  --s1:#A2C418;  --s2:#5B9BD5;  --s3:#E2913F;
  --s4:#B58AD6;  --s5:#4FC2AC;  --s6:#E4796B;  --s7:#9AA4B0;
  --enlace:#B9D84A;      --enlace-fuerte:#CDE775;
  --c0:#4E7A2E; --c1:#6E8F2E; --c2:#8E9330; --c3:#A8812F;
  --c4:#A9632C; --c5:#9E452C; --c6:#93302B;
  --calor-tinta-clara:#FFFFFF; --calor-tinta-oscura:#F2F0EE;
  --calor-sin:#1E1C1B;   --calor-sin-tinta:#6E6B69;
  --calor-alta:#1B1A19;
}

/* El botón de acción en oscuro va con tinta oscura sobre el lima */
[data-tema="oscuro"] .btn{color:#232221}
[data-tema="oscuro"] .chip[aria-pressed="true"]{color:#232221}
[data-tema="oscuro"] .sello.cliente{color:#232221}

/* ---- conmutador de tema --------------------------------------------- */
.tema{
  appearance:none;display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--linea-2);background:var(--superficie);color:var(--tinta-2);
  border-radius:20px;padding:5px 11px;font:inherit;font-size:12.5px;cursor:pointer;line-height:1.25;
}
.tema:hover{background:var(--superficie-2);color:var(--tinta)}
.tema svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.9;
          stroke-linecap:round;stroke-linejoin:round}
.tema .t-txt{white-space:nowrap}
.tema .luna{display:none}
[data-tema="oscuro"] .tema .luna{display:block}
[data-tema="oscuro"] .tema .sol{display:none}
/* En la pantalla de ingreso no hay barra: el conmutador flota arriba a la derecha */
.tema.suelto{position:fixed;top:14px;right:16px;z-index:50;box-shadow:0 2px 10px -4px var(--sombra)}

*{box-sizing:border-box}
body{
  margin:0;background:var(--fondo);color:var(--tinta);
  font:15px/1.5 system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}
a{color:var(--accion-fuerte)}
:focus-visible{outline:3px solid var(--naranja);outline-offset:2px;border-radius:3px}
@media (prefers-reduced-motion: reduce){*{animation:none!important;transition:none!important}}

/* =====================================================================
   ARMAZÓN · barra lateral + franja superior + lienzo

   La navegación va en COLUMNA a la izquierda porque esto ya no es un
   tablero: es un contenedor de módulos que va a seguir creciendo, y una
   fila horizontal de pestañas se queda sin ancho a la tercera entrada.
   En columna, agregar un módulo es agregar un renglón.

   La barra se pliega a solo iconos en pantallas de escritorio y se
   convierte en un cajón sobre el contenido por debajo de 900 px, que es
   donde la planta abre la plataforma desde el celular.
   ===================================================================== */
.saltar{position:absolute;left:-9999px;top:0;background:var(--superficie);color:var(--tinta);
        padding:10px 14px;border-radius:0 0 var(--radio) 0;z-index:200}
.saltar:focus{left:0}

body.con-lateral{display:block}

/* ---- barra lateral --------------------------------------------------- */
.lateral{
  position:fixed;top:0;left:0;bottom:0;width:250px;z-index:60;
  display:flex;flex-direction:column;
  background:var(--lat-fondo);color:var(--lat-tinta);
  border-right:1px solid var(--lat-linea);
  transition:width .16s ease, transform .16s ease;
}
.lat-marca{
  display:flex;align-items:center;gap:11px;padding:16px 14px;text-decoration:none;color:inherit;
  border-bottom:1px solid var(--lat-linea);min-height:64px;
}
.lat-marca img{display:block;flex:none;height:30px;width:auto;border-radius:4px;background:#fff;padding:3px}
.lat-marca span{display:block;min-width:0}
.lat-marca b{display:block;font-size:14px;line-height:1.2;color:var(--lat-tinta-fuerte)}
.lat-marca em{display:block;font-style:normal;font-size:10.5px;letter-spacing:.08em;
              text-transform:uppercase;color:var(--lat-tinta-3);margin-top:2px}

.lat-nav{flex:1;overflow-y:auto;padding:10px 8px 18px}
.lat-grupo{margin:14px 0 5px;padding:0 10px;font-size:10.5px;font-weight:700;
           letter-spacing:.11em;text-transform:uppercase;color:var(--lat-tinta-3)}
.lat-grupo:first-child{margin-top:4px}
.lat-nav a,.lat-nav .pendiente{
  display:flex;align-items:center;gap:11px;padding:9px 10px;margin-bottom:2px;
  border-radius:var(--radio);text-decoration:none;color:var(--lat-tinta);
  font-size:14px;font-weight:500;line-height:1.3;
}
.lat-nav a:hover{background:var(--lat-hover);color:var(--lat-tinta-fuerte)}
/* La página en la que se está: franja lima a la izquierda. Es el único
   sitio de la barra donde aparece el verde de marca a plena saturación,
   para que señale una sola cosa. */
.lat-nav a[aria-current="page"]{
  background:var(--lat-activo);color:var(--lat-tinta-fuerte);font-weight:700;
  box-shadow:inset 3px 0 0 var(--verde);
}
.lat-nav a[aria-current="page"] .ic{stroke:var(--verde)}
.lat-nav .pendiente{color:var(--lat-tinta-3);cursor:default}
.lat-nav .ic{width:19px;height:19px;flex:none;fill:none;stroke:currentColor;
             stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.lat-txt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lat-nav .sello{margin-left:auto;flex:none}
.sello.pronto{background:var(--lat-hover);color:var(--lat-tinta-3);font-size:10px;
              letter-spacing:.06em;text-transform:uppercase}

/* ---- las vistas del tablero, colgando del módulo ---------------------
   Van en la MISMA barra gris y no en un riel aparte: son el módulo por
   dentro, y sacarlas a una segunda columna obligaba a leer dos menús para
   saber dónde se está. Se distinguen por sangría y por cuerpo más chico,
   que es como se lee una jerarquía; la línea vertical de la izquierda
   ata el grupo a la entrada de la que cuelga.
   -------------------------------------------------------------------- */
.lat-sub{margin:1px 0 6px;padding:2px 0 2px 19px;position:relative}
.lat-sub::before{content:"";position:absolute;left:19px;top:3px;bottom:3px;
                 width:1px;background:var(--lat-linea)}
.lat-sub button{
  appearance:none;border:0;background:none;width:100%;text-align:left;cursor:pointer;
  font:inherit;font-size:13px;font-weight:500;color:var(--lat-tinta-3);
  padding:6px 10px 6px 13px;margin:0 0 1px;border-radius:0 var(--radio) var(--radio) 0;
  line-height:1.3;display:block;position:relative;
}
.lat-sub button:hover{background:var(--lat-hover);color:var(--lat-tinta-fuerte)}
.lat-sub button[aria-selected="true"]{
  background:var(--lat-activo);color:var(--lat-tinta-fuerte);font-weight:700;
  box-shadow:inset 2px 0 0 var(--verde);
}
.lat-sub .sub-grupo{margin:8px 0 2px;padding:0 10px 0 13px;font-size:9.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--lat-tinta-3);opacity:.75}
.lat-sub .sub-grupo:first-child{margin-top:2px}
/* Plegada a solo iconos no hay dónde escribir: el submenú desaparece y se
   vuelve a la barra completa para navegar entre vistas. */
[data-lateral="plegada"] .lat-sub{display:none}

.lat-yo{display:flex;align-items:center;gap:10px;padding:12px 14px;
        border-top:1px solid var(--lat-linea);font-size:13px}
.lat-yo .lat-txt{line-height:1.25}
.lat-yo b{display:block;font-weight:600;color:var(--lat-tinta-fuerte);
          overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lat-yo em{display:block;font-style:normal;font-size:10.5px;letter-spacing:.05em;
           text-transform:uppercase;color:var(--lat-tinta-3);
           overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.avatar{flex:none;width:32px;height:32px;border-radius:50%;display:grid;place-items:center;
        background:var(--verde);color:#232221;font-size:12px;font-weight:700;letter-spacing:.02em}

/* ---- plegada: solo iconos ------------------------------------------- */
[data-lateral="plegada"] .lateral{width:60px}
[data-lateral="plegada"] .lat-txt,
[data-lateral="plegada"] .lat-marca span,
[data-lateral="plegada"] .lat-nav .sello{display:none}
[data-lateral="plegada"] .lat-grupo{
  height:1px;margin:12px 10px;padding:0;overflow:hidden;background:var(--lat-linea);color:transparent}
[data-lateral="plegada"] .lat-nav a,
[data-lateral="plegada"] .lat-nav .pendiente,
[data-lateral="plegada"] .lat-marca,
[data-lateral="plegada"] .lat-yo{justify-content:center;padding-left:0;padding-right:0}
[data-lateral="plegada"] .principal{margin-left:60px}

/* ---- franja superior y lienzo ---------------------------------------- */
.principal{margin-left:250px;transition:margin-left .16s ease;min-height:100vh;display:flex;flex-direction:column}
.superior{
  position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:14px;
  padding:11px 22px;min-height:64px;
  background:var(--superficie);border-bottom:1px solid var(--linea);
}
.hamburguesa{appearance:none;border:1px solid transparent;background:none;cursor:pointer;
  color:var(--tinta-2);padding:6px;border-radius:var(--radio);display:grid;place-items:center;flex:none}
.hamburguesa:hover{background:var(--superficie-2);color:var(--tinta)}
.hamburguesa svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round}
.miga{min-width:0;margin-right:auto}
.miga p{margin:0;font-size:10.5px;font-weight:700;letter-spacing:.11em;
        text-transform:uppercase;color:var(--tinta-3)}
.miga h1{margin:1px 0 0;font-size:19px;line-height:1.2;font-weight:700;
         overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sup-der{display:flex;align-items:center;gap:10px;flex:none}

.lienzo{flex:1;max-width:1320px;width:100%;margin:0 auto;padding:22px 22px 50px}
.pie{max-width:1320px;width:100%;margin:0 auto;padding:0 22px 30px;color:var(--tinta-3);font-size:12px}
.pie p{margin:0 0 5px;max-width:96ch}
/* ---- pantallas sueltas: ingreso, recuperación, contraseña nueva ------
   Aquí no hay barra ni franja superior: solo una tarjeta. Se centra en la
   pantalla completa, y la leyenda del pie se centra con ella. Alineada a
   la izquierda bajo una tarjeta centrada, la leyenda se leía como si
   perteneciera a otra página.
   -------------------------------------------------------------------- */
body.suelta{min-height:100vh;display:flex;flex-direction:column;justify-content:center}
body.suelta .lienzo{max-width:none;width:100%;margin:0;padding:24px 20px 8px}
body.suelta .estrecha{margin:0 auto;max-width:430px}
body.suelta .pie{max-width:74ch;margin:0 auto;padding:16px 20px 24px;text-align:center}
body.suelta .pie p{max-width:none}

/* ---- franja de la vista previa del cliente ---------------------------
   Va en naranja, el color de lo provisional, y NO en verde ni en rojo: no
   es un estado bueno ni un error, es un estado temporal del que hay que
   acordarse de salir. Ocupa el ancho completo por encima del contenido
   para que sea imposible olvidar que está puesta. */
.lupa{background:var(--naranja-suave);border-bottom:2px solid var(--naranja)}
.lupa-in{max-width:1320px;margin:0 auto;padding:11px 22px;display:flex;align-items:center;
         gap:12px;flex-wrap:wrap}
.lupa-ojo{flex:none;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;
          background:var(--naranja);color:#fff}
.lupa-ojo svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;
              stroke-linecap:round;stroke-linejoin:round}
.lupa-txt{flex:1;min-width:240px;font-size:13.5px;color:var(--naranja-texto);line-height:1.35}
.lupa-txt b{display:block}
.lupa .btn{flex:none;background:var(--naranja);border-color:var(--naranja);color:#fff}
.lupa .btn:hover{background:var(--naranja-texto);border-color:var(--naranja-texto)}
[data-tema="oscuro"] .lupa .btn{color:#232221}

/* ---- franja de versión en validación ---------------------------------
   Naranja, el color de lo provisional, pero en tinta y filete y no en
   bloque: la franja de la lupa es un estado del que el personal tiene que
   acordarse de salir; esta es una condición de la plataforma que se lee y
   se sigue trabajando. Si las dos coinciden, se distinguen a simple vista. */
.validando{background:var(--superficie-2);border-top:1px solid var(--naranja);
           border-bottom:1px solid var(--naranja)}
.validando p{max-width:1320px;margin:0 auto;padding:7px 22px;font-size:12.5px;line-height:1.4;
             color:var(--naranja-texto);text-align:center}
.validando b{font-weight:700}
body.suelta .validando{position:sticky;top:0;z-index:5}
/* En las pantallas sueltas el botón de tema flota arriba a la derecha, que
   es justo donde va la franja. Con la franja encendida baja al flujo de la
   página, debajo de ella: flotando la tapaba, y la franja puede ocupar dos
   o tres renglones en un teléfono, así que ninguna distancia fija sirve. */
body.suelta.en-validacion .tema.suelto{position:static;display:flex;margin:10px 16px 0 auto;width:max-content}

/* El velo que tapa el contenido cuando la barra se abre sobre él en móvil */
.velo{position:fixed;inset:0;z-index:55;background:rgba(20,19,19,.5)}

.marca-sola{display:block;margin:0 auto 18px}
/* El logotipo es un PNG de tinta oscura sobre transparente: sobre fondo
   oscuro la palabra «bioLab» y la línea de la razón social desaparecen.
   No se cambia el archivo —el logotipo es el logotipo— sino el papel que
   lleva debajo, que es lo mismo que se hace al imprimirlo sobre un fondo
   de color. La placa se pone SOLO en tema oscuro. */
[data-tema="oscuro"] .marca-sola{
  background:#FFFFFF;padding:10px 18px;border-radius:8px;box-sizing:content-box;
}

@media (max-width:900px){
  .lateral{transform:translateX(-100%);width:250px;box-shadow:0 0 40px -10px var(--sombra)}
  [data-lateral="abierta"] .lateral{transform:none}
  .principal,[data-lateral="plegada"] .principal{margin-left:0}
  [data-lateral="plegada"] .lateral{width:250px}
  [data-lateral="plegada"] .lat-txt,
  [data-lateral="plegada"] .lat-marca span,
  [data-lateral="plegada"] .lat-nav .sello{display:block}
  [data-lateral="plegada"] .lat-nav a,
  [data-lateral="plegada"] .lat-nav .pendiente,
  [data-lateral="plegada"] .lat-marca,
  [data-lateral="plegada"] .lat-yo{justify-content:flex-start;padding-left:10px;padding-right:10px}
  [data-lateral="plegada"] .lat-grupo{height:auto;background:none;color:var(--lat-tinta-3);margin:14px 0 5px;padding:0 10px}
  [data-lateral="plegada"] .lat-sub{display:block}
  .superior{padding:10px 14px}
  .lienzo{padding:16px 14px 40px}
  .pie{padding:0 14px 24px}
  .miga h1{font-size:17px}
}

/* ---- tarjetas y formularios ---------------------------------------- */
.tarjeta{background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);padding:22px;margin-bottom:18px}
.tarjeta h1{margin:0 0 4px;font-size:19px}
.tarjeta h2{margin:18px 0 12px;font-size:16px}
.tarjeta h2:first-child{margin-top:0}
.tarjeta .sub{margin:0 0 18px;color:var(--tinta-2);font-size:14px;max-width:80ch}
.estrecha{max-width:430px;margin:7vh auto}

label.c{display:block;margin-bottom:14px}
label.c span{display:block;font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-2);font-weight:700;margin-bottom:4px}
input[type=text],input[type=password],input[type=email],input[type=date],input[type=number],input[type=search],input[type=file],select,textarea{
  width:100%;padding:9px 11px;border:1px solid var(--linea-2);border-radius:5px;
  font:inherit;background:var(--superficie);color:var(--tinta);
}
input:focus,select:focus,textarea:focus{border-color:var(--accion);outline:none;box-shadow:0 0 0 3px var(--accion-suave)}
.rejilla{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:0 16px}
fieldset.perfiles{border:1px solid var(--linea);border-radius:var(--radio);padding:10px 14px 14px;margin:0 0 14px}
fieldset.perfiles legend{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-2);font-weight:700;padding:0 6px}
.marca-perfil{display:inline-flex;align-items:center;gap:6px;margin-right:16px;font-size:14px}
.marca-perfil input{width:auto}
.en-linea{display:inline-flex;gap:6px;align-items:center;margin:1px 4px 1px 0}
.en-linea input[type=text]{width:auto}
.acciones-celda{white-space:nowrap}
.modulo-fila{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:5px}
.modulo-fila:last-child{margin-bottom:0}
.modulo-fila .ayuda{margin:0}
.filtros-linea{display:flex;gap:14px;flex-wrap:wrap;align-items:flex-end;margin-bottom:16px}
.filtros-linea label.c{margin-bottom:0}
.filtros-linea .acciones{margin-top:0}
.pie-tabla{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:10px 0 0;color:var(--tinta-3);font-size:13px}
.filtros-linea select,.filtros-linea input[type=date]{width:auto}

.btn{
  display:inline-block;padding:9px 16px;border:1px solid var(--accion);border-radius:5px;
  background:var(--accion);color:#fff;font:inherit;font-weight:600;text-decoration:none;cursor:pointer;
}
.btn:hover{background:var(--accion-fuerte);border-color:var(--accion-fuerte)}
.btn.chico{padding:5px 11px;font-size:13px}
.btn.suave{background:var(--superficie);color:var(--tinta);border-color:var(--linea-2);font-weight:500}
.btn.suave:hover{background:var(--superficie-2)}
.btn.peligro{background:var(--rojo);border-color:var(--rojo)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.acciones{display:flex;gap:10px;align-items:center;margin-top:6px;flex-wrap:wrap}

/* ---- avisos --------------------------------------------------------- */
.aviso{padding:11px 15px;border-radius:var(--radio);margin-bottom:16px;font-size:14px;border:1px solid transparent}
.aviso.bien{background:var(--verde-suave);border-color:#CFE08E;color:var(--verde-texto)}
.aviso.ojo{background:var(--naranja-suave);border-color:#F0C79B;color:var(--naranja-texto)}
.aviso.mal{background:var(--rojo-suave);border-color:#E7B7B0;color:var(--rojo)}

/* ---- tablas --------------------------------------------------------- */
.envoltura{overflow-x:auto;border:1px solid var(--linea);border-radius:var(--radio)}
table{border-collapse:collapse;width:100%;font-size:14px;background:var(--superficie)}
th{text-align:left;font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--tinta-2);
   font-weight:700;padding:10px 12px;border-bottom:2px solid var(--linea);white-space:nowrap;background:var(--superficie)}
/* Todo arranca arriba, en la misma línea. Cuando una celda ocupa tres
   renglones —«DETECCIÓN DE LISTERIA MONOCYTOGENES»— las demás tienen que
   quedar a la altura del primero, no centradas contra el bloque. Las
   pastillas y las barritas heredan la misma línea: son contenido de la
   celda, no adornos flotando en ella. */
td{padding:9px 12px;border-bottom:1px solid var(--linea);vertical-align:top;line-height:1.45}
td .pastilla,td .mini{vertical-align:top}
td .pastilla{margin-top:-1px}
th{vertical-align:bottom}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover td{background:var(--superficie-2)}
th.num,td.num{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
/* Tablas con el ancho declarado columna por columna. El encabezado deja de
   ir en una sola línea —«Norma de referencia» no cabe— y las celdas parten
   las palabras largas en vez de estirar su columna. */
table.fija{table-layout:fixed}

/* «Resultados frente a especificación»: once columnas. El reparto vive
   aquí porque en el HTML iría en un atributo `style`, y eso lo bloquea la
   política de seguridad: sin él las once quedaban en partes iguales y las
   palabras largas se partían a mitad. El ancho va donde está el texto —el
   ítem y el ensayo—, no donde está «R1» o una pastilla. */
/* Once columnas. La Especificación estaba en 8 % y no le cabía «Sin
   fuente registrada» ni «Menor o igual a 1 UFC/g»: el texto se salía de
   su celda y se montaba encima de la Norma de referencia, de modo que
   las letras de la norma se veían tachadas. Eran dos textos
   superpuestos, no un estilo. Se le dan 13 % a costa del Ensayo y el
   Ítem, que tienen holgura, y se obliga a partir palabra donde no
   quepa. */
table.t-espec th:nth-child(1){width:8%}   /* Muestra              */
table.t-espec th:nth-child(2){width:7%}   /* Fecha                */
table.t-espec th:nth-child(3){width:6%}   /* Tipo                 */
table.t-espec th:nth-child(4){width:13%}  /* Ítem                 */
table.t-espec th:nth-child(5){width:6%}   /* Lote                 */
table.t-espec th:nth-child(6){width:15%}  /* Ensayo               */
table.t-espec th:nth-child(7){width:8%}   /* Resultado            */
table.t-espec th:nth-child(8){width:10%}  /* Especificación       */
table.t-espec th:nth-child(9){width:4%}   /* Regla                */
table.t-espec th:nth-child(10){width:14%} /* Conformidad          */
table.t-espec th:nth-child(11){width:9%}  /* Norma de referencia  */

/* LA PASTILLA PUEDE PARTIRSE EN DOS RENGLONES DENTRO DE UNA TABLA.
   `.pastilla` lleva `white-space:nowrap`, que está bien para «Conforme»
   y «No conforme» pero no para «Sin fuente de especificación», que tiene
   veintiocho caracteres. En una columna del 8 % ese texto se salía de su
   celda y caía encima de la norma de referencia, la columna siguiente:
   las letras de la norma se veían tachadas porque eran dos textos
   superpuestos.
   Se resuelve en dos partes —la columna se ensancha y la pastilla puede
   bajar de renglón— porque ensanchar sola no basta el día que el LIMS
   traiga un texto más largo. */
table.fija td .pastilla{white-space:normal;text-align:left}

/* Que ninguna celda se salga de su columna. `break-word` solo parte la
   palabra que de verdad no cabe, y antes prueba a bajarla entera al
   renglón siguiente, que es como se lee un texto. */
table.t-espec td{white-space:normal;overflow-wrap:break-word;word-break:normal}

/* Últimas corridas de la ingesta (1.32). El detalle se lleva la mitad:
   es el que explica por qué una corrida no creó carga. */
table.t-corridas th:nth-child(1){width:18%}  /* Cuándo    */
table.t-corridas th:nth-child(2){width:11%}  /* Disparo   */
table.t-corridas th:nth-child(3){width:13%}  /* Resultado */
table.t-corridas th:nth-child(4){width:8%}   /* Versión   */
table.t-corridas th:nth-child(5){width:50%}  /* Detalle   */
table.t-corridas td{white-space:normal;overflow-wrap:break-word}

/* Los ensayos de una muestra, dentro de la ventana. En partes iguales el
   ensayo recibía un séptimo del ancho y «MONOCYTOGENES» no cabía entero. */
table.t-muestra th:nth-child(1){width:21%}  /* Ensayo                  */
table.t-muestra th:nth-child(2){width:12%}  /* Resultado               */
table.t-muestra th:nth-child(3){width:13%}  /* Conformidad             */
/* 10 % y no 7 %: «No aplica» no cabía y se partía en «No aplic / a». (1.37) */
table.t-muestra th:nth-child(4){width:10%}  /* Regla                   */
table.t-muestra th:nth-child(5){width:16%}  /* Fuente de especificación*/
table.t-muestra th:nth-child(6){width:13%}  /* Especificación          */
table.t-muestra th:nth-child(7){width:15%}  /* Norma de referencia     */

/* Comparativo de la lectura previa (1.21). Cuatro columnas: el concepto
   se lleva la mitad y las tres cifras reparten el resto. Los anchos van
   aquí y no en un atributo `style=`: el `.htaccess` declara
   `style-src 'self'`, que en CSP nivel 3 también bloquea los estilos en
   línea. Un `style=` no se aplicaría y la tabla saldría con las cuatro
   columnas repartidas en partes iguales y las palabras partidas. */
table.t-comparativo th:nth-child(1){width:46%}  /* Concepto      */
table.t-comparativo th:nth-child(2){width:18%}  /* Carga vigente */
table.t-comparativo th:nth-child(3){width:18%}  /* Archivo nuevo */
table.t-comparativo th:nth-child(4){width:18%}  /* Diferencia    */

table.fija th{white-space:normal;line-height:1.25}
/* `anywhere` partía cualquier palabra por donde cayera: «MONOCYTO/GENES»,
   «SALSALCHICH/A». `break-word` solo parte la palabra que de verdad no
   cabe en su columna, y antes prueba a bajarla entera al renglón
   siguiente, que es como se lee un texto. */
table.fija td{overflow-wrap:break-word;word-break:normal}
/* Los códigos y las fechas NO se parten. «MB-67348» en dos renglones se
   lee como dos cosas, y «2026-09-12» partido deja de ser una fecha. La
   columna que los lleva se ensancha si hace falta; son cortos y caben. */
td.mono,th.mono{white-space:nowrap}
table.fija td.mono{overflow-wrap:normal}

/* ---- filas que se despliegan ---------------------------------------
   Registros agrupa por orden: una orden es lo que el cliente pidió de una
   vez, y sus muestras son el detalle. La fila madre resume; el triángulo
   abre el detalle debajo, sin salir de la página ni perder el sitio. */
/* ---- filas que abren algo ------------------------------------------
   Una fila clicable que no se anuncia no se oprime. El código de muestra
   va en el color de acción y subrayado —la convención de enlace que todo
   el mundo ya conoce— y la fila entera se ilumina al pasar por encima.
   El subrayado va separado del texto para que no se coma los descendentes
   ni se confunda con el guion del código. */
tbody tr[data-k]{cursor:pointer}
tbody tr[data-k] td:first-child{color:var(--enlace);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:2px;font-weight:600}
tbody tr[data-k]:hover td{background:var(--superficie-2)}
tbody tr[data-k]:hover td:first-child{color:var(--enlace-fuerte);text-decoration-thickness:2px}
tbody tr[data-k]:focus-visible{outline:2px solid var(--verde);outline-offset:-2px}

tr.madre{cursor:pointer}
tr.madre:hover td{background:var(--superficie-2)}
td.abrir{width:34px;text-align:center;color:var(--tinta-3);user-select:none}
td.abrir b{display:inline-block;transition:transform .12s ease;font-size:11px;font-style:normal}
tr.madre[aria-expanded="true"] td.abrir b{transform:rotate(90deg)}
tr.madre[aria-expanded="true"] td{background:var(--superficie-2)}
tr.hija > td{background:var(--fondo);padding:0 0 0 34px;border-bottom:1px solid var(--linea)}
tr.hija table{border:0;font-size:13px;background:transparent}
tr.hija th{background:transparent;border-bottom:1px solid var(--linea);font-size:10px}
tr.hija td{padding:7px 10px}
tr.hija tbody tr{cursor:pointer}
tr.hija tbody tr:hover td{background:var(--superficie)}

/* ---- comparar dos muestras ------------------------------------------ */
.comparar{display:flex;gap:10px 14px;flex-wrap:wrap;align-items:flex-end;
  background:var(--superficie-2);border:1px solid var(--linea);border-radius:var(--radio);
  padding:12px 16px;margin-bottom:16px}
.comparar label.c{margin-bottom:0}
.comparar input{min-width:150px}
.dif{background:var(--naranja-suave);color:var(--naranja-texto);font-weight:600}
.solo-uno{color:var(--tinta-3);font-style:italic}

/* ---- distintivos ---------------------------------------------------- */
.sello{display:inline-block;padding:2px 9px;border-radius:20px;font-size:11.5px;font-weight:700;white-space:nowrap}
.sello.activo{background:var(--verde-suave);color:var(--verde-texto)}
.sello.inactivo{background:var(--superficie-2);color:var(--tinta-3)}
.sello.alerta{background:var(--naranja-suave);color:var(--naranja-texto);font-weight:700}
.sello.falla{background:var(--rojo-suave);color:var(--rojo);font-weight:700}
.sello.rol{background:var(--accion-suave);color:var(--accion-fuerte);font-weight:600;margin:1px 2px 1px 0}
.sello.cliente{background:var(--verde);color:#1B2430;font-weight:700}

.vacio{text-align:center;padding:48px 20px;color:var(--tinta-3)}
.vacio h3{margin:0 0 6px;color:var(--tinta-2);font-size:15px}
.ayuda{font-size:12.5px;color:var(--tinta-3);margin-top:3px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* cifras de la lectura previa de una carga */
.cifras{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:12px;margin:0 0 20px}
.cifras div{background:var(--superficie-2);border-radius:var(--radio);padding:12px 14px}
.cifras b{display:block;font-size:22px;line-height:1.1;font-weight:700}
.cifras span{display:block;font-size:11.5px;color:var(--tinta-2);margin-top:2px}

/* =====================================================================
   TABLERO
   ===================================================================== */
.cargando{display:flex;align-items:center;gap:12px;padding:60px 20px;justify-content:center;color:var(--tinta-2)}
.hilandera{width:18px;height:18px;border:2px solid var(--linea-2);border-top-color:var(--accion);
           border-radius:50%;animation:giro .8s linear infinite;display:block}
@keyframes giro{to{transform:rotate(360deg)}}

/* El riel claro de la v03.5 se retiró: las vistas viven en la barra gris.
   Queda `.tablero-col` como envoltura por si el submenú no se pudo montar.
   -------------------------------------------------------------------- */
.tablero-col{min-width:0}
/* Respaldo: si el submenú de la barra gris no se pudo montar —plantilla
   vieja en el servidor— las vistas se dibujan dentro del contenido. Feo
   antes que inalcanzable. */
.tab-lat{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:14px;background:var(--superficie);
  border:1px solid var(--linea);border-radius:var(--radio);padding:7px}
.tab-lat button{appearance:none;border:0;background:none;cursor:pointer;font:inherit;font-size:13.5px;
  color:var(--tinta-2);padding:8px 12px;border-radius:var(--radio);white-space:nowrap}
.tab-lat button[aria-selected="true"]{background:var(--accion-suave);color:var(--tinta);font-weight:700}
.tab-lat .sub-grupo{display:none}

.barra-filtros{background:var(--superficie-2);border:1px solid var(--linea);border-radius:var(--radio);
  padding:12px 16px;display:flex;gap:14px 18px;flex-wrap:wrap;align-items:flex-end;margin-bottom:18px}
.barra-filtros label.c{margin-bottom:0}
/* `hidden` en un elemento con display propio no basta: la regla de
   `label.c` lo vuelve a mostrar. Se refuerza para que la vista pueda
   esconder el selector que ella misma reemplaza con chips. */
.barra-filtros label.c[hidden]{display:none}
.barra-filtros select,.barra-filtros input[type=search]{min-width:150px}
.grupo-chips{display:flex;gap:5px;flex-wrap:wrap}
.chip{appearance:none;border:1px solid var(--linea-2);background:var(--superficie);color:var(--tinta-2);
      padding:6px 11px;border-radius:20px;font:inherit;font-size:13px;cursor:pointer;line-height:1.25}
.chip[aria-pressed="true"]{background:var(--accion);border-color:var(--accion);color:#fff;font-weight:600}
.chip i{font-style:italic}
/* El chip de un patógeno lleva su punto de serie: es el mismo color con
   el que sale en la gráfica de arriba, y así no hace falta leyenda. */
.chip .punto{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:baseline}
/* Los siete colores de serie, disponibles como clase para el punto del
   chip y para la muestra de la leyenda. En las gráficas el color sigue
   viajando como atributo del SVG. */
.s1{background:var(--s1)} .s2{background:var(--s2)} .s3{background:var(--s3)} .s4{background:var(--s4)}
.s5{background:var(--s5)} .s6{background:var(--s6)} .s7{background:var(--s7)}
.conteo{margin-left:auto;font-size:13px;color:var(--tinta-2);font-variant-numeric:tabular-nums;align-self:center}
.conteo b{color:var(--tinta)}

.bloque{display:grid;gap:18px;margin-bottom:18px}
.b2{grid-template-columns:repeat(auto-fit,minmax(380px,1fr));align-items:start}

.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(165px,1fr));gap:12px;margin-bottom:18px}
.kpi{background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);padding:14px 16px}
.kpi .k-lab{display:block;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-2);font-weight:700}
.kpi .k-val{display:block;font-size:28px;font-weight:700;line-height:1.1;margin:4px 0 2px}
.kpi .k-val small{font-size:15px;font-weight:600;color:var(--tinta-2)}
.kpi .k-pie{display:block;font-size:12.5px;color:var(--tinta-2)}
.kpi.foco{border-color:var(--verde);box-shadow:inset 4px 0 0 var(--verde)}
.k-pie .sube{color:var(--verde-texto);font-weight:700}
.k-pie .baja{color:var(--rojo);font-weight:700}

.pastilla{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:20px;font-size:12px;font-weight:600;white-space:nowrap}
.pastilla::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.pastilla.ok{background:var(--verde-suave);color:var(--verde-texto)}
.pastilla.nc{background:var(--rojo-suave);color:var(--rojo)}
.pastilla.na{background:var(--superficie-2);color:var(--tinta-3)}
.pastilla.al{background:var(--naranja-suave);color:var(--naranja-texto)}

/* La barra diminuta es un SVG: su ancho es un atributo del rectángulo y
   no un `style`, que la política de seguridad bloquea. */
svg.mini{display:block;width:100%;min-width:54px;height:6px;margin-top:5px;overflow:visible}
svg.mini .pista{fill:var(--superficie-2)}
svg.mini .lleno{fill:var(--s1)}
svg.mini.alto .lleno{fill:var(--rojo)}

/* ---- gráficas ------------------------------------------------------- */
.lienzo-grafica{overflow-x:auto}
.grafica{display:block;width:100%;height:auto}
.grafica text{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-size:10px;fill:var(--tinta-3);font-variant-numeric:tabular-nums}
.grafica .rot{font-family:inherit;font-size:11px;fill:var(--tinta-2)}
.grafica .cifra{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:10.5px;fill:var(--tinta);font-weight:600}
.grafica .malla{stroke:var(--linea);stroke-width:1}
.grafica .eje{stroke:var(--linea-2);stroke-width:1}
/* La muestra de color se marca con clase. Antes la regla era `.leyenda i`
   y agarraba también las cursivas del nombre científico —«<i>Listeria</i>
   <i>monocytogenes</i>»—, que quedaban aplastadas en cuadros de 11 px y
   encimadas unas sobre otras. */
.leyenda{display:flex;gap:16px;flex-wrap:wrap;margin-top:10px;font-size:13px;color:var(--tinta-2)}
.leyenda span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.leyenda i.sw{width:11px;height:11px;border-radius:3px;display:block;flex:none}
.leyenda i:not(.sw){font-style:italic;display:inline;width:auto;height:auto;border-radius:0}

.globo{position:fixed;z-index:90;pointer-events:none;background:var(--superficie);border:1px solid var(--linea-2);
  border-radius:var(--radio);padding:9px 12px;box-shadow:0 6px 24px -8px var(--sombra);font-size:13px;
  max-width:270px;opacity:0;transition:opacity .09s}
.globo.si{opacity:1}
.globo b{display:block;margin-bottom:4px}
.globo dl{margin:0;display:grid;grid-template-columns:auto auto;gap:1px 14px;font-size:12.5px}
.globo dt{color:var(--tinta-3)}
.globo dd{margin:0;text-align:right;font-variant-numeric:tabular-nums}

/* ---- mapa de calor -------------------------------------------------- */
.calor{overflow:auto;max-height:620px;border:1px solid var(--linea);border-radius:var(--radio)}
.calor table{font-size:12.5px;min-width:560px}
.calor td.celda{padding:0;border:0}
.calor .cel{height:27px;margin:1px;border-radius:3px;display:grid;place-items:center;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px;font-variant-numeric:tabular-nums}
.calor th.punto{text-align:left;text-transform:none;letter-spacing:0;font-size:12.5px;color:var(--tinta);
  position:sticky;left:0;z-index:2;max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:400;border-right:1px solid var(--linea);background:var(--superficie)}
.escala{display:flex;align-items:center;gap:8px;margin-top:12px;font-size:12px;color:var(--tinta-3);flex-wrap:wrap}
.escala u{display:flex;gap:2px;text-decoration:none}
.escala u i{width:24px;height:12px;border-radius:2px;display:block}
.escala u i.c0{background:var(--c0)} .escala u i.c1{background:var(--c1)}
.escala u i.c2{background:var(--c2)} .escala u i.c3{background:var(--c3)}
.escala u i.c4{background:var(--c4)} .escala u i.c5{background:var(--c5)}
.escala u i.c6{background:var(--c6)}
.escala i.sin-muestreo{width:24px;height:12px;border-radius:2px;display:inline-block;
  background:var(--calor-sin);vertical-align:-1px;margin-right:6px}
.escala .aparte{margin-left:18px;display:inline-flex;align-items:center}

/* El tramo del mapa de calor decide fondo y tinta a la vez: si viajaran
   por separado podrían desincronizarse y dejar texto oscuro sobre fondo
   oscuro en el extremo de la rampa. */
.calor .cel.sin-muestreo{background:var(--calor-sin);color:var(--calor-sin-tinta)}
.calor .cel.c0{background:var(--c0);color:var(--calor-tinta-clara)}
.calor .cel.c1{background:var(--c1);color:var(--calor-tinta-oscura)}
.calor .cel.c2{background:var(--c2);color:var(--calor-tinta-oscura)}
.calor .cel.c3{background:var(--c3);color:var(--calor-tinta-oscura)}
.calor .cel.c4{background:var(--c4);color:var(--calor-tinta-oscura)}
.calor .cel.c5{background:var(--c5);color:var(--calor-tinta-clara)}
.calor .cel.c6{background:var(--c6);color:var(--calor-tinta-clara)}

/* ---- ventana de detalle --------------------------------------------- */
dialog{border:1px solid var(--linea-2);border-radius:8px;background:var(--superficie);color:var(--tinta);
  padding:0;max-width:min(900px,94vw);width:100%;box-shadow:0 24px 60px -20px var(--sombra)}
dialog::backdrop{background:rgba(20,19,19,.55)}
.v-cab{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;border-bottom:1px solid var(--linea)}
.v-cab h2{margin:0;font-size:17px}
.v-cab .ayuda{margin-top:2px}
.v-cuerpo{padding:18px 20px;max-height:64vh;overflow:auto}
/* Dentro de la ventana los encabezados SÍ parten. La regla general los
   deja en una sola línea, y «FUENTE DE ESPECIFICACIÓN» o «NORMA DE
   REFERENCIA» en un renglón fijan un ancho mínimo que ninguna ventana
   alcanza: la tabla se iba de ancho y aparecía el desplazamiento. */
.v-cuerpo th{white-space:normal;line-height:1.25;vertical-align:bottom}
.v-cuerpo table{width:100%;table-layout:fixed}
.v-cuerpo td{overflow-wrap:break-word;word-break:normal}
.v-cuerpo td.mono{overflow-wrap:normal}
.v-cuerpo .pastilla{white-space:normal}
.v-pie{padding:12px 20px;border-top:1px solid var(--linea);display:flex;gap:10px;justify-content:flex-end}
.cerrar{margin-left:auto;appearance:none;border:0;background:none;cursor:pointer;color:var(--tinta-3);font-size:24px;line-height:1;padding:0 4px}

@media (max-width:640px){
  .barra-in{gap:12px}
  .quien .yo{display:none}
  .conteo{margin-left:0;width:100%}
  .kpi .k-val{font-size:24px}
}

/* ---- impresión: el informe mensual en PDF ---------------------------
   El informe se imprime SIEMPRE en claro, esté la pantalla como esté: en
   oscuro saldría una página negra con tinta clara, que ninguna impresora
   agradece y que el cliente no puede archivar. Se reponen los tokens del
   tema claro y el resto de las reglas siguen sin enterarse.
   -------------------------------------------------------------------- */
@media print{
  :root,[data-tema="oscuro"]{
    color-scheme:light;
    --verde-texto:#4C5E0B; --verde-suave:#EEF5D9;
    --accion:#575556; --accion-fuerte:#3F3D3E; --accion-suave:#E8E7E7;
    --enlace:#4C5E0B; --enlace-fuerte:#3A480A;
    --naranja-texto:#8A4A10; --naranja-suave:#FBEEE0;
    --rojo:#A63A2E; --rojo-suave:#F7E3E0;
    --amarillo-texto:#6E5200; --amarillo-suave:#FBF0C2;
    --tinta:#2A2828; --tinta-2:#575556; --tinta-3:#8A8786;
    --fondo:#FFFFFF; --superficie:#FFFFFF; --superficie-2:#EEEEED;
    --linea:#DEDDDC; --linea-2:#C6C4C3;
    --s1:#7A9412; --s2:#2F6BAD; --s3:#C4661A;
    --s4:#7B4E9E; --s5:#1F7A6B; --s6:#A6322F; --s7:#5A6470;
    --c0:#7FA64A; --c1:#A8BF52; --c2:#D2CF5A; --c3:#E8B84E;
    --c4:#E0913F; --c5:#D06437; --c6:#B8352F;
    --calor-tinta-clara:#FFFFFF; --calor-tinta-oscura:#241F1C;
    --calor-sin:#3A3838; --calor-sin-tinta:#B9B6B4;
    --calor-alta:#FFFFFF;
  }
  .lateral,.superior,.velo,.saltar,.tab-nav,.tab-lat,.barra-filtros,.no-imprimir,.pie a,.tema{display:none!important}
  .tablero-marco{display:block}

  /* ---- imprimir una ventana abierta -------------------------------
     Un <dialog> modal se dibuja encima, pero al imprimir el navegador
     compone TODA la página igual: salían ochenta y siete hojas del
     tablero completo con la ventana en la primera. Cuando hay una
     ventana abierta se apaga el resto del documento y la ventana pasa a
     ser el flujo normal de la página.

     Además la ventana deja de tener alto máximo y la tabla deja de
     desplazarse: en pantalla el desplazamiento resuelve el ancho, pero en
     papel lo que queda fuera del marco simplemente no existe, y así se
     perdían «Especificación» y «Norma de referencia». */
  body.ventana-abierta > *:not(dialog){display:none!important}
  body.ventana-abierta dialog[open]{
    position:static;display:block;max-width:100%;width:100%;max-height:none;
    border:0;box-shadow:none;padding:0;margin:0;
  }
  body.ventana-abierta dialog[open]::backdrop{display:none}
  /* Al imprimir una ventana se apaga el resto de la página, franja
     incluida. En versión en validación el papel lo tiene que decir igual. */
  body.en-validacion.ventana-abierta dialog[open]::before{
    content:"VERSIÓN EN VALIDACIÓN · Esta información no debe usarse para tomar decisiones. El documento oficial de los resultados es el informe de ensayo firmado.";
    display:block;margin:0 0 10px;padding:6px 8px;border:1px solid #8A4A10;color:#8A4A10;
    font-size:9.5px;font-weight:700;text-align:center}
  .validando{background:#fff!important;border-color:#8A4A10!important}
  .validando p{color:#8A4A10!important;padding:4px 0}
  body.ventana-abierta .v-cuerpo{max-height:none;overflow:visible;padding:0}
  body.ventana-abierta .v-cab{padding:0 0 10px;border-bottom:1px solid var(--linea)}
  body.ventana-abierta .v-pie,body.ventana-abierta .v-cab .cerrar{display:none!important}
  /* En papel no hay desplazamiento que valga: lo que no cabe en el ancho
     de la hoja no existe. La tabla se obliga a ocupar exactamente el
     ancho disponible y a repartirlo entre sus columnas, los encabezados
     parten en varios renglones y el texto largo se acomoda dentro de su
     celda en vez de empujarla. */
  body.ventana-abierta .envoltura{overflow:visible!important;border:1px solid var(--linea);width:100%}
  body.ventana-abierta table{width:100%!important;table-layout:fixed;font-size:10.5px}
  body.ventana-abierta th{white-space:normal!important;line-height:1.2;vertical-align:bottom;
    font-size:8.5px;letter-spacing:.03em}
  body.ventana-abierta td{overflow-wrap:break-word;word-break:normal;white-space:normal!important}
  /* `td.mono` y `th.num` llevan `nowrap` para que un código o una cifra no
     se parta. En papel eso también empuja el ancho, así que se levanta:
     un código partido es feo, una columna que no sale no es nada. */
  body.ventana-abierta td.mono,body.ventana-abierta th.mono,
  body.ventana-abierta td.num,body.ventana-abierta th.num{white-space:normal!important}
  body.ventana-abierta .pastilla{white-space:normal;padding:1px 5px;font-size:9.5px}
  body.ventana-abierta th,body.ventana-abierta td{padding:4px 5px}
  body.ventana-abierta .kpi{padding:8px 10px}
  body.ventana-abierta .k-val{font-size:20px}
  body.ventana-abierta .kpis{page-break-inside:avoid}
  body.ventana-abierta tr{page-break-inside:avoid}
  /* La franja de la vista previa SÍ se imprime: si alguien imprime un
     informe mirándolo como el cliente, el papel tiene que decirlo. */
  .principal,[data-lateral="plegada"] .principal{margin-left:0}
  body{background:#fff;font-size:10.5pt;color:#2A2828}
  .lienzo{max-width:none;padding:0}
  .tarjeta,.kpi{break-inside:avoid;border-color:#bbb;box-shadow:none}
  .envoltura,.calor{overflow:visible;border-color:#bbb}
  th{background:#f0f0f0!important}
  .vista{display:none!important}
  .vista.si{display:block!important}

  /* ---- impresión del tablero (1.36, P29) ----------------------------
     El Informe ejecutivo salía sin las columnas NO CONF. y CONFORMIDAD,
     con palabras partidas y con una hoja casi en blanco:
     · las tarjetas de un bloque de dos columnas quedaban a media hoja y
       la tabla no cabía: en papel cada tarjeta ocupa el ancho completo;
     · `break-inside:avoid` en una tarjeta con una tabla larga la mandaba
       entera a la hoja siguiente y dejaba la anterior casi vacía: se deja
       partir la tarjeta y se protege solo cada renglón;
     · el texto parte por palabra; los encabezados, en varios renglones. */
  .bloque{display:block!important}
  .bloque > *{width:auto!important;margin-bottom:12px}
  .tarjeta{break-inside:auto;overflow:visible}
  .tarjeta h2,.tarjeta .sub{break-after:avoid}
  .vista table,.tarjeta table{width:100%!important;table-layout:auto!important;font-size:9.5px}
  .vista th,.tarjeta th{white-space:normal!important;line-height:1.2}
  .vista td,.tarjeta td{white-space:normal!important;word-break:normal;overflow-wrap:break-word}
  .vista td.mono,.vista td.num,.tarjeta td.mono,.tarjeta td.num{white-space:nowrap!important}
  .vista tr,.tarjeta tr{break-inside:avoid}
  .lienzo-grafica,.calor{break-inside:avoid}
  /* El pie oculta sus enlaces al imprimir, pero el del alcance de la
     acreditación ES el dato: «puede revisarse en el siguiente enlace:» y
     el enlace no salía. */
  .pie a.acreditacion{display:inline!important;color:#2A2828;text-decoration:none}
  @page{margin:14mm}
}

/* La rueda dentro de la ventana movía también la página de fondo
   (observación 43). Con la ventana abierta la página no se desplaza. */
body.ventana-abierta{overflow:hidden}
#ventana .v-cuerpo{overscroll-behavior:contain}
abbr.f-est{text-decoration:none;cursor:help;font-weight:700;color:var(--naranja-texto)}


/* ---- utilitarias ----------------------------------------------------
   Nacieron de retirar los 42 atributos `style=` del tablero: la política
   `style-src 'self'` los bloquea y no se aplicaba ninguno. Son pocas y
   con nombre de lo que hacen, no de cuánto miden.
   -------------------------------------------------------------------- */
.sin-margen{margin:0}
.sep-arriba{margin-top:12px}
.sep-arriba-14{margin-top:14px}
.sep-arriba-6{margin-top:6px}
.sep-abajo{margin-bottom:14px}
.sep-abajo-16{margin-bottom:16px}
.nota-chips{margin:6px 0 0}
.nota-bajo-barra{margin:-8px 0 16px}
.tenue{opacity:.7}
.empuje{flex:1}
.rotulo{text-transform:uppercase;letter-spacing:.08em}
.titulo-informe{font-size:22px;margin:2px 0 4px}
.sub-informe{margin:0 0 12px}
.kpis.compactos{grid-template-columns:repeat(auto-fit,minmax(135px,1fr))}
.rotulo-ficha{width:120px;text-transform:none;font-size:12px}
.rotulo-ficha.ancha{width:190px}
.sep-arriba-20{margin-top:20px}
.fecha-chica{width:auto;padding:3px 6px}
/* La versión, discreta pero siempre a la vista: es la única forma de
   saber qué está corriendo sin abrir un archivo del servidor. */
.pie .version{font-variant-numeric:tabular-nums;opacity:.65;margin-top:6px}

/* =====================================================================
   R0.2 · Módulo Resultados con el diseño de la maqueta v2 aprobada por
   Gerencia. Todo bajo .mq para no tocar las pantallas de la 1.35.
   ===================================================================== */
.mq,.mq-dlg{--accion-tinta:#FFFFFF;--azul-suave:#E3EDF8;--azul-texto:#1F4F85}
[data-tema="oscuro"] .mq,[data-tema="oscuro"] .mq-dlg{--accion-tinta:#232221;--azul-suave:#23334A;--azul-texto:#8DBBEA}
.mq .caja{background:var(--superficie);border:1px solid var(--linea);border-radius:var(--radio);padding:16px 18px;margin-bottom:16px}
.mq .caja h2{margin:0 0 4px;font-size:16px}
.mq .caja h3{margin:14px 0 6px;font-size:14px}
.mq .nota{color:var(--tinta-3);font-size:13px;margin:0 0 10px;max-width:92ch}
.mq .fila{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.mq .campo{display:flex;flex-direction:column;gap:3px;font-size:12px;color:var(--tinta-2);margin:0;text-transform:none;letter-spacing:0;font-weight:400}
.mq .campo.ancho{flex:1;min-width:190px}
.mq .campo.ancho input{width:100%}
.mq select,.mq input[type=text],.mq input[type=date],.mq input[type=email],.mq input[type=password],.mq textarea{background:var(--superficie);border:1px solid var(--linea-2);border-radius:var(--radio);padding:6px 9px;font-size:14px;color:var(--tinta);width:auto}
.mq textarea{width:100%;font:inherit}
.mq .btn{appearance:none;border:1px solid var(--linea-2);background:var(--superficie);color:var(--tinta);border-radius:var(--radio);padding:6px 12px;font-size:13.5px;font-weight:600;cursor:pointer;line-height:1.3;white-space:nowrap;text-decoration:none;display:inline-block}
.mq .btn:hover{background:var(--superficie-2)}
.mq .btn.prim{background:var(--accion);border-color:var(--accion);color:var(--accion-tinta)}
.mq .btn.prim:hover{background:var(--accion-fuerte)}
.mq .btn.chico{padding:3px 9px;font-size:12.5px}
.mq .btn[disabled]{opacity:.45;cursor:not-allowed}
.mq form.en-linea{display:inline-flex;gap:6px;align-items:center;margin:1px 4px 1px 0}
.mq .aviso{border-radius:var(--radio);padding:10px 14px;margin-bottom:14px;font-size:14px;border:1px solid}
.mq .aviso.naranja{background:var(--naranja-suave);border-color:var(--naranja);color:var(--naranja-texto)}
.mq .aviso.verde{background:var(--verde-suave);border-color:var(--verde);color:var(--verde-texto)}
.mq .aviso.azul{background:var(--azul-suave);border-color:var(--azul-texto);color:var(--azul-texto)}
.mq .fila-aviso{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.mq .fila-aviso > span{flex:1;min-width:240px}
.mq .docs{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.mq .docs .lbl{font-size:13px;font-weight:600;margin-right:4px}
.mq .doc{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--linea-2);border-radius:14px;padding:3px 11px;font-size:13px;background:var(--superficie);cursor:pointer;color:var(--enlace);text-decoration:none}
.mq .doc:hover{background:var(--verde-suave)}
.mq svg.ic14{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.8;flex:none}
.mq .tabla-env{overflow-x:auto;border:1px solid var(--linea);border-radius:var(--radio);background:var(--superficie)}
.mq table{border-collapse:collapse;width:100%;font-size:13.5px;table-layout:auto}
.mq th{background:var(--superficie-2);text-align:left;font-size:12px;font-weight:700;color:var(--tinta-2);padding:8px 10px;border-bottom:1px solid var(--linea-2);vertical-align:bottom;white-space:normal;text-transform:none;letter-spacing:0}
.mq td{padding:7px 10px;border-bottom:1px solid var(--linea);vertical-align:middle}
.mq tr.grupo td{background:var(--gris-suave);font-weight:600;font-size:13px;padding:6px 10px}
.mq tr.grupo .anexo{font-weight:500}
.mq tr.elegido td{background:var(--verde-suave)}
.mq .num{font-variant-numeric:tabular-nums;white-space:nowrap}
.mq .col-desc{min-width:170px}
.mq .celda-inf{white-space:nowrap}
.mq td.acc{min-width:170px}
.mq td.acc .btn,.mq td.acc form{margin:2px 0}
.mq .fix-mark{color:var(--verde-texto);font-weight:700}
.mq .pdf{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--linea-2);border-radius:var(--radio);padding:3px 8px;background:var(--superficie);cursor:pointer;font-size:12.5px;font-weight:600;color:var(--enlace);white-space:nowrap;text-decoration:none}
.mq .pdf:hover{background:var(--verde-suave)}
.mq .pdf.prelim{border-style:dashed}
.mq .bloq{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;color:var(--naranja-texto);white-space:nowrap}
.mq .nada{color:var(--tinta-3);font-size:12.5px;white-space:nowrap}
.mq .pill{display:inline-block;padding:1px 9px;border-radius:11px;font-size:12px;font-weight:600;white-space:nowrap}
.mq .p-proc{background:var(--superficie-2);color:var(--tinta-2)}
.mq .p-pre{background:var(--azul-suave);color:var(--azul-texto)}
.mq .p-ter{background:var(--verde-suave);color:var(--verde-texto)}
.mq .p-des{background:var(--gris-suave);color:var(--tinta)}
.mq .p-ret{background:var(--naranja-suave);color:var(--naranja-texto)}
.mq .p-venc{background:var(--rojo-suave);color:var(--rojo)}
.mq .p-ok{background:var(--verde-suave);color:var(--verde-texto)}
/* R0.4 · A15 · el informe cargado que el perfil no abre */
.mq .pdf.sin-abrir{cursor:default;color:var(--tinta-2);text-decoration:none}
.mq .pdf.sin-abrir:hover{background:var(--superficie)}
/* R0.8 · progreso del envío de a uno y botón inactivo con explicación */
.mq .aviso.progreso .lista{max-height:320px;overflow:auto;margin:6px 0}
.mq .btn.inactivo{opacity:.55;cursor:not-allowed}
.mq .pedir-codigo{list-style:none;margin:8px 0;padding:8px;border:1px solid var(--linea-2);border-radius:var(--radio);background:var(--superficie)}
.mq .c-anexos .pdf{margin:0 4px 4px 0}
/* R0.7 · retraso: motivo externo y novedad, bajo la celda del informe */
.mq .nota.retraso{display:block;margin-top:4px;color:var(--naranja-texto);white-space:normal}
/* R0.4 · A7 · amarillo del semáforo: vence hoy */
.mq .p-hoy{background:var(--amarillo-suave);color:var(--amarillo-texto)}
.mq .visto{color:var(--verde-texto);font-weight:600;white-space:nowrap}
.mq .novisto{color:var(--tinta-3);white-space:nowrap}
.mq .colsel{position:relative}
.mq .colsel .menu{position:absolute;right:0;top:calc(100% + 4px);z-index:30;background:var(--superficie);border:1px solid var(--linea-2);border-radius:var(--radio);box-shadow:0 10px 30px -12px var(--sombra);padding:10px 12px;min-width:250px}
.mq .colsel label{display:flex;gap:8px;align-items:center;font-size:13px;padding:3px 0;margin:0;text-transform:none;font-weight:400;letter-spacing:0;color:var(--tinta)}
.mq .colsel label.fijo{color:var(--tinta-3)}
.mq .drop{display:block;border:2px dashed var(--linea-2);border-radius:var(--radio);padding:18px;text-align:center;color:var(--tinta-2);background:var(--superficie-2);cursor:pointer;margin:0;text-transform:none;font-weight:400;letter-spacing:0}
.mq .drop.encima{border-color:var(--verde);background:var(--verde-suave)}
.mq .drop b{color:var(--tinta)}
.mq .grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:900px){.mq .grid2{grid-template-columns:1fr}}
.mq .kv{display:grid;grid-template-columns:max-content 1fr;gap:6px 14px;font-size:14px;margin:0}
.mq .kv dt{color:var(--tinta-3)}
.mq .kv dd{margin:0}
.mq .tabs{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}
.mq .tabs a{border:1px solid var(--linea-2);background:var(--superficie);padding:5px 12px;border-radius:16px;font-size:13px;color:var(--tinta);text-decoration:none}
.mq .tabs a[aria-current="page"]{background:var(--accion);border-color:var(--accion);color:var(--accion-tinta)}
.mq .barras text{font-size:11px;fill:var(--tinta-2)}
.mq .barras .ok{fill:#7A9412}.mq .barras .tarde{fill:#C4661A}
.mq .leyenda{display:flex;gap:14px;font-size:12.5px;color:var(--tinta-2);margin-top:6px}
.mq .leyenda i{display:inline-block;width:11px;height:11px;border-radius:2px;margin-right:5px;vertical-align:-1px}
.mq .leyenda .ok{background:#7A9412}.mq .leyenda .tarde{background:#C4661A}
.mq .huella{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11.5px;word-break:break-all;color:var(--tinta-2)}
.mq .chk{display:flex;gap:8px;align-items:center;font-size:14px;margin:4px 0;text-transform:none;font-weight:400;letter-spacing:0;color:var(--tinta)}
.mq .x-ubic{border:0;background:none;cursor:pointer;color:inherit;font-weight:700;padding:0 0 0 4px;line-height:1}
.mq tr.inactiva td{opacity:.6}
.mq ul.lista{margin:0;padding-left:18px;font-size:14px}
dialog.mq-dlg{border:1px solid var(--linea-2);border-radius:8px;background:var(--superficie);color:var(--tinta);padding:0;max-width:min(640px,94vw);width:100%;box-shadow:0 20px 60px -20px var(--sombra)}
dialog.mq-dlg::backdrop{background:rgba(20,20,20,.45)}
.mq-dlg .dlg-cab{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--linea)}
.mq-dlg .dlg-cab h2{margin:0;font-size:16px}
.mq-dlg .dlg-cuerpo{padding:14px 16px;font-size:14px}
.mq-dlg .dlg-cuerpo h3{margin:12px 0 6px;font-size:14px}
.mq-dlg .dlg-pie{padding:10px 16px;border-top:1px solid var(--linea);display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap}
/* menú: las subvistas de Resultados cuelgan del módulo, como en la maqueta */
.lat-nav a.lat-hija{padding:6px 10px 6px 40px;font-size:13px;color:var(--lat-tinta-3)}
.lat-nav a.lat-hija[aria-current="page"]{color:var(--lat-tinta-fuerte);font-weight:700}
/* columnas ocultables de Mis informes */
.mq table.cols.oculta-sitio .c-sitio,.mq table.cols.oculta-recibo .c-recibo,.mq table.cols.oculta-desc .c-desc,
.mq table.cols.oculta-tipo .c-tipo,.mq table.cols.oculta-prom .c-prom,.mq table.cols.oculta-pub .c-pub,
.mq table.cols.oculta-estado .c-estado,.mq table.cols.oculta-factura .c-factura,.mq table.cols.oculta-visto .c-visto{display:none}
/* R0.10 · Mis informes y Seguimiento: los títulos de las columnas van
   centrados en los dos sentidos y quedan a la vista al bajar la página. La
   tabla desplaza de lado dentro de su caja, y eso impide el position:sticky
   en los títulos; resultados.js pone encima una copia fija de la fila de
   títulos, alineada con las columnas. Solo Resultados: el Tablero no usa .mq. */
.mq th{text-align:center;vertical-align:middle}
.mq .thead-flotante{position:fixed;z-index:35;overflow:hidden;pointer-events:none;box-shadow:0 2px 6px -3px rgba(0,0,0,.35)}
.mq .thead-flotante[hidden]{display:none}
.mq .thead-flotante table{border-collapse:collapse;table-layout:fixed}
@media print{.mq .thead-flotante{display:none}}

/* 1.39 · R46 · barra de avance de carga de informes en Publicar (sin style= en línea: CSP) */
.mq .avance progress{width:100%;height:14px;accent-color:var(--verde,#2e7d32);margin:6px 0 4px}
.mq .avance h3{margin:0 0 4px}
