/* estilos.css — Panel clínico con la marca Ellie Care.
 *
 * Los valores de marca NO viven acá: vienen de `vendor/brand/tokens.css`, copia verbatim de
 * `elliecare/ellie-brand` (commit 4dd6271). Este archivo solo **mapea** esos tokens a las variables
 * semánticas que usa el panel (`--fondo`, `--panel`, `--tinta`…), así el día que cambie la marca se
 * re-copia el archivo de tokens y no hay que buscar hex sueltos por el CSS.
 *
 * Reglas de marca que este archivo respeta (brand/identity/color.md):
 *  - **Mint `#B8E65C` es el color de conversión**: solo CTA y acción principal, con texto navy
 *    encima (mint como texto sobre blanco es 1.4:1 → ilegible). No se usa de decoración.
 *  - **Purple `#9933FF` MUY controlado**: íconos, highlights y series secundarias de gráficos.
 *    Nunca en botones principales ni fondos grandes.
 *  - **Navy `#2F3A4D` (11.4:1 AAA)** para superficies oscuras, encabezados y la serie principal.
 *  - **Soft accents** (`#F0FFD1` / `#D9B3FF`) para cajas informativas y estados positivos.
 *  - WCAG 1.4.1: el color nunca es el único indicador — cada estado lleva ícono y texto.
 */

@import url("vendor/brand/tokens.css");

/* Poppins vendoreada (subset latin). Marca: una sola familia para todo, pesos 300-800. */
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 300; font-display: swap; src: url("vendor/brand/fonts/poppins-300.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/brand/fonts/poppins-400.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 500; font-display: swap; src: url("vendor/brand/fonts/poppins-500.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 600; font-display: swap; src: url("vendor/brand/fonts/poppins-600.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 700; font-display: swap; src: url("vendor/brand/fonts/poppins-700.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-style: normal; font-weight: 800; font-display: swap; src: url("vendor/brand/fonts/poppins-800.woff2") format("woff2"); }

:root {
  /* ── escala de texto del panel ────────────────────────────────────────────
   * La marca trae siete pasos fluidos (--text-xs … --text-2xl, en clamp con vw). Son los que
   * mandan para títulos y prosa. Pero el panel es una herramienta densa y arriba de esos siete
   * habían crecido QUINCE tamaños fijos en px: 8,5 · 9 · 9,5 · 10 · 10,5 · 11 · 11,5 · 12 · 13 ·
   * 13,5 · 14 · 15 · 16 · 27 · 28 · 32. Ocho de ellos eran "chico" en ocho sabores distintos,
   * elegidos de a uno, y cuatro caían por debajo del piso de lectura. En una sola pantalla se
   * contaron catorce tamaños: ningún dato podía destacar sobre otro porque todos competían.
   *
   * Ahora hay TRES nombres, y dos de ellos no son un tamaño nuevo: son un alias de un paso de la
   * marca, para que el CSS del panel diga qué papel cumple el texto y la marca decida cuánto mide.
   * El único tamaño propio es `--t-micro`: la marca no baja de --text-xs y el panel necesita un
   * escalón más para unidades y fechas, sin cruzar el piso de lectura.
   *
   * Si hace falta un tamaño nuevo, no se inventa: se elige uno de estos tres o uno de la marca.
   */
  --t-micro: 11px;              /* unidades, fechas, conteos: el piso de lectura del panel */
  --t-nota: var(--text-xs);     /* notas, sub-celdas, leyendas, chips */
  --t-nombre: var(--text-sm);   /* la fila: de quién o de qué estamos hablando */

  /* ── superficies y texto: mapeo a la marca ───────────────────────────────── */
  --fondo: var(--gray-bg);              /* #F2F2F2 — "separación de secciones" */
  --panel: var(--white);
  /* Grises FRÍOS, derivados del navy de la tinta y las reglas. Los anteriores (#EAEBE9 / #DFE1DE)
     tiraban a verde y, al lado del navy, las pastillas y los chips se veían sucios. Contraste de
     --tinta-tenue medido: 5,3 sobre --panel-2 y 4,8 sobre --panel-3 (antes 5,1 y 4,6). */
  --panel-2: #EDEFF3;                   /* un paso más que gray-bg, para zebra y chips */
  --panel-3: #E1E5EB;
  --tinta: var(--text-dark);            /* #1A1A2E */
  --tinta-suave: var(--text-muted);     /* #5A5A7A */
  /* Derivado de --text-muted un paso más claro, para metadata. Se había verificado solo contra
     blanco (4,9:1) y el panel casi nunca es blanco: sobre --fondo daba 4,41:1, sobre --panel-2
     4,13:1 y sobre --panel-3 3,76:1. Las solapas inactivas y los sufijos tipo "/100" quedaban
     abajo de AA en tres de las cuatro superficies claras. Medido sobre las cuatro:
     blanco 6,1 · --fondo 5,45 · --panel-2 5,10 · --panel-3 4,64. */
  --tinta-tenue: #606078;
  /* Tinta para texto que va ENCIMA de un relleno --peligro. En claro el peligro es #C0392B y el
     blanco da 5,44:1; en oscuro el peligro se invierte a un salmón claro (#F08A7A) y el mismo
     blanco cae a 2,44:1 — "REQUIERE ATENCIÓN", la etiqueta más importante de la ficha, era
     ilegible en oscuro. Mismo patrón que --sobre-acento, que ya existía para el mismo problema. */
  --sobre-peligro: #FFFFFF;
  --regla: rgba(47, 58, 77, 0.14);      /* navy translúcido: la regla pertenece a la marca */
  --regla-suave: rgba(47, 58, 77, 0.08);
  --grilla: rgba(47, 58, 77, 0.10);
  /* Divisoria de día en los gráficos (Chart.js y SVG). Sin definir, var() dejaba el trazo en
     'none' y las divisorias de la curva de batería no se veían. Mismo valor que el reporte. */
  --divisoria: #9AA6BF;

  --acento: var(--blue-deep);           /* serie principal de datos y foco: navy */
  --acento-2: var(--pink);              /* serie secundaria / highlight — uso controlado */
  --cta: var(--mint);                   /* SOLO botón primario */
  --cta-tinta: var(--blue-dark);        /* texto sobre mint: navy (11.8:1) */
  /* Tokens de interfaz. En claro NO son mint: mint sobre blanco da 1,4:1, así que el anillo de foco
     y la raya de la solapa activa prácticamente no se veían, y los carteles con borde mint y fondo
     lima usaban el color de "acción" como decoración (contra la regla de marca). */
  --foco: var(--blue-deep);             /* anillo de foco de teclado */
  --marca-linea: var(--blue-deep);      /* solapa activa, borde de carteles y líneas de lectura */
  --realce: #F4F6FA;                    /* hover de fila y fondo de cartel: gris frío, no lima */

  /* ── estados clínicos ────────────────────────────────────────────────────────
   * ⚠ Los colores semánticos NO están aprobados en la marca v1.0.0: están diferidos a
   * v1.0.1 (brand/tokens/colors.json → semantic._status) porque hay que resolver el
   * contraste del warning y decidir si son estados de app o alarmas clínicas
   * (IEC 60601-1-8). Se usa la PROPUESTA CANDIDATA registrada, tal cual, sin inventar hex.
   * `--aviso-texto` es la única derivación: #B8860B da 3.3:1 y no pasa AA como texto normal,
   * así que para texto se oscurece a #8A6508 (5.3:1 ✓) y el original queda para rellenos. */
  --ok: #2E7D5B;                        /* candidato success · 5.0:1 ✓ AA */
  --aviso: #B8860B;                     /* candidato warning · relleno/ícono */
  --aviso-texto: #8A6508;               /* derivado para texto · 5.3:1 ✓ AA */
  --peligro: #C0392B;                   /* candidato danger · 5.4:1 ✓ AA */
  --info: var(--blue-deep);             /* candidato info = navy · 11.4:1 ✓ AAA */

  /* ── tipografía (todo Poppins, marca aprobada) ───────────────────────────── */
  --ff: var(--font-body);
  --ff-d: var(--font-heading);
  --ff-m: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;

  --lateral: 264px;
}

/* Modo oscuro: no está en la marca v1.0.0. Se deriva del propio navy de marca
   (`--blue-dark` como fondo, `--blue-deep` como panel) en vez de inventar una paleta gris:
   así el oscuro sigue siendo Ellie y no un tema genérico. Los estados se aclaran para
   mantener contraste sobre navy, conservando el tono de la propuesta candidata.
   Se activa con `data-tema="oscuro"` en <html> (js/00-tema.js: sigue al sistema salvo que el
   botón del header haya guardado una elección), no con `prefers-color-scheme` directo. */
:root{color-scheme:light}
:root[data-tema="oscuro"]{
  color-scheme: dark;
  --fondo: #161E2B;
  --panel: var(--blue-dark);          /* #1E2838 */
  --panel-2: #26324A;
  --panel-3: #2F3A4D;                 /* = blue-deep */
  --tinta: #ECEEF2;
  --tinta-suave: #B3BACB;
  /* #8A93A8 daba 4,16:1 sobre --panel-2 (el relleno de las pastillas de puntaje): el "/100" de
     las tarjetas de dominio no pasaba AA. Medido: 5,13 sobre --panel-2, 6,70 sobre --fondo. */
  --tinta-tenue: #9BA4B9;
  --sobre-peligro: #1E2838;   /* 6,09:1 sobre el salmón claro del modo oscuro */
  --regla: rgba(255, 255, 255, 0.12);
  --regla-suave: rgba(255, 255, 255, 0.07);
  --grilla: rgba(255, 255, 255, 0.10);
  --divisoria: #6C7A99;
  /* El navy no contrasta sobre navy. Se usan los soft accents de la marca, que sí, y **no** mint:
     mint queda reservado al CTA para que no pierda su significado de "acción principal".
     --acento acá es CLARO (soft-green): sirve para texto/líneas sobre panel oscuro, NUNCA como
     fondo sólido con texto blanco (el par se invierte y queda blanco sobre verde claro). Un
     fondo sólido con texto claro usa --blue-deep, que no cambia entre temas. */
  --acento: var(--soft-green);        /* #F0FFD1 — serie principal de datos sobre navy */
  --acento-2: var(--soft-purple);     /* #D9B3FF — serie secundaria / highlight */
  --foco: var(--mint);
  --marca-linea: var(--mint);
  --realce: var(--panel-2);
  --ok: #6FC49A;
  --aviso: #E5B23F;
  --aviso-texto: #E5B23F;
  --peligro: #F08A7A;
}

*{box-sizing:border-box}
/* `[hidden]` del UA es `display:none`, y cualquier clase propia con `display:flex` le gana por
   especificidad: sin esto, el cartel de error y el rango de fechas quedaban visibles siempre. */
[hidden]{display:none !important}
body{margin:0;background:var(--fondo);color:var(--tinta);font-family:var(--ff);
  font-size:var(--text-base);line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3{margin:0;font-family:var(--ff-d);letter-spacing:-0.01em}
a{color:var(--acento-2);text-decoration-thickness:1px;text-underline-offset:2px}
a:hover{text-decoration-color:var(--mint)}
button,select,input{font-family:inherit;font-size:var(--text-sm);color:inherit}

/* ── header: banda navy de marca con el logo blanco ── */
.top{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  padding:10px 20px;background:var(--gradient-blue);color:#fff;position:sticky;top:0;z-index:20;
  box-shadow:var(--shadow-card)}
.marca{display:flex;align-items:center;gap:13px;cursor:pointer}
.marca .logo{height:44px;width:auto;display:block}
.marca h1{font-size:var(--text-lg);font-weight:var(--weight-semibold);color:#fff;line-height:1.1}
.marca .sub{font-size:var(--text-xs);color:rgba(255,255,255,.7)}
/* Una sola línea, todo a 36 px y centrado con la marca. Antes cada select llevaba su rótulo en
   mayúsculas ENCIMA y los botones no: los selects bajaban 20 px respecto de Actualizar, el estado y
   el ⚙, y el "Instalar app" quedaba flotando entre la marca y los controles. Los rótulos pasan a ser
   solo para lector de pantalla en escritorio (los valores se explican solos: "ES", "Producción
   LATAM", "Últimos 7 días") y vuelven a verse en el teléfono, donde los controles se apilan.
   Orden visual: marca · controles (empujados a la derecha) · acciones (instalar). */
.top-controles{display:flex;align-items:center;gap:10px;flex-wrap:wrap;order:1;margin-left:auto}
.top-acciones{order:2}
@media (min-width:901px){
  .top .campo>span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .top .campo select,.top .campo input,.top .btn,.top .btn-ico{height:36px}
  .top .btn{display:inline-flex;align-items:center;padding:0 14px}
  .top .btn-ico{width:36px}
  .top #sel-idioma{min-width:64px}
  .top .rango-inputs input{min-width:0}
  /* Frescura y utilidades separadas de los filtros de datos por una línea tenue. */
  .top .estado{padding-left:12px;border-left:1px solid rgba(255,255,255,.18)}
}
.campo{display:flex;flex-direction:column;gap:3px}
.campo>span{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.08em;
  color:rgba(255,255,255,.72);font-weight:var(--weight-medium)}
.top .campo select,.top .campo input{background:rgba(255,255,255,.12);color:#fff;
  border:1px solid rgba(255,255,255,.22);border-radius:var(--radius-sm);padding:6px 9px;min-width:126px}
.top .campo select option{color:var(--text-dark);background:#fff}
.campo input[type=date]{min-width:auto;color-scheme:dark}
.rango-inputs{display:flex;gap:5px}
.pii{font-size:var(--text-xs);font-family:var(--ff-m);color:var(--mint)}
.sesion{display:flex;align-items:center;gap:8px;font-size:var(--text-xs);color:rgba(255,255,255,.85)}
.sesion b{font-weight:var(--weight-semibold)}
.sesion button{background:transparent;border:1px solid rgba(255,255,255,.3);color:#fff;
  border-radius:var(--radius-pill);padding:3px 10px;cursor:pointer;font-size:var(--t-micro)}
.sesion button:hover{background:rgba(255,255,255,.12)}
.estado{font-size:var(--text-xs);color:rgba(255,255,255,.72);max-width:240px;line-height:1.35}
.estado b{color:var(--mint)}

/* Botones. Mint = acción principal, con texto navy (regla de marca). */
.btn{background:var(--cta);color:var(--cta-tinta);border:0;border-radius:var(--radius-pill);
  padding:7px 15px;cursor:pointer;font-weight:var(--weight-semibold);font-size:var(--text-sm);
  box-shadow:var(--shadow-soft);transition:transform .18s var(--ease-premium),box-shadow .18s var(--ease-premium)}
.btn:hover{box-shadow:var(--shadow-glow-mint);transform:translateY(-1px)}
.btn-sec{background:transparent;color:inherit;border:1px solid var(--regla);box-shadow:none}
.top .btn-sec{color:#fff;border-color:rgba(255,255,255,.3)}
.btn-sec:hover{background:var(--panel-2);box-shadow:none;transform:none}
.top .btn-sec:hover{background:rgba(255,255,255,.12)}
.btn-chico{padding:4px 10px;font-size:var(--text-xs)}

.aviso-global{margin:0;padding:10px 20px;background:var(--panel);border-bottom:2px solid var(--peligro);
  color:var(--peligro);font-size:var(--text-sm);display:flex;gap:10px;align-items:flex-start}
.aviso-global code{font-family:var(--ff-m);font-size:var(--t-nota)}

/* ── layout ── */
/* Barra lateral de filtros: empresa (siempre) y buscador (solo en la lista de Pacientes). Vuelve a
   ser columna porque es donde se la busca, pero más angosta que la original (264 px contra 296) y
   con los controles agrupados en una tarjeta: dos filtros no necesitan una columna de 300 px de
   aire. Sticky, así el filtro de empresa queda a mano con la tabla scrolleada. En la ficha no
   aplica ningún filtro y se esconde entera (`body.vista-ficha`): la ficha usa todo el ancho. */
.layout{display:grid;grid-template-columns:var(--lateral) minmax(0,1fr);min-height:calc(100vh - 64px)}
body.vista-ficha .layout{grid-template-columns:minmax(0,1fr)}
body.vista-ficha .lateral{display:none}
.lateral{border-right:1px solid var(--regla);background:var(--panel);padding:18px 16px;
  display:flex;flex-direction:column;gap:12px;position:sticky;top:var(--alto-top,64px);align-self:start;
  max-height:calc(100vh - var(--alto-top,64px));overflow-y:auto}
.lateral-tit{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.08em;font-weight:var(--weight-semibold);
  color:var(--tinta-tenue);margin:0 2px}
.lateral-cuerpo{display:flex;flex-direction:column;gap:16px;background:var(--fondo);border:1px solid var(--regla-suave);
  border-radius:var(--radius);padding:14px 12px}
.bloque{display:flex;flex-direction:column;gap:6px}
.bloque[hidden]{display:none}
.lateral .campo{gap:6px}
.lateral .campo>span{color:var(--tinta-suave);font-size:var(--text-xs);letter-spacing:.06em}
.lateral .campo select,.lateral .campo input{width:100%;height:38px;background:var(--panel);
  border:1px solid var(--regla);border-radius:var(--radius-sm);padding:0 10px}
.lateral .campo input:focus,.lateral .campo select:focus{outline:2px solid var(--foco);outline-offset:1px}
.lateral .ayuda{margin:0}
.resumen-empresa{font-size:var(--text-xs);color:var(--tinta-suave);font-variant-numeric:tabular-nums}
.resumen-empresa:empty{display:none}

/* Escritorio: la lateral deja de ser columna y pasa a ser una BARRA de filtro arriba del contenido.
   Quedó con un solo control (empresa) y ocupaba 264 px de ancho en todas las pantallas de la
   cohorte: el tablero y la tabla ganan ese ancho. En el teléfono sigue como plegable (ver abajo). */
@media (min-width:901px){
  .layout{grid-template-columns:minmax(0,1fr)}
  .lateral{position:static;max-height:none;overflow:visible;border-right:0;background:transparent;
    padding:14px 22px 0;flex-direction:row;align-items:center;gap:12px}
  .lateral-tit{display:none}
  .lateral-cuerpo{flex-direction:row;align-items:center;flex-wrap:wrap;gap:10px 22px;background:transparent;border:0;padding:0}
  .lateral .bloque{flex-direction:row;align-items:center;gap:12px}
  .lateral .campo{flex-direction:row;align-items:center;gap:8px}
  .lateral .campo>span{white-space:nowrap}
  .lateral .campo select{width:auto;min-width:220px;max-width:340px;height:34px}
  .lateral .campo input{width:280px;height:34px}
  body:not(.vista-ficha) .lateral+.principal{padding-top:12px}
}
/* Pantallas muy anchas: el contenido no se estira más allá de ~1760 px. A 2.560 px las tarjetas de
   KPI medían 400 px con un número de dos cifras y los gráficos se aplanaban. */
.layout{width:100%;max-width:1760px;margin-inline:auto}
/* "← Pacientes" es navegación, no un link de contenido: tinta suave, no violeta. */
.ficha-top .volver:hover{color:var(--tinta)}

/* Buscador arriba de la tabla de Pacientes (js/02-cohorte.js → barraBusquedaLista): input,
   botón y —si hay— el chip del filtro por señal heredado del tablero. */
.busqueda-lista{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 12px}
.busqueda-lista input{flex:1 1 260px;max-width:520px;height:38px;background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius-sm);padding:0 11px;font:inherit;color:var(--tinta)}
.busqueda-lista input:focus{outline:2px solid var(--foco);outline-offset:1px}
.busqueda-lista .btn{height:38px}

/* Por debajo de 900 px la lateral deja de ser columna: se apila arriba del contenido y se pliega
   (js/15-movil.js). Con el grid fijo el contenido caía a 79 px y la página scrolleaba de costado. */
@media (max-width:900px){
  .layout{grid-template-columns:minmax(0,1fr)}
  .lateral{border-right:0;border-bottom:1px solid var(--regla);position:static;max-height:none;
    overflow-y:visible;padding:10px 14px}
  .lateral-tit{display:none}
  .busqueda-lista input{max-width:none}
}
.ayuda{font-size:var(--text-xs);color:var(--tinta-tenue);line-height:1.45}
.check{display:flex;align-items:center;gap:8px;font-size:var(--text-sm);cursor:pointer}
.check input{accent-color:var(--blue-deep)}
.principal{padding:20px 22px 64px;min-width:0}
.cargando{padding:44px;text-align:center;color:var(--tinta-tenue);font-size:var(--text-sm)}

/* ── KPIs ── */
.kpis{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-bottom:18px}
.kpi{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius-sm);
  padding:10px 12px;display:flex;flex-direction:column;gap:1px;box-shadow:var(--shadow-soft)}
.kpi .k{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;color:var(--tinta-tenue);
  font-weight:var(--weight-medium)}
.kpi .v{font-family:var(--ff-d);font-size:var(--text-xl);font-weight:var(--weight-bold);line-height:1.15}
.kpi .v em{font-size:var(--text-xs);font-style:normal;color:var(--tinta-tenue);margin-left:4px;font-weight:400}
.kpi .s{font-size:var(--text-xs);color:var(--tinta-tenue)}
.kpi.alerta{border-left:3px solid var(--peligro)}
.kpi.aviso{border-left:3px solid var(--aviso)}
.lateral .kpi{padding:8px 10px}
.lateral .kpi .v{font-size:var(--text-md)}
/* KPIs de apoyo a un gráfico (hipnograma, pasos, calorías, desvío de temperatura): más chicos y
   más juntos que los de cabecera de solapa. Son el pie de foto del gráfico que tienen debajo, no
   el titular de la pantalla — con el tamaño grande, siete de estos empujaban el gráfico fuera de
   la primera pantalla, que es justo lo que se quería mostrar. */
/* Columnas de 170 px como mínimo: con minmax(118px,1fr) y tres KPIs en una tarjeta ancha, auto-fill
   dejaba columnas vacías a la derecha y cada KPI en 118 px, con el rótulo y el pie partidos en
   tres líneas ("TOTAL DEL / PERÍODO", "sobre 7 día(s) con / dato"). */
.kpis-chicos,.kpis-hipno{grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:8px;margin-bottom:12px}
.kpis-chicos .kpi,.kpis-hipno .kpi{padding:7px 9px}
.kpis-chicos .kpi .v,.kpis-hipno .kpi .v{font-size:var(--text-md)}
.kpis-chicos .kpi .k,.kpis-hipno .kpi .k{font-size:var(--t-micro);letter-spacing:.05em}
.kpis-chicos .kpi .s,.kpis-hipno .kpi .s{font-size:var(--t-micro);line-height:1.3}

/* ── tablas ── */
/* position:relative hace del wrap el containing block de los absolutos de adentro (.sem .sr,
   .score-banda). Sin eso su containing block es el body, escapan del recorte de overflow-x y
   ensanchan el documento: a 375 px la lista de pacientes llegaba a 579 px. */
.tabla-wrap{position:relative;overflow-x:auto;background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-soft)}
table{border-collapse:collapse;width:100%;font-size:var(--text-sm)}
thead th{position:sticky;top:0;background:var(--panel);text-align:left;font-size:var(--text-xs);
  text-transform:uppercase;letter-spacing:.07em;color:var(--tinta-tenue);font-weight:var(--weight-semibold);
  padding:9px 8px;border-bottom:1px solid var(--regla);white-space:nowrap}
tbody td{padding:7px 8px;border-bottom:1px solid var(--regla-suave);white-space:nowrap}
/* Por debajo de 1500 px tambien cede la empresa: en la vista multi-empresa es contexto util, pero
   menos que el motivo por el que hay que mirar al paciente. Sigue en la ficha y en el filtro. */
@media (max-width:1500px){ .col-empresa{display:none} }
/* El nombre se recorta con puntos suspensivos (completo en el title) en vez de estirar la fila. */
@media (max-width:1700px){ .cel-pac{max-width:172px} }

/* La columna de hallazgos se limita en ancho para que no empuje la tabla fuera de la pantalla. */
/* Ancho MINIMO para los hallazgos: sin esto la reparticion de espacio la ganaba la columna con mas
   texto (Paciente) y "Que mirar" quedaba en 98 px, o sea ~25 caracteres de 165. */
/* Solo la lista de pacientes: sin acotar, TODA tabla del panel (métricas, eventos, batería…) le
   daba 200 px mínimos a su última columna, aunque fuera un número. */
.tabla-roster tbody td:last-child{white-space:normal;min-width:200px;max-width:250px}
.tabla-roster thead th:last-child{min-width:200px}
tbody tr.clickable{cursor:pointer}
/* Foco visible: la fila ahora se alcanza con Tab, y sin un anillo claro no se sabe dónde estás. */
tbody tr.clickable:focus-visible{outline:2px solid var(--foco);outline-offset:-2px}
tbody tr.clickable:focus-visible td{background:var(--realce)}
:root[data-tema="oscuro"] tbody tr.clickable:focus-visible td{background:var(--panel-2)}

/* Encabezado ordenable: se lee como algo que se puede tocar, y marca por dónde está ordenado. */
thead th.orden{cursor:pointer;user-select:none}
thead th.orden:hover{color:var(--tinta)}
thead th.orden:focus-visible{outline:2px solid var(--foco);outline-offset:-2px}
thead th.orden.on{color:var(--tinta)}
thead th.orden .flecha{margin-left:3px;color:var(--acento);font-size:var(--t-micro);vertical-align:middle}
tbody tr.clickable:hover td{background:var(--realce)}
:root[data-tema="oscuro"] tbody tr.clickable:hover td{background:var(--panel-2)}
td.num,th.num{text-align:right;font-family:var(--ff-m);font-size:var(--t-nota)}
td.mono{font-family:var(--ff-m);font-size:var(--t-nota);color:var(--tinta-suave)}
.nombre{font-weight:var(--weight-semibold)}
.sub-celda{font-size:var(--text-xs);color:var(--tinta-tenue)}

/* ── badges ── */
.badge{display:inline-block;font-family:var(--ff-m);font-size:var(--t-micro);text-transform:uppercase;
  letter-spacing:.05em;padding:2px 7px;border-radius:var(--radius-full);background:var(--panel-2);
  color:var(--tinta-suave);font-weight:var(--weight-medium)}
.b-prioritario{background:var(--peligro);color:var(--sobre-peligro)}
.b-atencion{background:var(--aviso);color:#231A00}          /* texto oscuro: el warning no pasa AA en blanco */
/* Aviso que se repite en muchas filas (pulso "alto para el período" en la tabla de alertas): el
   ámbar sólido en 12 de 16 filas convertía la tabla en una franja amarilla y ya no destacaba nada.
   Tinte + contorno: se ve, pero deja que lo sólido quede para lo que es excepción. */
.b-aviso-suave{background:color-mix(in srgb,var(--aviso) 14%,transparent);color:var(--aviso-texto);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--aviso) 45%,transparent)}
/* Seguimiento / normal / "sí": el estado MÁS tranquilo iba en navy sólido y era lo que más gritaba
   de la pantalla en modo claro. Tinte suave del acento (navy en claro, verde suave en oscuro). */
.b-seguimiento{background:color-mix(in srgb,var(--acento) 12%,transparent);color:var(--acento)}
.b-estable,.b-sin_hallazgos{background:var(--soft-green);color:var(--blue-dark)}
.b-alta{color:var(--ok)} .b-media{color:var(--aviso-texto)} .b-baja{color:var(--peligro)}
.chip{display:inline-block;font-family:var(--ff-m);font-size:var(--t-micro);padding:2px 6px;
  border-radius:var(--radius-sm);background:var(--fondo);border:1px solid var(--regla);
  margin:1px 2px 1px 0;color:var(--tinta-suave)}
.punto{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px;vertical-align:middle}
.p-normal{background:var(--ok)} .p-alto{background:var(--aviso)} .p-alto_severo{background:var(--peligro)}
.p-bajo{background:var(--pink)} .p-sin_dato{background:var(--tinta-tenue)}

/* ── ficha ── */
.ficha-top{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius);
  padding:16px 18px;margin-bottom:16px;box-shadow:var(--shadow-card)}
.ficha-top .volver{background:none;border:0;color:var(--tinta-suave);cursor:pointer;padding:0;
  font-size:var(--text-sm);margin-bottom:6px;font-weight:var(--weight-medium)}
.ficha-top h2{font-family:var(--ff-d);font-size:var(--text-2xl);font-weight:var(--weight-bold);
  color:var(--blue-deep);margin-bottom:2px}
:root[data-tema="oscuro"] .ficha-top h2{color:var(--tinta)}
.ident{display:flex;flex-wrap:wrap;gap:7px 24px;margin:10px 0 14px}
.ident .d{display:flex;flex-direction:column}
.ident .d span{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;color:var(--tinta-tenue);
  font-weight:var(--weight-medium)}
.ident .d strong{font-size:var(--text-sm);font-weight:var(--weight-semibold)}
/* "Último dato" de la cabecera: en ámbar pasado el hueco de 6 h, en rojo pasadas 24 h. */
.ident .d-aviso strong{color:var(--aviso-texto)}
.ident .d-alerta strong{color:var(--peligro)}
.acciones{display:flex;gap:9px;flex-wrap:wrap;align-items:center}
.acciones a.btn{text-decoration:none}
.banda{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;padding:10px 13px;
  border-radius:var(--radius-sm);background:var(--fondo);border-left:4px solid var(--tinta-tenue);
  font-size:var(--text-sm);margin:10px 0}
.banda-prioritario{border-left-color:var(--peligro)}
.banda-atencion{border-left-color:var(--aviso)}
.banda-seguimiento{border-left-color:var(--blue-deep)}
.banda-sin_hallazgos{border-left-color:var(--ok);background:var(--soft-green)}
:root[data-tema="oscuro"] .banda-sin_hallazgos{background:var(--panel-2)}

.tabs{display:flex;gap:4px;border-bottom:1px solid var(--regla);margin-bottom:16px;flex-wrap:wrap}
.tabs button{background:none;border:0;border-bottom:2px solid transparent;padding:9px 14px;
  cursor:pointer;color:var(--tinta-tenue);font-size:var(--text-sm);font-weight:var(--weight-medium)}
.tabs button.on{color:var(--blue-deep);border-bottom-color:var(--marca-linea);font-weight:var(--weight-semibold)}
:root[data-tema="oscuro"] .tabs button.on{color:var(--tinta)}
.tabs button:hover{color:var(--tinta)}

/* ── tira de estadísticas: reemplaza las tablas de una sola fila ──
   Agrupada y con aire: 12 números seguidos, con una línea entre cada par, son un muro. El aire
   entre grupos hace el trabajo que hacían los separadores, y sin ruido visual. */
.tira{display:flex;flex-wrap:wrap;gap:10px 30px;background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius-sm);padding:13px 16px;box-shadow:var(--shadow-soft)}
.tira .tg{display:flex;flex-direction:column;gap:5px}
.tira .tg+.tg{padding-left:30px;border-left:1px solid var(--regla-suave)}
.tg-tit{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.09em;color:var(--tinta-tenue);
  font-weight:var(--weight-semibold)}
.tg-items{display:flex;flex-wrap:wrap;gap:6px 22px;align-items:baseline}
.tira .ti{display:flex;flex-direction:column;min-width:52px}
.tira .ti b{font-family:var(--ff-d);font-size:var(--text-md);font-weight:var(--weight-semibold);
  line-height:1.15;letter-spacing:-.01em}
.tira .ti em{font-size:var(--t-micro);font-style:normal;text-transform:uppercase;letter-spacing:.07em;
  color:var(--tinta-tenue);margin-top:1px}
/* El número que importa se lee primero; los de contexto quedan un escalón atrás. */
.tira .ti-dest b{font-size:var(--text-xl);color:var(--blue-deep)}
:root[data-tema="oscuro"] .tira .ti-dest b{color:var(--tinta)}
.tira .ti-aviso b{color:var(--aviso-texto)}
.tira .ti-alerta b{color:var(--peligro)}
@media (max-width:900px){.tira{gap:10px 18px}.tira .tg+.tg{padding-left:18px}}

/* ── plegables: las tablas largas no pueden estar siempre abiertas ── */
details.pleg{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius-sm);
  margin-bottom:14px;box-shadow:var(--shadow-soft)}
details.pleg>summary{cursor:pointer;padding:10px 14px;display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;color:var(--tinta-suave);
  font-weight:var(--weight-semibold);list-style:none}
details.pleg>summary::-webkit-details-marker{display:none}
details.pleg>summary::before{content:"▸";display:inline-block;transition:transform .15s var(--ease-premium);color:var(--tinta-tenue)}
details.pleg[open]>summary::before{transform:rotate(90deg)}
details.pleg>summary:hover{background:var(--fondo)}
details.pleg>summary .sub{text-transform:none;letter-spacing:0;font-weight:400;color:var(--tinta-tenue);font-size:var(--text-xs)}
.pleg-cuerpo{padding:0 14px 14px}
.pleg-cuerpo>.tabla-wrap{box-shadow:none}

/* ── grilla de señales (small multiples) ── */
/* auto-fit: con 3 señales en 1900 px se estiran y ocupan la fila en vez de dejar una columna vacía. */
.grilla-senales{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:12px}
/* Series densas (HRV): 2–3 por fila y más alto; a 300 px cada tramo era una raya. */
.grilla-senales.ancha{grid-template-columns:repeat(auto-fill,minmax(min(100%,440px),1fr));gap:14px}
.grilla-senales.ancha .grafico.mini{height:200px}
.grilla-senales .sen{margin:0;display:flex;flex-direction:column;gap:8px}
.sen-tit{font-size:var(--text-sm);font-weight:var(--weight-semibold)}
.sen-tit .sub{font-weight:400;color:var(--tinta-tenue);font-size:var(--text-xs)}
.grafico.mini{height:140px}
.grilla-senales .tira{border:0;padding:0;box-shadow:none;background:none;gap:4px}
.grilla-senales .tira .ti b{font-size:var(--text-sm)}

/* ── infografía del resumen (misma que el reporte) ── */
/* `stretch` y no `center`: el bloque del índice y la fila de dominios tienen que terminar a la
   misma altura. Con `center` la fila de tarjetas quedaba flotando en el medio de un bloque más
   alto y las cuatro tarjetas se veían de tamaños distintos según cuánto texto traía cada una. */
.resumen-cab{display:grid;grid-template-columns:minmax(320px,368px) 1fr;gap:18px;align-items:stretch;margin-bottom:16px}
/* El anillo y su texto en la primera fila; la aritmética abajo, ocupando el ancho entero de la
   tarjeta. Antes los tres chips se apilaban en una columna de 24ch y la tarjeta crecía a lo alto
   hasta descolocar toda la cabecera. */
.indice{display:grid;grid-template-columns:auto 1fr;gap:10px 14px;align-content:center;
  background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-soft)}
.indice svg.anillo{width:112px;height:112px;border:0;background:none;flex:0 0 auto;align-self:center}
.indice-txt{min-width:0}
.indice-banda{font-family:var(--ff-d);font-size:var(--text-lg);font-weight:var(--weight-bold);line-height:1.15}
.banda-i-optimo{color:var(--ok)} .banda-i-limite{color:var(--aviso-texto)}
.banda-i-alto,.banda-i-bajo{color:var(--peligro)} .banda-i-sin_dato{color:var(--tinta-tenue)}
.indice-nota{font-size:var(--text-xs);color:var(--tinta-tenue);margin-top:5px;line-height:1.45}
/* La aritmética del índice, al lado del anillo: 83 − 9 = 74. Sin esto el número grande es un
   veredicto sin fuente, y la pregunta "¿de dónde sale?" se la hace todo el que abre la ficha. */
/* Fila completa bajo el anillo, con las tres piezas del mismo ancho: apiladas en la columna
   angosta del texto la tarjeta crecía hasta el doble de alto que la fila de dominios. */
.doms{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
/* Las cuatro tarjetas son una GRILLA DE FILAS FIJAS, no una pila de bloques que crece con su
   contenido. Antes cada una medía distinto: "Variación térmica" ocupa dos líneas de título y
   empujaba su puntaje a la línea siguiente, "Movimiento" traía dos líneas de subtítulo y las
   otras una, y el resultado eran cuatro tarjetas desalineadas donde nada se podía comparar de
   izquierda a derecha. Con filas fijas, el título, el puntaje, la pastilla, el número grande y
   la chispa están SIEMPRE a la misma altura en las cuatro. */
/* La última fila absorbe la altura sobrante (la del bloque del índice, que es más alto cuando
   trae el aviso de noches sin evaluar) y la chispa se ancla al pie. Con filas fijas quedaban
   80 px de vacío debajo de la chispa en las cuatro tarjetas. */
.dom{display:grid;grid-template-rows:auto auto auto auto minmax(28px,1fr);
  background:var(--panel);border:1px solid var(--regla);border-top:3px solid var(--tinta-tenue);
  border-radius:var(--radius-sm);padding:10px 12px 6px;box-shadow:var(--shadow-soft);min-width:0}
.dom-optimo{border-top-color:var(--ok)} .dom-limite{border-top-color:var(--aviso)}
.dom-alto,.dom-bajo{border-top-color:var(--peligro)}
/* Sin datos: borde punteado y valor tenue, SIN bajar la opacidad de toda la tarjeta: el
   subtítulo que explica por qué no hay dato quedaba en ~3:1 y es justo lo que hay que leer. */
.dom-sin_dato{border-top-color:var(--tinta-tenue);border-top-style:dashed}
.dom-sin_dato .dom-valor{color:var(--tinta-tenue)}
/* La tarjeta lleva a su sección de Salud. La flecha va posicionada y NO como fila del grid: las
   filas son fijas para que las cuatro tarjetas queden alineadas, y una fila más las desalinea.
   Aparece al pasar por encima o al enfocar con el teclado; en reposo la tarjeta se ve igual que
   antes — cuatro flechas permanentes compiten con el puntaje, que es lo que hay que leer. */
.dom-ir{position:relative;cursor:pointer;transition:border-color .12s,box-shadow .12s,transform .12s}
.dom-ir::after{content:"→";position:absolute;right:10px;bottom:6px;font-size:var(--t-nota);
  color:var(--tinta-tenue);opacity:0;transition:opacity .12s,transform .12s;pointer-events:none}
.dom-ir:hover{border-color:var(--acento);box-shadow:var(--shadow-card);transform:translateY(-1px)}
.dom-ir:hover::after{opacity:1;transform:translateX(2px)}
/* El foco se ve SIEMPRE que llegue por teclado, no solo en hover: es la única pista de que la
   tarjeta es accionable para quien no usa mouse. */
.dom-ir:focus-visible{outline:2px solid var(--acento);outline-offset:2px}
.dom-ir:focus-visible::after{opacity:1}
@media (prefers-reduced-motion:reduce){.dom-ir,.dom-ir::after{transition:none}.dom-ir:hover{transform:none}}
/* Tres columnas y sin `wrap`: el puntaje no puede caer nunca a la línea de abajo. El título tiene
   permiso para usar dos renglones y ahí se corta. */
.dom-top{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:6px;font-size:var(--t-nota);
  min-height:30px}
.dom-ico{font-size:var(--t-nombre)}
/* Enlace a la lista de lo que un gráfico deja afuera (relojes sin ningún dato, en el tablero). */
.tb-nota-sin{display:inline-block;margin-top:8px;padding:4px 0;background:none;border:0;color:var(--tinta-suave);
  font:inherit;font-size:var(--t-nota);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.tb-nota-sin:hover{color:var(--tinta)}
.tb-nota-sin:focus-visible{outline:2px solid var(--foco);outline-offset:2px;border-radius:4px}
/* Ítems de leyenda que un gráfico apaga cuando su serie no tiene datos (p. ej. RMSSD por noche):
   `.leg` es flex y pisaba el `hidden` del navegador. */
.leg[hidden]{display:none}
/* En caja alta y no en versalitas: las mayúsculas ocupan ~15% más y "MOVIMIENTO" —una palabra que
   no puede partirse— pedía 75 px en una columna de 64 y salía "MOVIMIENTC". Se había resuelto
   bajando el cuerpo a 10 px, que es por debajo del piso de lectura del panel y volvió a romperse
   al unificar la escala. Quitar la caja alta lo arregla de raíz: "Movimiento" entra en 63 px, y de
   paso estos cuatro títulos se leen como nombres y no como etiquetas de sistema. */
/* `overflow-wrap:anywhere` es la red: una palabra más ancha que su columna no puede envolver, así
   que desborda y el `overflow:hidden` la corta a la mitad —"Movimient", "Cambio de temperatur"—
   sin siquiera usar el segundo renglón que tiene disponible. Con esto parte la palabra antes que
   comerse el final, que es el mal menor de los dos. */
.dom-label{font-weight:var(--weight-semibold);font-size:var(--text-sm);
  line-height:1.2;min-width:0;overflow:hidden;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
/* Puntaje 0-100 del dominio, arriba a la derecha: el color dice el estado y el número dice cuánto.
   Va sobre fondo neutro y no al revés — el color de estado como relleno con texto claro encima no
   pasa contraste en modo oscuro. El texto de estado baja a su propia línea (flex-basis:100%). */
.dom-puntaje{white-space:nowrap;font-family:var(--ff-d);font-weight:var(--weight-bold);
  font-size:var(--text-base);line-height:1.15;padding:1px 8px;border-radius:var(--radius-pill);background:var(--panel-2)}
.dom-puntaje em{font-size:var(--t-micro);font-style:normal;font-weight:400;color:var(--tinta-tenue);margin-left:1px}
.dom-optimo .dom-puntaje{color:var(--ok)}
.dom-limite .dom-puntaje{color:var(--aviso-texto)}
.dom-alto .dom-puntaje,.dom-bajo .dom-puntaje{color:var(--peligro)}
.dom-estado{flex-basis:100%;text-align:right;font-family:var(--ff-m);font-size:var(--t-micro);text-transform:uppercase;color:var(--tinta-tenue);white-space:nowrap}
/* Por qué la tarjeta está en ese color: la métrica (o el hallazgo) que manda. Sin esto, "94/100 ·
   atención" se lee como un error del panel. Se trunca con ellipsis: el texto entero va en el title. */
.dom-motivo{display:block;text-transform:none;font-family:var(--ff);font-size:var(--t-micro);color:var(--tinta-suave);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:1px}
/* La pastilla de atención: el canal propio del estado, ahora que el color de la tarjeta lo decide
   el puntaje. Es una línea completa y con fondo para que compita de igual a igual con el número —
   si fuera texto tenue al pie, un dominio verde con una métrica fuera de rango se leería como
   "todo bien" y volveríamos al problema opuesto. */
.dom-flag{font-size:var(--t-micro);line-height:1.35;padding:2px 7px;border-radius:var(--radius-pill);
  margin:3px 0 5px;min-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  background:var(--panel-2);color:var(--tinta-suave)}
.dom-flag b{font-weight:var(--weight-semibold);text-transform:uppercase;font-size:var(--t-micro);letter-spacing:.04em}
.dom-flag-ok{background:transparent;color:var(--tinta-tenue);padding-left:0;text-transform:uppercase;
  font-family:var(--ff-m);font-size:var(--t-micro);letter-spacing:.04em}
/* Mismos pares fondo/texto que las pastillas del panel de métricas (.est-*): fondo claro fijo con
   tinta oscura, que contrasta en los dos temas. */
.dom-flag.flag-limite{background:#FBEFD6;color:#6B4E06}
/* "a mirar: …" en un dominio verde: misma caja y altura que la pastilla (las cuatro tarjetas
   siguen alineadas) pero sin fondo de color, en tinta suave. */
.dom-flag.dom-flag-nota{background:transparent;color:var(--tinta-suave);padding-left:0}
/* Alto y bajo, el MISMO par rojo: la pastilla dice cuán grave es, igual que el borde de la
   tarjeta. Antes "bajo" iba en lila (el color de "por debajo del rango" de la tabla de métricas)
   y la tarjeta quedaba con borde rojo y pastilla lila: dos códigos de color para una sola cosa.
   La dirección la dice la flecha (▼ / ▲) delante del motivo. */
.dom-flag.flag-alto,.dom-flag.flag-bajo{background:#F8DFDB;color:#8C2418}
.dom-valor{font-family:var(--ff-d);font-size:var(--text-xl);font-weight:var(--weight-bold);line-height:1.15;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dom-valor em{font-size:var(--t-micro);font-style:normal;color:var(--tinta-tenue);margin-left:4px;font-weight:400}
/* Dos renglones exactos, ni uno más: el subtítulo de una tarjeta traía dos líneas y el de la de
   al lado una, y esa diferencia corría la chispa de lugar en toda la fila. */
.dom-sub{font-size:var(--t-micro);color:var(--tinta-tenue);height:2.7em;line-height:1.35;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.dom-chispa{align-self:end}
.dom-chispa svg{width:100%;height:28px;display:block}
/* La franja llega dibujada al ancho real (1:1): no se estira; solo se achica si la tarjeta
   queda más angosta que cuando se pintó. */
.franja-card svg{width:auto;max-width:100%;height:auto;display:block;background:none;border:0}
.franja-leyendas{margin-top:8px}
/* SVG de lib/svg.js dibujados al ancho real de la tarjeta (anchoSvg): 1:1, sin estirarse. */
.tarjeta > svg.g{display:block;width:100%;max-width:100%;height:auto}
/* Los SVG compartidos con el PDF (lib/svg.js) traen el tamaño del texto en atributos pensados para
   papel: 8,5–9 px en ejes y rótulos, en gris tenue y el título del eje X en itálica. En pantalla,
   al lado de un gráfico de Chart.js (10–11 px, tinta suave, sin itálica), la misma ficha parecía
   hecha con dos herramientas. El CSS pisa los atributos de presentación solo en la app: el PDF
   sigue igual. Los números grandes (anillo, valores destacados) no se tocan. */
svg.g text[font-size="8"],svg.g text[font-size="8.5"],svg.g text[font-size="9"]{font-size:10px}
svg.g text[font-size="10"]{font-size:10.5px}
svg.g text[fill="var(--tinta-tenue)"]{fill:var(--tinta-suave)}
svg.g text[font-style="italic"]{font-style:normal}
.leyendas .sw.sw-punto{width:8px;height:8px;border-radius:50%;background:var(--peligro);border:0}
/* Muestras de leyenda que dibujan lo mismo que el gráfico: gris con borde (noche sin evaluar),
   línea punteada (umbral / RMSSD) y los dos marcos de la banda de la noche. */
.leyendas .sw.sw-gris{background:color-mix(in srgb,var(--tinta-tenue) 35%,transparent);border-color:var(--tinta-tenue)}
.leyendas .sw.sw-linea{height:0;width:16px;border:0;border-top:2px dashed var(--peligro);border-radius:0}
.leyendas .sw.sw-linea-2{border-top-color:var(--acento-2)}
.leyendas .sw.sw-sesion{background:transparent;border:0;box-shadow:inset 0 3px 0 var(--mint),inset 0 -3px 0 var(--mint)}
.leyendas .sw.sw-cama{background:transparent;border:0;box-shadow:inset 0 3px 0 var(--tinta-tenue),inset 0 -3px 0 var(--tinta-tenue)}
/* La caja de percentiles se dibuja con un viewBox de 520: estirada al ancho del contenedor, su
   texto se escala al doble y compite con los títulos de sección. Se limita para que salga 1:1. */
svg.caja{display:block;width:100%;max-width:560px;height:auto;background:none;border:0;margin:2px 0 4px}
.franja-tit{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;
  color:var(--tinta-suave);font-weight:var(--weight-semibold);margin-bottom:8px}
.franja-tit .sub{text-transform:none;letter-spacing:0;font-weight:400;color:var(--tinta-tenue)}

/* ── panel de resultados estilo laboratorio ── */
table.panel{border-collapse:collapse;width:100%;font-size:var(--text-sm)}
table.panel th{text-align:left;font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.06em;
  color:var(--tinta-tenue);font-weight:var(--weight-semibold);padding:8px 10px 8px 0;
  border-bottom:1px solid var(--regla);white-space:nowrap}
table.panel td,table.panel tbody th{padding:7px 10px 7px 0;border-bottom:1px solid var(--regla-suave);vertical-align:middle}
table.panel tbody th{font-size:var(--text-sm);font-weight:var(--weight-semibold);white-space:normal;min-width:14ch;text-transform:none;letter-spacing:0}
table.panel tbody th[title]{cursor:help}
table.panel .val{white-space:normal;font-family:var(--ff-d);font-size:var(--text-md)}
table.panel .val b{white-space:nowrap}
table.panel .val .uni{display:block;line-height:1.2}
table.panel .val .uni{font-family:var(--ff);font-size:var(--t-micro);color:var(--tinta-tenue)}
table.panel .graf{width:240px}
/* Panel angosto: el gráfico de rango se achica (es SVG, escala) antes que obligar a deslizar la tabla. */
@media (max-width:820px){table.panel .graf{width:130px}table.panel td,table.panel tbody th{padding-right:8px}}
table.panel .graf svg{width:100%;height:auto;display:block;background:none;border:0}
table.panel .delta{white-space:nowrap;font-family:var(--ff-m);font-size:var(--t-nota)}
/* Referencia clínica: dos líneas en pantalla, completa en el tooltip (y entera en el reporte). */
.ref-txt{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;cursor:help}
table.panel .delta .mejora{color:var(--ok)} table.panel .delta .empeora{color:var(--aviso-texto)}
table.panel .delta-sub{font-family:var(--ff);font-size:var(--t-micro);color:var(--tinta-tenue)}
table.panel th .delta-sub{font-weight:400;margin-top:2px}
table.panel .nota-excluidas{color:var(--aviso-texto);font-weight:600}
.indice-noches{color:var(--aviso-texto);font-weight:600;margin-top:4px}
table.panel .ref{font-size:var(--t-micro);color:var(--tinta-tenue);line-height:1.35;max-width:34ch;white-space:normal}
.pastilla{display:inline-block;font-size:var(--t-micro);font-weight:var(--weight-semibold);text-transform:uppercase;
  letter-spacing:.05em;padding:2px 8px;border-radius:var(--radius-full);white-space:nowrap}
.est-optimo{background:var(--soft-green);color:#1F5C42}
.est-limite{background:#FBEFD6;color:#6B4E06}
.est-alto{background:#F8DFDB;color:#8C2418}
.est-bajo{background:var(--soft-purple);color:#4A1E75}
.est-sin_dato{background:var(--fondo);color:var(--tinta-tenue)}

/* ── hallazgos agrupados ── */
/* Tira de severidad: una barra proporcional + el conteo. Responde "¿cuánto hay y de qué gravedad?"
   en un vistazo, que es la pregunta previa a leer un solo hallazgo. */

/* Tarjeta compacta: severidad, dominio y título en UNA línea; la evidencia en línea, no en grilla. */
.hall-cab{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.hall-cab h4{margin:0}
.ev-linea{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:var(--text-xs);color:var(--tinta-suave);margin:6px 0 0}
.ev-linea b{color:var(--tinta-tenue);font-weight:400}
.hall-meta{margin-top:8px}
.hall-meta>summary{font-size:var(--t-micro);color:var(--tinta-tenue);cursor:pointer;list-style:none}
.hall-meta>summary::-webkit-details-marker{display:none}
.hall-meta>summary::before{content:"▸ "}
.hall-meta[open]>summary::before{content:"▾ "}
.hall-meta>summary:hover{color:var(--tinta-suave)}

.grupo-hall{margin-bottom:14px}
.grupo-tit{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;
  font-weight:var(--weight-semibold);margin-bottom:8px;display:flex;align-items:center;gap:8px}
.grupo-tit.sev-alerta{color:var(--peligro)}
.grupo-tit.sev-aviso{color:var(--aviso-texto)}
.grupo-tit.sev-info{color:var(--tinta-suave)}

/* Sub-solapas de Salud: pastillas, un escalón visual por debajo de las solapas principales. */
.subtabs{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 16px}
.subtabs button{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius-pill);
  padding:6px 14px;cursor:pointer;font-size:var(--text-sm);color:var(--tinta-suave);
  display:flex;align-items:center;gap:6px;transition:background .15s var(--ease-premium)}
.subtabs button .ico{font-size:var(--t-nombre)}
.subtabs button:hover{background:var(--fondo)}
.subtabs button.on{background:var(--blue-deep);border-color:var(--blue-deep);color:#fff;font-weight:var(--weight-semibold)}
:root[data-tema="oscuro"] .subtabs button.on{background:var(--mint);border-color:var(--mint);color:var(--blue-dark)}
/* Control segmentado: elige la granularidad de un gráfico (día / semana / mes). Es un cambio de
   lectura sobre el mismo dato, así que va chico y pegado al gráfico, no como una solapa más. */
.seg{display:inline-flex;border:1px solid var(--regla);border-radius:var(--radius-pill);overflow:hidden;margin:0 0 10px}
.seg button{background:transparent;border:0;padding:5px 12px;cursor:pointer;font-size:var(--text-xs);
  color:var(--tinta-tenue);font-family:inherit}
.seg button + button{border-left:1px solid var(--regla)}
.seg button:hover{background:var(--fondo);color:var(--tinta)}
.seg button.on{background:var(--blue-deep);color:#fff;font-weight:var(--weight-semibold)}
:root[data-tema="oscuro"] .seg button.on{background:var(--mint);color:var(--blue-dark)}

/* ── hipnograma ── */
.selector-noche{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;margin:6px 0 12px}
.selector-noche .campo select{min-width:150px;background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius-sm);padding:6px 9px}
.hipno{position:relative;padding-bottom:16px}
/* El hipnograma es lo más importante de la solapa Sueño y ahora abre la sección: la tarjeta se
   distingue del resto (borde de acento) y la banda es más alta, que es lo que se mira de lejos
   cuando se proyecta la ficha en una reunión. */
.tarjeta-hipno{border-left:3px solid var(--acento);padding-top:14px}
.kpis-hipno{margin-bottom:10px}
.banda-ep{display:flex;gap:1px;height:76px;border-radius:var(--radius-sm);overflow:hidden;
  background:var(--fondo);border:1px solid var(--regla)}
@media (max-width:900px){.banda-ep{height:56px}}
.banda-ep .ep{flex:1 1 0;min-width:0;cursor:help}
/* El período de reposo se resalta con una franja mint arriba y abajo: la banda cuenta las 18 h de
   la ventana, pero la noche es solo el tramo marcado. Mint porque tiene que verse sobre las cinco
   clases de color, incluido el navy de "dormido". */
.banda-ep .ep.en-reposo{box-shadow:inset 0 4px 0 var(--mint),inset 0 -4px 0 var(--mint)}
/* Dentro del reposo, lo que NO es la sesión de sueño continuo (dormitar de mañana, el rato antes
   de dormirse) lleva la franja atenuada: sigue siendo "en la cama", pero no es la noche que miden
   "durmió", eficiencia y despertares. */
.banda-ep .ep.en-reposo:not(.en-sesion){box-shadow:inset 0 4px 0 var(--tinta-tenue),inset 0 -4px 0 var(--tinta-tenue)}
.ep-dormido{background:var(--acento)}
.ep-micro{background:var(--aviso)}
.ep-movimiento{background:var(--acento-2)}
.ep-despierto{background:var(--peligro)}
.ep-quieto_dia{background:var(--panel-3)}
/* El cartel de "esta noche no cuenta" va arriba de los KPIs del hipnograma. */
.aviso-noche{margin-bottom:10px}
.ep-sin_dato{background:repeating-linear-gradient(45deg,var(--panel-2),var(--panel-2) 3px,var(--fondo) 3px,var(--fondo) 6px)}
.marcas{position:relative;height:12px;margin-top:3px}
.marcas .marca-h{position:absolute;font-size:var(--t-micro);color:var(--tinta-tenue);font-family:var(--ff-m);transform:translateX(-50%)}
.leyendas{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:12px;font-size:var(--text-xs);color:var(--tinta-suave)}
.leyendas .leg{display:flex;align-items:center;gap:6px}
.leyendas .sw{width:14px;height:12px;border-radius:3px;display:inline-block;border:1px solid var(--regla-suave)}
.reposo-info{margin-top:11px;padding:9px 12px;background:var(--realce);border-left:3px solid color-mix(in srgb,var(--marca-linea) 45%,transparent);
  border-radius:var(--radius-sm);font-size:var(--text-sm)}
:root[data-tema="oscuro"] .reposo-info{background:var(--panel-2)}
.hallazgo .ev,.tarjeta .ev{display:grid;grid-template-columns:auto 1fr;gap:2px 14px;font-size:var(--text-xs)}
.tarjeta .ev dt{color:var(--tinta-tenue)}
.tarjeta .ev dd{margin:0}

.sec{margin-bottom:24px}
.sec>h3{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.08em;color:var(--tinta-suave);
  font-weight:var(--weight-semibold);margin-bottom:9px}
.sec>h3 .sub{text-transform:none;letter-spacing:0;color:var(--tinta-tenue);font-weight:400;font-size:var(--text-xs)}
.tarjeta{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius-sm);
  padding:13px 15px;margin-bottom:12px;box-shadow:var(--shadow-soft)}
/* El título de una tarjeta es un subtítulo, no un encabezado de página: sin esto hereda el h3
   grande y compite visualmente con el título de la sección que la contiene.
   `.tile-cab h3` va acá porque el selector de hijo directo no lo alcanzaba: el título de las
   tarjetas de "qué pasó en el período" era el ÚNICO encabezado sin estilo del panel y salía a
   18,7 px del navegador, más grande que el título de cualquier otra tarjeta. */
.tarjeta>h3,.tile-cab h3{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;
  color:var(--tinta-suave);font-weight:var(--weight-semibold);margin-bottom:9px}
.tile-cab h3{margin-bottom:0}
.grafico{position:relative;height:262px}
.grafico.chico{height:192px}
.dos{display:grid;grid-template-columns:1fr 1fr;gap:13px}
/* Una tarjeta dentro de .dos no lleva su margen inferior (lo pone el gap) y necesita min-width:0
   o el SVG de adentro impone su ancho intrínseco y rompe la grilla. */
.dos>.tarjeta{margin-bottom:0;min-width:0}
@media (max-width:1100px){.dos{grid-template-columns:1fr}}

/* Barra de ventana: el selector de ancho a la izquierda y las flechas a la derecha, en la misma
   línea. En pantallas angostas la barra se apila para que las flechas no queden fuera. */
/* ── veredicto de una sub-solapa: la respuesta antes de los números ── */
.veredicto{background:var(--panel);border:1px solid var(--regla);border-left:4px solid var(--tinta-tenue);
  border-radius:var(--radius-sm);padding:12px 15px;margin-bottom:14px;box-shadow:var(--shadow-soft)}
.veredicto.ver-optimo{border-left-color:var(--ok)}
.veredicto.ver-limite{border-left-color:var(--aviso)}
.veredicto.ver-alto{border-left-color:var(--peligro)}
.veredicto.ver-sin_dato{border-left-color:var(--tinta-tenue)}
.ver-txt b{display:block;font-family:var(--ff-d);font-size:var(--text-lg);font-weight:var(--weight-bold);line-height:1.25}
.ver-optimo .ver-txt b{color:var(--ok)}
.ver-limite .ver-txt b{color:var(--aviso-texto)}
.ver-alto .ver-txt b{color:var(--peligro)}
.ver-txt span{display:block;font-size:var(--text-sm);color:var(--tinta-suave);margin-top:2px}
/* auto-fit: con 2 o 3 tarjetas (las técnicas ocultas) llenan el ancho, sin columnas vacías. */
.ver-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-top:11px}

/* ── salud por stream: una barra por señal, en vez de una columna de porcentajes ── */
.streams{display:flex;flex-direction:column;gap:5px;margin:2px 0 4px}
.stream-fila{display:grid;grid-template-columns:minmax(120px,220px) 1fr 46px minmax(80px,150px);
  align-items:center;gap:9px;font-size:var(--text-xs)}
.st-nom{font-weight:var(--weight-semibold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-barra{background:var(--regla-suave);border-radius:var(--radius-full);height:9px;overflow:hidden}
.st-barra i{display:block;height:100%;border-radius:var(--radius-full);background:var(--ok)}
.st-flojo .st-barra i{background:var(--aviso)}
.st-mal .st-barra i{background:var(--peligro)}
/* Apagado por config: rayado, no rojo. Un stream que hace lo que se le pidió no es una falla, y
   pintarlo de rojo manda a investigar el reloj equivocado. */
.st-off .st-barra{background:repeating-linear-gradient(45deg,var(--panel-2),var(--panel-2) 3px,var(--fondo) 3px,var(--fondo) 6px)}
.st-val{font-family:var(--ff-m);text-align:right;color:var(--tinta-suave);font-size:var(--t-micro)}
.st-ver{color:var(--tinta-tenue);font-size:var(--t-micro);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-mal .st-ver{color:var(--peligro)}

.barra-ventana{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin-bottom:10px}
.barra-ventana .seg{margin-bottom:0}
.nav-ventana{display:inline-flex;align-items:center;gap:8px}
.nav-ventana .rango{font-size:var(--text-xs);color:var(--tinta-suave);font-variant-numeric:tabular-nums;
  min-width:15ch;text-align:center}
.nav-ventana button{background:transparent;border:1px solid var(--regla);border-radius:var(--radius-pill);
  width:26px;height:26px;line-height:1;cursor:pointer;color:var(--tinta-suave);font-size:15px}
.nav-ventana button:hover:not(:disabled){background:var(--fondo);color:var(--tinta)}
.nav-ventana button:disabled{opacity:.35;cursor:default}
/* Cartel informativo: neutro. El fondo lima con borde mint decía "positivo" y "acción" en avisos
   que casi siempre son "no hay dato". */
.nada{font-size:var(--text-sm);color:var(--tinta-suave);background:var(--realce);
  padding:10px 13px;border-radius:var(--radius-sm);border-left:3px solid color-mix(in srgb,var(--marca-linea) 45%,transparent)}
/* Dos carteles seguidos se tocaban y se leían como un solo bloque de texto largo. Van separados,
   y separados también de lo que sigue: son avisos sobre el período, no encabezado de los KPI. */
.nada + .nada,.aviso-medible + .nada{margin-top:10px}
.nada + .kpis,.nada + .kpis-chicos,.nada + .tarjeta,.nada + .sec{margin-top:16px}
:root[data-tema="oscuro"] .nada{background:var(--panel-2);border-left-color:var(--mint)}
.nota{font-size:var(--text-xs);color:var(--tinta-suave)}
.leyenda{font-size:var(--text-xs);color:var(--tinta-tenue);margin-top:7px}
/* Mismo aspecto que `.leyenda` pero siempre a la vista: es un DATO chico (sobre cuántas horas se
   comparó, un aviso de alcance), no una nota de método, y plegarNotas no lo esconde detrás de un
   "Cómo leerlo" que al abrirse decía "30 h con · 53 h sin". */
.nota-dato{font-size:var(--text-xs);color:var(--tinta-tenue);margin-top:7px}
.ba-interna{margin:0 0 10px}

/* "No se pudo medir": no es una alerta clínica ni un error, es una ausencia de dato. Por eso va en
   gris con borde neutro y NO en ámbar — el ámbar le decía al operador que había algo que atender
   en el paciente, cuando lo único que pasó es que el reloj no estuvo puesto de noche. */
.aviso-medible{display:flex;flex-direction:column;gap:3px;background:var(--panel-2);
  border:1px solid var(--regla);border-left:4px solid var(--tinta-tenue);
  border-radius:var(--radius-sm);padding:11px 14px;margin-bottom:13px}
.aviso-medible b{font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--tinta)}
.aviso-medible span{font-size:var(--text-xs);color:var(--tinta-suave);line-height:1.45}
.aviso-medible .aviso-medible-pie{color:var(--tinta-tenue)}

/* ── vista simple / vista técnica (ver aplicarTecnico en js/01-nucleo.js) ──
   Por defecto el body NO lleva la clase `tecnico`: todo lo marcado .solo-tecnico desaparece y
   las notas metodológicas se pliegan a una línea (click para abrir). Con la clase, se ve todo. */
body:not(.tecnico) .solo-tecnico{display:none !important}
/* `.solo-salud` / `.solo-detalle`: todo lo del paciente y su reloj que antes pedía el ⚙ (HRV, EDA,
   sueño por noche, batería, enlace, eventos crudos). Lo ve quien entra, equipo o empresa cliente:
   `aplicarTecnico` pone `.detalle` siempre. Ver mostrarDetalle() en js/01-nucleo.js. */
body:not(.tecnico):not(.detalle) .solo-salud,
body:not(.tecnico):not(.detalle) .solo-detalle{display:none !important}
body:not(.tecnico) .leyenda:not(.abierta),
body:not(.tecnico) .tb-sec-sub:not(.abierta),
body:not(.tecnico) .tile-nota:not(.abierta){display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;
  overflow:hidden;cursor:pointer}
body:not(.tecnico) .leyenda.abierta,body:not(.tecnico) .tb-sec-sub.abierta,body:not(.tecnico) .tile-nota.abierta{cursor:pointer}
/* El detalle de un hallazgo y los avisos (.nada) se pliegan a DOS líneas, no a una: son la
   explicación de un título, y con una sola línea queda cortada la frase que importa. */
body:not(.tecnico) .hall-detalle:not(.abierta),
body:not(.tecnico) .nada:not(.abierta){display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;cursor:pointer}
body:not(.tecnico) .hall-detalle.abierta,body:not(.tecnico) .nada.abierta{cursor:pointer}
/* El subtítulo metodológico de cada sección ("percentiles aproximados sobre…") solo en técnica.
   El de la franja de días y el de los plegables NO son metodológicos y se quedan. */
body:not(.tecnico) .sec>h3 .sub{display:none}
/* Ícono de vista técnica en el encabezado: discreto apagado, marca cuando está activo. */
.btn-ico{display:inline-flex;align-items:center;justify-content:center;background:transparent;
  border:1px solid rgba(255,255,255,.3);color:#fff;border-radius:var(--radius-pill);
  width:30px;height:30px;cursor:pointer;font-size:15px;line-height:1;opacity:.7;padding:0}
.btn-ico:hover{opacity:1;background:rgba(255,255,255,.12)}
.btn-ico.on{background:var(--mint);color:var(--blue-dark);border-color:var(--mint);opacity:1}

/* ── hallazgos ── */
.hallazgo{background:var(--panel);border:1px solid var(--regla);border-left:4px solid var(--tinta-tenue);
  border-radius:var(--radius-sm);padding:12px 15px;margin-bottom:11px;box-shadow:var(--shadow-soft)}
.hallazgo.sev-alerta{border-left-color:var(--peligro)}
.hallazgo.sev-aviso{border-left-color:var(--aviso)}
.hallazgo.sev-info{border-left-color:var(--blue-deep)}
.hallazgo h4{margin:6px 0 4px;font-family:var(--ff-d);font-size:var(--text-md);
  font-weight:var(--weight-semibold);color:var(--blue-deep)}
:root[data-tema="oscuro"] .hallazgo h4{color:var(--tinta)}
.hallazgo p{margin:.3em 0;font-size:var(--text-sm);max-width:100ch}
.hallazgo .ev{display:grid;grid-template-columns:auto 1fr;gap:1px 14px;margin:8px 0;font-size:var(--text-xs)}
.hallazgo .ev dt{color:var(--tinta-tenue)}
.hallazgo .ev dd{margin:0;font-family:var(--ff-m);font-size:var(--t-nota)}
.hallazgo .accion{background:var(--soft-green);padding:7px 10px;border-radius:var(--radius-sm);
  font-size:var(--text-sm);border-left:3px solid var(--ok)}
:root[data-tema="oscuro"] .hallazgo .accion{background:var(--panel-2)}
.hallazgo .pie-h{display:flex;flex-wrap:wrap;gap:3px 18px;font-size:var(--t-micro);color:var(--tinta-tenue);
  border-top:1px dashed var(--regla);padding-top:6px;margin-top:8px}
.hallazgo code{font-family:var(--ff-m);font-size:var(--t-micro)}

/* ── heatmap de cobertura ── */
.heat{display:grid;gap:2px;font-size:var(--t-micro);overflow-x:auto}
.heat .fila{display:grid;align-items:center;gap:2px}
.heat .et{font-size:var(--text-xs);color:var(--tinta-suave);white-space:nowrap;padding-right:7px;text-align:right;
  position:sticky;left:0;z-index:1;background:var(--panel);overflow:hidden;text-overflow:ellipsis}
/* Veredicto arriba de todo en Calidad: la respuesta antes que los números. */
.lectura-cab{margin:0 0 14px}
/* La celda lleva el número adentro. La opacidad se aplica al FONDO (pseudo-elemento) y no a la
   celda entera: con opacity en el contenedor el número heredaba la transparencia y en los días
   flojos quedaba ilegible. */
.heat .c{position:relative;height:22px;border-radius:3px;background:var(--fondo);
  border:1px solid var(--regla-suave);display:grid;place-items:center;overflow:hidden}
.heat .c.on{border-color:transparent}
.heat .c.on::before{content:"";position:absolute;inset:0;background:var(--acento);opacity:var(--op,1)}
.heat .c span{position:relative;font-family:var(--ff-m);font-size:var(--t-micro);color:var(--tinta);line-height:1}
/* Halo del color del panel en vez de elegir el color por intensidad: con la celda al ~50% ningún
   color de texto contrasta contra el relleno. */
.heat .c span{text-shadow:0 0 2px var(--panel),0 0 2px var(--panel)}
.heat .c.on span{color:var(--tinta)}

.heat .dias{display:grid;gap:2px;font-size:var(--t-micro);color:var(--tinta-tenue);text-align:center}

.detalle-json{font-family:var(--ff-m);font-size:var(--t-nota);background:var(--fondo);border:1px solid var(--regla);
  border-radius:var(--radius-sm);padding:11px;max-height:420px;overflow:auto;white-space:pre-wrap;word-break:break-word}

/* ── contraste BigQuery ↔ API (solapa "API vs BigQuery") ───────────────────────── */
.par-controles{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;margin:0 0 12px}
.par-controles .nota{margin:0;flex:1 1 240px}
.par-vers{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:10px;margin:0 0 14px}
.par-ver{border:1px solid var(--regla);border-left-width:4px;border-radius:6px;padding:9px 11px;background:var(--panel)}
.par-ver .pv-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px;margin-bottom:3px}
.par-ver .pv-top span{font-size:var(--t-micro);letter-spacing:.05em;text-transform:uppercase;color:var(--tinta-tenue)}
.par-ver .pv-txt{font-size:var(--t-nota);color:var(--tinta-suave);line-height:1.4}
.pv-ok{border-left-color:var(--ok)} .pv-aviso{border-left-color:var(--aviso)}
.pv-alerta{border-left-color:var(--peligro)} .pv-sin_dato{border-left-color:var(--regla)}
/* Un número que difiere se marca, pero nunca solo con color (WCAG 1.4.1): va con ≠ o signo. */
.mal{color:var(--peligro-txt,var(--peligro));font-weight:600}

/* ── selector de fuente del gráfico (BigQuery / API / ambas) ────────────────────── */
.fuente-sel{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;margin:0 0 10px}
.fs-lbl{font-size:var(--t-micro);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-tenue)}
.fs-btns{display:inline-flex;border:1px solid var(--regla);border-radius:6px;overflow:hidden}
.fs-btn{background:var(--panel);border:none;border-left:1px solid var(--regla);padding:5px 12px;
  font:inherit;font-size:var(--t-nota);color:var(--tinta-suave);cursor:pointer}
.fs-btn:first-child{border-left:none}
.fs-btn:hover{background:var(--panel-2)}
/* Mismos tokens que el botón primario de marca: --cta/--cta-tinta ya resuelven el contraste
   en los dos temas (navy sobre mint). Con --acento + blanco, en dark el texto desaparecía. */
.fs-btn.on{background:var(--cta);color:var(--cta-tinta);font-weight:600}
.fs-btn:disabled{opacity:.6;cursor:progress}
.fuente-sel .nota{margin:0;flex:1 1 260px;font-size:var(--t-nota)}

/* ── ramas de lectura: BigQuery | API Ellie ─────────────────────────────────────── */
/* Van ARRIBA de las solapas y se ven más pesadas que ellas a propósito: elegir la fuente
   del dato es una decisión de otro orden que elegir qué solapa mirar. */
.ramas{display:flex;gap:8px;margin:14px 0 10px;border-bottom:2px solid var(--regla);padding-bottom:10px}
.rama{display:flex;flex-direction:column;gap:1px;text-align:left;background:var(--panel);
  border:1px solid var(--regla);border-radius:8px;padding:8px 16px;cursor:pointer;font:inherit;min-width:180px}
.rama:hover{background:var(--panel-2)}
.rama .r-tit{font-family:var(--ff-d,inherit);font-size:var(--t-nombre);font-weight:600;color:var(--tinta)}
.rama .r-sub{font-size:var(--t-micro);color:var(--tinta-tenue)}
.rama.on{background:var(--cta);border-color:var(--cta)}
.rama.on .r-tit,.rama.on .r-sub{color:var(--cta-tinta)}
.rama.on .r-sub{opacity:.8}

/* cabecera de la rama de la API: de dónde salió cada cosa */
.api-cab{margin:0 0 12px}
.api-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:5px}
.api-cab .nota{margin:3px 0 0}
@media (max-width:700px){.ramas{flex-direction:column}.rama{min-width:0}}

/* ── revisión global de UI (2026-08-19) ─────────────────────────────────────────── */

/* KPIs secundarios de la cohorte: describen el dataset, no ordenan trabajo — van compactos. */
.kpis-sec{margin:2px 0 14px;padding:8px 14px;background:var(--panel);border:1px solid var(--regla);
  border-radius:var(--radius,8px)}
/* La tira ya trae su propio borde y fondo: adentro de .kpis-sec quedaba una tarjeta dentro de otra
   (doble borde, doble relleno) para cuatro números. El contenedor pone el marco; la tira, no. */
.kpis-sec .tira{margin:0;border:0;padding:0;background:none;box-shadow:none}

/* paginador del roster */
.paginador{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:12px 0 4px}
.paginador .nota{margin:0}

/* menú nativo de descargas del reporte 360 */
details.mas{position:relative;display:inline-block}
details.mas summary{list-style:none;cursor:pointer;display:inline-block}
details.mas summary::-webkit-details-marker{display:none}
details.mas .mas-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:40;min-width:210px;
/* Separador con título dentro del menú del reporte: agrupa la variante sin sueño para que no se
   lea como un formato más de descarga. */
.mas-menu .mas-sep{margin:6px 0 2px;padding:6px 12px 0;border-top:1px solid var(--regla);
  font-family:var(--ff-m);font-size:var(--t-micro);letter-spacing:.09em;text-transform:uppercase;color:var(--tinta-tenue)}
  background:var(--panel);border:1px solid var(--regla);border-radius:8px;box-shadow:var(--shadow-hover,0 8px 24px rgba(0,0,0,.18));
  padding:6px;display:flex;flex-direction:column}
details.mas .mas-menu a,details.mas .mas-menu button{display:block;width:100%;text-align:left;
  background:none;border:0;font:inherit;font-size:var(--text-sm,13px);color:var(--tinta);
  padding:8px 10px;border-radius:6px;cursor:pointer;text-decoration:none}
details.mas .mas-menu a:hover,details.mas .mas-menu button:hover{background:var(--panel-2)}

/* ── tabla de cohorte: la cola de triage ─────────────────────────────────────────────
 *
 * Es la pantalla donde se decide A QUIÉN LLAMAR PRIMERO, y hasta acá se leía como una planilla:
 * medido sobre la tabla real, 10 tamaños de fuente distintos, 25 nodos de texto por fila, y la
 * columna que dice POR QUÉ el paciente está en la lista ocupando 200 px a 9,5 px mientras cinco
 * columnas de un número solo se llevaban el resto del ancho. Con todo en rojo, el paciente de 41
 * y el de 51 pesaban exactamente igual.
 *
 * Dos reglas, y de ellas sale todo lo de abajo:
 *
 *   1. UNA SOLA COSA FUERTE POR FILA: el puntaje. Todo lo demás queda en tinta hasta que se lee.
 *   2. EL ROJO ES POSICIÓN, NO SUPERFICIE. La urgencia la lleva la regla del borde izquierdo y el
 *      puntaje; el texto que la explica va en tinta normal. Pintar de rojo también el motivo no
 *      agrega información — duplica la misma señal y gasta el único color que tiene que saltar.
 *
 * Escala de la tabla: cuatro tamaños, ni uno más. Cada uno tiene un trabajo.
 */
/* La tabla usa la escala del panel (--t-micro · --t-nota · --t-nombre) y agrega un solo paso propio:
   el puntaje, que es lo único de la lista que se lee de lejos. */
.tabla-wrap table{ --t-score: var(--text-lg); }
/* La escala vale solo si TODO se mapea a ella. Media docena de nodos por fila (`.sub-celda`, el IMEI,
   la empresa, el `<b>` de los días con dato) venían de otras pantallas con su tamaño heredado —12,48
   px y 14,08 px— y metían dos escalones intermedios en cada fila. La celda fija el piso de la escala
   y solo las clases nombradas abajo lo pisan; así un nodo nuevo nace dentro de la escala. */
.tabla-roster td{font-size:var(--t-nota)}
.tabla-wrap table .sub-celda{font-size:var(--t-nota)}

/* El score manda: es la primera columna y la razón del orden de la tabla. */
.score-cel{display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:62px}
.score-num{font-family:var(--ff-d,inherit);font-size:var(--t-score);font-weight:700;line-height:1;
  padding:2px 8px;border-radius:6px;font-variant-numeric:tabular-nums}
/* La banda ("REVISAR", "URGENTE") salió de la celda: repetía en versalitas lo que el color y el
   número ya dicen, y era el tercer tamaño de fuente dentro de una sola celda. Sigue en el árbol de
   accesibilidad —no `display:none`— porque para quien usa lector de pantalla el color del número no
   existe, y la banda es la única forma de saber si un 66 es "revisar" o "urgente". */
.score-banda{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.score-num.b-prioritario{background:color-mix(in srgb,var(--peligro) 16%,transparent);color:var(--peligro)}
.score-num.b-atencion{background:color-mix(in srgb,var(--aviso) 18%,transparent);color:var(--aviso-texto)}
.score-num.b-seguimiento{background:var(--panel-2);color:var(--tinta-suave)}
.score-num.b-estable{background:color-mix(in srgb,var(--ok) 14%,transparent);color:var(--ok)}

/* Qué mirar: por qué este paciente está en la lista. Es la columna que el operador vino a leer,
   y era la más chica de la tabla. Sube de 10,5 px a la escala de datos y gana ancho a costa de
   las columnas de un número, que no necesitan 120 px para mostrar "88 bpm". */
.ins-cel{display:flex;flex-direction:column;gap:3px;max-width:none}
/* Dos líneas en vez de una con puntos suspensivos: el motivo por el que el paciente está en la
   lista es lo que el operador vino a leer. Antes había que pasar el mouse por cada fila. */
.ins{font-size:var(--t-nota);line-height:1.35;overflow:hidden;white-space:normal;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;
  padding-left:8px;border-left:2px solid var(--regla);color:var(--tinta-suave)}
/* La severidad la lleva la regla del borde, no el texto: el texto se lee, la regla se escanea. */
.ins-alerta{border-left-color:var(--peligro);color:var(--tinta)}
.ins-aviso{border-left-color:var(--aviso)}

/* Filtro por señal, arriba de la tabla. Reusa los tokens del selector de fuente. */
.filtro-senal{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin:0 0 10px}
.filtro-senal .fs-btns{flex-wrap:wrap}
.filtro-senal .fs-btn b{font-weight:700;opacity:.75;margin-left:3px}
.filtro-senal .fs-btn:disabled{opacity:.4;cursor:not-allowed}

/* Anchos de la tabla de cohorte. Sin esto "Paciente" se comía 431px y la columna "Qué mirar"
   —el motivo por el que el paciente está en la lista— quedaba fuera de pantalla. El texto
   completo siempre queda en el title. */
.cel-pac{max-width:210px}
.cel-pac .nombre{font-size:var(--t-nombre);font-weight:var(--weight-semibold)}
.cel-pac .nombre,.cel-pac .sub-celda{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cel-emp{max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Reparto del ancho. Las cinco columnas de una cifra se fijan angostas para que "Qué mirar" —que
   es la única que explica la fila— se quede con lo que sobra. Sin esto el navegador repartía por
   contenido y le daba 200 px a la columna más larga de la tabla. */
.tabla-roster{table-layout:auto}
.tabla-roster th.c-ins,.tabla-roster td.c-ins{width:auto;min-width:340px}

/* La urgencia como POSICIÓN: una regla en el borde de la fila. Da ritmo vertical a 50 filas y
   deja el color fuera del texto, que es donde estorbaba. */
.tabla-roster tbody tr{border-left:3px solid transparent}
.tabla-roster tbody tr.f-bajo{border-left-color:var(--peligro)}
.tabla-roster tbody tr.f-alto{border-left-color:var(--aviso)}
.tabla-roster tbody tr td:first-child{padding-left:11px}
.cel-emp .sub-celda{overflow:hidden;text-overflow:ellipsis}
/* Acá había dos `.ins-cel{max-width:250px}` / `{max-width:230px}` de una versión anterior. Por orden
   de cascada ganaban al `max-width:none` de arriba, así que la columna recibía 340 px de la tabla y
   el contenido se seguía plegando dentro de 230: el motivo se cortaba a mitad de frase aunque hubiera
   ancho de sobra. El ancho de esta columna lo fija `.c-ins`, en un solo lugar. */

/* ── índice de salud en la cohorte: 100 = mejor ───────────────────────────────────
   Escala PROPIA, distinta de la del score de atención: son dos números con sentidos
   opuestos (salud alta = bien · atención alta = mirar ya) y compartir la paleta haría
   que un 90 se leyera como alarma. */
.score-num.s-optimo{background:color-mix(in srgb,var(--ok) 16%,transparent);color:var(--ok)}
.score-num.s-limite{background:color-mix(in srgb,var(--aviso) 16%,transparent);color:var(--aviso-texto)}
.score-num.s-alto{background:color-mix(in srgb,var(--peligro) 12%,transparent);color:var(--peligro)}
.score-num.s-bajo{background:var(--peligro);color:var(--sobre-peligro)}
.score-num.s-sin_dato{background:var(--panel-2);color:var(--tinta-tenue)}
/* Solo aparece cuando faltan métricas (ver 02-cohorte.js). Entra en la escala: 8,5 px era el tamaño
   más chico de la pantalla y estaba en la columna que más se mira. */
.score-met{font-size:var(--t-micro);color:var(--tinta-tenue);letter-spacing:.02em}

/* Prioridad operativa: chica y aparte del índice de salud. */
.prio{display:inline-block;min-width:26px;padding:1px 6px;border-radius:10px;font-size:var(--t-nota);
  font-weight:600;cursor:help}

/* ── Asistente de IA (js/14-chat.js) ────────────────────────────────────────────
 * Lanzador flotante abajo a la derecha + tarjeta de chat. Dos modos: "flotante" (tarjeta sobre el
 * contenido, anclada al lanzador) y "dock" (columna fija a la derecha que corre el layout para
 * leer la ficha y el chat a la vez). --chat-top lo fija el JS con la altura real del header. */
:root{--chat-ancho:420px;--chat-top:64px}

.chat-fab{position:fixed;right:20px;bottom:20px;z-index:21;display:flex;align-items:center;gap:0;height:48px;padding:0 0 0 0;
  border:0;border-radius:var(--radius-pill);background:var(--gradient-blue);color:#fff;cursor:pointer;
  box-shadow:0 10px 28px rgba(30,40,56,.35),0 2px 6px rgba(0,0,0,.15);transition:transform .15s,box-shadow .15s,padding .2s}
.chat-fab img{width:48px;height:48px;padding:10px;box-sizing:border-box;border-radius:50%;display:block}
/* Lugar para el lanzador al final de la página: sin esto, lo último de cada solapa (el último
   gráfico, el "Cómo leerlo") quedaba siempre debajo del botón y no había forma de leerlo. */
body:has(.chat-fab) .layout{padding-bottom:84px}
.chat-fab-txt{max-width:0;overflow:hidden;white-space:nowrap;font-size:var(--text-sm);font-weight:var(--weight-semibold);
  transition:max-width .25s,padding .25s;padding:0}
.chat-fab:hover{transform:translateY(-2px);box-shadow:0 14px 32px rgba(30,40,56,.4)}
.chat-fab:hover .chat-fab-txt,.chat-fab:focus-visible .chat-fab-txt{max-width:140px;padding-right:18px}
.chat-fab.activo{background:var(--blue-dark)}
.chat-fab:focus-visible{outline:3px solid var(--foco);outline-offset:2px}
.chat-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--mint);
  color:var(--cta-tinta);font-size:var(--t-nota);font-weight:700;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 2px var(--fondo)}
.chat-badge[hidden]{display:none}

.chat{position:fixed;z-index:20;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--regla);
  color:var(--tinta);overflow:hidden}
.chat[hidden]{display:none}
.chat.flotante{right:20px;bottom:80px;width:var(--chat-ancho);height:min(720px,calc(100vh - 110px));border-radius:18px;
  box-shadow:0 18px 50px rgba(30,40,56,.28),0 2px 8px rgba(0,0,0,.10);animation:chat-aparecer .18s ease-out}
.chat.dock{top:var(--chat-top);right:0;bottom:0;width:var(--chat-ancho);border-radius:0;border-width:0 0 0 1px;
  box-shadow:-6px 0 22px rgba(47,58,77,.10)}
body.chat-dock .layout{margin-right:var(--chat-ancho)}
body.chat-dock .chat-fab{right:calc(var(--chat-ancho) + 22px)}
@keyframes chat-aparecer{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}

.chat-cab{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 12px 10px 14px;
  background:var(--gradient-blue);color:#fff}
.chat-tit{display:flex;align-items:center;gap:10px;font-size:var(--text-sm);min-width:0}
.chat-tit b{font-family:var(--ff-d)}
.chat-ico{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;
  background:rgba(255,255,255,.12);flex:0 0 auto}
.chat-ico img{width:22px;height:22px;display:block}
.chat-acciones{display:flex;gap:2px}
.chat-icobtn{width:30px;height:30px;border:0;border-radius:8px;background:transparent;color:#fff;font-size:14px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center}
.chat-icobtn:hover{background:rgba(255,255,255,.14)}

.chat-msgs{flex:1;overflow:auto;padding:16px 14px;display:flex;flex-direction:column;gap:14px;scroll-behavior:smooth;scrollbar-width:thin}
/* Estado vacío abajo, pegado a la caja: saludo corto + preguntas sugeridas en una columna. */
.chat-vacio{margin-top:auto;display:flex;flex-direction:column;gap:16px}
.chat-hola{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:0 2px}
.chat-hola-ico{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;
  background:var(--gradient-blue);margin-bottom:6px;box-shadow:var(--shadow-soft)}
.chat-hola-ico img{width:26px;height:26px;display:block}
.chat-hola b{font-family:var(--ff-d);font-size:var(--text-lg);line-height:1.2;color:var(--tinta)}
.chat-hola p{margin:0;font-size:var(--text-sm);line-height:1.5;color:var(--tinta-suave)}
.chat-cards{display:flex;flex-direction:column;gap:8px}
.chat-card{display:flex;align-items:center;justify-content:space-between;gap:12px;text-align:left;font:inherit;font-size:var(--text-sm);
  line-height:1.35;padding:11px 14px;border-radius:12px;border:1px solid var(--regla);background:transparent;color:var(--tinta);
  cursor:pointer;transition:background .15s,border-color .15s}
.chat-card i{font-style:normal;flex:0 0 auto;color:var(--tinta-tenue);transition:transform .15s,color .15s}
.chat-card:hover{background:var(--panel-2);border-color:var(--acento)}
.chat-card:hover i{transform:translateX(3px);color:var(--acento)}
.chat-card:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
.chat-msg{display:flex;flex-direction:column;gap:6px;max-width:100%}
.chat-msg.usuario{align-items:flex-end}
.chat-burbuja{padding:9px 12px;border-radius:14px;font-size:var(--text-sm);line-height:1.5;max-width:94%;overflow-wrap:anywhere}
.chat-msg.usuario .chat-burbuja{background:var(--blue-deep);color:#fff;border-bottom-right-radius:4px;white-space:pre-wrap}
.chat-msg.asistente .chat-burbuja{background:var(--fondo);border:1px solid var(--regla);border-bottom-left-radius:4px;max-width:100%}
.chat-burbuja p{margin:0 0 8px} .chat-burbuja p:last-child{margin-bottom:0}
.chat-burbuja>p:first-child{font-weight:500}
.chat-burbuja h4{margin:10px 0 4px;font-size:var(--text-sm);color:var(--acento)} .chat-burbuja h4:first-child{margin-top:0}
.chat-burbuja ul,.chat-burbuja ol{margin:4px 0 8px;padding-left:20px}
.chat-burbuja li{margin:2px 0} .chat-burbuja li ul{margin:2px 0 2px}
.chat-burbuja code{font-family:var(--ff-m);font-size:var(--t-nota);background:var(--panel-2);padding:1px 4px;border-radius:4px}
.chat-burbuja hr{border:0;border-top:1px solid var(--regla);margin:8px 0}
.chat-llamado{margin:6px 0;padding:6px 10px;border-left:3px solid var(--aviso);background:rgba(184,134,11,.08);border-radius:0 8px 8px 0;font-size:var(--text-xs)}
.chat-tabla{overflow-x:auto;margin:6px 0}
.chat-tabla table{font-size:var(--text-xs);width:100%} .chat-tabla th{font-weight:600;color:var(--tinta-suave)}
.chat-tabla th,.chat-tabla td{padding:4px 6px;border-bottom:1px solid var(--regla);text-align:left;white-space:nowrap}
.chat-rel{font-family:var(--ff-m);font-size:var(--t-nota);color:var(--acento);text-decoration:underline dotted}
.chat-cursor{display:inline-block;animation:chat-parpadeo 1s steps(2) infinite;color:var(--acento)}
@keyframes chat-parpadeo{50%{opacity:0}}
.chat-pensando{color:var(--tinta-tenue);font-style:italic;display:inline-flex;align-items:center;gap:6px}
.chat-puntos i{display:inline-block;width:5px;height:5px;margin-right:2px;border-radius:50%;background:var(--acento);
  animation:chat-rebote 1.1s infinite ease-in-out}
.chat-puntos i:nth-child(2){animation-delay:.15s} .chat-puntos i:nth-child(3){animation-delay:.3s}
@keyframes chat-rebote{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-4px);opacity:1}}
.chat-herr{display:flex;flex-wrap:wrap;gap:4px}
.chat-h{font-size:var(--t-micro);padding:2px 8px;border-radius:var(--radius-pill);background:var(--panel-2);color:var(--tinta-suave);cursor:help}
.chat-h.en-curso{color:var(--acento)} .chat-h.ok{color:var(--ok)} .chat-h.error{color:var(--peligro)}
.chat-fig{margin:0;padding:8px 10px 6px;border:1px solid var(--regla);border-radius:12px;background:var(--panel)}
.chat-fig figcaption{font-size:var(--text-xs);font-weight:600;color:var(--tinta);margin-bottom:4px;display:flex;flex-wrap:wrap;gap:6px;align-items:baseline}
.chat-fig-sub{font-weight:400;color:var(--tinta-tenue)}
.chat-canvas{position:relative;height:170px}
.chat-error{font-size:var(--text-xs);color:var(--peligro);padding:4px 8px;border-left:3px solid var(--peligro)}
.chat-nota{font-size:var(--text-xs);color:var(--tinta-tenue);font-style:italic}
.chat-meta{font-size:var(--t-micro);color:var(--tinta-tenue)}
.chat-link{background:none;border:0;padding:0;font:inherit;font-size:var(--t-micro);color:var(--tinta-tenue);cursor:pointer;text-decoration:underline dotted}
.chat-link:hover{color:var(--acento)}
.chat-accs{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}
.chat-acc{font-size:var(--t-micro);padding:4px 10px;border-radius:var(--radius-pill);border:1px solid var(--acento);background:transparent;
  color:var(--acento);cursor:pointer;text-decoration:none;font-family:inherit}
.chat-acc:hover{background:var(--blue-deep);color:#fff}
.chat-sigs{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.chat-sug{display:flex;gap:6px;overflow-x:auto;padding:6px 12px;border-top:1px solid var(--regla-suave);scrollbar-width:none}
.chat-sug[hidden]{display:none}
.chat-chip{flex:0 0 auto;font:inherit;font-size:var(--text-xs);padding:5px 10px;border-radius:var(--radius-pill);border:1px solid var(--regla);
  background:var(--panel);color:var(--tinta-suave);cursor:pointer;white-space:nowrap;max-width:280px;overflow:hidden;text-overflow:ellipsis}
.chat-chip:hover{background:var(--panel-2);color:var(--tinta)}
.chat-form{display:flex;flex-direction:column;gap:8px;padding:10px 12px 12px;border-top:1px solid var(--regla-suave)}
/* Dentro de una ficha: "Este paciente | Todos". Reemplaza a la franja de contexto de arriba. */
.chat-alcance{display:inline-flex;align-self:flex-start;gap:2px;padding:3px;border-radius:var(--radius-pill);background:var(--panel-2)}
.chat-alcance[hidden]{display:none}
.chat-alcance button{display:inline-flex;align-items:center;gap:5px;border:0;background:transparent;color:var(--tinta-suave);
  font:inherit;font-size:var(--text-xs);padding:4px 11px;border-radius:var(--radius-pill);cursor:pointer}
.chat-alcance button:hover{color:var(--tinta)}
.chat-alcance button.on{background:var(--panel);color:var(--tinta);font-weight:var(--weight-semibold);box-shadow:var(--shadow-soft)}
.chat-alcance button:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
/* Una sola caja: el texto y el botón de enviar adentro. El foco se marca con el borde y un halo
   suave, no con el contorno verde de 2 px que rodeaba todo el campo. */
.chat-caja{display:flex;align-items:flex-end;gap:6px;padding:5px 5px 5px 14px;border:1px solid var(--regla);border-radius:20px;
  background:var(--fondo);transition:border-color .15s,box-shadow .15s}
.chat-caja:focus-within{border-color:var(--foco);box-shadow:0 0 0 3px color-mix(in srgb,var(--foco) 16%,transparent)}
.chat-caja textarea{flex:1;min-width:0;box-sizing:border-box;resize:none;border:0;outline:none;background:transparent;color:inherit;
  font:inherit;font-size:var(--text-sm);line-height:1.4;height:34px;max-height:140px;padding:7px 0}
.chat-caja textarea:disabled{cursor:not-allowed}
.chat-enviar,.chat-detener{flex:0 0 auto;width:34px;height:34px;border:0;border-radius:50%;cursor:pointer;font-size:14px;
  display:inline-flex;align-items:center;justify-content:center}
.chat-enviar{background:var(--cta);color:var(--cta-tinta)} .chat-enviar:hover{filter:brightness(.96)}
.chat-enviar:disabled{opacity:.4;cursor:not-allowed;filter:none}
.chat-detener{background:var(--peligro);color:var(--sobre-peligro)}
.chat-enviar[hidden],.chat-detener[hidden]{display:none}
.chat-off{padding:10px 12px;border-radius:12px;background:var(--panel-2);border-left:3px solid var(--peligro);
  color:var(--tinta-suave);font-size:var(--text-sm);line-height:1.45}
@media (max-width:1100px){
  body.chat-dock .layout{margin-right:0}
  .chat.dock{width:min(100vw,440px);box-shadow:-10px 0 30px rgba(47,58,77,.25)}
  body.chat-dock .chat-fab{right:22px}
}
@media (max-width:640px){
  /* Anclado a los cuatro bordes y no con width:100vw: 100vw incluye la barra de scroll, y el chat
     quedaba 15 px corrido a la izquierda, con el ícono de la cabecera cortado contra el borde. */
  .chat.flotante{inset:0;width:auto;height:auto;border-radius:0}
  body.chat-abierto .chat-fab{display:none}
  .chat-enviar,.chat-detener{width:40px;height:40px}
}
:root[data-tema="oscuro"] .chat{box-shadow:0 18px 50px rgba(0,0,0,.5)}
:root[data-tema="oscuro"] .chat-card:hover i{color:var(--mint)}
:root[data-tema="oscuro"] .chat-card:hover{border-color:var(--mint)}
:root[data-tema="oscuro"] .chat-badge{box-shadow:0 0 0 2px var(--panel)}

/* ── cohorte: solapas Tablero | Pacientes ─────────────────────────────────────────
   La cohorte tiene dos sub-vistas sobre el mismo roster (js/02-cohorte.js y js/02b-tablero.js).
   Reusan .tabs de la ficha para que la navegación se lea igual en toda la app. */
.ctabs{margin-bottom:14px}
.ctab-n{display:inline-block;font-family:var(--ff-m);font-size:var(--t-micro);padding:1px 6px;border-radius:var(--radius-full);
  background:var(--panel-2);color:var(--tinta-suave);margin-left:4px;vertical-align:middle}
.tabs button.on .ctab-n{background:var(--blue-deep);color:#fff}
:root[data-tema="oscuro"] .tabs button.on .ctab-n{background:var(--mint);color:var(--blue-dark)}

/* Chip del filtro que vino del tablero (no está en la barra de "requieren atención en"). */
.fs-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px 4px 10px;border-radius:var(--radius-pill);
  background:var(--panel-2);color:var(--blue-deep);font-size:var(--text-xs)}
:root[data-tema="oscuro"] .fs-chip{background:var(--panel-2);color:var(--tinta)}
.fs-chip .fs-lbl{color:inherit;opacity:.75}
.fs-chip .ctab-n{background:var(--blue-deep);color:#fff}
.fs-quitar{background:none;border:0;font:inherit;font-size:var(--t-nota);color:inherit;cursor:pointer;text-decoration:underline dotted;padding:0 2px}
.fs-quitar:hover{opacity:.8}

/* ── tablero de cohorte ── */
.kpis-tablero{grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}
/* KPI clickeable: abre la lista con su filtro. Se marca con el hover y el foco, no con el color. */
.kpi-link{cursor:pointer;border-radius:var(--radius-sm)}
.kpi-link .kpi{height:100%;box-sizing:border-box;transition:box-shadow .15s var(--ease-premium),transform .15s var(--ease-premium)}
.kpi-link:hover .kpi,.kpi-link:focus-visible .kpi{box-shadow:var(--shadow-card);transform:translateY(-1px);border-color:var(--acento)}
.kpi-link:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
.tbl-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-bottom:12px}
.tbl-grid.tres{grid-template-columns:repeat(3,minmax(0,1fr))}
.tbl-grid .tarjeta{margin-bottom:0;min-width:0}
.tarjeta>h3 .sub{text-transform:none;letter-spacing:0;font-weight:400;color:var(--tinta-tenue);font-size:var(--text-xs)}
@media (max-width:1250px){.tbl-grid.tres{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:900px){.tbl-grid,.tbl-grid.tres{grid-template-columns:1fr}}

/* Embudo: una fila por escalón, la barra proporcional al total y el número afuera de la barra
   (adentro, sobre el relleno navy, el texto oscuro se perdía cuando la barra era ancha). */
.embudo{display:flex;flex-direction:column;gap:3px;padding:10px 14px}
.emb-fila{display:grid;grid-template-columns:minmax(180px,230px) 1fr 64px 150px 120px;gap:14px;align-items:center;
  padding:7px 8px;border-radius:var(--radius-sm);cursor:pointer;border:1px solid transparent}
.emb-fila:hover,.emb-fila:focus-visible{background:var(--fondo);border-color:var(--regla)}
.emb-fila:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
.emb-txt{display:flex;flex-direction:column;line-height:1.3}
.emb-txt b{font-size:var(--text-sm);font-weight:var(--weight-semibold)}
.emb-txt span{font-size:var(--t-micro);color:var(--tinta-tenue)}
.emb-barra{position:relative;height:24px;background:var(--panel-2);border-radius:var(--radius-sm);overflow:hidden}
.emb-relleno{position:absolute;left:0;top:0;bottom:0;background:var(--acento);border-radius:var(--radius-sm);
  transition:width .3s var(--ease-premium)}
.emb-aviso .emb-relleno{background:var(--aviso)} .emb-alerta .emb-relleno{background:var(--peligro)}
.emb-n{font-family:var(--ff-d);font-size:var(--text-md);font-weight:var(--weight-bold);text-align:right}
.emb-alerta .emb-n{color:var(--peligro)} .emb-aviso .emb-n{color:var(--aviso-texto)}
.emb-pct{display:flex;flex-direction:column;font-size:var(--t-micro);color:var(--tinta-tenue);line-height:1.35;font-family:var(--ff-m)}
.emb-caen{font-size:var(--t-micro);color:var(--aviso-texto);font-family:var(--ff-m);text-align:right}
@media (max-width:1000px){.emb-fila{grid-template-columns:minmax(140px,180px) 1fr 56px 120px}.emb-caen{display:none}}

/* Bandas del índice de salud: barra proporcional + leyenda clickeable con conteo y porcentaje. */
.bandas{display:flex;height:12px;border-radius:var(--radius-full);overflow:hidden;background:var(--regla-suave);margin:2px 0 8px}
.bnd-bajo{background:var(--peligro)} .bnd-alto{background:var(--peligro);opacity:.55}
.bnd-limite{background:var(--aviso)} .bnd-optimo{background:var(--ok)}
.bnd-sin_dato{background:var(--tinta-tenue);opacity:.3}
.bandas-leyenda{display:flex;flex-wrap:wrap;gap:4px 8px;margin-bottom:8px}
.bnd-lg{display:inline-flex;align-items:center;gap:5px;background:none;border:1px solid transparent;border-radius:var(--radius-pill);
  padding:2px 8px 2px 4px;font:inherit;font-size:var(--text-xs);color:var(--tinta-suave);cursor:pointer}
.bnd-lg:hover,.bnd-lg:focus-visible{background:var(--fondo);border-color:var(--regla);color:var(--tinta)}
.bnd-lg b{font-family:var(--ff-d);font-size:var(--text-sm);color:var(--tinta)}
.bnd-lg em{font-style:normal;color:var(--tinta-tenue);font-family:var(--ff-m);font-size:var(--t-micro)}
.bnd-sw{width:10px;height:10px;border-radius:3px;display:inline-block;flex:0 0 auto}

.top-tabla .score-num{font-family:var(--ff-d);font-weight:var(--weight-bold)}

/* ── tablero v2: jerarquía, contraste y las tres fuentes de "qué pasó" ─────────────
   El único encabezado de la página es la PREGUNTA de cada sección; los títulos de tarjeta quedan
   un escalón abajo (chicos, en mayúsculas). Dentro del tablero las etiquetas secundarias usan la
   tinta suave y no la tenue: en dark la tenue sobre el panel daba ~4:1 y se perdía. */

/* ── Veredicto: la primera línea del tablero ──────────────────────────────────────
 * Reemplaza a la fila de cinco KPI. Una sola cosa fuerte —la oración— y todo lo demás en tinta.
 * El estado va en la REGLA del borde izquierdo, no en un panel de color: un bloque rojo a ancho
 * completo cada vez que se abre el tablero grita antes de que nadie haya leído nada, y después
 * el rojo de la lista ya no significa nada. Misma regla que las filas de la lista de pacientes.
 */
.veredicto-tb{background:var(--panel);border:1px solid var(--regla);border-left:4px solid var(--tinta-tenue);
  border-radius:var(--radius-sm);padding:20px 24px;margin:0 0 22px;box-shadow:var(--shadow-soft)}
.veredicto-tb.ver-alerta{border-left-color:var(--peligro)}
.veredicto-tb.ver-aviso{border-left-color:var(--aviso)}
.veredicto-tb.ver-ok{border-left-color:var(--ok)}

/* El botón va PEGADO a la oración, no contra el borde de la pantalla: con space-between quedaban
   600 px de aire entre "Hay 15 personas para revisar" y el botón que abre esas 15, y dejaba de
   leerse como la acción de esa frase. */
.ver-fila{display:flex;align-items:baseline;gap:20px;flex-wrap:wrap}
/* Oración, no etiqueta: sin versalitas, sin eyebrow arriba, sin dos puntos. Se lee de corrido. */
.ver-titulo{font-family:var(--ff-d);font-size:var(--text-xl);font-weight:var(--weight-bold);
  line-height:1.2;letter-spacing:-.01em;margin:0;max-width:30ch}
.ver-apoyo{margin:6px 0 0;color:var(--tinta-suave);max-width:62ch}
.ver-btn{flex:0 0 auto;align-self:center}

/* Los hechos del período. Botones que se leen como texto: la acción es abrir esa lista, así que
   tienen que invitar a tocarlos sin convertirse en cuatro botones compitiendo con el de arriba. */
.ver-hechos{list-style:none;display:flex;flex-wrap:wrap;gap:8px 26px;margin:18px 0 0;padding:18px 0 0;
  border-top:1px solid var(--regla-suave)}
.ver-hecho{background:none;border:0;padding:2px 0;cursor:pointer;font-family:inherit;
  font-size:var(--text-base);color:var(--tinta);border-bottom:2px solid var(--regla);
  transition:border-color .12s ease}
.ver-hecho:hover{border-bottom-color:var(--tinta)}
.ver-hecho.alerta{border-bottom-color:var(--peligro)}
.ver-hecho.aviso{border-bottom-color:var(--aviso)}
.ver-hecho:focus-visible{outline:2px solid var(--acento);outline-offset:3px;border-radius:2px}

@media (prefers-reduced-motion:reduce){.ver-hecho{transition:none}}
@media (max-width:720px){
  .veredicto-tb{padding:16px 17px}
  .ver-fila{flex-direction:column;align-items:flex-start;gap:12px}
  .ver-btn{align-self:stretch}
}
.tb-sec{margin-bottom:28px}
/* `.sec>h3` ya fija mayúsculas y tamaño chico: el selector va con la misma especificidad + clase
   para ganarle, si no la pregunta salía en versalitas de 11px como un título de tarjeta más. */
.tb-sec>h3.tb-sec-tit{font-family:var(--ff-d);font-size:var(--text-lg);font-weight:var(--weight-semibold);letter-spacing:-.01em;
  text-transform:none;color:var(--tinta);margin:0 0 2px;padding-top:8px;border-top:1px solid var(--regla)}
.tb-sec-sub{font-size:var(--text-xs);color:var(--tinta-suave);margin-bottom:12px}
body:not(.tecnico) .tb-sec-sub{display:none !important}
.tb-sec>h3.tb-sec-tit{display:flex;align-items:center;gap:10px}
/* Subtítulo de tarjeta en su propia línea, debajo del título en versalita: en la misma línea se
   partía en dos renglones mezclando mayúsculas y minúsculas ("ÍNDICE DE SALUD cuántos pacientes
   hay en / cada banda"). */
.tbl-card>h3 .sub{display:block;margin-top:3px;line-height:1.35}
.tb-leyenda{margin-top:2px}
.emb-grid{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}
@media (max-width:1100px){.emb-grid{grid-template-columns:1fr}}
.kpis-tablero .kpi .k,.kpis-tablero .kpi .s,.kpis-tablero .kpi .v em{color:var(--tinta-suave)}
.kpis-tablero .kpi .s{font-size:var(--t-nota);line-height:1.4}
.tbl-card>h3 .sub,.embudo .emb-txt span,.embudo .emb-pct,.bnd-lg em,.tbl-card .leyenda{color:var(--tinta-suave)}
.embudo .emb-txt span,.embudo .emb-pct,.embudo .emb-caen{font-size:var(--t-nota)}

/* Las tres fuentes: sala de alertas, botón del reloj, detector. Tarjetas iguales, lado a lado. */
.tb-fuentes{margin-bottom:12px}
.tb-tile{display:flex;flex-direction:column;gap:6px;border-top:3px solid var(--tinta-tenue)}
.tile-alerta{border-top-color:var(--peligro)} .tile-aviso{border-top-color:var(--aviso)}
.tile-cab{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.tb-tile .tile-cab h3{margin:0}
.tile-fuente{font-size:var(--t-micro);color:var(--tinta-suave);white-space:nowrap}
.tile-num{font-family:var(--ff-d);font-size:32px;font-weight:var(--weight-bold);line-height:1.05;background:none;border:0;padding:0;
  color:var(--tinta);text-align:left;font-variant-numeric:tabular-nums}
button.tile-num{cursor:pointer}
button.tile-num:hover,button.tile-num:focus-visible{text-decoration:underline dotted;text-underline-offset:5px}
.num-alerta{color:var(--peligro)} .num-aviso{color:var(--aviso-texto)}
.fuentes-nota{margin:-8px 0 16px;font-size:var(--t-nota);color:var(--tinta-suave);line-height:1.5;max-width:78ch}
.tile-filas{display:flex;flex-wrap:wrap;gap:4px 18px}
.tile-filas .tf{display:flex;flex-direction:column;min-width:0}
.tile-filas .tf b{font-family:var(--ff-d);font-size:var(--text-md);font-weight:var(--weight-semibold);line-height:1.2}
.tile-filas .tf span{font-size:var(--t-nota);color:var(--tinta-suave);line-height:1.35}
.tile-chips{display:flex;flex-wrap:wrap;gap:4px 6px;align-items:center}
.tile-chips-lbl{font-size:var(--t-micro);color:var(--tinta-suave);margin-right:2px}
.tile-chip{font-size:var(--t-nota);padding:2px 8px;border-radius:var(--radius-pill);background:var(--panel-2);color:var(--tinta)}
.tile-chip b{font-family:var(--ff-d)}
.tile-nota{font-size:var(--t-nota);color:var(--tinta-suave);line-height:1.4;margin-top:auto;padding-top:6px;border-top:1px solid var(--regla-suave)}
.tile-espera{padding:6px 0;text-align:left}
@media (max-width:1250px){.tb-fuentes{grid-template-columns:1fr}}

/* Avisos del reloj: una fila por tipo, nombre · barra · número · pacientes. HTML y no canvas. */
.lista-barras{display:flex;flex-direction:column;gap:5px}
.lb-grupo{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.06em;color:var(--tinta-suave);font-weight:var(--weight-semibold);margin:8px 0 2px}
.lb-grupo:first-child{margin-top:0}
/* La etiqueta puede partirse en dos líneas: "Pulso sobre su baseline" truncado a "Pulso sobre su…"
   dejaba la fila sin sentido. La barra cede ancho antes que el texto.
   La última columna lleva el denominador ("N de T personas") con white-space:nowrap: en 64px fijos
   el texto se salía de la caja y arrastraba el desborde hasta el documento. Con auto la columna
   mide lo que mide el texto y las columnas en fr ceden el ancho. */
.lb-fila{display:grid;grid-template-columns:minmax(150px,1.6fr) minmax(50px,1.6fr) 56px auto;gap:10px;align-items:center;font-size:var(--text-sm)}
.lb-lbl{line-height:1.25;font-size:var(--t-nota)}
.lb-bar{height:10px;background:var(--panel-2);border-radius:var(--radius-full);overflow:hidden;display:block}
.lb-bar i{display:block;height:100%;border-radius:var(--radius-full)}
.lb-acento{background:var(--acento)} .lb-acento2{background:var(--acento-2)}
.lb-n{font-family:var(--ff-d);text-align:right;font-variant-numeric:tabular-nums}
.lb-p{font-size:var(--t-nota);color:var(--tinta-suave);white-space:nowrap}
/* Avisos a todo el ancho: un grupo por columna. Señales que llegan: filas clickeables. */
/* Dos listas lado a lado solo si cada una tiene ~440 px: con la barra lateral abierta a 960 px
   quedaban de 286 px y la etiqueta se comprimía a 37 px. Por debajo, una debajo de la otra. */
.lb-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(440px,100%),1fr));gap:6px 32px}
@media (max-width:900px){.lb-cols{grid-template-columns:1fr}}
.lb-compacta{gap:3px}
/* Avisos del reloj (tbAvisos): cada lista es UNA grilla y sus filas se reparten en ella
   (display:contents). Así las barras quedan alineadas de fila a fila y "296 de 360 personas" tiene
   el ancho que pide: con columnas fijas por fila ese texto medía el doble de su columna (64 px) y,
   sin poder cortar renglón, se montaba sobre la lista de al lado. En pantalla angosta sí corta. */
.lb-avisos{display:grid;grid-template-columns:minmax(7em,1.3fr) minmax(40px,1fr) max-content minmax(0,max-content);
  column-gap:12px;row-gap:7px;align-items:center;min-width:0}
.lb-avisos .lb-grupo{grid-column:1/-1}
.lb-avisos .lb-fila{display:contents}
.lb-avisos .lb-lbl{white-space:normal;overflow:visible;text-overflow:clip;min-width:0}
.lb-avisos .lb-p{white-space:normal}
.lb-btn{background:none;border:0;padding:2px 4px;margin:0 -4px;border-radius:var(--radius-sm);cursor:pointer;font:inherit;color:inherit;text-align:left;width:calc(100% + 8px)}
.lb-btn:hover,.lb-btn:focus-visible{background:var(--fondo)}
.lb-btn:disabled{cursor:default;opacity:.55}
.lb-btn:disabled:hover{background:none}
.lb-muerta{font-style:normal;font-size:var(--t-micro);color:var(--aviso-texto)}
/* El embudo a todo el ancho: la barra crece y los porcentajes caben en una línea. */
.embudo .emb-fila{grid-template-columns:minmax(180px,230px) minmax(160px,1fr) 64px minmax(190px,230px) 130px}
.embudo .emb-pct{flex-direction:row;gap:12px;white-space:nowrap}
@media (max-width:1300px){.embudo .emb-fila{grid-template-columns:minmax(150px,200px) 1fr 60px 120px 110px}.embudo .emb-pct{flex-direction:column;gap:0;white-space:normal}}
@media (max-width:1000px){.embudo .emb-fila{grid-template-columns:minmax(140px,180px) 1fr 56px 120px}}

/* ── ficha: pulido visual (2026-09-10) ──────────────────────────────────────────────
   Tres cosas: (1) una sola fila de navegación —solapas a la izquierda, rama de lectura a la
   derecha como control segmentado—; (2) jerarquía: el título de una SECCIÓN de la solapa es más
   grande y en minúsculas, el de una TARJETA queda chico y en versalitas, así se distinguen de un
   vistazo; (3) los textos secundarios pasan de tinta tenue a suave y de 9–10 px a 10.5–11 px, y
   nada se trunca con puntos suspensivos en la cabecera del resumen. */

/* 1. cabecera del paciente */
.ficha-top{padding:18px 22px 16px}
.ficha-top .volver{font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.06em;margin-bottom:8px}
.ficha-top h2{font-size:28px;line-height:1.1;letter-spacing:-.02em}
.ident{margin:12px 0 16px;gap:9px 28px;padding-top:12px;border-top:1px solid var(--regla-suave)}
.ident .d span{color:var(--tinta-suave)}
.ident .d strong{line-height:1.3}
/* Paciente | Reloj: dos grupos rotulados, separados por una regla vertical que se cae cuando el
   segundo grupo baja de renglón (pantalla angosta). */
.ident-grupo{display:flex;flex-wrap:wrap;gap:7px 24px;align-content:flex-start}
.ident-grupo+.ident-grupo{padding-left:28px;border-left:1px solid var(--regla-suave)}
.ident-tit{flex-basis:100%;font-size:var(--t-micro);font-weight:var(--weight-bold);letter-spacing:.1em;
  text-transform:uppercase;color:var(--acento)}
:root[data-tema="oscuro"] .ident-tit{color:var(--mint)}
@media (max-width:900px){.ident-grupo+.ident-grupo{padding-left:0;border-left:0}}

/* Índice "En esta sección" (indiceSecciones en js/01-nucleo.js): saltos a cada sección de la
   sub-solapa. Más liviano que las sub-solapas —es navegación dentro de la página, no otra vista—:
   una línea de texto sobre una regla, sin caja. */
.indice-sec{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 4px;margin:-6px 0 18px;
  padding:0 0 10px;border-bottom:1px solid var(--regla-suave)}
.indice-tit{font-size:var(--t-micro);font-weight:var(--weight-bold);letter-spacing:.1em;text-transform:uppercase;
  color:var(--tinta-tenue);margin-right:6px}
.indice-sec button{background:none;border:0;padding:3px 8px;border-radius:var(--radius-pill);cursor:pointer;
  font:inherit;font-size:var(--text-xs);color:var(--tinta-suave)}
.indice-sec button:hover{background:var(--panel);color:var(--tinta)}
.indice-sec button:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
/* El salto deja el título debajo de la fila sticky de solapas, no tapado por ella. */
#tab-cuerpo .sec,#tab-cuerpo details.pleg{scroll-margin-top:calc(var(--alto-top,64px) + 64px)}
@media (max-width:700px){.indice-sec{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .indice-sec button{flex:0 0 auto}}
.acciones .badge{padding:6px 10px;font-size:var(--t-micro);letter-spacing:.06em}

/* ── ficha limpia (2026-09-23) ──────────────────────────────────────────────────────
   Menos texto a la vista y una sola jerarquía en todas las solapas: SECCIÓN (título grande) ›
   TARJETA (versalita chica) › DETALLE (plegable, en minúscula). El método —cómo se calculó, qué no
   es— va en un ⓘ o en "Cómo leerlo", nunca corrido entre el título y el dato. */

/* ⓘ del subtítulo de una sección (infoI en js/01-nucleo.js). Solo en la ficha y fuera de la vista
   técnica, que muestra el subtítulo entero. El globo sale con hover o con foco de teclado. */
.info-i{display:none}
body:not(.tecnico) .info-i{display:inline-flex;align-items:center;justify-content:center;
  align-self:center;flex:0 0 auto;width:17px;height:17px;border-radius:50%;border:1px solid var(--regla);
  color:var(--tinta-tenue);font:italic 600 11px/1 Georgia,serif;cursor:help;position:relative}
body:not(.tecnico) .info-i:hover,
body:not(.tecnico) .info-i:focus-visible{color:var(--tinta);border-color:var(--tinta-suave);outline:none}
.info-i::after{content:attr(data-info);position:absolute;left:-8px;top:calc(100% + 8px);width:max-content;
  max-width:min(340px,78vw);padding:9px 12px;border-radius:10px;background:var(--panel-2);border:1px solid var(--regla);
  box-shadow:var(--shadow-card);color:var(--tinta-suave);font:400 var(--text-xs)/1.45 var(--ff);letter-spacing:0;
  text-transform:none;text-align:left;white-space:normal;opacity:0;visibility:hidden;transform:translateY(-3px);
  transition:opacity .12s,transform .12s,visibility .12s;z-index:40;pointer-events:none;display:none}
/* display:none hasta el hover: oculto con visibility igual contaba en el ancho de la página, y un ⓘ
   pegado al borde derecho sumaba scroll horizontal en el panel angosto. */
.info-i:hover::after,.info-i:focus::after{display:block;opacity:1;visibility:visible;transform:none}

/* "ⓘ Cómo leerlo" (plegarNotas en js/01-nucleo.js): la nota de método a un click, pegada al
   gráfico o la tabla que explica. Abierta se lee entera: nada de una línea cortada con "…". */
.nota-pleg{margin-top:8px}
.nota-pleg>summary{display:inline-flex;align-items:center;gap:6px;cursor:pointer;list-style:none;
  font-size:var(--text-xs);color:var(--tinta-tenue);border-radius:var(--radius-pill);padding:2px 8px 2px 0}
.nota-pleg>summary::-webkit-details-marker{display:none}
.nota-pleg>summary::before{content:"i";display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;
  border-radius:50%;border:1px solid var(--regla);font:italic 600 10px/1 Georgia,serif}
.nota-pleg>summary:hover,.nota-pleg[open]>summary{color:var(--tinta-suave)}
.nota-pleg>summary:focus-visible{outline:2px solid var(--foco);outline-offset:1px}
.nota-pleg .leyenda{display:block!important;-webkit-line-clamp:unset!important;overflow:visible!important;cursor:auto!important;
  margin-top:6px;max-width:110ch;line-height:1.5;color:var(--tinta-suave)}

/* Plegables de la ficha: son DETALLE, no encabezados. En versalita competían con los títulos de
   sección; en minúscula y un punto más chicos se leen como lo que son. Su nota de método pasa al
   `title` del summary (ver plegable()). */
#tab-cuerpo details.pleg>summary{text-transform:none;letter-spacing:0;font-size:var(--text-sm);
  font-weight:var(--weight-semibold);color:var(--tinta-suave)}
#tab-cuerpo details.pleg>summary:hover{color:var(--tinta)}
body.vista-ficha:not(.tecnico) #tab-cuerpo details.pleg>summary .sub{display:none}

/* Aire entre secciones: con menos texto, el espacio es lo que separa un bloque del siguiente. */
#tab-cuerpo .sec{margin-bottom:30px}
#tab-cuerpo .sec>.dos+.tarjeta,#tab-cuerpo .sec>.dos+.tira{margin-top:12px}
/* Una tira de números DENTRO de una tarjeta (su nivel habitual, debajo del gráfico nocturno): sin
   su propia caja, separada del gráfico por una regla. */
.tarjeta>.tira{border:0;background:none;box-shadow:none;padding:10px 0 0;margin-top:10px;border-top:1px solid var(--regla-suave);border-radius:0}
/* Una sección DENTRO de otra (el pulso de la noche dentro de "Cómo pasó cada noche") es un nivel
   más abajo: con el mismo título que la madre parecían dos bloques hermanos. */
#tab-cuerpo .sec .sec{margin:18px 0 0}
#tab-cuerpo .sec .sec>h3{font-size:var(--text-sm)}
/* La fila de números de cabecera ocupa el ancho: con auto-fill, tres KPI quedaban apretados a la
   izquierda y el resto de la fila vacía, como si faltaran números. Las filas chicas (dentro de una
   tarjeta) siguen con su grilla propia. */
/* 140 px de mínimo: con 160 la cabecera de Batería (9 KPIs) dejaba el noveno solo en otra fila. */
#tab-cuerpo .kpis:not(.kpis-chicos):not(.kpis-hipno){grid-template-columns:repeat(auto-fit,minmax(140px,1fr))}

/* Línea de LECTURA: la conclusión que sale del dato ("la batería toca su piso a las 06:00"). No
   es método, así que no se pliega: es lo primero que conviene leer debajo del gráfico. */
.lectura{margin:10px 0 0;padding:8px 12px;border-left:3px solid var(--marca-linea);background:var(--realce);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;font-size:var(--text-sm);color:var(--tinta);line-height:1.45}
/* Banda del último telechequeo (normal / límite / fuera): dato, pegado al valor. */
.tc-banda{margin-top:4px;font-size:var(--text-xs)}

/* Los carteles de la ficha se leen enteros: cortados a dos renglones terminaban justo antes de la
   parte que explica ("…solo se ven acá y en l…"). Los que eran explicación larga pasaron a notas. */
body.vista-ficha #tab-cuerpo .nada{display:block;-webkit-line-clamp:unset;overflow:visible;cursor:auto}

/* 2. solapas + rama en una fila */
.tabs-fila{display:flex;align-items:flex-end;justify-content:space-between;gap:12px 20px;flex-wrap:wrap;
  border-bottom:1px solid var(--regla);margin-bottom:18px}
.tabs-fila .tabs{border-bottom:0;margin:0;flex:1 1 auto}
.tabs-fila .ramas{margin:0 0 7px;border:0;padding:3px;gap:2px;background:var(--panel-2);border-radius:var(--radius-pill)}
.tabs-fila .rama{min-width:0;padding:5px 13px;border:0;border-radius:var(--radius-pill);background:transparent;flex-direction:row}
.tabs-fila .rama .r-tit{font-size:var(--t-nota);font-weight:var(--weight-semibold);color:var(--tinta-suave)}
.tabs-fila .rama .r-sub{display:none}
.tabs-fila .rama:hover{background:transparent}
.tabs-fila .rama:hover .r-tit{color:var(--tinta)}
.tabs-fila .rama.on{background:var(--panel);box-shadow:var(--shadow-soft)}
.tabs-fila .rama.on .r-tit{color:var(--tinta)}
@media (max-width:900px){.tabs-fila .ramas{order:-1;margin:0 0 8px}}

/* 3. jerarquía dentro de una solapa: sección grande, tarjeta chica */
/* Descendiente y no hijo directo: las sub-solapas (Salud → Cardíaco, Operativo → Batería…) anidan
   sus secciones en #sub-cuerpo y quedaban en versalitas chicas mientras Resumen ya iba en
   minúsculas. La jerarquía tiene que ser la misma en toda la ficha. */
#tab-cuerpo .sec{margin-bottom:22px}
#tab-cuerpo .sec>h3{font-family:var(--ff-d);font-size:var(--text-md);text-transform:none;letter-spacing:-.01em;
  color:var(--tinta);font-weight:var(--weight-semibold);margin-bottom:10px;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
#tab-cuerpo .sec>h3 .sub{color:var(--tinta-suave);font-size:var(--text-xs);font-family:var(--ff);font-weight:400;letter-spacing:0}
#tab-cuerpo>.resumen-cab,#tab-cuerpo>details.pleg,#tab-cuerpo>.tarjeta{margin-bottom:16px}
#tab-cuerpo details.pleg>summary .sub,.tarjeta .leyenda,.sec .leyenda{color:var(--tinta-suave)}

/* 4. cabecera del resumen: índice + dominios */
.indice{padding:16px 18px;gap:12px 16px}
.indice svg.anillo{width:120px;height:120px}
/* A 28 px, "Con observaciones" pedía 213 px en una caja de 194 y se cortaba. El número del anillo
   ya es lo grande de esta tarjeta; la banda es su etiqueta y no tiene que competir con él. */
.indice-banda{font-size:var(--text-lg);line-height:1.15}
.indice-nota{color:var(--tinta-suave);margin-top:7px}
.dom{padding:12px 14px 8px;grid-template-rows:auto auto auto auto minmax(30px,1fr)}
.dom-top{min-height:32px}
.dom-top{gap:5px}
.dom-puntaje{font-size:var(--text-base);padding:2px 9px}
/* La pastilla de estado tiene DOS renglones fijos y no se trunca: "REVISAR · Pulso de reposo (…"
   dejaba justamente sin leer la parte que dice por qué. Altura fija para que las cuatro tarjetas
   sigan alineadas aunque una necesite un renglón y otra dos. */
.dom-flag{white-space:normal;text-overflow:clip;height:calc(2.6em + 6px);min-height:0;line-height:1.3;padding:3px 9px;
  border-radius:9px;margin:4px 0 6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:var(--t-micro)}
.dom-flag b{font-size:var(--t-micro)}
.dom-flag-ok{display:flex;align-items:center;padding-left:0;font-size:var(--t-micro)}
.dom-valor{font-size:28px}
.dom-valor em{font-size:var(--t-nota);color:var(--tinta-suave)}
.dom-sub{font-size:var(--t-micro);color:var(--tinta-suave);height:2.8em}
.dom-sub b{color:var(--tinta)}

/* 5. franja de días: la explicación como nota al pie, no como párrafo del cuerpo */
.franja-card{padding:14px 16px 12px}
.franja-tit{margin-bottom:10px}
.franja-card .leyenda{font-size:var(--t-nota);color:var(--tinta-suave);max-width:125ch;line-height:1.45}
.franja-card .leyenda+.leyenda{margin-top:8px;padding:6px 0 0 10px;border-left:2px solid var(--regla)}

/* 6. panel de resultados */
table.panel th{padding-bottom:9px}
table.panel tbody tr:hover td,table.panel tbody tr:hover th{background:var(--fondo)}
table.panel tbody th .delta-sub,table.panel .delta-sub{color:var(--tinta-suave);font-size:var(--t-micro)}
table.panel .ref{color:var(--tinta-suave)}
table.panel .val .uni{color:var(--tinta-suave);font-size:var(--t-micro)}

/* 7. hallazgos */
.hallazgo{padding:13px 16px}
.hallazgo .hall-meta>summary,.hallazgo .pie-h{color:var(--tinta-suave)}

/* ── pulido global (2026-09-10) ─────────────────────────────────────────────────── */

/* Bloque de datos clave/valor (Operativo → El reloj, Datos y fuentes → Identidad). Reusa la
   forma de la cabecera del paciente; sin esto `dato()` salía como "IMEI350850722593740". */
.datos{display:flex;flex-wrap:wrap;gap:10px 30px}
.datos .d{display:flex;flex-direction:column;gap:1px;min-width:0}
.datos .d span{font-size:var(--t-micro);text-transform:uppercase;letter-spacing:.08em;color:var(--tinta-suave);font-weight:var(--weight-medium)}
.datos .d strong{font-size:var(--text-sm);font-weight:var(--weight-semibold);line-height:1.3;overflow-wrap:anywhere}

/* Columna Semáforo de la lista: 2×2, cada luz con su palabra. El color vive en el punto; el texto
   queda en tinta suave para no competir con el índice, que es lo que ordena la lista. */
.sem-cel{display:grid;grid-template-columns:max-content max-content;gap:5px 12px}
.sem{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-micro);line-height:1.2;color:var(--tinta-suave);white-space:nowrap}
.sem i{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;
  font-style:normal;font-size:10px;font-weight:700;line-height:1;color:#fff;background:var(--regla)}
.sem-ok i{background:var(--ok)}
.sem-aviso i{background:var(--aviso);color:var(--blue-dark)}
.sem-alerta i{background:var(--peligro)}
.sem-alerta{color:var(--tinta);font-weight:var(--weight-semibold)}
.sem-sin_dato i{background:transparent;border:1px dashed var(--tinta-tenue);color:var(--tinta-tenue)}
.sem .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* Sub-solapa sin datos: la palabra en vez de un punto. */
.subtabs button .sub-vacia{font-size:var(--t-micro);color:var(--tinta-tenue);margin-left:4px;text-transform:lowercase}
/* Vacía con borde punteado, no con opacidad: al .6 la etiqueta quedaba en 2,7:1 de contraste. */
.subtabs button.vacia{border-style:dashed;background:transparent}

/* Estado de carga: un indicador que se mueve, no solo texto. */
.cargando{display:flex;align-items:center;justify-content:center;gap:10px;color:var(--tinta-suave)}
.cargando::before{content:"";width:16px;height:16px;border-radius:50%;border:2px solid var(--regla);border-top-color:var(--acento);
  animation:girar .8s linear infinite;flex:0 0 auto}
@keyframes girar{to{transform:rotate(360deg)}}
.tb-vacio{padding:28px 20px;font-size:var(--text-sm)}

/* Navegación de la ficha: volver + anterior/siguiente sobre la lista, en una línea. */
.ficha-nav{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.ficha-nav .volver{margin-bottom:0}
.nav-pos{font-size:var(--text-xs);color:var(--tinta-suave);margin-left:auto;font-family:var(--ff-m)}
.nav-btn{background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius-pill);padding:4px 12px;cursor:pointer;
  font:inherit;font-size:var(--text-xs);color:var(--tinta-suave);font-weight:var(--weight-medium)}
.nav-btn:hover:not(:disabled){background:var(--panel-2);color:var(--tinta)}
.nav-btn:disabled{opacity:.35;cursor:default}
/* La fila de solapas se queda pegada bajo la cabecera global mientras se scrollea la solapa, y
   muestra el nombre del paciente cuando la cabecera ya no se ve. */
.tabs-fila{position:sticky;top:var(--alto-top,64px);z-index:15;background:var(--fondo);padding-top:6px}
.tabs-paciente{font-family:var(--ff-d);font-weight:var(--weight-semibold);font-size:var(--text-sm);color:var(--tinta);
  align-self:center;padding:0 14px 8px 0;margin-right:6px;border-right:1px solid var(--regla);white-space:nowrap;max-width:26ch;
  overflow:hidden;text-overflow:ellipsis}
.tabs-fila .tabs-paciente[hidden]{display:none}
/* Lista compacta en dos columnas: el botón no puede ser más ancho que su columna, y la etiqueta
   tiene que poder encogerse (min-width:0) o la grilla se desborda y las columnas se pisan. */
.lb-cols .lb-btn{width:100%;margin:0;padding:2px 6px}
.lb-compacta .lb-fila{grid-template-columns:minmax(0,1.5fr) minmax(40px,1fr) 44px 40px;gap:8px}
.lb-compacta .lb-lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--t-nota)}
.lb-compacta .lb-p{font-size:var(--t-micro)}

/* KPIs del tablero: 6 por fila en pantallas anchas, 3+3 en notebooks. Con auto-fit quedaban 5 y
   una tarjeta huérfana en la segunda fila. */
.kpis-tablero{grid-template-columns:repeat(6,minmax(0,1fr))}
@media (max-width:1400px){.kpis-tablero{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:760px){.kpis-tablero{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Cabecera del resumen en notebook (1001-1400 px): el índice como columna angosta y centrada al
   lado de los cuatro dominios. Antes ocupaba una banda a todo el ancho con el anillo a la
   izquierda y 300-420 px vacíos a la derecha, y los dominios quedaban una fila más abajo.
   Debajo de 1000 px: índice arriba (anillo + texto en fila) y dominios de a dos. */
@media (max-width:1400px){
  .resumen-cab{grid-template-columns:220px minmax(0,1fr)}
  .indice{grid-template-columns:1fr;justify-items:center;text-align:center;align-items:center}
  .doms{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (max-width:1000px){
  .resumen-cab{grid-template-columns:1fr}
  .indice{grid-template-columns:auto 1fr;justify-items:start;text-align:left}
  .doms{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* Encabezado de la lista de pacientes pegado al scrollear, cuando la tabla entra sin scroll
   horizontal (en pantallas angostas el contenedor tiene que poder scrollear y sticky no aplica). */
@media (min-width:1300px){
  .tabla-roster{overflow:visible}
  .tabla-roster thead th{position:sticky;top:calc(var(--alto-top,64px) - 1px);z-index:6;background:var(--panel);box-shadow:0 1px 0 var(--regla)}
}

/* ═══════════════════════════════════════════════════════════════════════════════════
   EL PANEL EN UN TELÉFONO, Y COMO APP INSTALADA
   ═══════════════════════════════════════════════════════════════════════════════════

   El panel sigue siendo una herramienta de escritorio: se triagean cientos de personas y eso no
   se hace con el pulgar. Pero se abre desde el teléfono cuando alguien pregunta por UN paciente
   —guardia, visita, traslado— y ahí lo que importa es llegar a la ficha, no comparar la cohorte.

   Tres decisiones ordenan todo lo que sigue:

    1. **El cromo se pliega, el contenido no.** Header (zona/período/idioma) y barra lateral
       (seis filtros) suman ~380 px antes del primer paciente sobre un viewport de 667. Los dos
       son plegables y arrancan CERRADOS abajo de 900 px (js/15-movil.js). Arriba de 900 px los
       botones no existen y nada cambia respecto de lo que ya había.
    2. **44 px de blanco mínimo para el dedo.** WCAG 2.2 AA pide 24 px en web e iOS/Android
       recomiendan 44/48. En una app que se toca con una mano mientras se camina, se toma el
       número grande. No se toca el escritorio: es solo dentro del media query.
    3. **Las muescas y la barra de gestos existen.** Con viewport-fit=cover el contenido llega
       al borde físico, así que todo lo pegado a un borde suma env(safe-area-inset-*). En un
       dispositivo sin muesca esos valores son 0 y no cambia nada.

   No se toca user-scalable: el panel muestra números clínicos chicos y bloquear el zoom sería
   romper WCAG 1.4.4 para ganar un pixel de prolijidad.
   ────────────────────────────────────────────────────────────────────────────────── */

/* Visible solo en pantalla chica. Mismo patrón que .solo-tecnico, otro eje.
   Las dos formas compuestas no son decorativas: `.btn-ico` y `.lateral-toggle` declaran su propio
   `display` más abajo en el archivo, así que con la misma especificidad ganaban ellas y los
   botones de móvil aparecían en escritorio. Se empata la especificidad (0,2,0) en los dos lados. */
.solo-movil{display:none}
.btn-ico.solo-movil,.lateral-toggle.solo-movil{display:none}

/* Acciones del header que NO se pliegan: instalar y el propio botón que despliega el resto. */
.top-acciones{display:flex;align-items:center;gap:8px;flex:0 0 auto}
#btn-instalar{white-space:nowrap;display:inline-flex;align-items:center;gap:6px}

/* El ☰ de ajustes reusa `.btn-ico` (definido más arriba, con el ⚙ de vista técnica): mismo
   tamaño, mismo tratamiento. Lo único que se agrega es el anillo de foco, que no estaba: en el
   teléfono el ⚙ y el ☰ quedan uno al lado del otro y hay que ver cuál tiene el foco. */
.btn-ico:focus-visible{outline:2px solid var(--foco);outline-offset:2px}

/* Cabecera plegable de la barra de filtros. En escritorio no se muestra (.solo-movil). El cuerpo
   (`.lateral-cuerpo`) se define en la sección de layout: fila en escritorio, columna en móvil. */
.lateral-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;gap:10px;
  background:var(--panel-2);border:1px solid var(--regla);border-radius:var(--radius-sm);
  padding:0 14px;min-height:44px;cursor:pointer;font:inherit;font-size:var(--text-sm);
  font-weight:var(--weight-semibold);color:var(--tinta)}
.lateral-toggle:focus-visible{outline:2px solid var(--foco);outline-offset:2px}
.lateral-toggle-ico{transition:transform .18s var(--ease-premium);font-size:12px;color:var(--tinta-tenue)}
.lateral-toggle[aria-expanded="true"] .lateral-toggle-ico{transform:rotate(180deg)}
@media (prefers-reduced-motion:reduce){.lateral-toggle-ico{transition:none}}

/* Aviso flotante de la app instalada (versión nueva, pasos de iOS). Lo arma js/16-pwa.js.
   Va abajo y centrado: arriba compite con el header sticky, y a la derecha lo tapa el lanzador
   del asistente. role=status ya está en el HTML: no roba el foco a quien está leyendo. */
.pwa-aviso{position:fixed;left:50%;transform:translateX(-50%);z-index:30;
  bottom:calc(18px + env(safe-area-inset-bottom));width:min(520px,calc(100vw - 28px));
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:var(--panel);border:1px solid var(--regla);border-radius:var(--radius);
  box-shadow:var(--shadow-hover);padding:12px 14px;font-size:var(--text-sm);color:var(--tinta)}
.pwa-aviso-txt{flex:1 1 220px;line-height:1.5}
.pwa-aviso-acciones{display:flex;gap:8px;flex-wrap:wrap}
:root[data-tema="oscuro"] .pwa-aviso{box-shadow:0 18px 50px rgba(0,0,0,.5)}

/* Muescas y barra de gestos: lo que toca un borde suma su inset. Sin muesca, todos valen 0. */
.top{padding-top:calc(10px + env(safe-area-inset-top));
  padding-left:calc(20px + env(safe-area-inset-left));padding-right:calc(20px + env(safe-area-inset-right))}
.principal{padding-left:calc(22px + env(safe-area-inset-left));padding-right:calc(22px + env(safe-area-inset-right));
  padding-bottom:calc(64px + env(safe-area-inset-bottom))}
.chat-fab{right:calc(22px + env(safe-area-inset-right));bottom:calc(22px + env(safe-area-inset-bottom))}

/* ── pantalla chica ───────────────────────────────────────────────────────────── */
@media (max-width:900px){
  .solo-movil{display:inline-flex}
  .btn-ico.solo-movil{display:inline-flex}
  .lateral-toggle.solo-movil{display:flex}

  /* El header queda en una línea: marca + acciones. Los controles bajan a su propia fila y
     solo existen cuando se los pide (js/15-movil.js pone/saca chrome-abierto en el body). */
  .top{gap:10px;padding-top:calc(8px + env(safe-area-inset-top));padding-bottom:8px;
    padding-left:calc(14px + env(safe-area-inset-left));padding-right:calc(14px + env(safe-area-inset-right))}
  /* Desplegado, el header pasa de 60 a ~210 px y sigue siendo sticky. Se le pone techo: a media
     pantalla deja de crecer y scrollea adentro, así nunca se come el contenido que se fue a ver. */
  .top-controles{flex-basis:100%;order:3;gap:10px;max-height:50vh;overflow-y:auto;align-items:flex-end;margin-left:0}
  body:not(.chrome-abierto) .top-controles{display:none}
  .marca .logo{height:34px;flex:0 0 auto}
  /* La marca cede primero: antes de que el botón de instalar se caiga a una segunda línea (el
     header pasaba de 60 a 105 px), el título se recorta con puntos suspensivos.
     `flex-basis:0` y no `auto`: con `auto` la base es el ancho del texto SIN cortar —"Producción
     LATAM" en una línea— y eso ya supera el ancho del header, así que la línea se partía igual.
     Con base 0 la marca pide cero y se queda con lo que sobra después de las acciones. */
  .marca{gap:10px;min-width:0;flex:1 1 0;overflow:hidden}
  .marca>div{min-width:0}
  .marca h1{font-size:var(--text-md)}
  .marca h1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* El subtítulo NO se recorta a una línea: ahí va la zona y la ley de protección de datos que
     aplica ("São Paulo · Ley 25.326 / LGPD"). Cortado queda "Ley 25.326 / LGPD · A…", que es
     justo la parte que hay que poder leer. Se le permiten dos líneas y recién ahí se corta. */
  .marca .sub{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
    line-height:1.25;font-size:var(--t-micro)}
  /* El estado de la fuente es diagnóstico de soporte: en el teléfono se lleva una línea entera
     de un header que tiene que medir 56 px. Sigue disponible en el escritorio. */
  .estado{display:none}
  .top .campo select,.top .campo input{min-width:0;width:100%}
  .top-controles .campo{flex:1 1 140px}
  .top-controles .rango{flex:1 1 100%}

  /* Barra lateral plegada: en el teléfono es una barra de 44 px, no una columna de 300. */
  .lateral{padding:10px calc(14px + env(safe-area-inset-right)) 10px calc(14px + env(safe-area-inset-left));gap:10px}
  body:not(.filtros-abiertos) .lateral-cuerpo{display:none}
  body:not(.filtros-abiertos) .lateral{border-bottom-color:var(--regla-suave)}

  .principal{padding:14px calc(14px + env(safe-area-inset-right)) calc(88px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-left))}

  /* Dedo: 44 px de alto y 16 px de texto en todo lo que se toca o se escribe. Los 16 px no son
     estéticos — abajo de eso iOS hace zoom solo al enfocar un input y deja la página corrida. */
  .btn,.btn-ico,.lateral-toggle{min-height:44px}
  .btn-ico{min-width:44px}
  .btn-chico{min-height:40px;padding:6px 14px}
  select,input,textarea,.lateral .campo select,.lateral .campo input{font-size:16px;min-height:44px}
  .check{min-height:44px}
  .check input{width:20px;height:20px}
  .tabs button,.subtabs button,.seg button{min-height:44px}

  /* Solapas de la ficha: una tira que se desliza, no seis renglones apilados. */
  .tabs,.subtabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity;
    -webkit-overflow-scrolling:touch}
  .tabs::-webkit-scrollbar,.subtabs::-webkit-scrollbar{display:none}
  /* Pista de que hay más pastillas a la derecha: sin barra de scroll, las últimas quedaban fuera
     de vista sin aviso. El padding hace que, si todo entra, nada quede desvanecido. */
  .subtabs{padding-right:28px;-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}
  .tabs button,.subtabs button{flex:0 0 auto;scroll-snap-align:start}
  .tabs-paciente{max-width:14ch}

  /* Tablas: la de cohorte tiene más columnas que ancho de teléfono. Se desliza en su caja (nunca
     la página: el scroll horizontal del documento es lo que hacía el panel inusable a 375 px). */
  .tabla-wrap{-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .cel-pac{max-width:none}

  /* El lanzador del asistente compite con el pulgar: se achica y se acerca al borde seguro. */
  .chat-fab{right:calc(14px + env(safe-area-inset-right));bottom:calc(14px + env(safe-area-inset-bottom));height:48px}
  .chat-fab img{width:48px;height:48px;padding:9px}
  /* El texto que aparece al pasar el mouse no tiene sentido sin mouse. */
  .chat-fab-txt{display:none}
}

@media (max-width:640px){
  /* Gráficos: 262 px de alto se comen la pantalla entera antes de llegar al número. */
  .grafico{height:210px}
  .grafico.chico{height:170px}
  .grafico.mini{height:120px}
  .ver-kpis,.kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  .kpis-chicos,.kpis-hipno{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pwa-aviso{width:calc(100vw - 20px);bottom:calc(10px + env(safe-area-inset-bottom))}
  /* A 375 px "Instalar app" + ☰ + el título no entran en una línea. Queda el símbolo, con
     aria-label: el título del panel dice dónde estás y eso vale más que la palabra del botón. */
  .btn-txt{display:none}
  #btn-instalar{padding:0;min-width:44px;justify-content:center;font-size:var(--text-md)}
}

/* ── ya instalada (sin barra de direcciones) ──────────────────────────────────── */
@media (display-mode: standalone), (display-mode: minimal-ui){
  /* No hay botón "atrás" del navegador a la vista: el logo, que ya vuelve a la cohorte, tiene
     que leerse como algo que se toca y no como una decoración. */
  .marca{border-radius:var(--radius-sm);padding:2px 6px;margin-left:-6px}
  .marca:active{background:rgba(255,255,255,.12)}
  /* Ofrecer instalar dentro de la app instalada no tiene sentido; js/16-pwa.js ya lo esconde,
     esto lo cubre si el navegador entra en standalone con la pestaña ya abierta. */
  #btn-instalar{display:none}
}

/* ── embudo del tablero en pantalla chica ──────────────────────────────────────
   Medido a 375 px: la fila del embudo es una grilla de 5 columnas cuyo mínimo (140 + 56 + 120 +
   3 gaps de 14) da 366 px de contenido dentro de un contenedor de 347. Eso empujaba el ANCHO DEL
   DOCUMENTO a 435 px y hacía que la página entera se desplazara de costado — el modo de falla
   que la barra lateral ya tenía resuelto y que este bloque volvía a introducir.

   En el teléfono la misma fila se lee en dos renglones, que es como se lee de todos modos:
   arriba "qué escalón es" y el número; abajo la barra y los porcentajes. */
@media (max-width:700px){
  .embudo{padding:10px}
  .embudo .emb-fila,.emb-fila{grid-template-columns:minmax(0,1fr) auto;gap:6px 10px;align-items:center}
  .emb-txt{grid-column:1;grid-row:1;min-width:0}
  .emb-n{grid-column:2;grid-row:1}
  .emb-barra{grid-column:1;grid-row:2}
  .embudo .emb-pct,.emb-pct{grid-column:2;grid-row:2;flex-direction:row;gap:8px;white-space:nowrap;justify-content:flex-end}
  .emb-caen{display:none}
}

/* ── objetivos táctiles que quedaban por debajo del umbral ─────────────────────
   Medidos en el tablero a 375 px: las leyendas de bandas de salud (26 px), los "hechos" del
   resumen (27 px) y los números de los tiles (34 px). Ninguno viola WCAG 2.2 AA —los tres pasan
   los 24 px— pero con el pulgar, en movimiento, 26 px es una apuesta. Se agrandan solo en
   pantalla chica: en escritorio el diseño compacto es correcto y no se toca. */
@media (max-width:900px){
  .bnd-lg{min-height:40px;padding-left:10px;padding-right:10px}
  .ver-hechos{gap:12px 22px}
  .ver-hecho{padding:6px 0}
  .tile-num{min-height:44px}
}

/* ── listas de barras del tablero en pantalla chica ────────────────────────────
   Medido a 375 px: `.lb-fila` (avisos del reloj y señales disponibles) declara un mínimo de
   150 + 50 + 56 + 64 + 3 gaps de 10 = 350 px dentro de una tarjeta de 316. El sobrante no se
   recorta —la fila no tiene overflow propio— así que crecía el documento a 435 px y toda la
   página se desplazaba de costado. La variante `.lb-compacta` ya resolvía esto con `minmax(0,…)`
   y elipsis; acá se le aplica el mismo criterio a la fila normal, solo abajo de 900 px. */
@media (max-width:900px){
  .lb-cols,.lista-barras{min-width:0}
  .lb-fila{grid-template-columns:minmax(0,1.3fr) minmax(32px,1fr) 40px auto;gap:8px;min-height:36px}
  .lb-lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .lb-p{font-size:var(--t-micro)}
}

/* ── Cardíaco: pulso nocturno + su nivel habitual, lado a lado ─────────────────── */
.dos.dos-ref{grid-template-columns:minmax(0,2fr) minmax(260px,1fr);align-items:stretch}
.dos.dos-ref>.tarjeta{margin-bottom:0}
@media (max-width:1100px){.dos.dos-ref{grid-template-columns:1fr}}
.habitual{display:flex;flex-direction:column;gap:6px}
.hab-tit{font-size:var(--text-xs);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--tinta-suave)}
.hab-num{display:flex;align-items:baseline;gap:6px;margin-top:4px}
.hab-num b{font-size:44px;line-height:1;font-weight:700;color:var(--tinta);font-variant-numeric:tabular-nums}
.hab-num span{font-size:var(--text-sm);color:var(--tinta-suave)}
.hab-k{font-size:var(--text-sm);color:var(--tinta-suave)}
/* El rango habitual como píldora fina (números en los extremos) y, debajo, el reposo del período
   contra su referencia en números. */
.hab-grafico{display:flex;flex-direction:column;gap:6px;margin:14px 0 2px;padding:0 12px}
.hab-fila{display:flex;flex-direction:column;gap:2px}
.hab-rot{font-size:var(--text-xs);color:var(--tinta-suave)}
.hab-rot b{color:var(--tinta);font-weight:600;font-variant-numeric:tabular-nums}
.hab-rot b.hab-fuera{color:var(--aviso)}
.hab-pista{position:relative;height:52px}
.hab-pista::before{content:"";position:absolute;left:0;right:0;top:24px;height:8px;border-radius:99px;background:var(--panel-3)}
.hab-banda{position:absolute;top:24px;height:8px;border-radius:99px;background:var(--acento);opacity:.45}
.hab-med{position:absolute;top:18px;width:3px;height:20px;margin-left:-1.5px;border-radius:2px;background:var(--acento)}
.hab-med span{position:absolute;bottom:calc(100% + 1px);left:50%;transform:translateX(-50%);white-space:nowrap;
  font-size:var(--text-xs);color:var(--tinta-suave);font-variant-numeric:tabular-nums}
.hab-lim{position:absolute;top:35px;transform:translateX(-50%);font-size:var(--text-xs);color:var(--tinta-suave);
  font-variant-numeric:tabular-nums}
/* Fila de reposo: tres números en fila (este período · referencia · diferencia), sin segunda
   pista debajo de la del rango. La diferencia en ámbar cuando pasa el corte de ±5 bpm. */
.hab-comp{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:4px}
.hab-comp > div{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:4px;padding:8px 10px;
  border-radius:var(--radius-sm);background:var(--panel-3)}
.hab-comp em{flex-basis:100%;font-style:normal;font-size:var(--t-micro);letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-suave)}
.hab-comp b{font-size:var(--text-lg);font-weight:700;color:var(--tinta);font-variant-numeric:tabular-nums;line-height:1.2}
.hab-comp span{font-size:var(--text-xs);color:var(--tinta-suave)}
.hab-dif.fuera{box-shadow:inset 0 0 0 1px var(--aviso)}
.hab-dif.fuera b{color:var(--aviso-texto)}
/* Pulso de reposo con pocas noches (≤4): una tarjeta por noche en lugar del gráfico vacío. */
.noches-rep-tit{font-size:var(--text-xs);color:var(--tinta-suave);margin-bottom:8px}
.noches-rep{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
/* Al lado de "Su nivel habitual" la tarjeta toma su alto: arriba las noches, abajo (empujada al
   pie) la tira que las ubica contra su referencia. */
.tarjeta:has(> .noches-rep){display:flex;flex-direction:column}
.noches-tira{position:relative;margin-top:auto;padding-top:26px;height:96px}
.noches-tira::before{content:"";position:absolute;left:0;right:0;top:56px;height:2px;background:var(--regla)}
.nt-ref{position:absolute;top:30px;height:52px;border-left:2px dashed var(--tinta-suave)}
.nt-ref span{position:absolute;bottom:calc(100% + 2px);left:0;transform:translateX(-50%);white-space:nowrap;
  font-size:var(--text-xs);color:var(--tinta-suave)}
.nt-pt{position:absolute;top:57px;width:0;height:0}
.nt-pt i{position:absolute;left:0;top:0;width:12px;height:12px;border-radius:50%;transform:translate(-50%,-50%);
  background:var(--acento);box-shadow:0 0 0 3px var(--panel)}
.nt-pt.fuera i{background:var(--aviso)}
.nt-pt.no-cuenta i{background:transparent;border:2px dashed var(--tinta-tenue);box-shadow:none}
.nt-pt span{position:absolute;top:10px;left:0;transform:translateX(-50%);white-space:nowrap;font-size:var(--text-xs);
  color:var(--tinta-suave);font-variant-numeric:tabular-nums}
.nt-pt span b{color:var(--tinta)}
.noche-rep{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:var(--radius-sm);
  background:var(--panel-3);border-left:3px solid var(--acento)}
.noche-rep em{font-style:normal;font-size:var(--text-xs);color:var(--tinta-suave);text-transform:capitalize}
.noche-rep b{font-size:32px;line-height:1;font-weight:700;color:var(--tinta);font-variant-numeric:tabular-nums}
.noche-rep div span{margin-left:4px;font-size:var(--text-sm);color:var(--tinta-suave)}
.noche-rep small{font-size:var(--text-xs);color:var(--tinta-suave);line-height:1.35}
.noche-rep.fuera{border-left-color:var(--aviso)}
.noche-rep.fuera small{color:var(--aviso-texto)}
/* La que no cuenta, en gris y con borde punteado: el dato existe pero no entra en el cálculo. */
.noche-rep.no-cuenta{border-left:3px dashed var(--tinta-tenue);opacity:.75}
.noche-rep.no-cuenta b{color:var(--tinta-suave)}
.hab-calc{margin-top:auto;padding-top:8px;border-top:1px solid var(--regla);font-size:var(--text-xs);color:var(--tinta-tenue)}
/* Caja de percentiles: al ancho real, con la carga de pulso alto/bajo en la misma tarjeta. */
.caja-pulso{display:flex;flex-direction:column;gap:10px}
.caja-pulso>.tira{border:0;padding:0;box-shadow:none;background:none}

/* ── Temperatura de cada noche: franja habitual y formas de la leyenda ────────── */
:root{--banda-temp:rgba(14,124,134,.13)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--banda-temp:rgba(184,230,92,.12)}}
:root[data-theme="dark"]{--banda-temp:rgba(184,230,92,.12)}
.sw-banda-temp{background:var(--banda-temp);border:1px dashed var(--acento)}
.leg .forma{display:inline-block;width:0;height:0;margin-right:2px;flex:0 0 auto}
.leg .f-dentro{width:9px;height:9px;border-radius:50%;background:var(--acento)}
.leg .f-sube{border:5px solid transparent;border-top:0;border-bottom:9px solid var(--aviso)}
.leg .f-baja{border:5px solid transparent;border-bottom:0;border-top:9px solid var(--acento-2)}

/* Conexión: cabecera de las barras de sensores y línea que explica qué es un reporte de estado. */
.stream-cab{font-size:var(--text-xs);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--tinta-suave);
  padding-bottom:4px;border-bottom:1px solid var(--regla);margin-bottom:2px}
.stream-cab .st-cab-func{grid-column:span 2}
.nota-intro{margin:0 0 12px;color:var(--tinta-suave)}
/* Seis números: 3 × 2 (6 en fila en pantallas anchas), nunca 5 + 1 huérfano. */
#tab-cuerpo #op-cuerpo .kpis.kpis-seis{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (min-width:1500px){#tab-cuerpo #op-cuerpo .kpis.kpis-seis{grid-template-columns:repeat(6,minmax(0,1fr))}}
@media (max-width:640px){#tab-cuerpo #op-cuerpo .kpis.kpis-seis{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Lista: "Uso" centrada, con aire entre ella y el semáforo. */
.tabla-roster th.c-uso,.tabla-roster td.c-uso{text-align:center;padding-left:20px;padding-right:28px;white-space:nowrap}
.tabla-roster th.col-sem,.tabla-roster td.col-sem{padding-left:16px}

/* Tablero → uso del reloj: tramos de la barra (diario → sin uso) y el ⓘ flotante de la lista. */
.bnd-uso-diario{background:var(--ok)} .bnd-uso-parcial{background:var(--acento)}
.bnd-uso-bajo{background:var(--aviso)} .bnd-uso-sin{background:var(--peligro)}
.uso-leyenda{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:2px 8px}
.info-i.siempre{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;width:16px;height:16px;
  border-radius:50%;border:1px solid var(--regla);color:var(--tinta-tenue);font:italic 600 10.5px/1 Georgia,serif;
  cursor:help;margin-left:4px;text-transform:none;letter-spacing:0}
.info-i.siempre:hover,.info-i.siempre:focus-visible{color:var(--tinta);border-color:var(--tinta-suave);outline:none}
.info-i.siempre::after{display:none !important}
.info-flotante{position:fixed;z-index:1000;display:none;padding:9px 12px;border-radius:10px;background:var(--panel-2);
  border:1px solid var(--regla);box-shadow:var(--shadow-card);color:var(--tinta-suave);font:400 var(--text-xs)/1.5 var(--ff);
  pointer-events:none}

/* Cardíaco → avisos de variabilidad en su sección y tarjetas implicadas marcadas. */
.hrv-avisos{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.hrv-aviso{border:1px solid var(--regla);border-left:4px solid var(--aviso);border-radius:var(--radius-md,12px);
  background:var(--panel);padding:12px 14px}
.hrv-aviso.sev-alerta{border-left-color:var(--peligro)}
.hrv-av-tit{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.hrv-aviso p{margin:6px 0 8px;color:var(--tinta-suave);font-size:var(--text-sm)}
.hrv-av-ev{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:var(--text-sm);color:var(--tinta);font-variant-numeric:tabular-nums}
.hrv-av-ev em{font-style:normal;color:var(--tinta-suave);margin-right:2px}
.hrv-av-crit{margin-top:8px;font-size:var(--text-xs);color:var(--tinta-suave)}
.hrv-av-crit b{color:var(--tinta)}
.sen.sen-marcada{box-shadow:inset 0 0 0 1.5px var(--aviso)}
.sen.sen-marcada.sev-alerta{box-shadow:inset 0 0 0 1.5px var(--peligro)}

/* Puntos de la curva de batería: resaltan al pasar el mouse (el tooltip es el <title> del SVG). */
svg.g .pt{cursor:crosshair}
svg.g .pt:hover circle:first-child{fill:var(--acento-2);fill-opacity:.25;stroke:var(--acento-2);stroke-width:1.5}

/* Al llegar desde un aviso: el bloque de donde sale se resalta un momento. */
@keyframes destacar{0%{box-shadow:0 0 0 0 transparent}15%{box-shadow:0 0 0 3px var(--aviso)}100%{box-shadow:0 0 0 0 transparent}}
.destacado{animation:destacar 2.4s ease-out;border-radius:var(--radius-md,12px)}
@media (prefers-reduced-motion:reduce){.destacado{animation:none;outline:3px solid var(--aviso)}}
.hall-ir{margin-top:8px;background:none;border:0;padding:0;color:var(--acento);font:600 var(--text-sm)/1.4 var(--ff);cursor:pointer}
.hall-ir:hover,.hall-ir:focus-visible{text-decoration:underline;outline:none}

/* Tablero → uso: cuatro números clave y listas de barras horizontales (rótulo · barra · n · %). */
.tb-uso-kpis{margin-bottom:12px}
#cohorte-cuerpo .kpis.tb-uso-kpis{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.tb-barras{display:flex;flex-direction:column;gap:4px;margin:4px 0 6px}
.tb-barra-fila{display:grid;grid-template-columns:minmax(190px,1.6fr) minmax(70px,1.2fr) 44px 36px;align-items:center;gap:10px;
  width:100%;padding:7px 8px;border:1px solid transparent;border-radius:10px;background:none;cursor:pointer;text-align:left;
  color:var(--tinta-suave);font:inherit;font-size:var(--text-sm)}
.tb-barra-fila:hover,.tb-barra-fila:focus-visible{background:var(--fondo);border-color:var(--regla);color:var(--tinta);outline:none}
.tbb-label{display:inline-flex;align-items:center;gap:8px;min-width:0}
.tbb-pista{height:10px;border-radius:99px;background:var(--regla-suave, var(--panel-3));overflow:hidden}
.tbb-relleno{display:block;height:100%;border-radius:99px}
.tbb-n{justify-self:end;font-family:var(--ff-d);color:var(--tinta);font-variant-numeric:tabular-nums}
.tbb-pct{justify-self:end;font-style:normal;color:var(--tinta-tenue);font-family:var(--ff-m);font-size:var(--t-micro)}
@media (max-width:640px){.tb-barra-fila{grid-template-columns:1fr 40px 36px}.tbb-pista{grid-column:1/-1;order:5}}

/* Tooltip de los gráficos SVG: el mismo diseño que el de Chart.js (07-graficos.js → crear()). */
.tip-grafico{position:fixed;z-index:1000;display:none;pointer-events:none;max-width:280px;
  padding:9px 11px;border-radius:12px;background:rgba(30,40,56,.96);border:1px solid rgba(184,230,92,.35);
  box-shadow:0 6px 18px rgba(0,0,0,.25);color:#fff;font:400 11px/1.45 var(--ff)}
.tip-grafico,.tip-grafico *{text-transform:none;letter-spacing:0}
.tip-grafico .tg-tit{font-weight:600;margin-bottom:2px}
.tip-grafico .tg-lin{color:rgba(255,255,255,.88);font-variant-numeric:tabular-nums}

/* Conexión → grilla día × hora: intensidad por minutos con dato, horas futuras rayadas. */
.grilla-horas{display:block;width:100%;height:auto;margin:4px 0 6px}
.grilla-horas .gh-c{stroke:none}
.gh-l0{fill:var(--panel-3)} .gh-l1{fill:var(--ok);fill-opacity:.3}
.gh-l2{fill:var(--ok);fill-opacity:.6} .gh-l3{fill:var(--ok);fill-opacity:1}
.grilla-horas .gh-fut{fill:transparent;stroke:var(--regla);stroke-dasharray:3 3}
.grilla-horas .gh-c:hover{stroke:var(--tinta);stroke-width:1.5}
.gh-tot{fill:var(--panel-3)} .gh-tot-ok{fill:var(--ok)} .gh-tot-medio{fill:var(--aviso)} .gh-tot-bajo{fill:var(--peligro)}
.grilla-horas .gh-tot-txt{fill:var(--tinta)}
.gh-sw{width:12px;height:12px;border-radius:3px}
.gh-sw.gh-l0{background:var(--panel-3)} .gh-sw.gh-l1{background:color-mix(in srgb,var(--ok) 30%,transparent)}
.gh-sw.gh-l2{background:color-mix(in srgb,var(--ok) 60%,transparent)} .gh-sw.gh-l3{background:var(--ok)}
.grilla-h-ley{margin-top:4px}

/* ── Análisis de batería (js/17-bateria.js, solapa interna) ──────────────────────
   Escala de consumo: cinco niveles relativos a la mediana del reloj, del gris (sin medir) al rojo
   (muy por encima de su mediana). Comparte la geometría de la grilla día × hora con .grilla-horas. */
.bd-l0{fill:var(--panel-3)}
.bd-l1{fill:var(--ok);fill-opacity:.55}
.bd-l2{fill:var(--aviso);fill-opacity:.55}
.bd-l3{fill:var(--peligro);fill-opacity:.6}
.bd-l4{fill:var(--peligro);fill-opacity:1}
.bd-carg{fill:var(--acento-2);fill-opacity:.75}
.bd-apag{fill:var(--tinta-tenue);fill-opacity:.45}
.bd-sw{width:12px;height:12px;border-radius:3px}
.bd-sw.bd-l0{background:var(--panel-3)}
.bd-sw.bd-l1{background:color-mix(in srgb,var(--ok) 55%,transparent)}
.bd-sw.bd-l2{background:color-mix(in srgb,var(--aviso) 55%,transparent)}
.bd-sw.bd-l3{background:color-mix(in srgb,var(--peligro) 60%,transparent)}
.bd-sw.bd-l4{background:var(--peligro)}
.bd-sw.bd-carg{background:color-mix(in srgb,var(--acento-2) 75%,transparent)}
.bd-sw.bd-apag{background:color-mix(in srgb,var(--tinta-tenue) 45%,transparent)}
/* Cintas de contexto de la línea de tiempo. */
.ba-linea{display:block;width:100%;height:auto;margin:4px 0 6px}
.ba-linea rect:hover{stroke:var(--tinta);stroke-width:1}
.bc-si{fill:var(--ok);fill-opacity:.7}
.bc-medio{fill:var(--ok);fill-opacity:.35}
.bc-no{fill:var(--tinta-tenue);fill-opacity:.25}
.bc-desc{fill:transparent;stroke:var(--regla);stroke-dasharray:2 2}
.bc-alerta{fill:var(--peligro)}
.bc-toque{fill:var(--acento)}
.bd-sw.bc-si{background:color-mix(in srgb,var(--ok) 70%,transparent)}
.bd-sw.bc-no{background:color-mix(in srgb,var(--tinta-tenue) 25%,transparent)}
.bd-sw.bc-desc{background:transparent;border:1px dashed var(--regla)}
.bd-sw.bc-alerta{background:var(--peligro)}
.bd-sw.bc-toque{background:var(--acento)}
/* Tarjetas "qué gasta más". */
.ba-sosp{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:13px}
.ba-sosp-card{margin-bottom:0;min-width:0}
.ba-sosp-top{border-left:3px solid var(--peligro)}
.ba-sosp-tit{display:flex;align-items:center;gap:8px;font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.07em;color:var(--tinta-suave);font-weight:var(--weight-semibold)}
.ba-sosp-n{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--blue-deep);color:#fff;font-family:var(--ff-m);font-size:var(--t-micro)}
.ba-sosp-cond{font-family:var(--ff-d);font-size:var(--text-md);font-weight:var(--weight-semibold);margin:6px 0 2px}
.ba-sosp-num{font-family:var(--ff-d);font-size:var(--text-xl);font-weight:var(--weight-bold);line-height:1.15}
.ba-sosp-vs{display:block;font-family:var(--ff);font-size:var(--text-xs);font-weight:400;color:var(--tinta-tenue);margin-top:2px}
.ba-sosp-delta{color:var(--peligro);font-weight:var(--weight-semibold);font-size:var(--text-sm);margin-top:4px}
.ba-sosp-por{margin-top:8px;border-top:1px solid var(--regla-suave);padding-top:6px}
.ba-barra{height:6px;border-radius:3px;background:var(--panel-3);margin:8px 0 0;overflow:hidden}
.ba-barra i{display:block;height:100%;background:var(--peligro);border-radius:3px}
.ba-barra i.ba-neg{background:var(--ok)}
.ba-barra-mini{height:4px;margin-top:4px;min-width:60px}
/* Tabla de factores. */
.ba-tabla td:first-child{min-width:150px}
.ba-d-fuerte{color:var(--peligro);font-weight:var(--weight-semibold)}
.ba-d-media{color:var(--aviso-texto)}
.ba-grupo{display:flex;gap:10px;align-items:baseline;padding:2px 0;border-bottom:1px dashed var(--regla-suave)}
.ba-grupo:last-child{border-bottom:0}
.ba-grupo span{flex:1;min-width:0}
.ba-grupo b{font-family:var(--ff-m);font-size:var(--text-xs)}
.ba-grupo em{font-style:normal;font-size:var(--t-micro);color:var(--tinta-tenue)}
body:not(.tecnico) .solo-tecnico-fila{display:none}
#ba-cuerpo .flojo{color:var(--tinta-tenue);font-size:var(--text-xs)}
/* La primera columna de la tabla de factores lleva nombre + condición (o la hipótesis, en los
   categóricos): se deja envolver para que la diferencia y los puntos extra no queden fuera de vista. */
.ba-tabla td:first-child{white-space:normal;min-width:170px;max-width:360px}
.ba-tabla td:first-child .leyenda{margin-top:2px}

/* ── Objetivos táctiles en pantallas de dedo ──
   Medido a 390 px: "← Pacientes" medía 17 px de alto, "Anterior/Siguiente" 28, "Ver dónde se ve"
   18 y el índice "En esta sección" 24. Con el dedo, errarle por 10 px es tocar lo de al lado. Solo
   con puntero grueso: en escritorio se conserva la densidad de siempre. */
@media (pointer:coarse){
  .ficha-nav .volver,.ficha-nav .nav-btn,.hall-ir,.indice-sec button,.tb-nota-sin{min-height:44px;display:inline-flex;align-items:center}
  .indice-sec button{padding-inline:10px}
}

/* ── HRV extendida (solapa interna de prueba, js/18-hrv-extendida.js) ── */
#hx-cuerpo .flojo{color:var(--tinta-tenue);font-size:var(--text-xs)}
.hx-grilla{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,440px),1fr));gap:14px;margin-top:12px}
.hx-grilla .tarjeta{margin:0}
.grafico.hx-cuadrado{height:380px;max-width:420px}
.hx-tabla tr.hx-on td{background:var(--acento-suave,rgba(14,124,134,.08))}
.hx-todas{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:6px 18px}
.hx-todas .d{display:flex;justify-content:space-between;gap:8px;border-bottom:1px dashed var(--grilla);padding:3px 0}
.hx-todas .d span{color:var(--tinta-suave)}
#hx-cuerpo tr.hx-f-no td{opacity:.85}
#hx-cuerpo select{font:inherit;padding:2px 6px;margin-left:6px}

/* ── Guía interactiva (js/19-guia.js) ──
   Una capa que se come los clicks, un foco que recorta la zona explicada (la sombra gigante es la
   que oscurece el resto) y un globo con el texto. Colores solo por tokens: en oscuro el globo es el
   panel navy y el botón sigue siendo el CTA mint con tinta navy. El borde mint del foco marca lo
   que se está mostrando sobre la pantalla oscurecida, y se ve igual en los dos temas. */
.guia-capa{position:fixed;inset:0;z-index:2000;background:transparent;cursor:default}
.guia-capa.oscura{background:rgba(12,17,26,.58)}
.guia-foco{position:fixed;z-index:2001;pointer-events:none;border-radius:14px;
  box-shadow:0 0 0 3px var(--mint),0 0 0 9999px rgba(12,17,26,.58);
  transition:top .32s var(--ease-premium),left .32s var(--ease-premium),width .32s var(--ease-premium),height .32s var(--ease-premium)}
.guia-foco.oculto{display:none}
/* Sobre el navy del modo oscuro, el mismo velo casi no se nota: más denso y más frío. */
:root[data-tema="oscuro"] .guia-capa.oscura{background:rgba(2,5,10,.72)}
:root[data-tema="oscuro"] .guia-foco{box-shadow:0 0 0 3px var(--mint),0 0 0 9999px rgba(2,5,10,.72)}
.guia-globo{position:fixed;z-index:2002;width:min(390px,calc(100vw - 24px));background:var(--panel);color:var(--tinta);
  border:1px solid var(--regla);border-radius:var(--radius-sm);box-shadow:var(--shadow-hover);padding:14px 18px 12px;
  font-family:var(--ff);animation:guia-entra .22s var(--ease-premium)}
.guia-globo.guia-centro{width:min(460px,calc(100vw - 24px))}
.guia-globo.guia-tarjeta{width:min(520px,calc(100vw - 24px));padding:22px 24px 18px}
/* Flecha que apunta a lo resaltado. --flecha-x / --flecha-y los pone el JS. */
.guia-globo[data-lado]::before{content:"";position:absolute;width:12px;height:12px;background:var(--panel);
  border:1px solid var(--regla);transform:rotate(45deg)}
.guia-globo[data-lado="abajo"]::before{top:-7px;left:calc(var(--flecha-x) - 6px);border-right:0;border-bottom:0}
.guia-globo[data-lado="arriba"]::before{bottom:-7px;left:calc(var(--flecha-x) - 6px);border-left:0;border-top:0}
.guia-globo[data-lado="derecha"]::before{left:-7px;top:calc(var(--flecha-y) - 6px);border-right:0;border-top:0}
.guia-globo[data-lado="izquierda"]::before{right:-7px;top:calc(var(--flecha-y) - 6px);border-left:0;border-bottom:0}
.guia-cab{display:flex;align-items:center;justify-content:space-between;gap:10px}
.guia-paso{font-size:var(--t-micro);font-weight:var(--weight-semibold);color:var(--tinta-tenue);letter-spacing:.04em;text-transform:uppercase}
.guia-x{background:transparent;border:0;color:var(--tinta-tenue);font-size:15px;line-height:1;cursor:pointer;
  width:32px;height:32px;border-radius:var(--radius-full);display:inline-flex;align-items:center;justify-content:center;margin-right:-8px}
.guia-x:hover{background:var(--panel-2);color:var(--tinta)}
.guia-barra{height:3px;background:var(--panel-3);border-radius:3px;margin:8px 0 12px;overflow:hidden}
.guia-barra i{display:block;height:100%;background:var(--marca-linea);border-radius:3px;transition:width .3s var(--ease-premium)}
.guia-tit{font-family:var(--ff-d);font-size:var(--text-base,16px);font-weight:var(--weight-semibold);line-height:1.3;margin:0 0 6px;color:var(--tinta)}
.guia-tarjeta .guia-tit{font-size:var(--text-lg);text-align:center}
.guia-txt{font-size:var(--text-sm);line-height:1.55;color:var(--tinta-suave);margin:0}
.guia-tarjeta .guia-txt{text-align:center}
.guia-bienv-ico{font-size:40px;text-align:center;line-height:1;margin-bottom:10px}
.guia-puntos{font-size:var(--text-xs);line-height:1.6;color:var(--tinta);background:var(--realce);border-radius:var(--radius-sm);
  padding:10px 12px;margin:14px 0 0;text-align:center}
:root[data-tema="oscuro"] .guia-puntos{background:var(--panel-2)}
.guia-nota{font-size:var(--t-nota);color:var(--tinta-tenue);text-align:center;margin:12px 0 0}
.guia-pie{display:flex;align-items:center;gap:8px;margin-top:14px;flex-wrap:wrap}
.guia-pie-centro{justify-content:center;margin-top:18px}
.guia-sp{flex:1}
.guia-pie .btn{min-height:36px}
.guia-saltar{background:transparent;border:0;color:var(--tinta-tenue);font:inherit;font-size:var(--text-xs);cursor:pointer;
  text-decoration:underline;text-underline-offset:3px;padding:6px 2px;min-height:36px}
.guia-saltar:hover{color:var(--tinta)}
.guia-globo button:focus-visible,.guia-globo a:focus-visible{outline:2px solid var(--foco);outline-offset:2px}
:root[data-tema="oscuro"] .guia-globo button:focus-visible{outline-color:var(--mint)}
.guia-teclas{font-size:var(--t-micro);color:var(--tinta-tenue);margin-top:8px;text-align:right}
.guia-espera{margin:6px 0;font-size:var(--text-sm);color:var(--tinta-suave);text-align:center}
.guia-espera::before{content:"";display:inline-block;width:12px;height:12px;margin-right:8px;vertical-align:-1px;
  border:2px solid var(--panel-3);border-top-color:var(--marca-linea);border-radius:50%;animation:guia-gira .8s linear infinite}
.guia-atajos{width:100%;border-collapse:collapse;margin-top:10px;font-size:var(--text-sm)}
.guia-atajos th,.guia-atajos td{padding:8px 6px;border-bottom:1px solid var(--regla-suave);text-align:left;vertical-align:middle}
.guia-atajos th{white-space:nowrap;font-weight:normal;width:1%}
.guia-atajos td{color:var(--tinta-suave)}
.guia-atajos kbd{display:inline-block;min-width:22px;padding:2px 7px;border:1px solid var(--regla);border-bottom-width:2px;
  border-radius:6px;background:var(--panel-2);font-family:var(--ff-m);font-size:var(--t-micro);color:var(--tinta);text-align:center}

/* Botón ? del encabezado: mismo tratamiento que ⚙ y ☾, pero a plena opacidad — es la puerta de
   entrada de quien recién llega. `pulso` late dos veces después de "Ahora no". */
.btn-ico.btn-guia{opacity:1;font-weight:var(--weight-bold);font-size:16px}
.btn-guia[aria-expanded="true"]{background:rgba(255,255,255,.16)}
.btn-guia.pulso{animation:guia-pulso 1.2s var(--ease-premium) 2}

/* Menú de ayuda: mismo lenguaje que el menú del Reporte 360 (details.mas). */
.guia-menu{position:fixed;z-index:60;min-width:270px;max-width:calc(100vw - 24px);background:var(--panel);color:var(--tinta);
  border:1px solid var(--regla);border-radius:var(--radius-sm);box-shadow:var(--shadow-hover);padding:6px;animation:guia-entra .16s var(--ease-premium)}
.guia-menu-tit{font-size:var(--t-micro);font-weight:var(--weight-semibold);text-transform:uppercase;letter-spacing:.05em;color:var(--tinta-tenue);padding:6px 10px 4px}
.guia-menu [role=menuitem]{display:flex;align-items:center;gap:10px;width:100%;min-height:40px;padding:6px 10px;border:0;background:transparent;
  color:inherit;font:inherit;font-size:var(--text-sm);text-align:left;text-decoration:none;border-radius:8px;cursor:pointer}
.guia-menu [role=menuitem]:hover:not([disabled]),.guia-menu [role=menuitem]:focus-visible{background:var(--realce);outline:none}
:root[data-tema="oscuro"] .guia-menu [role=menuitem]:hover:not([disabled]),
:root[data-tema="oscuro"] .guia-menu [role=menuitem]:focus-visible{background:var(--panel-2)}
.guia-menu [role=menuitem]:focus-visible{box-shadow:inset 0 0 0 2px var(--foco)}
.guia-menu [role=menuitem][disabled]{cursor:not-allowed;opacity:.6}
.guia-menu .gm-ico{width:22px;text-align:center;flex:0 0 auto}
.guia-menu .gm-txt{display:flex;flex-direction:column;line-height:1.3}
.guia-menu .gm-txt em{font-style:normal;font-size:var(--t-micro);color:var(--tinta-tenue)}
.guia-menu .gm-chico{font-size:var(--text-xs);color:var(--tinta-suave)}
.guia-menu-sep{height:1px;background:var(--regla-suave);margin:4px 6px}

/* Aviso de la primera ficha: abajo a la izquierda (el lanzador del asistente vive a la derecha). */
.guia-aviso{position:fixed;left:20px;bottom:20px;z-index:30;display:flex;align-items:center;gap:12px;max-width:min(470px,calc(100vw - 40px));
  background:var(--panel);color:var(--tinta);border:1px solid var(--regla);border-left:4px solid var(--marca-linea);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-hover);padding:12px 14px;animation:guia-sube .28s var(--ease-premium)}
.guia-aviso-ico{font-size:22px;line-height:1}
.guia-aviso-txt{display:flex;flex-direction:column;gap:2px;font-size:var(--text-xs);color:var(--tinta-suave);flex:1;min-width:0}
.guia-aviso-txt b{font-size:var(--text-sm);color:var(--tinta)}
.guia-aviso-acc{display:flex;gap:6px;flex:0 0 auto}

@keyframes guia-entra{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}}
@keyframes guia-sube{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes guia-gira{to{transform:rotate(360deg)}}
@keyframes guia-pulso{0%{box-shadow:0 0 0 0 rgba(184,230,92,.75)}100%{box-shadow:0 0 0 12px rgba(184,230,92,0)}}

/* Teléfono: el globo es una hoja de ancho completo (el JS la pone arriba o abajo según dónde esté
   lo resaltado), botones de 44 px y sin la línea de teclas, que con el dedo no aplica. */
@media (max-width:640px){
  .guia-globo:not(.guia-centro){width:calc(100vw - 24px)}
  .guia-globo[data-lado]::before{display:none}
  .guia-pie .btn,.guia-saltar,.guia-x{min-height:44px}
  .guia-x{width:44px}
  .guia-aviso{left:12px;right:12px;bottom:12px;max-width:none;flex-wrap:wrap}
  .guia-aviso-acc{width:100%;justify-content:flex-end}
  .guia-aviso-acc .btn{min-height:44px}
}
@media (max-width:640px),(pointer:coarse){.guia-teclas{display:none}}
@media (prefers-reduced-motion:reduce){
  .guia-foco,.guia-barra i{transition:none}
  .guia-globo,.guia-menu,.guia-aviso,.btn-guia.pulso,.guia-espera::before{animation:none}
}
@media print{.guia-capa,.guia-foco,.guia-globo,.guia-menu,.guia-aviso{display:none!important}}

/* ── Tarjetas de dominio a dos columnas en el teléfono ──
   Medido a 375 px: la tarjeta deja 139 px de cabecera y el ícono + la pastilla del puntaje se
   llevaban 65, así que el título quedaba en 74 px. "Movimiento" pide 75 y se partía en
   "Movimien/to"; "Cambio de temperatura" pedía tres renglones y el clamp de dos lo cortaba. Se
   achican el gap y el relleno de la pastilla (el número no cambia de tamaño) y se admite un
   tercer renglón, que solo usa el título largo. */
@media (max-width:520px){
  .dom-top{gap:3px}
  .dom-puntaje{padding:1px 5px}
  .dom-label{-webkit-line-clamp:3}
}

/* Navegación de la ficha a 375 px: "← Pacientes · 1 de 353 · Anterior" entraban en un renglón y
   "Siguiente" caía sola al de abajo, lejos de su par. Arriba "← Pacientes" y la posición; abajo
   los dos botones, mitad y mitad, que además quedan más fáciles de tocar. */
@media (max-width:520px){
  .ficha-nav .nav-btn{flex:1 1 calc(50% - 5px);justify-content:center}
}
