  /* ══════════════════════════════════════════════════════════════════
     PALETA — la de la web nueva del laboratorio.
     ══════════════════════════════════════════════════════════════════
     Tres familias y nada mas:
       · tinta    → el petroleo de la marca: el fondo que pesa y el texto.
       · turquesa → el acento, y SOLO el acento. Aparece poco y por eso se ve.
       · hueso    → el LIENZO de la pagina. Lo blanco queda para las piezas
                    que se apoyan encima: asi una tarjeta se ve como papel
                    sobre mesa y no como un rectangulo invisible.
     `arena` es la unica linea: hairlines de 1px en vez de bordes grises.

     LA REGLA QUE MAS SE ROMPE (docs/GUIA-VISUAL.md §1): nada se pinta del
     MISMO color del fondo sobre el que se apoya. Compila, no rompe nada, y
     simplemente no se ve. Aca: tinta es lienzo oscuro, hueso es lienzo claro,
     papel es SIEMPRE lo que se apoya encima. Nunca papel sobre papel ni
     hueso sobre hueso.

     Nada de colores sueltos mas abajo: todo sale de estos tokens. */
  :root {
    --tinta:#06282B; --tinta-900:#04191B; --tinta-700:#0A3A3E;
    --tinta-600:#0E4B50; --tinta-400:#2C7C82;
    --turquesa:#1ECAD3; --turq-300:#66D8DD; --turq-200:#9FE9EC;
    --turq-600:#0F7A82; --turq-700:#0C5F65; --turq-50:#EAFBFC;
    --hueso:#F6F3EE; --hueso-200:#EFEAE2; --hueso-300:#E4DDD2; --arena:#DAD2C5;
    /* CONTORNO DE CONTROL. `--arena` es el borde de las TARJETAS, donde ser
       sutil esta bien porque la tarjeta ya se separa por su fondo y su sombra.
       En un CAMPO el borde carga todo el peso -- es lo unico que dice donde se
       escribe-- y #DAD2C5 contra el papel casi no se ve. Lo señalo el dueño:
       «los bordes si estan muy tenues en los campos» (2026-09-28). */
    --borde-campo:#B3A491;
    --papel:#FFFFFF;
    --texto:#06282B; --texto-2:#5B564D;

    /* La unica linea sobre fondo oscuro. Un `border:1px solid var(--arena)`
       sobre tinta se ve como una grieta; esto se ve como un pliegue. */
    --linea-oscura:rgba(246,243,238,.13);

    /* Los tres estados que lee el medico de un vistazo. Se distinguen por
       COLOR, por TEXTO y por FORMA (el glifo del chip), nunca solo por color:
       en un telefono al sol, o con daltonismo, el color solo no alcanza. */
    --listos-fg:#0C5F65; --listos-bg:#EAFBFC; --listos-bd:#9FE9EC;
    --parcial-fg:#8A5200; --parcial-bg:#FDF3E2; --parcial-bd:#E8C48A;
    --proceso-fg:#5B564D; --proceso-bg:#EFEAE2; --proceso-bd:#DAD2C5;

    /* Fuera de rango. Se MARCA, nunca se interpreta. */
    --fuera-fg:#A82B1E; --fuera-bg:#FCEDEA; --fuera-bd:#E9B4AC;

    --err:#A82B1E; --espera:#8A5200;

    --display:'Fraunces',Georgia,'Times New Roman',serif;
    --sans:'Manrope','Segoe UI',system-ui,-apple-system,Roboto,sans-serif;

    /* Sombra larga y suave, de foto sobre mesa. Nada de sombras grises de
       caja de Bootstrap. */
    --pieza:0 24px 60px -24px rgba(4,25,27,.45);
    --pieza-corta:0 10px 28px -20px rgba(4,25,27,.5);
    --calma:cubic-bezier(.22,1,.36,1);
  }

  * { box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
  html { height:100%; }
  body {
    margin:0; min-height:100%;
    font-family:var(--sans); font-weight:500;
    color:var(--texto); background:var(--hueso);
    -webkit-font-smoothing:antialiased;
    /* NO lleva `overflow-x:hidden`. Taparlo esconde el sintoma y deja el
       desborde vivo: cada pieza tiene que caber de verdad (por eso los
       `min-width:0` de la rejilla de fechas y del nombre del paciente).
       Verificado a 390 y a 1280 px: 0 px de desborde. */
  }
  .display { font-family:var(--display); font-weight:700; letter-spacing:-.02em;
             font-variation-settings:'SOFT' 20,'WONK' 0; font-optical-sizing:auto; }
  .oculto { display:none !important; }
  .cifras { font-variant-numeric:tabular-nums; }

  /* El foco se VE. Un medico que llega con teclado (o una lectora de
     pantalla) tiene que saber donde esta parado. */
  :focus-visible { outline:2.5px solid var(--turq-600); outline-offset:2px; border-radius:6px; }
  .portada :focus-visible { outline-color:var(--turquesa); }

  /* ── EL GRANO ──────────────────────────────────────────────────────
     Una capa de ruido finisimo sobre todo. No se «ve»: se nota. Es lo que
     separa un degradado plano de papel impreso. Va fija, no captura clics y
     es la misma receta que `global.css` de la web. El SVG va incrustado:
     la CSP de `_headers` permite `img-src data:` y ningun archivo suelto. */
  body::after {
    content:''; position:fixed; inset:0; z-index:90; pointer-events:none;
    opacity:.038;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  /* ── MOVIMIENTO ────────────────────────────────────────────────────
     Un solo gesto, bien orquestado: las piezas SUBEN 18 px y se revelan. El
     ojo lo lee como «llego», no como «reboto».

     `backwards`, NUNCA `both`. Con `both` el elemento se queda en el primer
     fotograma —`opacity:0`— si la animacion no llega a avanzar, y la pagina
     entera se ve en blanco aunque el contenido este ahi. Paso de verdad al
     renderizar con la ventana oculta (2026-09-20): la ficha y las areas del
     detalle existian, ocupaban su alto, y no se veia una sola letra. Con
     `backwards` el estado en reposo es el NATURAL (visible) y el `from` solo
     manda durante el retardo: si la animacion no corre, todo se ve igual.
     Ademas nada lleva `opacity:0` en su estado base, por la misma razon. */
  @keyframes surgir { from { opacity:0; transform:translate3d(0,18px,0); } to { opacity:1; transform:none; } }
  @keyframes trazar { from { transform:scaleX(0); } to { transform:scaleX(1); } }
  .surge { animation:surgir .75s var(--calma) backwards; }

  /* Los retardos van en CLASES y no en `style=""` porque la CSP de este sitio
     es `style-src 'self'` SIN `unsafe-inline` (ver `_headers`): un atributo
     `style` lo descarta el navegador EN SILENCIO. En local no se nota —no hay
     CSP— y en Cloudflare las ocho entradas aparecerian todas de golpe en vez
     de escalonadas. El propio `_headers` lo advierte; esto lo cumple. */
  .surge-08 { animation-delay:.08s; }
  .surge-16 { animation-delay:.16s; }
  .surge-20 { animation-delay:.20s; }
  .surge-24 { animation-delay:.24s; }
  .surge-30 { animation-delay:.30s; }
  .surge-34 { animation-delay:.34s; }
  .surge-40 { animation-delay:.40s; }

  /* ══════════════════════════════════════════════════════════════════
     ENTRAR — la portada partida
     ══════════════════════════════════════════════════════════════════
     No es una caja blanca centrada. Es una portada: tinta arriba (o a la
     izquierda) con la marca y el titular de imprenta, hueso abajo (o a la
     derecha) con el formulario. La mitad donde se teclea es la CLARA a
     proposito: es la que se usa de pie, en consulta, a veces con sol. */
  body.entrando { padding:0; background:var(--hueso); }
  .entrada {
    min-height:100vh; min-height:100svh;
    display:grid; grid-template-rows:auto 1fr;
  }

  .portada {
    position:relative; isolation:isolate; overflow:hidden;
    background:linear-gradient(168deg,var(--tinta-700),var(--tinta) 45%,var(--tinta-900));
    color:var(--hueso);
    padding:24px 20px 0;
    display:flex; flex-direction:column;
  }
  /* Un resplandor turquesa muy abierto: da profundidad sin que se note. */
  .portada::before {
    content:''; position:absolute; z-index:-1; pointer-events:none;
    width:30rem; height:30rem; right:-11rem; top:-9rem; border-radius:50%;
    background:rgba(30,202,211,.20); filter:blur(110px);
  }
  .portada__in { flex:1 1 auto; max-width:30rem; display:flex; flex-direction:column; }

  /* El logo va INCRUSTADO, no como archivo aparte, y hay dos razones
     concretas:
       · `_redirects` tiene un comodin — un archivo faltante devuelve el
         HTML del portal y la imagen sale rota en vez de dar 404;
       · este sitio se sube en un .zip y el Compress-Archive de Windows
         escribe las rutas con barra INVERTIDA, asi que Cloudflare no crea
         la subcarpeta: crea un archivo llamado literalmente
         "brandlos-angeles.png" y el logo sale roto. Sin subcarpetas, eso
         no puede volver a pasar.
     Cuesta ~20KB de HTML y ahorra un viaje de red.
     Y va SOBRE LA TINTA, sin recuadro: es la version turquesa sobre
     transparencia, que es justo la que esta hecha para fondo oscuro. */
  /* 2026-09-20 (segunda vuelta): «agrandaria el logo mas». Tenia 150px y se
     veia chico para el hueco que tiene la portada. El `max-width` en % es el
     que manda en los telefonos angostos — sin el, en una pantalla de 320 px
     el logo se comeria todo el ancho. */
  .logotipo { width:206px; max-width:62%; height:auto; display:block; }

  /* El rotulo de seccion de la web: versalitas espaciadas con una linea
     turquesa delante. */
  .rotulo {
    display:flex; align-items:center; gap:12px; margin:20px 0 0;
    font-size:10.5px; font-weight:800; letter-spacing:.22em; text-transform:uppercase;
    color:var(--turq-300);
  }
  .rotulo::before {
    content:''; flex:0 0 auto; width:30px; height:1px; background:var(--turquesa);
    transform-origin:left; animation:trazar 1s var(--calma) .25s backwards;
  }

  .portada__titulo {
    font-family:var(--display); font-weight:700;
    font-size:clamp(28px,7.6vw,40px); line-height:1.04; letter-spacing:-.025em;
    font-variation-settings:'SOFT' 20,'WONK' 0; font-optical-sizing:auto;
    margin:12px 0 0; color:#fff; max-width:14ch;
  }
  /* El acento de la casa: la palabra que importa, en cursiva turquesa. */
  .portada__titulo em { font-style:italic; color:var(--turq-300); }
  .portada__titulo .punto { color:var(--turquesa); }

  .portada__lede {
    margin:13px 0 0; max-width:36ch;
    font-size:14.5px; font-weight:500; line-height:1.55; color:rgba(246,243,238,.78);
  }

  /* Los sellos, cosidos al pie de la portada — igual que las cifras del
     heroe de la web: cierran la escena en vez de interrumpirla. */
  .sellos {
    list-style:none; margin:20px -20px 0; padding:0;
    border-top:1px solid var(--linea-oscura);
    display:grid; grid-template-columns:repeat(3,1fr);
  }
  .sellos li { padding:11px 12px; border-left:1px solid var(--linea-oscura); }
  .sellos li:first-child { border-left:0; padding-left:20px; }
  .sellos b {
    display:block; font-size:10px; font-weight:800; letter-spacing:.13em;
    text-transform:uppercase; color:var(--turq-300); line-height:1.35;
  }
  /* El descriptor solo cabe con holgura en pantalla ancha. En el telefono
     manda el rotulo corto: tres renglones de letra de 9 px se leen a pulso. */
  .sellos span { display:none; }

  .acceso {
    background:var(--hueso);
    display:flex; flex-direction:column; justify-content:center;
    padding:20px 20px 22px;
  }
  .acceso__in { width:100%; max-width:26rem; margin:0 auto; }
  .acceso__titulo {
    font-family:var(--display); font-weight:700; letter-spacing:-.02em;
    font-variation-settings:'SOFT' 20,'WONK' 0; font-optical-sizing:auto;
    font-size:22px; line-height:1.18; margin:0 0 2px;
  }
  .acceso__pie {
    margin:5px 0 14px; font-size:13.5px; font-weight:500; color:var(--texto-2);
    line-height:1.5;
  }

  label {
    font-size:10.5px; font-weight:800; display:block; margin:14px 0 7px;
    letter-spacing:.16em; text-transform:uppercase; color:var(--tinta-400);
  }
  input[type=text], input[type=password], input[type=search], input[type=date] {
    width:100%; border:1.5px solid var(--arena); border-radius:12px;
    padding:14px 13px; font-size:17px; font-weight:700; font-family:inherit;
    color:var(--texto); background:var(--papel); outline:none;
    min-height:54px;              /* area tactil amplia: se usa de pie */
    -webkit-appearance:none; appearance:none;
    transition:border-color .2s var(--calma), box-shadow .2s var(--calma);
  }
  input:focus { border-color:var(--turq-600); box-shadow:0 0 0 3px var(--turq-50); outline:none; }
  input::placeholder { color:#8A8377; font-weight:600; opacity:1; }

  .boton {
    width:100%; min-height:56px; padding:15px; border:none; border-radius:999px;
    background:var(--turquesa); color:var(--tinta-900);
    font-size:16px; font-weight:800; font-family:inherit; cursor:pointer;
    margin-top:18px; letter-spacing:.02em;
    box-shadow:0 14px 30px -18px rgba(15,122,130,.9);
    transition:transform .25s var(--calma), background-color .2s, box-shadow .25s var(--calma);
  }
  .boton:hover { background:var(--turq-300); transform:translateY(-1px); }
  .boton:active { background:var(--turq-600); color:#fff; transform:none; }
  .boton[disabled] { opacity:.5; cursor:default; transform:none; }

  /* ── El ojito de la clave ── */
  .campo { position:relative; }
  .campo input { padding-right:58px; }
  .ojo {
    position:absolute; right:5px; top:50%; transform:translateY(-50%);
    width:48px; height:48px; margin:0; padding:0; border:none; border-radius:10px;
    background:none; color:var(--texto-2);
    display:flex; align-items:center; justify-content:center; cursor:pointer;
  }
  .ojo:hover { color:var(--turq-700); }
  .ojo:active { background:var(--hueso-200); }
  .ojo svg { width:25px; height:25px; }

  /* ── Mensajes ── */
  .msg { font-size:14.5px; font-weight:700; margin-top:14px; line-height:1.45; }
  .msg:empty { display:none; }
  /* Papel sobre hueso, con la barra de color a la izquierda: el mensaje se
     ve como una nota puesta encima, no como texto suelto. */
  .msg.err, .msg.espera {
    padding:12px 14px; border-radius:12px; background:var(--papel);
    border:1px solid var(--arena); border-left:4px solid currentColor;
    box-shadow:var(--pieza-corta);
  }
  .msg.err { color:var(--err); }
  .msg.espera { color:var(--espera); }

  .credito {
    display:flex; align-items:center; justify-content:center; gap:8px;
    margin-top:20px; padding-top:14px; border-top:1px solid var(--arena);
    font-size:11px; font-weight:600; color:var(--texto-2); letter-spacing:.04em;
  }
  .credito svg { width:15px; height:15px; color:var(--turq-600); flex:0 0 auto; }
  .credito b { color:var(--turq-700); font-weight:800; letter-spacing:.12em; }

  /* ── Escritorio: la portada se parte en dos columnas ── */
  @media (min-width:880px) {
    .entrada { grid-template-rows:none; grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr); }
    .portada { padding:48px 0 0 clamp(40px,5vw,84px); justify-content:center;
               box-shadow:20px 0 46px -30px rgba(4,25,27,.75); }
    .portada::before { width:40rem; height:40rem; right:-16rem; top:12%; }
    .portada__in { max-width:32rem; padding-right:40px; justify-content:center; }
    .logotipo { width:290px; max-width:none; }
    .portada__titulo { font-size:clamp(40px,4.2vw,56px); margin-top:18px; }
    .portada__lede { font-size:16.5px; margin-top:20px; }
    .sellos { margin:auto 0 0 calc(-1 * clamp(40px,5vw,84px)); padding-left:0; }
    .sellos li { padding:20px 22px; }
    .sellos li:first-child { padding-left:clamp(40px,5vw,84px); }
    .sellos span {
      display:block; margin-top:7px; font-size:12px; font-weight:500;
      line-height:1.4; color:rgba(246,243,238,.6); max-width:22ch;
    }
    .acceso { padding:48px clamp(40px,5vw,84px); }
    .acceso__in { max-width:23rem; margin:0; }
    .acceso__titulo { font-size:26px; }
  }

  /* ══════════════════════════════════════════════════════════════════
     YA ADENTRO — LA HERRAMIENTA
     ══════════════════════════════════════════════════════════════════
     TERCERA VUELTA, 2026-09-20. El dueño lo probó y dijo: «siento que es
     inmenso el texto, como que si fuera de juguete, debe ser más serio, es un
     portal de consulta». Y en seguida dijo con qué compararlo: la **Lista de
     trabajo** de LABXIS (`src/features/pacientes/ListaTrabajoScreen.jsx`).

     Así que de aquí para abajo los cuerpos son los del kit de los módulos
     (`src/shared/modUI.jsx`), no los de una portada:
       · título de la pantalla   21px  → 16px/800   (`Encabezado` de modUI)
       · línea de contexto       —     → 12px       (la de la Lista de trabajo)
       · encabezado de tabla     10px  → 10px/800   (`th`)
       · celda de tabla          12.5px → 12px      (`td` del kit es 12.5)
       · nombre del paciente     17.5px Fraunces → 12.5px Manrope/700
       · botones de la barra     16px, 56px de alto → 12.5px, 30px
       · campos                  17px, 54px de alto → 12.5px, 32px (escritorio)
       · chip de estado          10.5px → 9.5px     (`Chip` del kit es 10.5)

     LA PORTADA DEL INGRESO NO SE TOCA. Es la carta de presentación, su escala
     editorial es a propósito y al dueño le gusta. Por eso TODO lo compacto va
     colgado de `.app`, que solo existe ya adentro: ni un selector de esta
     sección alcanza al ingreso. */
  body.trabajando { padding:0; background:var(--hueso); }
  .app { max-width:680px; margin:0 auto; padding:0 14px 40px; }
  #pantallaLista.app { max-width:760px; }
  /* Las rejillas NO llevan el tope de lectura de 680 px. Ese tope existe para
     el texto corrido —una línea de 140 caracteres no se lee, se barre—, pero
     aplicado a una rejilla de tarjetas deja media ventana vacía, que es el
     defecto que señaló el dueño: «no se está aprovechando la pantalla, se ve
     todo englobado en el centro» (GUIA-VISUAL §9). */
  #pantallaInicio.app       { max-width:1500px; }
  #pantallaHerramientas.app { max-width:1500px; }

  /* ── LAS TARJETAS DE MÓDULO ────────────────────────────────────────
     Pedido del dueño (2026-09-21): «en vez de tener pestañas arriba,
     podemos hacer tarjetas independientes para que ellos puedan entrar y
     salir de los módulos […] como LABXIS, que es modular y le da más
     presencia».

     Es la MISMA pieza que `ModuloCard` de LABXIS (src/features/launcher/
     Launcher.jsx), con su geometría exacta: fondo de lienzo, borde que se
     vuelve de marca al pasar, radio 18, padding 18, azulejo de 46 px con el
     ícono en blanco, título 15/700 y bajada 11.5. No se copió el estilo «a
     ojo»: se leyó el componente, que es lo que la guía pide para que las dos
     plataformas no vuelvan a divergir (GUIA-VISUAL §7).

     La identidad turquesa es la del laboratorio; la ESTRUCTURA es la de
     LABXIS. Eso es el conglomerado que pidió el dueño. */
  .modulos {
    margin-top:16px; display:grid; gap:14px;
    grid-template-columns:repeat(auto-fill,minmax(270px,1fr));
  }
  /* ⚠️ FONDO BLANCO, NO `--hueso`. La primera versión copió el
     `background: T.canvas` de la tarjeta de LABXIS sin mirar SOBRE QUÉ SE
     APOYA: en LABXIS esa tarjeta vive sobre un panel blanco y contrasta; acá
     el fondo de la página YA es hueso, así que quedó pintada del mismo color
     que el fondo y se perdía. Es el defecto nº 1 de la guía visual (§1.B):
     «pintar algo del MISMO color del fondo sobre el que se apoya — compila,
     no rompe nada, y simplemente no se ve». El dueño ya lo había puesto como
     regla: tarjeta blanca que haga contraste. */
  .modulo {
    text-align:left; appearance:none; font:inherit; cursor:pointer;
    background:var(--papel); border:1px solid var(--arena); border-radius:18px;
    padding:18px; display:flex; flex-direction:column; gap:12px;
    transition:transform .16s var(--calma), box-shadow .16s var(--calma), border-color .16s var(--calma);
    animation:surgir .5s var(--calma) backwards;
  }
  .modulo:nth-of-type(2) { animation-delay:.05s; }
  .modulo:nth-of-type(3) { animation-delay:.10s; }
  .modulo:nth-of-type(n+4) { animation-delay:.15s; }
  .modulo:hover {
    border-color:var(--turquesa); transform:translateY(-2px);
    box-shadow:0 6px 22px rgba(6,40,43,.12);
  }
  .modulo:focus-visible { outline:2.5px solid var(--turq-600); outline-offset:2px; }
  /* EL DEGRADÉ DE LABXIS, con su valor real: `--grad` de `src/index.css`,
     `linear-gradient(48deg,#1D6E9C,#3BB394)`. Es el de los botones de la
     plataforma y lo que la vuelve reconocible de lejos.

     Acá es donde el dueño pidió «un conglomerado de los dos»: la ESTRUCTURA y
     este degradé son de LABXIS —la plataforma—, y el turquesa del resto de la
     pantalla es del Laboratorio Clínico Los Ángeles —quien contrata—. Va en
     valor literal y no en token porque este portal no carga el sistema de
     LABXIS; es una de las excepciones que la guía §6 permite para los
     portales estáticos. */
  .modulo__icono {
    width:46px; height:46px; border-radius:13px; flex-shrink:0;
    display:flex; align-items:center; justify-content:center;
    background:linear-gradient(48deg,#1D6E9C 0%,#3BB394 100%);
    color:#fff;
  }
  .modulo__t { font-size:15px; font-weight:800; color:var(--texto); line-height:1.2; }
  .modulo__d { font-size:11.5px; color:var(--texto-2); margin-top:4px; line-height:1.45; }

  .barra {
    background:linear-gradient(120deg,var(--tinta),var(--tinta-700));
    color:var(--hueso);
    position:sticky; top:0; z-index:10;
    box-shadow:0 2px 20px rgba(4,25,27,.26);
  }
  /* El filo turquesa: un pelo de acento que le da borde a la barra sin
     pintarla de color. */
  .barra::after {
    content:''; position:absolute; left:0; right:0; bottom:0; height:2px;
    background:linear-gradient(90deg,var(--turquesa),rgba(30,202,211,0) 70%);
  }


  .barra__in {
    max-width:1500px; margin:0 auto; padding:10px 16px;
    display:flex; align-items:center; gap:12px;
  }
  .barra__quien { flex:1 1 auto; min-width:0; }
  .barra__rotulo {
    font-size:9.5px; font-weight:800; letter-spacing:.24em; text-transform:uppercase;
    color:var(--turq-300); margin-bottom:4px;
  }
  /* Era Fraunces de 18/21 px. El nombre del médico es un rótulo de barra, no
     un titular: en sans y a 14 px pesa lo que tiene que pesar. */
  .barra__nombre {
    font-size:19px; font-weight:800; letter-spacing:-.015em;
    line-height:1.2; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    color:#fff;
  }
  .salir {
    flex:0 0 auto; min-height:32px; padding:0 13px;
    border:1px solid rgba(246,243,238,.34); border-radius:999px;
    background:none; color:var(--hueso);
    font-family:inherit; font-size:11px; font-weight:800; cursor:pointer;
    letter-spacing:.06em; text-transform:uppercase;
    transition:background-color .2s, border-color .2s;
  }
  .salir:hover { border-color:var(--turquesa); color:var(--turq-200); }
  .salir:active { background:rgba(246,243,238,.14); }

  /* ── LA CABECERA DE LA PANTALLA ─────────────────────────────────────
     La misma anatomía que la Lista de trabajo: a la izquierda el título con
     su línea de contexto —cuántas órdenes y entre qué fechas—, a la derecha
     el buscador y los botones. El contexto NO es decoración: es lo que deja
     tener los filtros plegados sin que el médico pierda de vista en qué rango
     está parado. */
  .cabecera {
    display:flex; align-items:center; justify-content:space-between;
    flex-wrap:wrap; gap:8px 12px; margin-top:12px;
  }
  .cabecera__quien { min-width:0; display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 9px; }
  .cabecera__titulo { margin:0; font-size:16px; font-weight:800; letter-spacing:-.01em; color:var(--texto); }
  .contexto {
    font-size:12px; font-weight:600; color:var(--texto-2);
    font-variant-numeric:tabular-nums; line-height:1.35;
  }
  .cabecera__acciones { display:flex; align-items:center; gap:7px; flex:1 1 220px; justify-content:flex-end; }

  /* ── Campos compactos — SOLO ya adentro ──
     OJO con el cuerpo en el teléfono: Safari de iOS hace ZOOM solo al enfocar
     un campo de MENOS de 16 px, y después no vuelve. Acá el zoom está abierto
     a propósito (el médico lee valores y referencias), así que un campo de
     12.5 px le dejaría la página ampliada a cada búsqueda. Por eso los campos
     se encogen de 720 px para arriba, que es donde hay ratón. */
  .app input[type=search], .app input[type=date], .app select.selsede {
    min-height:38px; padding:8px 11px; font-size:16px; font-weight:700; border-radius:9px;
  }
  .selsede {
    width:100%; border:1.5px solid var(--arena); font-family:inherit; color:var(--texto);
    background:var(--papel); outline:none; -webkit-appearance:none; appearance:none;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F7A82' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat:no-repeat; background-position:right 10px center; background-size:14px;
    padding-right:32px !important;
  }
  .selsede:focus { border-color:var(--turq-600); box-shadow:0 0 0 3px var(--turq-50); }

  .buscador { position:relative; flex:1 1 170px; max-width:280px; min-width:0; }
  .buscador input { padding-right:38px; }
  .lupa {
    position:absolute; right:3px; top:50%; transform:translateY(-50%);
    width:32px; height:32px; border:none; border-radius:8px; padding:0; margin:0;
    background:none; color:var(--turq-600); cursor:pointer;
    display:flex; align-items:center; justify-content:center;
  }
  .lupa:hover { background:var(--turq-50); }
  .lupa svg { width:17px; height:17px; }

  /* El botón de trabajo: el del kit de los módulos, no el botón de ingreso.
     34 px de alto en el teléfono (dedo) y 30 en escritorio. */
  .mini {
    flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center; gap:6px;
    min-height:34px; padding:0 13px; border-radius:9px;
    border:1px solid var(--arena); background:var(--papel); color:var(--texto);
    font-family:inherit; font-size:12.5px; font-weight:700; cursor:pointer;
    white-space:nowrap; letter-spacing:.01em;
    transition:border-color .18s, background-color .18s, color .18s;
  }
  .mini:hover { border-color:var(--turq-600); color:var(--turq-700); background:var(--turq-50); }
  .mini:active { background:var(--turq-50); }
  .mini[disabled] { opacity:.45; cursor:default; }
  .mini[disabled]:hover { border-color:var(--arena); color:var(--texto); background:var(--papel); }
  /* Plegado/desplegado de los filtros: un botón que ESTÁ ENCENDIDO se ve
     encendido. Una afordancia escondida no se encuentra, se tropieza con ella
     (GUIA-VISUAL §10). */
  .mini--on { border-color:var(--turq-600); background:var(--turq-50); color:var(--turq-700); }
  .mini--fuerte { background:var(--tinta); border-color:var(--tinta); color:var(--hueso); }
  .mini--fuerte:hover { background:var(--turq-700); border-color:var(--turq-700); color:#fff; }
  .mini--claro {
    background:rgba(246,243,238,.12); border-color:rgba(246,243,238,.34); color:#fff;
  }
  .mini--claro:hover { background:var(--turquesa); border-color:var(--turquesa); color:var(--tinta-900); }
  .mini--claro[disabled]:hover { background:rgba(246,243,238,.12); border-color:rgba(246,243,238,.34); color:#fff; }

  /* ── LA FRANJA DE FILTROS ──
     Plegada por omisión, igual que en la Lista de trabajo. No es por ahorrar
     espacio en escritorio: es que el médico abre el portal PARA VER LA LISTA,
     y un formulario de 200 px arriba empuja la primera fila fuera de la
     pantalla. El rango sigue a la vista en la línea de contexto, así que
     plegar no esconde ningún dato. */
  .franja {
    margin-top:10px; display:grid; gap:9px 14px; align-items:end;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    background:var(--papel); border:1px solid var(--arena); border-radius:12px;
    padding:11px 12px; box-shadow:var(--pieza-corta);
  }
  .franja__campo { min-width:0; }
  /* Sin esto manda la regla de `label` del ingreso (10.5px con 14px de margen
     arriba), que acá deja un renglón de aire entre cada campo. */
  .franja label { margin:0 0 5px; font-size:9.5px; letter-spacing:.14em; }
  .atajos { grid-column:1 / -1; display:flex; gap:6px; flex-wrap:wrap; margin:0; }
  .atajo {
    flex:0 0 auto; min-height:30px; padding:0 13px;
    border:1px solid var(--arena); border-radius:999px; background:var(--hueso);
    color:var(--texto-2); font-family:inherit; font-size:12px; font-weight:700; cursor:pointer;
    transition:border-color .2s, background-color .2s, color .2s;
  }
  .atajo:hover  { border-color:var(--turq-600); color:var(--turq-700); background:var(--turq-50); }
  .atajo:active { background:var(--turq-50); border-color:var(--turq-600); color:var(--turq-700); }
  #btnConsultar { grid-column:1 / -1; }

  /* ── LA BARRA DE ACCIONES ──
     La franja petróleo de la Lista de trabajo, con la misma división: a la
     IZQUIERDA lo que acota lo que se ve (las pestañas de estado con su
     conteo), a la DERECHA lo que opera sobre lo marcado. Son dos cosas
     distintas y así dejan de leerse como una sola tira de botones. */
  .acciones {
    margin-top:10px; display:flex; align-items:center; gap:7px; flex-wrap:wrap;
    background:linear-gradient(120deg,var(--tinta),var(--tinta-700));
    color:var(--hueso); border-radius:12px; padding:7px 9px;
  }
  .pestanas { display:flex; align-items:center; gap:5px; flex-wrap:wrap; min-width:0; }
  .pestana {
    display:inline-flex; align-items:center; gap:6px; min-height:30px; padding:0 11px;
    border:0; border-radius:8px; cursor:pointer; font-family:inherit;
    font-size:12.5px; font-weight:600; white-space:nowrap;
    background:rgba(246,243,238,.10); color:#fff;
    transition:background-color .18s;
  }
  .pestana:hover { background:rgba(246,243,238,.20); }
  .pestana--on { background:var(--turq-600); font-weight:800; }
  .pestana__n {
    font-size:11px; font-weight:800; border-radius:9px; padding:1px 6px; min-width:19px;
    text-align:center; background:rgba(246,243,238,.18); font-variant-numeric:tabular-nums;
  }
  .pestana--on .pestana__n { background:rgba(4,25,27,.30); }
  .acciones__der { display:flex; align-items:center; gap:8px; margin-left:auto; flex-wrap:wrap; }
  .acciones__sel {
    font-size:11.5px; font-weight:800; color:var(--turq-200); white-space:nowrap;
    font-variant-numeric:tabular-nums;
  }
  /* «Marcar todos» vive ACÁ y no en el encabezado de la tabla a propósito: en
     el teléfono el encabezado no se muestra (la fila se apila), así que un
     marcar-todos que viviera ahí no existiría justo donde más cuesta marcar
     una por una. Y al haber UNO SOLO no hay dos casillas que sincronizar. */
  .marcar {
    display:inline-flex; align-items:center; gap:7px; margin:0; cursor:pointer;
    font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
    color:var(--turq-200); min-height:30px;
  }
  .marcar:hover { color:#fff; }
  .casilla {
    width:15px; height:15px; margin:0; flex:0 0 auto; cursor:pointer;
    accent-color:var(--turq-600);
  }

  /* ── Avisos dentro de la lista ──
     Todos van en PAPEL o en su propio tinte, nunca del color del lienzo que
     tienen debajo: un aviso que no se ve es un aviso que no existe. */
  .aviso {
    margin-top:10px; padding:11px 13px; border-radius:11px;
    font-size:12.5px; font-weight:600; line-height:1.5;
    box-shadow:var(--pieza-corta);
  }
  .aviso--techo { background:var(--parcial-bg); border:1px solid var(--parcial-bd); border-left:4px solid var(--parcial-fg); color:var(--parcial-fg); }
  .aviso--vacio {
    background:var(--papel); border:1px solid var(--arena); color:var(--texto-2);
    text-align:center; padding:26px 18px; font-size:13px; font-weight:700;
  }
  .aviso--err   { background:var(--fuera-bg); border:1px solid var(--fuera-bd); border-left:4px solid var(--fuera-fg); color:var(--fuera-fg); }
  .aviso--espera{ background:var(--parcial-bg); border:1px solid var(--parcial-bd); border-left:4px solid var(--parcial-fg); color:var(--parcial-fg); }
  .aviso .reintentar {
    display:inline-block; margin-top:10px; min-height:32px; padding:0 18px;
    border:none; border-radius:999px; background:var(--tinta); color:var(--hueso);
    font-family:inherit; font-size:12px; font-weight:800; cursor:pointer;
    letter-spacing:.05em; text-transform:uppercase;
    transition:background-color .2s;
  }
  .aviso .reintentar:hover { background:var(--turq-700); }

  /* ══════════════════════════════════════════════════════════════════
     LA LISTA — UNA TABLA DE TRABAJO
     ══════════════════════════════════════════════════════════════════
     Se copia la FORMA de las tablas de los módulos —`src/shared/modUI.jsx`,
     `ListaTrabajoScreen.jsx`— traducida a la paleta de este portal:
       · la tabla va SIEMPRE sobre una tarjeta (papel), nunca sobre el lienzo;
       · el encabezado NO es una banda de color: es del mismo papel, con el
         rótulo en turquesa oscuro y una línea de 2 px abajo — la estructura la
         hace la LÍNEA, no un relleno (GUIA-VISUAL §2);
       · rayado alterno contra el papel de la tarjeta, nunca contra el lienzo
         (GUIA-VISUAL §1);
       · separadores de 1 px, cifras tabulares y CASILLA de selección al canto.

     En el TELÉFONO una tabla de nueve columnas no cabe, así que la MISMA fila
     se apila en cuatro renglones — que siguen alineados de fila a fila, porque
     la rejilla es la misma para todas. Denso y alineado, sin volver a las
     tarjetas grandes y sin obligar a desplazar de lado. */
  .ordenes { display:block; margin-top:10px; }

  .tabla {
    /* Las nueve columnas viven en UNA variable. El encabezado y el cuerpo son
       rejillas HERMANAS (no una <table> de verdad): si las dos no leen
       exactamente el mismo valor, las columnas dejan de alinear y no hay nada
       que lo avise.

       Los mínimos NO son al ojo: cada uno es lo que mide el dato más ancho que
       de verdad sale del catálogo, medido en la captura, con los cuerpos NUEVOS
       (celda de 12 px, chip de 9.5). Un mínimo corto no desborda: PARTE
       —«MAZ-2009260 01», «Mazatenang o»—, que se ve peor.
         casilla   28 → la casilla de 15 px con su aire
         estado   152 → el chip «RESULTADOS LISTOS» entero (es el más largo)
         paciente 154 → «Chávez de León María Esperanza» en un renglón
         dpi      112 → «2458 96321 0901» mide 102 medido en la captura
         edad      76 → «47 años · M»
         orden    112 → «MAZ-200926001» mide 99 en peso 800
         fecha     74 → «20/09/2026»
         sede      80 → «Mazatenango» (y si no cabe, se corta con puntos)
         pruebas   54 → el rótulo «PRUEBAS», que es más ancho que el número
       Suma 842 + 8 huecos de 10 + 24 de padding = 946 px. Por eso la tabla de
       una sola línea empieza a los 1000 de ventana y no antes. */
    /* ESTADO va en 158 y no en 142 (2026-09-28). El comentario de arriba ya
       decia 152 —«el chip RESULTADOS LISTOS entero»— pero la variable tenia
       142: diez menos que lo que el propio calculo pedia. El chip no cabia y
       se salia de su columna cruzando la linea divisoria hacia el nombre del
       paciente, que es lo que se veia como «encabezados desalineados» y
       «fichas mal medidas». Se le dan 158 para que quepa con aire, no al ras:
       al ras, cualquier rotulo de estado un poco mas largo lo vuelve a romper. */
    --cols: 28px 158px minmax(160px,1.9fr) minmax(116px,.75fr) 104px minmax(116px,.6fr) 88px minmax(92px,.9fr) 58px;
    background:var(--papel); border:1px solid var(--arena); border-radius:12px;
    overflow:hidden; box-shadow:var(--pieza-corta);
  }
  /* Tabla ancha → desplaza DENTRO de su tarjeta, nunca la página
     (GUIA-VISUAL §9). Es la red de seguridad: si una ventana angosta no le
     alcanza a las nueve columnas, lo que se corre de lado es la tabla. */
  .tabla__rueda { overflow-x:auto; }
  /* En el teléfono no hay encabezado que mostrar: la fila apilada se lee sola
     (el DPI lleva su rótulo, la edad su unidad, las pruebas su palabra). */
  .tabla__cab { display:none; }
  /* El cuerpo va aparte del encabezado para que el rayado y el «primera fila»
     se cuenten entre FILAS. Con las filas colgando junto al encabezado,
     `:nth-of-type` lo contaba a él como la primera y el rayado salía corrido. */
  .tabla__cuerpo { display:block; }

  .orden {
    display:grid; width:100%; text-align:left; cursor:pointer;
    font-family:inherit; color:var(--texto); background:transparent;
    border:0; border-top:1px solid var(--arena);
    padding:12px 14px; gap:3px 10px;
    grid-template-columns:auto minmax(0,auto) minmax(0,1fr) minmax(0,auto);
    grid-template-areas:
      "sel estado estado fecha"
      "sel pac    pac    pac"
      "sel dpi    dpi    edad"
      "sel folio  sede   pruebas";
    transition:background-color .15s;
  }
  .orden:first-of-type { border-top:0; }
  /* El rayado alterna contra TRANSPARENTE, que deja ver el papel de la
     tarjeta. Pintar la fila par del color del lienzo es el defecto nº 1 de la
     guía: no se ve. */
  .orden:nth-of-type(even) { background:var(--hueso); }
  .orden:hover  { background:var(--turq-50); }
  .orden:active { background:var(--hueso-200); }
  /* El riel de estado al canto. Va por sombra INTERIOR y no por borde: un
     borde de 3 px correría la rejilla 3 px en las filas y el encabezado
     quedaría desalineado. */
  .orden--listos  { box-shadow:inset 3px 0 0 var(--listos-fg); }
  .orden--parcial { box-shadow:inset 3px 0 0 var(--parcial-fg); }
  .orden--proceso { box-shadow:inset 3px 0 0 var(--proceso-bd); }
  /* Una fila marcada se tiene que ver marcada aunque la casilla quede fuera
     de la vista al desplazar la tabla de lado. */
  .orden--sel, .orden--sel:nth-of-type(even) { background:var(--turq-50); }
  .orden--sel { box-shadow:inset 3px 0 0 var(--turq-600); }
  /* Solo las primeras: 300 filas animando a la vez hacen que el teléfono
     tartamudee justo cuando el médico quiere leer. `backwards`, nunca `both`
     (ver la nota de MOVIMIENTO). */
  .tabla .orden:nth-of-type(-n+10) { animation:surgir .5s var(--calma) backwards; }
  .tabla .orden:nth-of-type(2) { animation-delay:.03s; }
  .tabla .orden:nth-of-type(3) { animation-delay:.06s; }
  .tabla .orden:nth-of-type(4) { animation-delay:.09s; }
  .tabla .orden:nth-of-type(5) { animation-delay:.12s; }
  .tabla .orden:nth-of-type(6) { animation-delay:.15s; }
  .tabla .orden:nth-of-type(n+7) { animation-delay:.18s; }

  /* ── Las celdas ──
     `min-width:0` en todas: sin él, una celda con un dato largo (un nombre de
     sede, un DPI tecleado con guiones) empuja su columna y se lleva por
     delante la alineación de toda la tabla. */
  .cel {
    min-width:0; font-size:12px; font-weight:600; color:var(--texto-2);
    line-height:1.35; overflow-wrap:anywhere; font-variant-numeric:tabular-nums;
  }
  /* La casilla es una <label> con toda la celda adentro: en un teléfono hay
     que poder marcar la fila sin apuntarle a 15 px de casilla. */
  .cel--sel {
    grid-area:sel; display:flex; align-items:flex-start; justify-content:center;
    margin:0; padding:2px 6px 0 0; text-transform:none; letter-spacing:0;
  }
  .cel--estado  { grid-area:estado; }
  .cel--pac     { grid-area:pac; margin:3px 0 2px; }
  .cel--dpi     { grid-area:dpi; }
  .cel--edad    { grid-area:edad; text-align:right; }
  .cel--folio   { grid-area:folio; color:var(--texto); font-weight:800; }
  .cel--fecha   { grid-area:fecha; text-align:right; }
  .cel--sede    { grid-area:sede; }
  .cel--pruebas { grid-area:pruebas; text-align:right; white-space:nowrap; }
  /* El DPI lleva su rótulo pegado SOLO en el teléfono, donde no hay
     encabezado que diga que es ese número. */
  .cel--dpi::before {
    content:'DPI '; font-size:9px; font-weight:800; letter-spacing:.14em;
    text-transform:uppercase; color:var(--tinta-400);
  }

  /* El nombre es el rótulo de la fila: es lo que el médico busca al barrer.
     Era Fraunces de 17.5 px —lo que el dueño llamó «de juguete»—; ahora es la
     misma sans del resto, a 13, con el peso haciendo la jerarquía. El serif
     se queda para la portada del ingreso, que es donde tiene sentido. */
  .pac__n { font-size:13px; font-weight:800; line-height:1.25; letter-spacing:-.01em; color:var(--texto); }
  /* POR QUÉ está viendo esa ficha. Debajo del nombre, igual que el código
     debajo del médico en `ComisionesMedicosScreen`. */
  .pac__via { margin-top:1px; font-size:10.5px; font-weight:600; color:var(--texto-2); }
  /* «6 pruebas» en el teléfono; en la tabla la palabra sobra, porque la dice
     el encabezado de la columna. La pluralización sigue en el JS: el CSS no
     sabe decir «1 prueba». */
  .cel__u { font-weight:600; }

  /* El chip: TEXTO + FORMA + color. El glifo cambia de forma con el estado
     —disco lleno, medio disco, anillo vacío— así que se distingue también en
     blanco y negro, con sol o con daltonismo. */
  .chip {
    flex:0 0 auto; display:inline-flex; align-items:center; gap:5px;
    padding:3px 8px; border-radius:999px; font-size:9.5px; font-weight:800;
    letter-spacing:.05em; text-transform:uppercase; border:1px solid transparent;
    white-space:nowrap; line-height:1.3;
  }
  .chip::before {
    content:''; width:8px; height:8px; border-radius:50%; flex:0 0 auto;
    border:1.5px solid currentColor; background:currentColor;
  }
  .chip--listos  { color:var(--listos-fg);  background:var(--listos-bg);  border-color:var(--listos-bd); }
  .chip--parcial { color:var(--parcial-fg); background:var(--parcial-bg); border-color:var(--parcial-bd); }
  .chip--proceso { color:var(--proceso-fg); background:var(--proceso-bg); border-color:var(--proceso-bd); border-style:dashed; }
  /* medio disco */
  .chip--parcial::before { background:linear-gradient(90deg,currentColor 50%,transparent 50%); }
  /* anillo vacío */
  .chip--proceso::before { background:none; }

  /* ══════════════════════════════════════════════════════════════════
     DETALLE — la anatomía de la pantalla de captura de LABXIS
     ══════════════════════════════════════════════════════════════════
     Pedido del dueño (2026-09-20, cuarta vuelta), señalando
     `ResultadosCapturaScreen.jsx`: «y adentro, al abrir el paciente, así se
     debe de ver o parecido». Se copió su ANATOMÍA, no sus píxeles:

       1. BARRA — Volver · folio · fecha · sede. En la app de escritorio el
          folio va en un chip monoespaciado turquesa y la fecha y la sede con
          su icono al lado; acá igual, con los cuerpos de esta escala.
       2. FRANJA DEL PACIENTE EN CELDAS — PACIENTE · DOCUMENTO · SEXO · EDAD,
          rótulo en versalitas turquesa arriba y dato abajo, con divisores de
          1 px. Y cuando la orden trae convenio, tres celdas más: FRENTE ·
          CUADRILLA · TICKET (pedido textual del dueño para Magdalena). La
          función NO manda esas llaves cuando no hay convenio, así que no hay
          celda vacía que pintar.
       3. HOJA POR ÁREA — banda oscura con el nombre del área y TABLA DENSA
          con encabezado de columnas: ANALITO | RESULTADO | MEDIDA |
          REFERENCIA, con separadores verticales y rayado, como el 4D.
       4. Una entrada de HISTORIAL por línea, al final de la fila, igual que
          en la mesa de trabajo.

     Los cuerpos son los de la tercera vuelta (el kit de `src/shared/modUI.jsx`)
     y no se volvieron a agrandar: el dueño ya dijo una vez que el texto grande
     se veía «de juguete».

     LA REGLA QUE MÁS SE ROMPE (docs/GUIA-VISUAL.md §1): nada se pinta del
     MISMO color del fondo sobre el que se apoya. Acá: el lienzo es hueso, la
     hoja del área es papel, el encabezado de sus columnas es hueso sobre el
     papel de la hoja, y dentro del diálogo —cuyo cuerpo es hueso— la gráfica y
     la tabla vuelven a ser papel. */
  .hoja__barra {
    display:flex; align-items:center; flex-wrap:wrap; gap:7px 9px; margin-top:12px;
  }
  .volver {
    display:inline-flex; align-items:center; gap:7px;
    min-height:32px; padding:0 16px 0 12px;
    border:1px solid var(--arena); border-radius:999px; background:var(--papel);
    color:var(--texto); font-family:inherit; font-size:12px; font-weight:800; cursor:pointer;
    letter-spacing:.05em; text-transform:uppercase;
    box-shadow:var(--pieza-corta);
    transition:border-color .2s, color .2s, transform .25s var(--calma);
  }
  /* Exportar se va al canto derecho de la barra: es una acción sobre lo que
     se está viendo, no parte del camino de vuelta. */
  #btnExportarOrden { margin-left:auto; }
  .volver:hover { border-color:var(--turq-600); color:var(--turq-700); transform:translateX(-2px); }
  .volver:active { background:var(--hueso-200); transform:none; }
  .volver svg { width:15px; height:15px; }

  /* El folio es la identidad de la orden: el mismo chip turquesa de la app de
     escritorio. Cifras tabulares para que dos folios seguidos se comparen
     dígito con dígito. */
  .folio {
    display:inline-flex; align-items:center; min-height:26px; padding:0 10px;
    border-radius:8px; background:var(--turq-50); border:1px solid var(--turq-200);
    color:var(--turq-700); font-size:12px; font-weight:800; letter-spacing:.02em;
    white-space:nowrap;
  }
  .pill {
    display:inline-flex; align-items:center; gap:5px; min-width:0;
    font-size:11.5px; font-weight:700; color:var(--texto-2);
  }
  .pill__i { width:13px; height:13px; flex:0 0 auto; color:var(--turq-600); }

  /* ── LA FRANJA DEL PACIENTE ────────────────────────────────────────
     Las celdas van separadas por el propio fondo de arena asomando entre
     ellas (`gap:1px`), no por bordes: con `border-left` una celda que salta
     de renglón se lleva su línea al canto izquierdo y se ve una raya suelta.
     Así la rejilla queda entera se acomoden como se acomoden. */
  .franja-pac {
    margin-top:10px; display:flex; flex-wrap:wrap;
    gap:1px; background:var(--arena); border:1px solid var(--arena);
    border-radius:11px; overflow:hidden; box-shadow:var(--pieza-corta);
    animation:surgir .5s var(--calma) backwards;
  }
  /* FLEX y no rejilla: en flex las celdas de la ultima fila CRECEN hasta
     llenarla, asi que la franja queda entera con 4 celdas, con 7 (cuando hay
     convenio) o con las que vengan. Con `grid-template-columns` quedaba un
     track vacio del color de la arena. */
  .franja-pac__c { flex:1 1 130px; background:var(--papel); padding:7px 12px; min-width:0; }
  .franja-pac__k {
    font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
    color:var(--turq-700);
  }
  .franja-pac__v {
    margin-top:2px; font-size:12.5px; font-weight:600; color:var(--texto); line-height:1.3;
    font-variant-numeric:tabular-nums;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  /* El NOMBRE ocupa el renglón entero y se muestra COMPLETO, partido si hace
     falta: cortarlo con puntos suspensivos le quita al médico justo el dato
     con el que reconoce a su paciente (misma decisión que la tabla de la
     lista y que la app de escritorio). */
  .franja-pac__c--pac { flex:1 1 100%; }
  .franja-pac__c--pac .franja-pac__v {
    font-size:14.5px; font-weight:800; letter-spacing:-.01em;
    white-space:normal; overflow:visible; overflow-wrap:anywhere;
  }

  /* ── LAS DOS COLUMNAS ──────────────────────────────────────────────
     En el teléfono no hay dos columnas: `.hojas` es un bloque y punto, el
     historial es una ventana que sube desde abajo y `.invita` no existe. La
     partición entra a los 1100 px, que es donde de verdad sobra ancho.
     Acá abajo solo queda declarado lo que vale en los DOS lados. */
  .hojas__pral { min-width:0; }
  .hojas__lado { min-width:0; }
  /* `display:none` en el teléfono, y NO con `.oculto`: el JS usa `.oculto`
     para encenderla y apagarla según haya un historial abierto, así que si
     además la escondiera acá, una de las dos reglas tendría que ganarle a la
     otra. Abajo de 1100 esto manda; de 1100 para arriba manda el JS. */
  .invita { display:none; }

  /* ── LA HOJA DE UN ÁREA ────────────────────────────────────────────
     Las cinco columnas viven en UNA variable, y el encabezado y las filas la
     leen los dos: si cada uno llevara su propia lista, el día que una cambie
     las columnas dejan de alinear y no hay nada que lo avise. */
  .hoja {
    --res:minmax(0,1fr) 72px 56px 84px 32px;
    margin-top:12px; background:var(--papel); border:1px solid var(--arena);
    border-radius:12px; overflow:hidden; box-shadow:var(--pieza-corta);
    animation:surgir .6s var(--calma) backwards;
  }
  .hoja:nth-of-type(2) { animation-delay:.06s; }
  .hoja:nth-of-type(3) { animation-delay:.12s; }
  .hoja:nth-of-type(n+4) { animation-delay:.16s; }
  .hoja__cab {
    background:linear-gradient(110deg,var(--tinta),var(--tinta-700));
    color:var(--hueso); padding:8px 12px;
    display:flex; align-items:baseline; gap:10px;
  }
  .hoja__nombre {
    flex:1 1 auto; min-width:0;
    font-size:13px; font-weight:800; letter-spacing:-.01em; line-height:1.25; color:#fff;
  }
  .hoja__val {
    flex:0 0 auto; font-size:10px; font-weight:800; color:var(--turq-300);
    font-variant-numeric:tabular-nums; letter-spacing:.06em;
  }
  .hoja__pie {
    padding:8px 12px 9px; border-top:1px solid var(--arena); background:var(--hueso);
    font-size:9.5px; font-weight:800; color:var(--texto-2); line-height:1.4;
    letter-spacing:.12em; text-transform:uppercase;
  }
  .hoja__sin { padding:10px 12px; font-size:11.5px; font-weight:600; color:var(--texto-2); }

  /* El encabezado de columnas: hueso sobre el papel de la hoja, con el filo
     turquesa abajo. Mismos cuerpos que el `th` del kit de los módulos. */
  .res__cab {
    display:grid; grid-template-columns:var(--res);
    background:var(--hueso); border-bottom:2px solid var(--turquesa);
  }
  .res__th {
    font-size:9px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
    color:var(--turq-700); padding:5px 7px; white-space:nowrap;
    border-right:1px solid var(--arena);
  }
  .res__th:last-child { border-right:none; }
  .res__th--der { text-align:right; }

  /* La fila: separadores verticales de 1 px y rayado, como la tabla de la
     mesa de trabajo. El rayado alterna contra el papel de la hoja, nunca
     contra el lienzo. */
  /* El cuerpo va aparte del encabezado para que el rayado se cuente entre
     FILAS. Con las filas colgando junto al encabezado, `:nth-child` lo
     contaria a el como la primera y el rayado saldria corrido. */
  .hoja__cuerpo { display:block; }
  .res {
    display:grid; grid-template-columns:var(--res); align-items:center;
    border-top:1px solid var(--hueso-200);
  }
  .res:first-child { border-top:none; }
  .res:nth-child(even) { background:var(--hueso); }
  .res__c {
    padding:5px 7px; min-width:0; font-size:11.5px; font-weight:600; color:var(--texto-2);
    line-height:1.3; border-right:1px solid var(--hueso-200);
  }
  .res__analito { color:var(--texto); font-weight:700; overflow-wrap:anywhere; }
  .res__valor {
    color:var(--texto); font-weight:800; text-align:right; overflow-wrap:anywhere;
    font-variant-numeric:tabular-nums; font-size:12.5px; letter-spacing:-.01em;
  }
  .res__medida { font-size:10.5px; }
  .res__ref { font-size:10.5px; font-variant-numeric:tabular-nums; }
  .res__ref--sin { color:var(--proceso-fg); font-style:italic; }
  .res__acc { padding:3px 3px; display:flex; align-items:center; justify-content:center; }

  /* Fuera de rango: color + triángulo + una barra al canto. NUNCA la palabra
     «alto» o «bajo» — el laboratorio entrega el dato, el diagnóstico es del
     médico. Salta, pero no grita: es un tinte, no un bloque rojo. */
  .res--fuera, .res--fuera:nth-child(even) {
    background:var(--fuera-bg); box-shadow:inset 3px 0 0 var(--fuera-fg);
  }
  .res--fuera .res__valor { color:var(--fuera-fg); }
  .res--fuera .res__ref { color:#8A4038; }
  /* OJO: `.marca` la crea el JS (crearMarca) para el triángulo. No es un
     nombre libre — dárselo también al logo del ingreso le metía `width:150px`
     al triángulo y le comía 157 px a la columna del valor. El logo se llama
     `.logotipo`. */
  .marca { display:inline-block; margin-right:5px; font-size:11px; color:var(--fuera-fg); vertical-align:1px; }
  /* EL TERCER ESTADO. `fuera_de_rango` puede venir en NULL —el 4DLab no
     siempre guardó referencias—, y eso NO es «dentro de rango»: es «no se
     sabe». Pintarlo como los demás le inventaría al médico una tranquilidad
     que el dato no tiene. Rombo hueco y gris: distinto en FORMA, no solo en
     color, para que se distinga en un teléfono al sol y con daltonismo. */
  .sinref { display:inline-block; margin-right:5px; font-size:11px; color:var(--proceso-fg); vertical-align:1px; }

  /* La entrada al historial, al final de la fila — igual que en la mesa de
     trabajo de LABXIS. 26 px en el teléfono: es lo mínimo que un dedo acierta
     sin agrandar la fila. */
  .lupa-hist {
    width:26px; height:26px; padding:0; flex:0 0 auto;
    display:inline-flex; align-items:center; justify-content:center;
    border:1px solid var(--arena); border-radius:7px; background:var(--papel);
    color:var(--turq-700); cursor:pointer;
    transition:border-color .16s, background-color .16s, color .16s;
  }
  .lupa-hist svg { width:14px; height:14px; }
  .lupa-hist:hover { background:var(--turq-50); border-color:var(--turq-600); color:var(--turq-700); }
  .lupa-hist:active { background:var(--hueso-200); }

  .pendiente {
    margin-top:10px; padding:11px 15px;
    background:var(--papel); border:1px solid var(--arena);
    border-left:4px solid var(--proceso-bd); border-radius:12px;
    box-shadow:var(--pieza-corta);
  }
  .pendiente__area { font-size:13px; font-weight:800; letter-spacing:-.01em; }
  .pendiente__txt {
    margin-top:4px; font-size:9.5px; font-weight:800; color:var(--texto-2);
    letter-spacing:.14em; text-transform:uppercase;
  }

  /* La leyenda va en PAPEL, no en hueso: sobre el lienzo hueso, un recuadro
     hueso es justo el defecto nº 1 de la guía visual — se ve como un borde
     suelto en vez de una nota. */
  .leyenda {
    margin-top:16px; padding:11px 14px; border-radius:12px;
    background:var(--papel); border:1px solid var(--arena);
    border-left:4px solid var(--fuera-bd);
    font-size:11.5px; font-weight:500; color:var(--texto-2); line-height:1.6;
  }
  .leyenda b { color:var(--fuera-fg); font-size:12px; }
  .leyenda b.leyenda__sr { color:var(--proceso-fg); }

  /* ══════════════════════════════════════════════════════════════════
     EL HISTORIAL DE UN ANALITO — el diálogo
     ══════════════════════════════════════════════════════════════════
     La misma ventana que `HistorialAnalitoDialog.jsx` de la app de
     escritorio: gráfica arriba y tabla abajo. Con dos diferencias que manda
     la función de la base (20261028):

       · NO hay columna «orden». La serie no devuelve ni folio ni sede de
         órdenes ajenas a propósito —un folio es un identificador que se puede
         volver a pedir—, así que esa columna dice de dónde viene el dato:
         LABXIS o el 4DLab.
       · La gráfica se dibuja A MANO en SVG. La CSP solo deja hablar con la
         Edge Function y traer letras de Google: ninguna librería de gráficos
         puede cargar, ni desde un CDN ni desde acá.

     En el teléfono el diálogo sube desde el borde de abajo (hoja) y en
     escritorio se centra. Por encima del grano (z-index 90) y de la barra
     (10). */
  /* Mientras la ventana tapa la pantalla, lo de atrás no se desplaza — si no,
     el dedo mueve la ficha de abajo creyendo que mueve la tabla del
     historial. De 1100 para arriba el historial NO tapa nada (es la columna
     de la derecha), así que la página tiene que poder desplazarse normal. */
  @media (max-width:1099px) { body.con-modal { overflow:hidden; } }
  /* ── EL SELECTOR DE EXÁMENES A EXPORTAR ────────────────────────────
     Filas anchas y clicables enteras, no una casilla de 13 px al lado de un
     texto: esto se usa con prisa y la casilla sola es un blanco chico
     (GUIA-VISUAL §10 — una afordancia que hay que cazar no es una
     afordancia). El contador de cuántas filas aporta cada examen va a la
     derecha, para poder decidir sin abrir el archivo. */
  .expsel { display:grid; gap:9px; }

  /* ── LAS SECCIONES DEL SELECTOR ────────────────────────────────────
     Una tarjeta por área —química sanguínea, orina, coprología—, que se abre.
     La cabecera va en el hundido y el contenido en papel: es la jerarquía de
     fondos de la guía (§1), y acá cumple una función concreta — se ve de un
     vistazo dónde empieza y termina cada sección. */
  .expgrp {
    border:1px solid var(--arena); border-radius:12px; overflow:hidden;
    background:var(--papel);
  }
  .expgrp__cab {
    display:flex; align-items:center; gap:10px; cursor:pointer; list-style:none;
    padding:11px 13px; background:var(--hueso-200); user-select:none;
  }
  .expgrp__cab::-webkit-details-marker { display:none; }
  /* El triángulo lo dibujamos nosotros: el nativo no se puede alinear ni
     colorear y queda pegado al borde. */
  .expgrp__cab::after {
    content:''; margin-left:auto; flex:0 0 auto;
    width:8px; height:8px; border-right:2px solid var(--turq-700);
    border-bottom:2px solid var(--turq-700); transform:rotate(45deg) translate(-2px,-2px);
    transition:transform .18s var(--calma);
  }
  .expgrp[open] > .expgrp__cab::after { transform:rotate(225deg) translate(-2px,-2px); }
  .expgrp__chk { width:18px; height:18px; accent-color:var(--turq-600); cursor:pointer; flex:0 0 auto; }
  .expgrp__t {
    font-size:10.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
    color:var(--turq-700); min-width:0;
  }
  .expgrp__c { font-size:11px; font-weight:600; color:var(--texto-2); }
  .expgrp__in { display:grid; gap:5px; padding:10px 11px 12px; }
  /* Dentro de la sección la fila ya no necesita su propio marco: la tarjeta
     del área es el marco. Anidar dos bordes es el defecto que la guía marca
     en §1 («no anidar tarjetas»). */
  .expgrp__in .expsel__it { border-color:transparent; padding:9px 11px; }
  .expgrp__in .expsel__it:hover { border-color:var(--turq-300); }
  .expsel__it {
    display:flex; align-items:center; gap:11px; cursor:pointer;
    padding:11px 13px; border-radius:10px; border:1px solid var(--arena);
    background:var(--papel); transition:border-color .14s var(--calma), background .14s var(--calma);
  }
  .expsel__it:hover { border-color:var(--turq-300); background:var(--turq-50); }
  .expsel__it input { width:18px; height:18px; accent-color:var(--turq-600); flex:0 0 auto; cursor:pointer; }
  .expsel__n { flex:1 1 auto; font-size:13.5px; font-weight:700; color:var(--texto); min-width:0; }
  .expsel__u { font-size:11px; font-weight:600; color:var(--texto-2); }
  .expsel__c {
    flex:0 0 auto; font-size:11px; font-weight:800; color:var(--turq-700);
    background:var(--turq-50); border-radius:999px; padding:3px 9px;
    font-variant-numeric:tabular-nums;
  }
  .expsel__pie {
    display:flex; gap:9px; justify-content:flex-end; align-items:center;
    padding:13px 18px; border-top:1px solid var(--arena); background:var(--hueso);
  }

  .modal {
    position:fixed; inset:0; z-index:120;
    display:flex; align-items:flex-end; justify-content:center;
  }
  .modal__fondo { position:absolute; inset:0; background:rgba(4,25,27,.62); }
  .modal__caja {
    position:relative; z-index:1; width:100%; max-width:720px; max-height:92vh;
    display:flex; flex-direction:column; overflow:hidden;
    background:var(--hueso); border:1px solid var(--arena);
    border-radius:16px 16px 0 0; box-shadow:var(--pieza);
    animation:surgir .32s var(--calma) backwards;
  }
  .modal__cab {
    flex:0 0 auto; display:flex; align-items:flex-start; gap:10px; padding:11px 14px;
    background:linear-gradient(110deg,var(--tinta),var(--tinta-700)); color:var(--hueso);
  }
  .modal__quien { flex:1 1 auto; min-width:0; }
  .modal__titulo {
    margin:0; font-size:14px; font-weight:800; letter-spacing:-.01em; color:#fff;
    line-height:1.25; overflow-wrap:anywhere;
  }
  .modal__sub {
    margin:3px 0 0; font-size:9.5px; font-weight:800; letter-spacing:.14em;
    text-transform:uppercase; color:var(--turq-300);
  }
  .modal__x {
    flex:0 0 auto; width:30px; height:30px; padding:0; border-radius:8px;
    display:inline-flex; align-items:center; justify-content:center;
    border:1px solid rgba(246,243,238,.34); background:none; color:var(--hueso);
    cursor:pointer; transition:border-color .2s, color .2s, background-color .2s;
  }
  .modal__x svg { width:15px; height:15px; }
  .modal__x:hover { border-color:var(--turquesa); color:var(--turq-200); }
  .modal__x:active { background:rgba(246,243,238,.14); }
  /* El cuerpo es LIENZO (hueso) y lo que va encima es papel: si el cuerpo
     fuera papel, la gráfica y la tabla —que son papel— desaparecerían. */
  .modal__cuerpo { flex:1 1 auto; min-height:0; overflow-y:auto; padding:12px 14px 16px; }

  .grafica {
    background:var(--papel); border:1px solid var(--arena); border-radius:11px;
    padding:8px 6px 4px;
  }
  .grafica svg { display:block; }

  /* La barra de exportación del panel del historial: entre la curva y la
     tabla, que es donde separa las dos cosas que se pueden bajar. */
  .hist__exp { display:flex; flex-wrap:wrap; gap:7px; margin-top:10px; }
  /* El mensaje de error vive acá dentro y tiene que ser del cuerpo del panel,
     no del de la portada: .msg mide 14,5 px, que acá sería un grito. */
  .hist__exp .msg { flex:1 1 100%; margin-top:2px; font-size:11.5px; }
  .grafica__nota {
    margin:0; padding:22px 12px; text-align:center;
    font-size:11.5px; font-weight:600; color:var(--texto-2); line-height:1.5;
  }
  .grafica__pie {
    margin:4px 6px 0; font-size:10px; font-weight:600; color:var(--texto-2);
    text-align:right; font-variant-numeric:tabular-nums;
  }
  /* Los colores de la gráfica van por CLASE y no por atributo: así salen de
     los mismos tokens que el resto y no hay un color suelto escrito a mano
     dentro del SVG. */
  .g-banda { fill:var(--turq-50); }
  .g-rejilla { stroke:var(--hueso-300); stroke-width:1; }
  .g-eje { fill:var(--texto-2); font-size:9px; font-weight:700; font-family:var(--sans); }
  .g-fecha { fill:var(--texto-2); font-size:9px; font-weight:600; font-family:var(--sans); }
  .g-linea { fill:none; stroke:var(--turq-600); stroke-width:2.2; stroke-linejoin:round; stroke-linecap:round; }
  /* RELLENO = LABXIS, CONTORNO = 4DLab (lo mismo que hace la app de
     escritorio). Y el color dice el estado del rango: turquesa dentro, rojo
     fuera, gris cuando NO SE SABE — que además va en rombo, para que se
     distinga sin color. */
  .g-p { stroke-width:2; stroke:var(--papel); }
  .g-p--dentro { fill:var(--turq-600); }
  .g-p--fuera { fill:var(--fuera-fg); }
  .g-p--sinref { fill:var(--proceso-fg); }
  .g-p--viejo { fill:var(--papel); }
  .g-p--viejo.g-p--dentro { stroke:var(--turq-600); }
  .g-p--viejo.g-p--fuera { stroke:var(--fuera-fg); }
  .g-p--viejo.g-p--sinref { stroke:var(--proceso-fg); }

  .hist__leyenda {
    display:flex; flex-wrap:wrap; gap:4px 14px; margin-top:9px;
    font-size:10px; font-weight:700; color:var(--texto-2);
  }
  .hist__llave { display:inline-flex; align-items:center; gap:4px; }
  .hist__llave::before { font-size:11px; line-height:1; }
  .hist__llave--dentro::before { content:'●'; color:var(--turq-600); }
  .hist__llave--fuera::before { content:'▲'; color:var(--fuera-fg); }
  .hist__llave--sinref::before { content:'◇'; color:var(--proceso-fg); }
  .hist__llave--viejo::before { content:'○'; color:var(--texto-2); }

  /* La tabla del historial: FECHA | ORIGEN | RESULTADO | UNIDAD | REFERENCIA.
     El encabezado va pegado arriba mientras la tabla se desplaza, y está
     DENTRO del mismo marco que se desplaza: si fuera hermano, la barra de
     desplazamiento le comería unos píxeles a las filas y dejaría de alinear
     con él. */
  .hist {
    --hist:84px 56px minmax(0,1fr) 48px minmax(0,76px);
    margin-top:10px; max-height:246px; overflow-y:auto;
    background:var(--papel); border:1px solid var(--arena); border-radius:11px;
  }
  .hist__cab {
    position:sticky; top:0; z-index:1; display:grid; grid-template-columns:var(--hist);
    background:var(--hueso); border-bottom:2px solid var(--turquesa);
  }
  /* En el telefono los rotulos bajan a 8.5: con 9 px, «REFERENCIA» no entra
     en su columna y se desborda encima de la de al lado. No se abrevian —un
     rotulo cortado se lee como otra cosa. */
  .hist__th {
    font-size:8.5px; font-weight:800; letter-spacing:.03em; text-transform:uppercase;
    color:var(--turq-700); padding:5px 6px; white-space:nowrap;
    border-right:1px solid var(--arena);
  }
  .hist__th:last-child { border-right:none; }
  .hist__th--der { text-align:right; }
  .hist__f {
    display:grid; grid-template-columns:var(--hist); align-items:center;
    border-top:1px solid var(--hueso-200);
  }
  .hist__f:first-of-type { border-top:none; }
  .hist__f:nth-of-type(even) { background:var(--hueso); }
  .hist__f--fuera, .hist__f--fuera:nth-of-type(even) {
    background:var(--fuera-bg); box-shadow:inset 3px 0 0 var(--fuera-fg);
  }
  .hist__c {
    padding:5px 7px; min-width:0; font-size:11px; font-weight:600; color:var(--texto-2);
    line-height:1.3; font-variant-numeric:tabular-nums;
    border-right:1px solid var(--hueso-200); overflow-wrap:anywhere;
  }
  .hist__c:last-child { border-right:none; }
  .hist__valor { color:var(--texto); font-weight:800; text-align:right; font-size:11.5px; }
  .hist__f--fuera .hist__valor { color:var(--fuera-fg); }
  /* De dónde salió el dato. Los del 4DLab van en gris y con el círculo hueco
     de la gráfica: son datos heredados, la curva los usa, pero quien lee
     tiene que saberlo. */
  .hist__origen { font-size:9px; font-weight:800; letter-spacing:.04em; color:var(--turq-700); }
  .hist__origen--viejo { color:var(--texto-2); }
  .hist__ref--sin { color:var(--proceso-fg); font-style:italic; }
  .hist__techo {
    margin:10px 0 0; padding:8px 11px; border-radius:10px;
    background:var(--papel); border:1px solid var(--arena); border-left:4px solid var(--turq-200);
    font-size:10.5px; font-weight:600; color:var(--texto-2); line-height:1.5;
  }

  /* Lo que ocupa la columna del historial mientras no hay ninguno abierto.
     Papel sobre el lienzo hueso, con la línea de puntos que dice «acá va algo
     que todavía no está». */
  .invita {
    background:var(--papel); border:1px dashed var(--arena); border-radius:13px;
    padding:18px 16px; text-align:center;
  }
  .invita__i { width:26px; height:26px; color:var(--turq-600); }
  .invita__t {
    margin:8px 0 0; font-size:13px; font-weight:800; letter-spacing:-.01em; color:var(--texto);
  }
  .invita__p {
    margin:6px 0 0; font-size:11.5px; font-weight:500; color:var(--texto-2); line-height:1.55;
  }

  /* ══════════════════════════════════════════════════════════════════
     LA BIENVENIDA — la pantalla donde cae el médico al entrar
     ══════════════════════════════════════════════════════════════════
     Pedido del dueño (2026-09-20, quinta vuelta): «hagamos una pantalla de
     bienvenida que diga Bienvenida, Rosa López por ejemplo. Muestra info que
     sirva… no de golpe los resultados, algo más interactivo».

     Cuelga de `.app`, así que hereda los cuerpos del kit de los módulos: ni
     una letra vuelve a la escala de la portada. La única que sube es el
     NOMBRE del médico, que es el titular de la pantalla.

     GUIA-VISUAL §1 aplicada a lo nuevo: el lienzo es hueso y TODO lo que se
     apoya encima va en papel, con la arena de línea. Ni un bloque del color
     del fondo sobre el que se apoya. */
  #pantallaInicio.app { max-width:1000px; }

  .saludo {
    display:flex; align-items:flex-end; justify-content:space-between;
    flex-wrap:wrap; gap:10px 16px; margin-top:14px;
  }
  .saludo__quien { min-width:0; flex:1 1 220px; }
  /* «Le damos la bienvenida» — la palabra que pidió el dueño, sin inventarle
     género a nadie. Va en el rótulo y no en el titular porque el titular es
     el NOMBRE: es lo que el médico busca para saber que entró a lo suyo. */
  .saludo__rotulo {
    margin:0; font-size:11px; font-weight:700; letter-spacing:.02em;
    color:var(--turq-700);
  }
  .saludo__nombre {
    margin:3px 0 0; font-size:30px; font-weight:800; letter-spacing:-.025em;
    line-height:1.15; color:var(--texto); overflow-wrap:anywhere;
  }
  .saludo__sub {
    margin:5px 0 0; font-size:12px; font-weight:600; color:var(--texto-2);
    font-variant-numeric:tabular-nums; line-height:1.35;
  }

  /* ── LOS TOTALES ───────────────────────────────────────────────────
     Mismo sistema que la franja del paciente del detalle: las celdas se
     separan con el fondo de arena asomando entre ellas (`gap:1px`), no con
     bordes, así una celda que salta de renglón no se lleva una raya suelta al
     canto. Y en flex las de la última fila CRECEN hasta llenarla. */
  .totales {
    margin-top:12px; display:flex; flex-wrap:wrap;
    gap:1px; background:var(--arena); border:1px solid var(--arena);
    border-radius:11px; overflow:hidden; box-shadow:var(--pieza-corta);
    animation:surgir .5s var(--calma) backwards;
  }
  .total { flex:1 1 118px; background:var(--papel); padding:8px 12px; min-width:0; }
  .total__k {
    font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
    color:var(--turq-700);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .total__v {
    margin-top:2px; font-size:19px; font-weight:800; color:var(--texto);
    line-height:1.15; letter-spacing:-.02em;
  }

  /* ── LAS CALCULADORAS ──────────────────────────────────────────────
     Una tarjeta por herramienta, en rejilla. Cada una es autónoma: sus
     campos, su resultado y su fuente. Nada de un formulario gigante donde
     no se sabe qué campo alimenta qué número. */
  .herrs {
    margin-top:14px; display:grid; gap:14px;
    grid-template-columns:repeat(auto-fill,minmax(310px,1fr));
    align-items:start;
  }
  /* Misma pieza que `.panel`: papel, borde de arena, radio 12 y la sombra
     corta. La estructura la hace la LÍNEA del encabezado, no un relleno de
     color (GUIA-VISUAL §2) — y la línea es `turq-200`, como en los paneles;
     el turquesa pleno acá gritaría al lado de ellos.
     La entrada escalonada es la misma que usan los paneles: sin ella, siete
     tarjetas aparecen de golpe y se sienten como un volcado. */
  .herr {
    background:var(--papel); border:1px solid var(--arena); border-radius:12px;
    overflow:hidden; box-shadow:var(--pieza-corta);
    animation:surgir .6s var(--calma) backwards;
  }
  .herr:nth-of-type(2) { animation-delay:.05s; }
  .herr:nth-of-type(3) { animation-delay:.10s; }
  .herr:nth-of-type(4) { animation-delay:.15s; }
  .herr:nth-of-type(n+5) { animation-delay:.19s; }
  .herr__cab { padding:12px 15px 10px; border-bottom:2px solid var(--turq-200); }
  /* Un escalón por encima del rótulo de un panel, y a propósito: el de un
     panel rotula una gráfica; este es el NOMBRE de una herramienta y es lo
     que el médico busca al barrer la pantalla. */
  .herr__t { margin:0; font-size:14px; font-weight:800; color:var(--texto); letter-spacing:-.01em; }
  .herr__para { margin:4px 0 0; font-size:11.5px; font-weight:600; color:var(--texto-2); line-height:1.5; }
  .herr__cuerpo { padding:12px 15px 14px; }
  .herr__campos { display:grid; gap:9px; grid-template-columns:repeat(auto-fit,minmax(128px,1fr)); }
  .herr__campo { display:flex; flex-direction:column; gap:3px; min-width:0; }
  .herr__k {
    font-size:9.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
    color:var(--turq-700);
  }
  /* CAMPOS GRANDES. El dueño: «los botones son minúsculos». Y no es solo
     gusto: 44 px de alto es el mínimo con el que un dedo acierta sin mirar,
     y estos se llenan con el paciente enfrente. El borde va en `arena`, que
     es el rol de CONTORNO DE CONTROL —ahí el borde carga todo el peso y a
     menos contraste el campo se pierde (GUIA-VISUAL §3). */
  .herr__campo input, .herr__campo select {
    font:inherit; font-size:15px; font-weight:600; padding:11px 12px; min-width:0;
    height:44px; box-sizing:border-box;
    border:1.5px solid var(--borde-campo); border-radius:10px; background:var(--hueso);
    color:var(--texto);
  }
  .herr__campo input:focus, .herr__campo select:focus {
    outline:2px solid var(--turquesa); outline-offset:-1px; border-color:var(--turquesa);
  }
  /* El resultado se apoya en TINTA, no en el papel de la tarjeta: es lo que
     el médico vino a ver y tiene que separarse de lo que él escribió. */
  .herr__res {
    margin-top:12px; padding:11px 13px; border-radius:10px;
    background:linear-gradient(120deg,var(--tinta),var(--tinta-700)); color:var(--hueso);
  }
  .herr__v { font-size:23px; font-weight:800; letter-spacing:-.02em; line-height:1.1; }
  .herr__u { font-size:11.5px; font-weight:600; color:var(--turq-200); margin-left:5px; }
  .herr__clase { margin-top:4px; font-size:12px; font-weight:700; color:var(--turq-200); }
  /* El estado vacío NO va punteado: un borde de guiones se lee como «acá
     falta algo» o como un error. Va en hueso, quieto, esperando. */
  .herr__res--vacio {
    background:var(--hueso); color:var(--texto-2);
    font-size:12px; font-weight:600; line-height:1.5;
  }
  .herr__nota {
    margin-top:9px; font-size:11px; line-height:1.55; color:var(--texto-2);
    background:var(--hueso); border-radius:9px; padding:9px 11px;
    border-left:2px solid var(--turq-200);
  }
  /* LA FÓRMULA, A UN CLIC — no escondida, pero tampoco dominando.
     Primera versión: fórmula y fuente siempre desplegadas. El dueño:
     «las herramientas tienen explicaciones que no se ven nada amigables».
     Tenía razón: un bloque de monoespaciada con coeficientes griegos es lo
     primero que ve el ojo y convierte una calculadora en un paper.

     Un `<details>` no es esconderla —el rótulo se lee siempre y abre con un
     clic—, y eso NO contradice que lo auditable tiene que estar disponible:
     está, solo que no compite con el resultado. */
  .herr__fuente { margin-top:11px; border-top:1px solid var(--hueso-300); padding-top:9px; }
  .herr__fuente > summary {
    cursor:pointer; list-style:none; font-size:11px; font-weight:700;
    color:var(--turq-700); display:flex; align-items:center; gap:6px;
    padding:2px 0; user-select:none;
  }
  .herr__fuente > summary::-webkit-details-marker { display:none; }
  .herr__fuente > summary::before {
    content:'+'; width:16px; height:16px; flex:0 0 auto; border-radius:5px;
    background:var(--turq-50); color:var(--turq-700);
    display:flex; align-items:center; justify-content:center;
    font-size:13px; font-weight:800; line-height:1;
  }
  .herr__fuente[open] > summary::before { content:'−'; }
  .herr__fuente > summary:hover { color:var(--tinta); }
  /* Abierta, la primera versión era un párrafo de monoespaciada con la fuente
     pegada abajo: se partía a mitad de fórmula y no se distinguía dónde
     terminaba una cosa y empezaba la otra. El dueño: «está muy mal, se ve muy
     desordenado, poca presencia, difícil de leer».
     Ahora son DOS bloques rotulados, y la fórmula vive en su propia caja
     hundida — que es el rol de `--input-bg` en LABXIS: texto crudo dentro de
     una tarjeta (GUIA-VISUAL §1). */
  .herr__pie { margin-top:9px; display:grid; gap:10px; }
  .herr__rot {
    font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
    color:var(--turq-700); margin-bottom:4px;
  }
  .herr__fuente-txt { font-size:11px; line-height:1.6; color:var(--texto-2); }
  /* La fórmula en monoespaciada: los coeficientes y los exponentes tienen que
     poder copiarse con la vista sin confundir un 1 con una l. El portal no
     define un token de fuente mono —no carga ninguna—, así que va la pila del
     sistema y no un `var()` que no existe. */
  /* La fórmula en su caja hundida. `word-break:break-word` NO: partía
     «0.9938^edad» por la mitad. Con `overflow-wrap:anywhere` solo parte
     cuando de verdad no cabe, y `hyphens:none` evita guiones inventados en
     medio de un coeficiente. */
  .herr__formula {
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    font-size:11px; line-height:1.75; color:var(--texto);
    background:var(--hueso-200); border-radius:9px; padding:10px 12px;
    overflow-wrap:anywhere; hyphens:none;
  }

  /* ── LA COMISIÓN — es SUYA, y por eso no se mezcla con los conteos ──
     Pedido del dueño: el médico ve lo que lleva ganado. Va en su propia
     pieza y en oscuro, aparte de las cifras de pacientes: ahí se habla de
     trabajo y acá de dinero, y mezclarlos hace que no se lea ninguna de las
     dos.

     Si el médico NO cobra comisión, esto NO SE PINTA — ni un cero ni un «no
     aplica». Mostrarle Q0.00 a alguien que no comisiona no informa nada y se
     lee como un reproche. */
  .comision {
    margin-top:12px; padding:14px 16px; border-radius:13px;
    background:linear-gradient(120deg,var(--tinta),var(--tinta-700));
    color:var(--hueso); box-shadow:var(--pieza-corta);
    animation:surgir .5s var(--calma) backwards;
    display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 18px;
  }
  .comision__k {
    flex:1 1 100%; font-size:9px; font-weight:800; letter-spacing:.14em;
    text-transform:uppercase; color:var(--turq-300);
  }
  .comision__v { font-size:27px; font-weight:800; letter-spacing:-.02em; line-height:1.1; }
  .comision__d { font-size:11.5px; color:var(--turq-200); }
  .comision__nota {
    flex:1 1 100%; margin-top:8px; padding-top:9px;
    border-top:1px solid var(--tinta-400);
    font-size:11px; line-height:1.55; color:var(--turq-200);
  }

  /* ── LOS PANELES DE BARRAS ─────────────────────────────────────────
     Una tarjeta por gráfica, sobre el lienzo. El encabezado NO es una banda
     de color: es del mismo papel, con el rótulo en turquesa oscuro y una
     línea de 2 px abajo — la estructura la hace la LÍNEA, no un relleno
     (GUIA-VISUAL §2), igual que el encabezado de la tabla de la lista. */
  /* `align-items:start` y no el estirado de omisión: si no, en un renglón de
     tres, la tarjeta de «Sexo» —tres barras— queda tan alta como la de «Lo
     que más le piden» —ocho— y se ve media tarjeta vacía. Cada gráfica mide
     lo que mide. */
  /* ── LOS PANELES VAN EN COLUMNAS, NO EN REJILLA (2026-09-28) ─────────
     Con `display:grid` cada FILA toma el alto del panel mas alto, y los
     cortos dejan un hueco enorme debajo: «Sexo» es una dona y al lado
     «Cuadrillas» lleva doce barras. Lo vio el dueno: «por que salen unos
     grandes espacios».
     `columns` acomoda en flujo: cada panel ocupa lo que mide y el siguiente
     arranca pegado. Es masonry sin una linea de JS. El precio es que el
     orden pasa a leerse por COLUMNA y no por fila -- da igual: son tarjetas
     independientes, ninguna depende de la de al lado.
     El margen inferior va en el panel (con `columns` el `gap` solo separa
     columnas, no lo de arriba y abajo), y `break-inside:avoid` es lo que
     impide que una tarjeta se parta a la mitad entre dos columnas. */
  .paneles { margin-top:12px; columns:1; column-gap:12px; }
  .panel {
    break-inside:avoid; margin-bottom:12px;
    background:var(--papel); border:1px solid var(--arena); border-radius:12px;
    overflow:hidden; box-shadow:var(--pieza-corta);
    animation:surgir .6s var(--calma) backwards;
  }
  .panel:nth-of-type(2) { animation-delay:.06s; }
  .panel:nth-of-type(3) { animation-delay:.12s; }
  .panel:nth-of-type(n+4) { animation-delay:.16s; }
  .panel__cab { padding:9px 12px 7px; border-bottom:2px solid var(--turq-200); }
  .panel__t {
    margin:0; font-size:10px; font-weight:800; letter-spacing:.14em;
    text-transform:uppercase; color:var(--turq-700);
  }
  .panel__n { margin:3px 0 0; font-size:10.5px; font-weight:600; color:var(--texto-2); }

  .barras { padding:8px 12px 10px; }
  /* EL RÓTULO VA ARRIBA DE LA BARRA, no al lado, y en TODOS los anchos. Con
     las tres cosas en un renglón, al nombre le queda una columna estrecha y
     «Frente 7 — Santa Elena de la Costa Sur» se corta en «Frente 7 — Sant…»,
     que es justo el frente que Magdalena está buscando (GUIA-VISUAL §9: texto
     cortado es un defecto, no un detalle). Se vio en la primera corrida del
     render, en el teléfono Y en el monitor de 1830 —donde cada panel mide
     ~390 px y el problema es el mismo—. Apilado el nombre se lee entero y la
     barra usa el ancho completo de la tarjeta. */
  .bar {
    display:grid; grid-template-columns:minmax(0,1fr) 42px;
    grid-template-areas:'k k' 't n';
    align-items:center; gap:2px 9px; padding:4px 0;
  }
  .bar__k { grid-area:k; }
  .bar__t { grid-area:t; }
  .bar__n { grid-area:n; }
  .bar__k {
    font-size:11.5px; font-weight:700; color:var(--texto); line-height:1.3;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .bar__t { display:block; min-width:0; }
  .bar__t svg { display:block; border-radius:3px; overflow:hidden; }
  /* La pista NO es del color del papel sobre el que se apoya: si lo fuera, no
     se vería dónde termina la barra (GUIA-VISUAL §1, el defecto nº 1). */
  .bar__fondo { fill:var(--hueso-200); }
  .bar__relleno { fill:var(--turq-600); }
  .bar__n {
    font-size:11.5px; font-weight:800; color:var(--texto-2); text-align:right;
    font-variant-numeric:tabular-nums;
  }

  /* ── LAS PROMOCIONES ───────────────────────────────────────────────
     «Sin ser intrusivo»: abajo de todo, detrás de una línea, en tipografía
     pequeña y sin un solo color de alarma. No compiten con los números: los
     acompañan. Si no hay promociones vigentes el JS ni pinta el bloque. */
  .promos {
    margin-top:22px; padding-top:13px; border-top:1px solid var(--arena);
    animation:surgir .7s var(--calma) backwards; animation-delay:.2s;
  }
  .promos__t {
    margin:0 0 9px; font-size:9px; font-weight:800; letter-spacing:.2em;
    text-transform:uppercase; color:var(--texto-2);
  }
  .promos__rej { display:grid; gap:9px; }
  .promo {
    background:var(--papel); border:1px solid var(--arena); border-radius:10px;
    padding:9px 11px;
  }
  .promo__t { margin:0; font-size:12.5px; font-weight:800; color:var(--texto); line-height:1.3; }
  .promo__d { margin:4px 0 0; font-size:11.5px; font-weight:600; color:var(--texto-2); line-height:1.4; }
  .promo__pie { margin-top:7px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .promo__precio { font-size:13px; font-weight:800; color:var(--turq-700); }
  .promo__cod {
    font-size:9.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
    color:var(--texto-2); border:1px solid var(--arena); border-radius:999px;
    padding:2px 8px;
  }

  /* ══════════════════════════════════════════════════════════════════
     PANTALLAS ANCHAS
     ══════════════════════════════════════════════════════════════════ */
  /* De 720 para arriba hay ratón: los campos bajan al cuerpo del kit (12.5 px)
     y la franja de filtros se acomoda en una sola fila. Abajo de 720 se
     quedan en 16 px por el zoom de iOS — ver la nota de los campos. */
  @media (min-width:720px) {
    .app input[type=search], .app input[type=date] { min-height:32px; padding:6px 10px; font-size:12.5px; }
    .buscador input { padding-right:34px; }
    .lupa { width:28px; height:28px; }
    .mini { min-height:30px; }
    .franja { grid-template-columns:150px 150px 190px auto minmax(0,1fr); }
    .app select.selsede { min-height:32px; padding:6px 10px; font-size:12.5px; }
    .atajos { grid-column:auto; }
    #btnConsultar { grid-column:auto; justify-self:end; }
    #pantallaDetalle.app { max-width:820px; padding-left:22px; padding-right:22px; }
    /* De acá para arriba hay ratón y hay alto: la ventana del historial
       deja de ser una hoja pegada al borde de abajo y se centra. */
    .modal { align-items:center; padding:24px; }
    .modal__caja { border-radius:16px; }
    .franja-pac__c--pac { flex:2 1 260px; }
    .franja-pac__c--pac .franja-pac__v { font-size:15.5px; }
    .hoja { --res:minmax(0,1.7fr) minmax(86px,.9fr) 66px 128px 36px; }
    .res__c { font-size:12.5px; padding:6px 10px; }
    .res__th { padding:5px 10px; }
    .res__valor { font-size:13.5px; }
    .res__medida, .res__ref { font-size:11.5px; }
    .hist { --hist:92px 74px minmax(0,1fr) 64px minmax(0,120px); }
    .hist__origen { font-size:9.5px; }
    .hist__c { font-size:12px; padding:6px 9px; }
    .hist__th { font-size:9px; letter-spacing:.05em; padding:5px 9px; }
    .hist__valor { font-size:12.5px; }
    /* La bienvenida: de acá para arriba caben dos gráficas de frente. */
    .saludo__nombre { font-size:23px; }
    .paneles { columns:2; }
    .promos__rej { grid-template-columns:repeat(2,minmax(0,1fr)); }
  }

  /* ── LA TABLA DE VERDAD: nueve columnas alineadas ──
     El encabezado y las filas leen `--cols`, la MISMA variable. La fila deja
     de ser cuatro renglones apilados y pasa a ser uno solo.

     Arranca a los 1040 px y no antes: con ESTADO en 158 las nueve columnas
     necesitan 1028 con huecos y padding, y por debajo manda la fila apilada,
     que se lee igual de bien y no obliga a desplazar de lado.

     Estaba en 1000 cuando ESTADO medía 142, y con ese ancho el chip no cabía
     (2026-09-28). Al darle los 158 que el cálculo de arriba siempre pidió, el
     mínimo subió y el umbral tenía que subir con él: si no, entre 1000 y 1028
     la tabla entra en modo columnas y se desplaza de lado enseguida, que es
     justo lo que este número existe para evitar.

     Consecuencia: un monitor de 1024 maximizado ahora ve la fila APILADA en
     vez de la tabla. Es a propósito — la apilada está diseñada y se lee sola;
     una tabla que hay que arrastrar de lado, no. */
  @media (min-width:1040px) {
    #pantallaLista.app { max-width:none; padding:0 24px 56px; }
    .tabla__cab, .orden {
      grid-template-columns:var(--cols); grid-template-areas:none;
      gap:0 10px; align-items:center;
      /* Sin esto, la fila mide lo que mide el contenedor y las columnas se le
         salen: el rayado y el riel de estado se cortarían a la mitad al
         desplazar de lado. `min-content` es la suma de los mínimos de
         `--cols`, así que no hay un número que mantener a mano. */
      min-width:min-content;
    }
    .tabla__cuerpo { min-width:min-content; }
    .tabla__cab {
      display:grid; padding:13px 14px;
      background:var(--hueso-200); border-bottom:2px solid var(--turquesa);
      font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase;
      color:var(--turq-700); white-space:nowrap;
      position:sticky; top:0; z-index:2;
    }
    .tabla__cab span:last-child { text-align:right; }
    .orden { padding:11px 14px; }
    /* En la tabla las celdas se colocan solas, en el orden del HTML. */
    .orden .cel { grid-area:auto; text-align:left; }
    .orden .cel--sel { align-items:center; padding:0; }
    .orden .cel--pruebas { text-align:right; }
    .orden .cel--pac { margin:0; }
    /* Los datos de una sola pieza NO se parten: un folio o una fecha cortados
       a la mitad («MAZ-2009260 / 01») se leen como otro dato. Si algún día no
       cabe, el que se corre es el ancho de la tabla, que para eso está la
       rueda. */
    .orden .cel--dpi, .orden .cel--edad,
    .orden .cel--folio, .orden .cel--fecha { white-space:nowrap; }
    /* `documento` es texto libre: el mostrador lo teclea con guiones, con
       espacios o pega un pasaporte. Si un día sale más ancho que su columna,
       que se corte con puntos —se ve que está cortado, y el DPI entero sigue
       estando en la ficha— y no que se monte encima de la edad. */
    .orden .cel--dpi, .orden .cel--folio { overflow:hidden; text-overflow:ellipsis; }
    /* La sede es lo único que puede crecer sin techo (un nombre largo de sede
       nueva): se corta con puntos en vez de empujar la columna. */
    .orden .cel--sede { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
    /* El rótulo y la palabra los dice el ENCABEZADO de la columna. */
    .cel--dpi::before { content:none; }
    .cel__u { display:none; }

    /* ── LAS COLUMNAS SE VEN ───────────────────────────────────────
       Pedido del dueño (2026-09-22): «cada fila dividida bien, por columnas
       visibles; no podemos dejar espacios sin delimitar porque confunde la
       vista; no líneas invisibles por favor».

       El aire lo da el padding de CADA celda y no el `gap`: con gap, la línea
       quedaría flotando a un costado en vez de partir la columna en dos. */
    .tabla__cab, .orden { gap:0; padding-left:3px; padding-right:3px; }
    .tabla__cab > span, .orden > .cel { padding-left:11px; padding-right:11px; min-width:0; }
    .tabla__cab > span + span,
    .orden > .cel + .cel { border-left:1px solid var(--arena); }
    /* La casilla es un control, no un dato: no lleva línea ni sangría. */
    .orden > .cel--sel, .tabla__cab > span:first-child { padding-left:4px; padding-right:4px; }
    /* En el encabezado la línea va más marcada: es la que ancla la lectura de
       toda la columna hacia abajo. */
    .tabla__cab > span + span { border-left-color:var(--turq-300); }
    /* El nombre SI se puede partir en dos renglones, y es a proposito: cortar
       «Coronado Barrios Luis Fernando de Jesús» con puntos suspensivos le quita
       al medico justo el dato con el que reconoce a su paciente. Una fila mas
       alta se lee; un nombre cortado, no. */
    .pac__n { font-size:12.5px; line-height:1.25; }
    .pac__via { margin-top:0; font-size:10px; }
    .barra__in { padding:9px 24px; }
    .cabecera { margin-top:16px; }
    #pantallaInicio.app { padding:0 24px 56px; }
  }

  /* A 1024 px —el monitor mas chico que hay en el laboratorio— todavia no
     alcanza para dos columnas, pero si para que la hoja deje de ser una
     columna de 820 en una ventana de 1009. */
  @media (min-width:960px) {
    #pantallaDetalle.app { max-width:940px; }
  }

  /* ══════════════════════════════════════════════════════════════════
     DE 1100 PX PARA ARRIBA — LA PANTALLA PARTIDA EN DOS
     ══════════════════════════════════════════════════════════════════
     «No se está aprovechando bien la pantalla» (el dueño, 2026-09-20, sobre
     una captura de 1830 px donde la ficha era una columna de 970 y el resto
     quedaba en blanco). La referencia que él mismo señaló —la pantalla de
     captura de LABXIS— usa el ancho entero.

     Acá el ancho se reparte, no se estira: a la izquierda las hojas y a la
     derecha el historial. Es la respuesta a los tres puntos a la vez:
       · el ancho se usa (la página pasa de 820 a 1400 px);
       · una orden de UNA sola prueba ya no queda flotando: al lado tiene el
         historial de esa prueba, que es justo lo que se quiere mirar cuando
         hay una sola;
       · y la tabla NO se estira a 1800: la columna principal tiene techo
         (~900 px), que es lo que hace falta para que el valor no se despegue
         del nombre del analito.

     El historial es el MISMO elemento del teléfono. Acá deja de ser una
     ventana flotante y pasa a ser el panel de la derecha: `position:static`,
     sin fondo oscuro y sin animación de entrada. El JS no se entera. */
  @media (min-width:1100px) {
    #pantallaDetalle.app { max-width:1400px; padding:0 24px 56px; }
    .hojas {
      display:grid; grid-template-columns:minmax(0,1fr) 420px;
      gap:16px; align-items:start; margin-top:2px;
    }
    /* El panel se queda a la vista mientras se recorre una química de doce
       analitos. 58 px es el alto de la barra pegajosa más su aire. */
    .hojas__lado { position:sticky; top:58px; }
    /* ⚠️ ACOTADO A #modalHist, no a `.modal` en general.
       Esto convierte el HISTORIAL en un panel dentro de la ficha cuando hay
       ancho: deja de flotar y se queda al lado de los resultados. Se escribió
       cuando el historial era el único modal del portal.
       Al llegar el selector de exportación, heredó estas reglas y se volvió un
       bloque ESTÁTICO al final del documento: se abría «hasta abajo» y el
       dueño tuvo que ir a buscarlo con el scroll (2026-09-22). Un diálogo que
       hay que ir a buscar no es un diálogo. */
    #modalHist.modal { position:static; display:block; z-index:auto; }
    #modalHist .modal__fondo { display:none; }
    #modalHist .modal__caja {
      width:100%; max-width:none; max-height:calc(100vh - 92px);
      border-radius:13px; box-shadow:var(--pieza-corta); animation:none;
    }
    #modalHist .modal__cuerpo { padding:12px 12px 14px; }
    .invita { display:block; }
    /* Con ~900 px de columna, la referencia y la medida se llevan lo suyo y
       el resto va al nombre del analito. Los separadores verticales son los
       que mantienen la lectura: sin ellos, a este ancho el ojo pierde el
       renglón entre el nombre y su valor. */
    .hoja { --res:minmax(0,1.5fr) minmax(96px,.7fr) 76px 152px 38px; }
    /* El historial vive en una columna de 420 px, no en una ventana de 720:
       los cuerpos vuelven a los del telefono y cada columna a lo que de
       verdad mide su rotulo. */
    .hist { --hist:80px 62px minmax(0,1fr) 58px minmax(0,88px); }
    .hist__c { font-size:11px; padding:5px 7px; }
    .hist__th { padding:5px 7px; }
    .hist__valor { font-size:11.5px; }
  }

  /* En un monitor de verdad grande se estira un poco más, pero con tope: una
     tabla de cuatro columnas a 1800 px deja el valor en la otra punta del
     nombre y se vuelve ilegible. */
  @media (min-width:1600px) {
    #pantallaDetalle.app { max-width:1520px; }
    .hojas { grid-template-columns:minmax(0,1fr) 470px; }
  }

  /* La bienvenida también reparte el ancho en vez de estirarse: tres gráficas
     por renglón y las promociones en una sola fila. En un monitor de 1830 px
     una columna de 1000 con cinco tarjetas apiladas es exactamente el
     «no se está aprovechando bien la pantalla» del dueño. */
  @media (min-width:1100px) {
    #pantallaInicio.app { max-width:1240px; }
    .paneles { columns:3; }
    .promos__rej { grid-template-columns:repeat(4,minmax(0,1fr)); }
  }



  /* ══════════════════════════════════════════════════════════════════
     SEXTA VUELTA (2026-09-28) — EL PORTAL v2
     ══════════════════════════════════════════════════════════════════
     Todo lo de abajo cuelga de `.app` o de la barra: la portada del ingreso
     sigue intacta. La jerarquía de fondos es la de siempre (GUIA-VISUAL §1):
     hueso es el lienzo, papel es lo que se apoya encima, arena es la línea,
     y la tinta se reserva a las piezas que tienen que PESAR (la barra, la
     cabecera del expediente, la cifra de la comisión). */

  /* ── EL AVATAR ─────────────────────────────────────────────────────
     Foto del médico o del paciente; mientras no hay foto, las iniciales
     sobre el degradé de LABXIS. Es la MISMA pieza en los cuatro tamaños. */
  .avatar {
    position:relative; flex:0 0 auto; overflow:hidden; border-radius:50%;
    display:inline-flex; align-items:center; justify-content:center;
    background:linear-gradient(48deg,#1D6E9C 0%,#3BB394 100%); color:#fff;
    font-weight:800; letter-spacing:.02em; line-height:1; user-select:none;
    box-shadow:0 0 0 2px rgba(255,255,255,.55), var(--pieza-corta);
  }
  .avatar__img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
  .avatar--barra { width:38px; height:38px; font-size:13px; border:0; padding:0; cursor:pointer; font-family:inherit; }
  .avatar--barra:hover { box-shadow:0 0 0 2px var(--turquesa); }
  .avatar--grande { width:64px; height:64px; font-size:21px; }
  .avatar--exp { width:64px; height:64px; font-size:21px; box-shadow:0 0 0 3px rgba(246,243,238,.35); }
  .avatar--perfil { width:112px; height:112px; font-size:36px; }
  .avatar--pac { width:42px; height:42px; font-size:14px; box-shadow:none; }

  /* ── EL CARRIL DE MÓDULOS ──────────────────────────────────────────
     En la barra en escritorio; al pie del teléfono. Es el MISMO <nav>. */
  .rail { display:flex; align-items:center; gap:2px; margin-left:auto; }
  .rail__b {
    display:inline-flex; align-items:center; gap:7px; min-height:36px; padding:0 12px;
    border:0; border-radius:9px; background:transparent; color:rgba(246,243,238,.72);
    font-family:inherit; font-size:12.5px; font-weight:700; cursor:pointer; white-space:nowrap;
    transition:background-color .16s, color .16s;
  }
  .rail__b svg { width:17px; height:17px; flex:0 0 auto; }
  .rail__b:hover { background:rgba(246,243,238,.10); color:#fff; }
  .rail__b--on { background:rgba(30,202,211,.16); color:var(--turq-200); }
  .rail__b--on svg { color:var(--turquesa); }

  @media (max-width:879px) {
    .rail {
      position:fixed; left:0; right:0; bottom:0; z-index:95; margin:0;
      display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:0;
      background:var(--papel); border-top:1px solid var(--arena);
      box-shadow:0 -6px 24px -14px rgba(4,25,27,.45);
      padding:6px 4px calc(6px + env(safe-area-inset-bottom,0px));
    }
    .rail__b {
      flex-direction:column; gap:3px; min-height:48px; padding:4px 2px; border-radius:10px;
      color:var(--texto-2); font-size:10px; letter-spacing:.02em;
    }
    .rail__b svg { width:21px; height:21px; }
    .rail__b:hover { background:transparent; color:var(--texto); }
    .rail__b--on { background:var(--turq-50); color:var(--turq-700); }
    .rail__b--on svg { color:var(--turq-600); }
    /* Para que la última fila de cualquier pantalla no quede debajo del
       carril. */
    body.trabajando .app { padding-bottom:92px; }
  }
  @media (min-width:880px) and (max-width:1099px) {
    .rail__b span { display:none; }
    .rail__b { padding:0 10px; }
  }

  /* ── LA BIENVENIDA ─────────────────────────────────────────────────
     El saludo lleva la foto y, a la derecha, el día de hoy en letras. */
  .saludo--hero { align-items:center; gap:14px 16px; }
  .saludo--hero .saludo__quien { flex:1 1 220px; }
  .saludo__hoy {
    margin:0; flex:0 0 auto; font-size:11.5px; font-weight:700; color:var(--texto-2);
    padding:6px 12px; border-radius:999px;
    background:var(--papel); border:1px solid var(--arena);
  }
  /* La comisión de la portada se puede abrir: es el resumen del módulo. */
  .comision--link { cursor:pointer; transition:transform .2s var(--calma), box-shadow .2s var(--calma); }
  .comision--link:hover { transform:translateY(-2px); box-shadow:0 12px 30px -16px rgba(4,25,27,.8); }
  .comision__ir {
    flex:0 0 auto; margin-left:auto; align-self:center; font-size:10.5px; font-weight:800;
    letter-spacing:.1em; text-transform:uppercase; color:var(--turq-300);
    display:inline-flex; align-items:center; gap:5px;
  }
  .comision__ir svg { width:14px; height:14px; }
  .comision__fuera { font-size:11.5px; color:var(--turq-200); font-weight:600; }
  .comision__fuera b { color:#fff; font-weight:800; }

  /* ── LAS DONAS ──────────────────────────────────────────────────────
     Para lo que es reparto de un total (sexo, edades). SVG a mano, misma
     razón de siempre: la CSP. Colores por clase, del mismo juego. */
  .dona { display:flex; align-items:center; gap:14px; padding:10px 12px 12px; }
  .dona svg { width:112px; height:112px; flex:0 0 auto; }
  .dona__n { font-size:22px; fill:var(--texto); font-weight:800; font-family:var(--sans); }
  .dona__k { font-size:8px; fill:var(--texto-2); letter-spacing:.08em; text-transform:uppercase; font-weight:800; font-family:var(--sans); }
  .dona__ley { flex:1 1 auto; min-width:0; display:grid; gap:5px; }
  .dona__it { display:grid; grid-template-columns:10px minmax(0,1fr) auto auto; gap:8px; align-items:center; font-size:11.5px; font-weight:600; color:var(--texto-2); }
  .dona__sw { width:10px; height:10px; border-radius:3px; }
  .dona__t { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:var(--texto); font-weight:700; }
  .dona__v { font-weight:800; color:var(--texto); font-variant-numeric:tabular-nums; }
  .dona__p { font-size:10.5px; font-variant-numeric:tabular-nums; min-width:34px; text-align:right; }
  .d-1 { fill:var(--turq-600); background:var(--turq-600); }
  .d-2 { fill:var(--tinta-400); background:var(--tinta-400); }
  .d-3 { fill:var(--turquesa); background:var(--turquesa); }
  .d-4 { fill:#8A5200; background:#8A5200; }
  .d-5 { fill:var(--tinta-700); background:var(--tinta-700); }
  .d-6 { fill:var(--turq-300); background:var(--turq-300); }
  .d-7 { fill:var(--arena); background:var(--arena); }
  .dona__hueco { fill:var(--papel); }

  /* ── POR PACIENTE / POR ORDEN — el segmentado ───────────────────────
     La forma de `Pildoras` del kit: riel hundido con borde, opción activa en
     papel con sombra (GUIA-VISUAL §7). */
  .vista {
    display:inline-flex; gap:3px; padding:3px; border-radius:10px;
    background:var(--hueso-200); border:1px solid var(--arena);
  }
  .vista__b {
    min-height:28px; padding:0 12px; border:0; border-radius:8px; background:transparent;
    color:var(--texto-2); font-family:inherit; font-size:12px; font-weight:700; cursor:pointer;
    transition:background-color .16s, color .16s, box-shadow .16s;
  }
  .vista__b--on { background:var(--papel); color:var(--turq-700); box-shadow:var(--pieza-corta); }
  /* El selector de sede de la cabecera de Pacientes: del mismo alto que el
     segmentado, y en el teléfono con su propio renglón para leerse entero. */
  .selsede--cab { width:auto; min-width:160px; flex:0 1 200px; }
  @media (max-width:719px) { .selsede--cab { flex:1 1 100%; } }
  @media (min-width:720px) { .app select.selsede--cab { min-height:36px; } }

  /* ── EL DIRECTORIO DE PACIENTES ─────────────────────────────────────
     Una tarjeta por paciente (se agrupa en el navegador lo que la lista ya
     trajo). Papel sobre hueso, borde de arena, y el borde se vuelve de marca
     al pasar — la misma pieza que la tarjeta de módulo. */
  .dir { margin-top:10px; display:grid; gap:10px; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); }
  .pac {
    text-align:left; appearance:none; font:inherit; cursor:pointer; color:var(--texto);
    background:var(--papel); border:1px solid var(--arena); border-radius:14px;
    padding:12px 13px 11px; display:flex; flex-direction:column; gap:9px; min-width:0;
    transition:transform .16s var(--calma), box-shadow .16s var(--calma), border-color .16s var(--calma);
    animation:surgir .45s var(--calma) backwards;
  }
  .pac:hover { border-color:var(--turquesa); transform:translateY(-2px); box-shadow:0 8px 24px -12px rgba(6,40,43,.35); }
  .pac:nth-child(2) { animation-delay:.03s; } .pac:nth-child(3) { animation-delay:.06s; }
  .pac:nth-child(4) { animation-delay:.09s; } .pac:nth-child(n+5) { animation-delay:.12s; }
  .pac__cab { display:flex; align-items:center; gap:10px; min-width:0; }
  .pac__quien { flex:1 1 auto; min-width:0; }
  .pac__nombre { font-size:13.5px; font-weight:800; line-height:1.2; letter-spacing:-.01em; overflow-wrap:anywhere; }
  .pac__meta { margin-top:2px; font-size:11px; font-weight:600; color:var(--texto-2); font-variant-numeric:tabular-nums; }
  .pac__pie { display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
  .pac__ult { font-size:10.5px; font-weight:700; color:var(--texto-2); font-variant-numeric:tabular-nums; }
  .pac__ult b { color:var(--texto); font-weight:800; }
  .pac__cnt {
    font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
    color:var(--turq-700); background:var(--turq-50); border-radius:999px; padding:3px 8px;
  }

  /* ── EL EXPEDIENTE ──────────────────────────────────────────────────
     Cabecera en tinta (es el documento que pesa), y debajo las celdas de
     admisión en papel, como la franja del paciente de la ficha. */
  .exp {
    margin-top:10px; border-radius:14px; overflow:hidden; background:var(--papel);
    border:1px solid var(--arena); box-shadow:var(--pieza-corta);
    animation:surgir .5s var(--calma) backwards;
  }
  .exp__cab {
    display:flex; align-items:center; flex-wrap:wrap; gap:12px 16px; padding:16px 16px 14px;
    background:linear-gradient(120deg,var(--tinta),var(--tinta-700)); color:var(--hueso);
    position:relative; isolation:isolate; overflow:hidden;
  }
  .exp__cab::before {
    content:''; position:absolute; z-index:-1; pointer-events:none;
    width:22rem; height:22rem; right:-8rem; top:-10rem; border-radius:50%;
    background:rgba(30,202,211,.18); filter:blur(70px);
  }
  .exp__quien { flex:1 1 220px; min-width:0; }
  .exp__rotulo { margin:0; font-size:9.5px; font-weight:800; letter-spacing:.22em; text-transform:uppercase; color:var(--turq-300); }
  .exp__nombre { margin:3px 0 0; font-size:21px; font-weight:800; letter-spacing:-.02em; line-height:1.15; color:#fff; overflow-wrap:anywhere; }
  .exp__chips { margin-top:8px; display:flex; flex-wrap:wrap; gap:6px; }
  .exp__chip {
    display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:999px;
    font-size:10px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
    background:rgba(246,243,238,.12); border:1px solid rgba(246,243,238,.22); color:var(--turq-200);
  }
  .exp__chip--conv { background:rgba(30,202,211,.16); border-color:rgba(30,202,211,.4); color:#fff; }
  .exp__kpis { display:flex; gap:1px; flex:0 0 auto; border-radius:10px; overflow:hidden; background:rgba(246,243,238,.14); }
  .exp__kpi { padding:8px 14px; background:rgba(4,25,27,.35); min-width:76px; }
  .exp__kpi b { display:block; font-size:19px; font-weight:800; letter-spacing:-.02em; color:#fff; line-height:1.1; }
  .exp__kpi span { font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--turq-300); }
  .exp__datos { display:flex; flex-wrap:wrap; gap:1px; background:var(--arena); }
  .dato { flex:1 1 150px; min-width:0; background:var(--papel); padding:8px 13px; }
  .dato__k { font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--turq-700); }
  .dato__v { margin-top:2px; font-size:12.5px; font-weight:600; color:var(--texto); line-height:1.35; overflow-wrap:anywhere; font-variant-numeric:tabular-nums; }
  .dato__v a { color:var(--turq-700); font-weight:800; text-decoration:none; }
  .dato__v a:hover { text-decoration:underline; }
  .dato--ancho { flex:2 1 300px; }

  /* Las pestañas del expediente: papel sobre hueso, con la activa en papel.
     Se llaman `.tab` a propósito: `.pestana` ya es el filtro de estado. */
  .tabs {
    margin-top:12px; display:flex; gap:4px; padding:4px; border-radius:12px;
    background:var(--hueso-200); border:1px solid var(--arena); overflow-x:auto;
  }
  .tab {
    flex:1 1 auto; min-height:34px; padding:0 12px; border:0; border-radius:9px; background:transparent;
    color:var(--texto-2); font-family:inherit; font-size:12.5px; font-weight:700; cursor:pointer;
    white-space:nowrap; display:inline-flex; align-items:center; justify-content:center; gap:7px;
    transition:background-color .16s, color .16s, box-shadow .16s;
  }
  .tab--on { background:var(--papel); color:var(--turq-700); box-shadow:var(--pieza-corta); }
  .tab__n { font-size:10.5px; font-weight:800; padding:1px 7px; border-radius:9px; background:var(--hueso); color:var(--texto-2); font-variant-numeric:tabular-nums; }
  .tab--on .tab__n { background:var(--turq-50); color:var(--turq-700); }
  .tab__n:empty { display:none; }

  .exp__panel { margin-top:10px; }
  .exp__acciones { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:8px 12px; margin-bottom:8px; }
  .exp__nota { margin:0; flex:1 1 260px; font-size:11.5px; font-weight:500; color:var(--texto-2); line-height:1.55; }

  /* Las órdenes del expediente: una tabla chica, del mismo molde. */
  .tord { background:var(--papel); border:1px solid var(--arena); border-radius:12px; overflow:hidden; box-shadow:var(--pieza-corta); }
  .tord__f {
    --tc:auto minmax(0,1fr) auto;
    display:grid; grid-template-columns:var(--tc); gap:5px 10px; align-items:center;
    grid-template-areas:'chip folio fecha' 'sede sede n';
    width:100%; text-align:left; padding:10px 13px; border:0; border-top:1px solid var(--arena);
    background:transparent; font:inherit; color:var(--texto); cursor:pointer; transition:background-color .15s;
  }
  .tord__f:first-child { border-top:0; }
  .tord__f:nth-child(even) { background:var(--hueso); }
  .tord__f:hover { background:var(--turq-50); }
  .tord__f > .chip { grid-area:chip; }
  .tord__folio { grid-area:folio; font-size:12px; font-weight:800; font-variant-numeric:tabular-nums; white-space:nowrap; }
  .tord__fecha { grid-area:fecha; font-size:11.5px; font-weight:600; color:var(--texto-2); white-space:nowrap; font-variant-numeric:tabular-nums; }
  .tord__sede { grid-area:sede; font-size:11.5px; font-weight:600; color:var(--texto-2); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .tord__conv { display:block; font-size:10px; font-weight:700; color:var(--turq-700); margin-top:1px; }
  .tord__n { grid-area:n; text-align:right; font-size:11px; font-weight:700; color:var(--texto-2); white-space:nowrap; font-variant-numeric:tabular-nums; }
  .tord__ir { display:none; color:var(--turq-600); }
  .tord__ir svg { width:15px; height:15px; }

  /* ── LA HISTORIA CLÍNICA — las anotaciones ─────────────────────────── */
  .notas { display:grid; gap:10px; }
  .nota { background:var(--papel); border:1px solid var(--arena); border-radius:12px; overflow:hidden; box-shadow:var(--pieza-corta); animation:surgir .4s var(--calma) backwards; }
  .nota__cab { display:flex; align-items:center; gap:10px; padding:9px 13px; border-bottom:1px solid var(--hueso-200); flex-wrap:wrap; }
  .nota__fecha { font-size:12.5px; font-weight:800; font-variant-numeric:tabular-nums; }
  .nota__dx { font-size:12px; font-weight:700; color:var(--turq-700); min-width:0; flex:1 1 160px; overflow-wrap:anywhere; }
  .nota__editar { margin-left:auto; }
  .nota__vit { display:flex; flex-wrap:wrap; gap:1px; background:var(--arena); border-bottom:1px solid var(--arena); }
  .nota__vit:empty { display:none; }
  .vit { flex:1 1 90px; background:var(--hueso); padding:6px 12px; }
  .vit__k { font-size:8.5px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--turq-700); }
  .vit__v { font-size:13px; font-weight:800; color:var(--texto); font-variant-numeric:tabular-nums; }
  .vit__v small { font-size:10px; font-weight:700; color:var(--texto-2); margin-left:2px; }
  .nota__txt { padding:9px 13px; font-size:12.5px; line-height:1.55; color:var(--texto); white-space:pre-wrap; overflow-wrap:anywhere; }
  .nota__med { padding:0 13px 10px; font-size:11.5px; color:var(--texto-2); line-height:1.5; white-space:pre-wrap; overflow-wrap:anywhere; }
  .nota__med b { font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--turq-700); display:block; margin-bottom:2px; }

  /* Los formularios (la anotación, el perfil): campos con rótulo, nunca
     placeholder como etiqueta (GUIA-VISUAL §10). */
  .forma { display:grid; gap:10px; }
  .forma__rej { display:grid; gap:10px; grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); }
  .forma__campo { display:flex; flex-direction:column; gap:3px; min-width:0; }
  .forma__campo label { margin:0; font-size:9.5px; letter-spacing:.12em; }
  .forma__campo input, .forma__campo select, .forma__campo textarea {
    font:inherit; font-size:15px; font-weight:600; padding:10px 12px; min-height:44px; min-width:0;
    /* EL CAMPO VA EN PAPEL, NO EN HUESO (2026-09-28). La caja del modal ya es
       `--hueso`, asi que un campo `--hueso` queda pintado DEL MISMO COLOR DEL
       FONDO SOBRE EL QUE SE APOYA y solo lo insinua un borde de #DAD2C5. Lo
       senalo el dueno viendo la ventana de anotacion: «los colores tampoco se
       distinguen bien los campos». Es el defecto n.º 1 de la GUIA-VISUAL.
       Blanco funciona en los dos sitios donde vive `.forma`: sobre el hueso del
       modal contrasta el relleno, y sobre papel sigue el borde marcando. */
    border:1.5px solid var(--borde-campo); border-radius:10px; background:var(--papel); color:var(--texto);
    box-sizing:border-box; width:100%; -webkit-appearance:none; appearance:none;
  }
  /* LA FLECHA DEL DESPLEGABLE (2026-09-28). La regla de arriba pone
     `appearance:none` para que el campo se vea igual en Chrome, Safari y
     Firefox -- y de paso le quita al `select` la flecha NATIVA. Sin ponerle
     una propia, el desplegable queda identico a una caja de texto vacia y el
     medico no sabe que ahi se elige. Lo señalo el dueño viendo Banco y Tipo
     de cuenta: dos cajas con un guion adentro.
     Va como fondo en `data:`, que la CSP permite en `img-src`. */
  .forma__campo select {
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1.5L6 6.5L11 1.5' fill='none' stroke='%238A7F70' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat:no-repeat; background-position:right 12px center;
    background-size:11px 8px; padding-right:34px; cursor:pointer;
  }
  .forma__campo textarea { min-height:70px; resize:vertical; line-height:1.45; }
  .forma__campo input:focus, .forma__campo select:focus, .forma__campo textarea:focus {
    outline:2px solid var(--turquesa); outline-offset:-1px; border-color:var(--turquesa); box-shadow:none;
  }
  .forma__campo--fecha { grid-column:1 / -1; }
  .modal__cuerpo .msg { font-size:12.5px; margin-top:4px; }
  .expsel__aire { flex:1 1 auto; }
  .mini--peligro { color:var(--err); border-color:var(--fuera-bd); }
  .mini--peligro:hover { background:var(--fuera-bg); border-color:var(--fuera-fg); color:var(--fuera-fg); }
  .mini--exp svg { width:14px; height:14px; }

  /* Las calculadoras llenas desde el expediente: dicen DE DÓNDE salió cada
     número, porque un valor que aparece solo sin decir de qué orden es no
     lo puede firmar nadie. */
  .herrs--exp { margin-top:0; }
  .herr__origen {
    margin:8px 0 0; font-size:10.5px; font-weight:700; color:var(--turq-700);
    display:flex; flex-wrap:wrap; gap:4px 10px;
  }
  .herr__origen span { display:inline-flex; align-items:center; gap:4px; }
  .herr__origen span::before { content:'●'; font-size:8px; }
  .herr__campo input.lleno { border-color:var(--turq-300); background:var(--turq-50); }
  .herr--sin { opacity:.72; }

  /* ── MI COMISIÓN ───────────────────────────────────────────────────── */
  .atajos--com { grid-column:auto; }
  .atajo--on { border-color:var(--turq-600); background:var(--turq-50); color:var(--turq-700); }
  .kpis { margin-top:12px; display:grid; gap:10px; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); animation:surgir .5s var(--calma) backwards; }
  .kpi { background:var(--papel); border:1px solid var(--arena); border-radius:13px; padding:12px 14px; box-shadow:var(--pieza-corta); min-width:0; }
  .kpi__k { font-size:9px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; color:var(--turq-700); }
  .kpi__v { margin-top:4px; font-size:24px; font-weight:800; letter-spacing:-.02em; line-height:1.1; color:var(--texto); font-variant-numeric:tabular-nums; }
  .kpi__d { margin-top:4px; font-size:11px; font-weight:600; color:var(--texto-2); line-height:1.4; }
  .kpi--tinta { background:linear-gradient(120deg,var(--tinta),var(--tinta-700)); border-color:var(--tinta); color:var(--hueso); }
  .kpi--tinta .kpi__k { color:var(--turq-300); }
  .kpi--tinta .kpi__v { color:#fff; }
  .kpi--tinta .kpi__d { color:var(--turq-200); }
  .kpi--fuera { border-left:4px solid var(--parcial-fg); }
  .kpi--fuera .kpi__v { color:var(--parcial-fg); }
  .kpi--fuera .kpi__k { color:var(--parcial-fg); }

  .tcom { background:var(--papel); border:1px solid var(--arena); border-radius:12px; overflow:hidden; box-shadow:var(--pieza-corta); margin-top:10px; }
  .tcom__rueda { overflow-x:auto; }
  .tcom__cab { display:none; }
  .tcom__f {
    --cc:auto minmax(0,1fr) auto;
    display:grid; grid-template-columns:var(--cc); gap:3px 10px; align-items:center;
    grid-template-areas:'estado estado total' 'pac pac pac' 'folio sede fecha' 'motivo motivo motivo';
    padding:11px 13px; border-top:1px solid var(--arena); font-size:12px; color:var(--texto-2); font-weight:600;
  }
  .tcom__f:first-child { border-top:0; }
  .tcom__f:nth-child(even) { background:var(--hueso); }
  .tcom__f--si { box-shadow:inset 3px 0 0 var(--listos-fg); }
  .tcom__f--no { box-shadow:inset 3px 0 0 var(--parcial-fg); }
  .tcom__estado { grid-area:estado; }
  .tcom__pac { grid-area:pac; color:var(--texto); font-weight:800; font-size:13px; }
  .tcom__folio { grid-area:folio; font-weight:800; color:var(--texto); font-variant-numeric:tabular-nums; }
  .tcom__sede { grid-area:sede; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .tcom__fecha { grid-area:fecha; text-align:right; font-variant-numeric:tabular-nums; }
  .tcom__total { grid-area:total; text-align:right; font-weight:800; color:var(--texto); font-variant-numeric:tabular-nums; font-size:13px; }
  .tcom__motivo { grid-area:motivo; font-size:11px; }
  .chip--si { color:var(--listos-fg); background:var(--listos-bg); border-color:var(--listos-bd); }
  .chip--no { color:var(--parcial-fg); background:var(--parcial-bg); border-color:var(--parcial-bd); }
  .chip--no::before { background:none; }
  .leyenda--com { border-left-color:var(--parcial-bd); }

  /* ── MI PERFIL ───────────────────────────────────────────────────────── */
  .perfil { margin-top:12px; display:grid; gap:12px; }
  .tarjeta { background:var(--papel); border:1px solid var(--arena); border-radius:12px; overflow:hidden; box-shadow:var(--pieza-corta); animation:surgir .5s var(--calma) backwards; }
  .tarjeta__cab { padding:10px 14px 8px; border-bottom:2px solid var(--turq-200); }
  .tarjeta__cuerpo { padding:14px; }
  .perfil__fotoin { display:flex; align-items:center; gap:18px; flex-wrap:wrap; }
  .perfil__fotoacc { flex:1 1 200px; display:grid; gap:8px; }
  .perfil__subir { justify-self:start; }
  .formas { display:grid; gap:8px; }
  .formapago {
    display:flex; align-items:flex-start; gap:12px; padding:11px 13px; margin:0; cursor:pointer;
    border:1.5px solid var(--arena); border-radius:12px; background:var(--hueso);
    font-size:12px; font-weight:500; letter-spacing:0; text-transform:none; color:var(--texto-2); line-height:1.5;
    transition:border-color .16s, background-color .16s;
  }
  .formapago:hover { border-color:var(--turq-300); }
  .formapago input { width:18px; height:18px; margin:2px 0 0; accent-color:var(--turq-600); flex:0 0 auto; }
  .formapago > span { display:block; min-width:0; }
  .formapago b { display:block; font-size:13px; font-weight:800; color:var(--texto); margin-bottom:2px; }
  .formapago--on { border-color:var(--turq-600); background:var(--turq-50); }
  .forma__rej--pago { margin-top:10px; }
  /* CADA CAMPO LO QUE PIDE, no cinco iguales (2026-09-28). `.forma__rej` los
     reparte a partes iguales con `auto-fit`, y el resultado es un NIT de ocho
     digitos con el mismo ancho que «Banco de los Trabajadores (Bantrab)» o que
     el nombre completo del titular. Lo señalo el dueño: «el NIT no ocupa ni
     necesita tanto espacio, lo que daria chance a un campo mas grande para el
     nombre de la cuenta».
     Solo de 900 px para arriba: mas abajo siguen apilandose, que es lo
     correcto en un telefono. */
  @media (min-width:900px) {
    .forma__rej--pago {
      grid-template-columns:.7fr 1.5fr .85fr 1.15fr 1.8fr;
    }
  }
  .perfil__pie { display:flex; align-items:center; justify-content:flex-end; gap:12px; flex-wrap:wrap; }
  .perfil__pie .msg { flex:1 1 240px; margin:0; font-size:12.5px; }

  /* ── Anchos de las pantallas nuevas ───────────────────────────────── */
  #pantallaExpediente.app, #pantallaComision.app, #pantallaPerfil.app { max-width:1000px; }
  @media (min-width:720px) {
    .tcom__f { grid-template-areas:'estado pac pac' 'folio sede fecha' 'motivo motivo total'; }
    .tord__f { --tc:auto minmax(0,1fr) auto auto auto auto; grid-template-areas:none; }
    .tord__f > * { grid-area:auto; }
    .tord__ir { display:inline-flex; }
    .tord__n { text-align:left; }
    .exp__nombre { font-size:24px; }
    .perfil { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
      .perfil__pie { grid-column:1 / -1; }
    #perfilPago { grid-column:1 / -1; }
    .notas { grid-template-columns:repeat(auto-fill,minmax(320px,1fr)); align-items:start; }
  }
  @media (min-width:1000px) {
    #pantallaExpediente.app, #pantallaComision.app { max-width:none; padding:0 24px 56px; }
    #pantallaPerfil.app { max-width:1100px; }
    /* La tabla de la comisión de verdad: siete columnas alineadas. */
    .tcom__cab, .tcom__f {
      --cc:120px 96px minmax(200px,1.6fr) minmax(110px,.8fr) 122px minmax(220px,1.4fr) 104px;
      grid-template-columns:var(--cc); grid-template-areas:none; gap:0; padding:0 3px; min-width:min-content;
    }
    .tcom__cab {
      display:grid; background:var(--hueso-200); border-bottom:2px solid var(--turquesa);
      font-size:10.5px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--turq-700);
      white-space:nowrap; position:sticky; top:0; z-index:2;
    }
    .tcom__cab > span, .tcom__f > * { padding:10px 11px; min-width:0; grid-area:auto; text-align:left; }
    .tcom__cab > span + span, .tcom__f > * + * { border-left:1px solid var(--arena); }
    .tcom__cab > span + span { border-left-color:var(--turq-300); }
    .tcom__cab > span:last-child, .tcom__total { text-align:right; }
    .tcom__folio, .tcom__fecha { white-space:nowrap; }
    .tcom__motivo { font-size:11.5px; }
  }
  @media (min-width:1100px) {
    #pantallaExpediente.app { max-width:1280px; }
    #pantallaComision.app { max-width:1280px; }
    .exp__cab { padding:18px 20px 16px; }
  }
  @media (prefers-reduced-motion:reduce) { * { transition:none !important; animation:none !important; } }
