/* ==========================================================================
   Anamnesis Viva · maqueta navegable — HOJA DE ESTILOS COMPARTIDA
   --------------------------------------------------------------------------
   Los tokens son LITERALMENTE los de docs/diseno/DESIGN-SYSTEM.md, con los
   mismos nombres. Si algo se contradice, manda la imagen de referencia
   docs/diseno/referencia-dashboard.jpeg.
   Sin frameworks, sin build, sin CDN: todo funciona offline.
   ========================================================================== */

:root {
  /* superficie */
  --fondo-app: #f5f6f8;        /* lienzo general gris muy claro */
  --superficie: #ffffff;       /* tarjetas, sidebar, topbar */
  --superficie-suave: #f8f9fb; /* cabeceras de tabla, zonas secundarias */
  --borde: #e8eaee;            /* bordes hairline de tarjeta y divisores */
  --borde-fuerte: #dfe2e7;

  /* ---- tinta -----------------------------------------------------------
     Los cuatro peldaños llevan su razón de contraste MEDIDA con la fórmula de
     luminancia relativa de la WCAG contra las tres superficies del sistema
     (--superficie #ffffff · --superficie-suave #f8f9fb · --fondo-app #f5f6f8).
     Los dos de abajo se recalibraron el 12-ago-2026: `--texto-mudo` era
     #9ca3af y se quedaba en 2,54:1 sobre blanco —ni el umbral de texto normal
     (4,5:1) ni el de texto grande (3:1)—, y `--texto-suave` era #6b7280, que
     cumplía sobre blanco (4,83:1) pero NO sobre el lienzo (4,47:1). El usuario
     principal de esta herramienta es un médico mayor y ambos tonos visten
     rótulos de 11 px con contenido informativo: la cláusula de accesibilidad
     del sistema de diseño estaba mal calibrada y gana la corrección.         */
  --tinta: #111827;            /* titulares, cifras KPI, botón primario — 17,74 / 16,84 / 16,41 */
  --texto: #374151;            /* cuerpo — 10,31 / 9,78 / 9,53 */
  --texto-suave: #5d636f;      /* secundario, celdas menos importantes — 6,04 / 5,73 / 5,58 */
  --texto-mudo: #6a717f;       /* rótulos de sección, placeholders, ejes — 4,91 / 4,66 / 4,54 */

  /* acentos (chips de icono, series de datos) */
  --azul: #3b82f6;   --azul-suave: #dbeafe;    /* dato principal, gráficas */
  --verde: #10b981;  --verde-suave: #d1fae5;   /* positivo, "en línea", éxito */
  --ambar: #f59e0b;  --ambar-suave: #fef3c7;   /* espera, atención */
  --rojo: #ef4444;   --rojo-suave: #fee2e2;    /* negativo, señalado, fuera de rango */
  --violeta: #8b5cf6; --violeta-suave: #ede9fe;/* métricas agregadas, secundario */

  /* geometría */
  --radio-tarjeta: 16px;
  --radio-control: 10px;       /* botones, inputs, selects */
  --radio-caja: 12px;          /* tarjetas interiores, avisos, tooltips */
  --radio-pill: 999px;         /* badges, chips de estado, avatares */
  --sombra-tarjeta: 0 1px 2px rgb(16 24 40 / .04);
  --sombra-flotante: 0 12px 32px rgb(16 24 40 / .12);  /* tooltips, menús */

  /* ---- pares de acento (texto y borde sobre el fondo -suave) --------------
     Cada acento necesita tres piezas para que un pill/badge/aviso tenga
     contraste AA: fondo (-suave), texto (-texto) y borde (-borde). Están
     documentados en docs/diseno/DESIGN-SYSTEM.md; ningún hex suelto en el
     código.                                                                 */
  --azul-claro: #93c5fd;       /* categoría del donut */
  --azul-fuerte: #2563eb;      /* barra destacada, degradado */
  --azul-texto: #1e40af;   --azul-borde: #bfdbfe;   --azul-hondo: #1e3a8a;
  --verde-texto: #065f46;  --verde-borde: #a7f3d0;  --verde-hondo: #047857;
  --ambar-texto: #92400e;  --ambar-borde: #fcd34d;  --ambar-hondo: #78350f;
  --ambar-icono: #b45309;
  --ambar-tenue: #fdf8ec;      /* filas de una propuesta sin validar */
  --rojo-texto: #991b1b;   --rojo-borde: #fecaca;   --rojo-hondo: #7f1d1d;
  --rojo-icono: #b91c1c;
  --violeta-texto: #5b21b6; --violeta-borde: #ddd6fe; --violeta-hondo: #4c1d95;
  --violeta-icono: #6d28d9;
  --violeta-tenue: #f8f6fe;    /* filas de un dato que no se puede comparar */

  /* derivados de la maqueta (no sustituyen a los de arriba) */
  --gris: #6b7280;   --gris-suave: #f1f2f4;    /* estados neutros del sistema */

  /* ---- LA GEOMETRÍA DEL ARMAZÓN TAMBIÉN ES RELATIVA (12-ago-2026) ----------
     Estas dos medidas van en `rem` por la misma razón que la tipografía: son las
     cajas que CONTIENEN texto. Declaradas en píxeles, subir el tamaño de letra
     del navegador al 150 % hacía que la miga de pan se saliera de la topbar por
     arriba (medido: top −16 px, fuera del viewport) y que los rótulos del menú
     lateral se cortaran («Cola de vali…»), es decir, pérdida de contenido justo
     en el ajuste que la WCAG 2.1 SC 1.4.4 exige soportar hasta el 200 %. En rem,
     la caja crece con su contenido y la proporción del diseño se conserva a
     cualquier escala. Lo vigila C19.5, que además prohíbe volver a clavar en
     píxeles la ALTURA de una caja con texto. */
  --ancho-lateral: 16rem;      /* 256 px con la letra de fábrica */
  --alto-superior: 4rem;       /*  64 px con la letra de fábrica */

  /* Altura REAL de la cabecera pegajosa, medida en el navegador por el armazón
     (`AVUI.medirCabecera`): la topbar sola y la topbar más la banda de identidad.
     Los valores de aquí son solo el respaldo para el instante anterior a la
     primera medición; quien manda es lo medido, porque la cabecera envuelve y su
     altura depende del texto que le toque y de la letra del usuario. */
  --alto-cabecera: var(--alto-superior);
  --alto-cabecera-total: calc(var(--alto-superior) + 3.25rem);
}

/* ------------------------------------------------------------- tipografía --
   Inter servida desde el propio proyecto: la maqueta se enseña en el ordenador
   de la consulta, donde Inter no tiene por qué estar instalada, y no hay CDN
   (todo funciona sin red). Licencia SIL OFL en fuentes/LICENSE-Inter.txt.     */

@font-face {
  font-family: 'InterVariable';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fuentes/InterVariable.woff2') format('woff2');
}
/* Respaldo estático para navegadores sin fuentes variables (solo se descarga
   si hace falta). */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fuentes/Inter-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fuentes/Inter-SemiBold.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('fuentes/Inter-Bold.woff2') format('woff2');
}

/* --------------------------------------------------------------- base ----- */

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

/* ---- LA ESCALA TIPOGRÁFICA ES RELATIVA (12-ago-2026) -----------------------
   Toda la hoja declara `font-size` en `rem` sobre esta raíz: `100 %` es el
   tamaño de letra que el usuario tiene configurado en su navegador (16 px de
   fábrica), así que 0.6875rem son los 11 px del sistema de diseño cuando nadie
   ha tocado nada, y 16,5 px cuando alguien ha subido la letra al 150 %. Con
   `font-size` en píxeles fijos —como estaba hasta hoy, 184 declaraciones— ese
   ajuste no surtía ningún efecto: es un ajuste DISTINTO del zoom de página, y
   es el que un usuario mayor tiene puesto sin acordarse de él (WCAG 2.1 SC
   1.4.4). La raíz NO se declara en píxeles: eso volvería a clavar la escala e
   ignoraría la preferencia del usuario, que es justo lo que se corrige (y lo
   comprueba C19.3, que además deja la hoja limpia de píxeles al grep).

   ÚNICA EXCEPCIÓN, y está cerrada por el linter (familia C19.3): los tres
   selectores que tipografían un `<text>` dentro de un `viewBox` FIJO
   (`.donut-cifra`, `.donut-unidad`, `.im-mini-sello-texto`). Ahí el «px» no es
   un píxel de pantalla sino una unidad de usuario del SVG, y crecer con la
   letra del navegador no ampliaría el dibujo: lo desbordaría —la cifra del
   donut se saldría del agujero del anillo y el sello de simulación de su banda,
   que es la garantía que C16.9 vigila—. Esas figuras se amplían con el zoom de
   página, que escala el SVG entero, y su dato vive además fuera de la figura
   (leyenda, tooltip y tabla), en texto que sí sigue a la escala relativa. */
html { font-size: 100%; -webkit-text-size-adjust: 100%; }

/* ---- las anclas aterrizan DEBAJO de la cabecera pegajosa --------------------
   La cabecera son dos filas: la topbar y, debajo, la banda que identifica al
   paciente. Sin compensarlas, cualquier salto por ancla —la marca del mapa que
   lleva a su lesión (§11), la lesión que vuelve a su marca— deja el destino
   tapado por la banda: se llegaría a una lesión sin ver cuál es, que es justo la
   identidad que la cabecera existe para garantizar. La compensación va en
   `scroll-padding-top` del contenedor de desplazamiento (una sola línea para
   toda la maqueta, presente y futura) en vez de en un `scroll-margin-top` por
   destino, que habría que recordar añadir en cada ancla nueva.

   La medida NO puede estar clavada: hasta hoy sumaba `--alto-superior` + 60 px,
   124 px fijos, y con la letra del navegador al 200 % la cabecera real medía
   128 px, así que el destino del ancla aterrizaba TAPADO (comprobado con
   `#estudio-EST-2807` de la galería). Ahora la altura la mide el armazón en el
   navegador y la publica en `--alto-cabecera-total`; aquí solo se le añade aire.
   Lo vigila C19.5. */
html { scroll-padding-top: calc(var(--alto-cabecera-total) + 0.75rem); }

body {
  margin: 0;
  font-family: 'InterVariable', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI',
               Roboto, Helvetica, Arial, sans-serif;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--texto);
  background: var(--fondo-app);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; color: var(--tinta); font-weight: 700; letter-spacing: -.01em; }
p { margin: 0 0 10px; }
a { color: inherit; }
button { font: inherit; color: inherit; }

/* números tabulares donde manda el design system */
.num, table, .kpi-cifra, .cifra, input, .tabular { font-variant-numeric: tabular-nums; }

/* accesibilidad: focus siempre visible */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--azul);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Texto solo para lectores de pantalla. `left/top: 0` no es cosmético: sin ellos
   la caja de 1 px se queda donde caiga el flujo, y dentro de una tabla ancha con
   scroll horizontal eso son cientos de píxeles a la derecha del documento — con
   la letra del navegador al 150 %, la pantalla de pacientes ganaba 278 px de
   scroll horizontal vacío por culpa del rótulo invisible de una columna (medido
   el 12-ago-2026). Anclado al origen de su bloque contenedor, no arrastra nada. */
.solo-lectores {
  position: absolute; left: 0; top: 0; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------ estructura -- */

.capa {
  display: grid;
  grid-template-columns: var(--ancho-lateral) minmax(0, 1fr);
  min-height: 100vh;
}

/* ---- sidebar ---- */

.barra-lateral {
  position: sticky; top: 0; align-self: start;
  height: 100vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 18px;
  padding: 14px 12px;
  background: var(--superficie);
  border-right: 1px solid var(--borde);
}

.marca {
  display: flex; align-items: center; gap: 10px;
  padding: 10px;
  border: 1px solid var(--borde);
  border-radius: var(--radio-caja);
  background: var(--superficie);
  text-decoration: none;
}
.marca:hover { background: var(--superficie-suave); }
.marca-logo {
  width: 36px; height: 36px; flex: 0 0 36px;
  border-radius: var(--radio-control);
  background: var(--tinta); color: #fff;
  display: grid; place-items: center;
  font-weight: 700; font-size: 0.8125rem; letter-spacing: .02em;
}
/* Los rótulos del lateral ENVUELVEN en vez de truncarse. Con `text-overflow:
   ellipsis` se leía «Unidad de Onc…» y «Usuario de demostr…»: a 1280 px ya
   pasaba con la letra de fábrica, y al 150 % desaparecía una de cada cuatro
   letras de todos ellos. Un rótulo cortado no tiene otro canal donde leerse
   —no hay `title` ni panel—, y eso es pérdida de contenido en el ajuste de
   tamaño de letra (SC 1.4.4). Dos líneas ocupan sitio; una palabra a medias
   no informa. */
.marca-txt { min-width: 0; line-height: 1.25; }
.marca-espacio {
  display: block; font-size: 0.6875rem; color: var(--texto-mudo);
  overflow-wrap: break-word;
}
.marca-nombre {
  display: block; font-size: 0.875rem; font-weight: 700; color: var(--tinta);
  overflow-wrap: break-word;
}
.marca .icono-chevron { margin-left: auto; color: var(--texto-mudo); flex: 0 0 auto; }

.nav-grupo { display: flex; flex-direction: column; gap: 2px; }
.nav-rotulo {
  padding: 6px 10px;
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-mudo);
}
.nav-item {
  display: flex; align-items: center; gap: 10px;
  min-height: 38px; padding: 8px 10px;
  border: 1px solid transparent; border-radius: var(--radio-control);
  color: var(--texto); text-decoration: none; font-size: 0.875rem;
}
.nav-item:hover { background: var(--superficie-suave); }
.nav-item .ico { color: var(--texto-suave); flex: 0 0 auto; }
.nav-item.activo {
  background: var(--superficie-suave);
  border-color: var(--borde);
  color: var(--tinta); font-weight: 600;
}
.nav-item.activo .ico { color: var(--tinta); }
.nav-item.mudo { color: var(--texto-suave); }
/* Igual que los rótulos de la marca: el nombre de una pantalla se lee entero o
   no se lee («Cola de vali… 10», «Archivo doc… 22»). El contador sigue anclado a
   la derecha porque es `margin-left: auto` sobre un flex que no envuelve. */
.nav-item-txt { min-width: 0; overflow-wrap: break-word; }
.nav-contador {
  margin-left: auto; flex: 0 0 auto;
  min-width: 22px; padding: 1px 7px;
  border-radius: var(--radio-pill);
  background: var(--superficie-suave); border: 1px solid var(--borde);
  font-size: 0.6875rem; font-weight: 600; color: var(--texto-suave);
  text-align: center; font-variant-numeric: tabular-nums;
}
.nav-item.activo .nav-contador { background: #fff; }

.nav-sub { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 2px 18px; padding-left: 12px; border-left: 1px solid var(--borde); }
.nav-sub .nav-item { min-height: 34px; font-size: 0.8125rem; }

.lateral-pie { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
.nota-lateral {
  padding: 10px 12px;
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
  font-size: 0.71875rem; color: var(--texto-suave); line-height: 1.45;
}
.tarjeta-usuario {
  display: flex; align-items: center; gap: 10px;
  padding: 10px;
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie);
}
.tarjeta-usuario .icono-chevron { margin-left: auto; color: var(--texto-mudo); }

.avatar {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: var(--radio-pill);
  background: var(--tinta); color: #fff;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 700;
}
.avatar--suave { background: var(--superficie-suave); color: var(--texto); border: 1px solid var(--borde); }
.avatar--azul { background: var(--azul-suave); color: var(--azul-texto); }
.avatar--verde { background: var(--verde-suave); color: var(--verde-texto); }
.avatar--ambar { background: var(--ambar-suave); color: var(--ambar-texto); }
.avatar--violeta { background: var(--violeta-suave); color: var(--violeta-texto); }
.avatar--grande { width: 52px; height: 52px; flex-basis: 52px; font-size: 1.0625rem; }

/* ---- topbar ---- */

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

/* La topbar CRECE con su contenido: `min-height`, nunca `height`. Con altura
   clavada, subir la letra del navegador al 150 % dejaba la miga de pan medio
   fuera del viewport (top −16 px) y pintando encima de la banda de identidad, es
   decir, tapando el invariante C15: de quién es la historia que se está
   leyendo.

   Crecer NO es envolver: la topbar sigue siendo UNA fila (sus piezas se
   encogen, como en la referencia del diseño), y lo que envuelve por dentro es la
   miga de pan. Con `flex-wrap: wrap` en esta fila, el buscador se caía a una
   segunda línea ya con la letra de fábrica y la cabecera pasaba de 64 a 110 px:
   el diseño manda mientras quepa. */
.barra-superior {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 14px;
  min-height: var(--alto-superior); padding: 0 24px;
  background: var(--superficie);
  border-bottom: 1px solid var(--borde);
}
/* ---- banda de identificación del paciente (cabecera común) ----
   Segunda fila de la cabecera, pegada bajo la topbar y presente en TODA pantalla
   de un solo paciente. Inconfundible sin ser chillona: la jerarquía la da el
   PESO —nombre en tinta 600, número en cifra tabular dentro de un chip hairline,
   edad y sexo en texto suave— y el fondo sigue siendo blanco. El color aquí no
   informa de nada, y por eso no hay color: el único acento posible es el ámbar
   del aviso «esta no es la historia abierta», que es un estado del sistema. */

/* La banda se pega bajo la topbar a la altura REAL de esta, medida en el
   navegador (`--alto-cabecera`), no a una altura supuesta: la topbar envuelve y
   con la letra al 150 % medía 79 px, así que una banda clavada en 64 px le
   pintaba encima y decapitaba el número de historia. */
.banda-paciente {
  position: sticky; top: var(--alto-cabecera); z-index: 29;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 24px;
  background: var(--superficie);
  border-bottom: 1px solid var(--borde);
}
.banda-paciente .avatar { width: 30px; height: 30px; flex-basis: 30px; font-size: 0.6875rem; }
.bp-rotulo {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--texto-mudo);
}
.bp-txt { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
/* El panel de alcance de la banda va a la derecha: la garantía de que el
   identificador se deriva y no se escribe a mano tiene que poder LEERSE. */
.bp-alcance { margin-left: auto; display: inline-flex; }
.bp-nombre { font-size: 0.9375rem; font-weight: 600; color: var(--tinta); }
.bp-datos { display: flex; align-items: baseline; gap: 7px; font-size: 0.8125rem; color: var(--texto-suave); }
.bp-hc {
  font-weight: 600; color: var(--texto);
  padding: 1px 8px; border: 1px solid var(--borde-fuerte); border-radius: var(--radio-pill);
  background: var(--superficie-suave);
}
.bp-dato--sin { color: var(--texto-mudo); font-style: italic; }
.bp-sep { color: var(--borde-fuerte); }
.bp-aviso { margin-left: auto; }

/* ---- identificador por FILA (pantallas que mezclan historias) ----
   Mismo criterio que la banda, en tamaño de tabla: el número de historia no se
   queda en gris mudo al lado del nombre, porque es el dato que evita leer los
   datos de una persona creyéndolos de otra. */
/* `flex-wrap` porque el identificador puede llevar detrás el aviso de
   identificación discrepante: en una celda estrecha baja de línea en vez de
   desbordar la columna. */
/* La identidad de una fila puede encogerse hasta donde haga falta: es lo último
   que debe empujar la página, y con `min-width: auto` el apellido más largo
   marcaba el suelo del ancho (medido a 200 %: 153 px en un hueco de 86). */
.idf { display: inline-flex; align-items: baseline; gap: 8px; row-gap: 4px; flex-wrap: wrap; min-width: 0; max-width: 100%; text-decoration: none; }
.idf--apilada { flex-direction: column; align-items: flex-start; gap: 2px; }
.idf-nombre { font-weight: 600; color: var(--tinta); min-width: 0; overflow-wrap: break-word; }
a.idf:hover .idf-nombre { text-decoration: underline; }
.idf-nombre--sin { font-weight: 500; color: var(--texto-mudo); font-style: italic; }
.idf-hc {
  font-size: 0.71875rem; font-weight: 600; color: var(--texto);
  padding: 1px 7px; border: 1px solid var(--borde-fuerte); border-radius: var(--radio-pill);
  background: var(--superficie-suave); white-space: nowrap;
}

/* Identificación del documento abierto en la cola de validación: caja interior
   (radio 12px) al principio de sus datos, no una nota al pie bajo los botones. */
.doc-identidad {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 14px; padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.doc-identidad-rotulo {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: var(--texto-mudo);
}
.doc-identidad .idf-nombre { font-size: 0.90625rem; }
.doc-identidad-nota { flex-basis: 100%; margin: 0; }

/* La miga de pan ENVUELVE: es texto derivado (el número de historia y el nombre
   de la pantalla), y con la letra grande no cabe en una línea. Envolver es lo que
   ya hacen la cabecera y el pie de las tarjetas por la misma razón. */
.migas { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; font-size: 0.875rem; color: var(--texto-mudo); min-width: 0; }
.migas a { text-decoration: none; color: var(--texto-suave); }
.migas a:hover { color: var(--tinta); }
.migas .sep { color: var(--borde-fuerte); }
.migas strong { color: var(--tinta); font-weight: 600; }

.buscador {
  margin-left: auto;
  display: flex; align-items: center; gap: 8px;
  width: min(380px, 34vw); padding: 8px 14px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  color: var(--texto-mudo);
}
.buscador input {
  border: 0; background: transparent; outline: none;
  width: 100%; font-size: 0.8125rem; color: var(--texto);
}
.buscador input::placeholder { color: var(--texto-mudo); }

.boton-icono {
  position: relative;
  width: 38px; height: 38px; flex: 0 0 38px;
  display: grid; place-items: center;
  background: var(--superficie); color: var(--texto-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  cursor: pointer;
}
.boton-icono:not(:disabled):not([aria-disabled='true']):hover {
  background: var(--superficie-suave); color: var(--tinta);
}
/* EL BOTÓN DE ICONO APAGADO SE VE APAGADO (ciclo 42). El botón de texto ya lo
   tenía (`.boton:disabled`, más abajo), pero esa regla no alcanza a los de
   icono, y los del zoom del visor se deshabilitan en los extremos de la escala:
   sin esto, en el estado inicial —100 %, «alejar» sin paso al que ir— quedaba en
   pantalla un control con el mismo fondo, el mismo borde, el mismo cursor de
   mano y el mismo realce al pasar por encima que su hermano vivo, que al
   pulsarlo no hace nada. Un control ofrecido que no responde es exactamente lo
   que este ciclo vino a retirar; que la razón sea buena (no hay paso siguiente)
   no lo salva: hay que DECIRLO, y aquí se dice con la misma vara que el resto. */
.boton-icono:disabled, .boton-icono[aria-disabled='true'] {
  opacity: .55; cursor: not-allowed;
}
/* Iconos pequeños: se mantiene el tamaño VISUAL y se agranda el área pulsable
   hasta los 40px que pide el design system (hit-área ≥40px). */
.boton-icono--mini { width: 30px; height: 30px; flex-basis: 30px; }
.boton-icono--mini::after { content: ''; position: absolute; inset: -5px; }
.boton-icono--desnudo { width: 28px; height: 28px; flex-basis: 28px; border: 0; background: transparent; }
.boton-icono--desnudo::after { content: ''; position: absolute; inset: -6px; }

/* Enlace de la barra superior QUE LLEVA SU CIFRA PUESTA (ciclo 42). Sustituye a
   la campana con punto rojo: aquel botón no llevaba a ninguna parte y el punto
   decía «hay algo» sin decir cuánto. Este es un enlace al mismo destino que su
   entrada del menú —el índice de novedades del inicio— y enseña el número.
   La altura va en `rem` y como SUELO: es una caja con texto dentro (C19.5). */
.enlace-conteo {
  display: inline-flex; align-items: center; gap: 7px;
  flex: 0 0 auto;
  min-height: 2.375rem; padding: 0 12px;
  background: var(--superficie); color: var(--texto-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  font-size: 0.8125rem; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.enlace-conteo:hover { background: var(--superficie-suave); color: var(--tinta); }
.enlace-conteo .num { font-variant-numeric: tabular-nums; }

/* banner de maqueta: discreto pero visible en las 3 páginas */
.aviso-maqueta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px 5px 8px;
  background: var(--ambar-suave); color: var(--ambar-texto);
  border: 1px solid var(--ambar-borde); border-radius: var(--radio-pill);
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  white-space: nowrap;
}

/* ---- lienzo ---- */

.lienzo { padding: 24px 24px 40px; display: flex; flex-direction: column; gap: 22px; }

.cabecera-pagina { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.saludo { font-size: 1.5625rem; line-height: 1.25; }
.saludo .coletilla, .titulo-seccion .coletilla {
  font-size: 0.875rem; font-weight: 400; color: var(--texto-suave); margin-left: 6px;
}
/* Separador de sección (Nivel 1 → Nivel 2, entrada a la pantalla lado a lado).
   El rótulo mudo de 11px queda reservado a tarjetas y cabeceras de tabla: una
   separación de sección se marca con PESO tipográfico, no con mayúsculas. */
.titulo-seccion {
  font-size: 1.0625rem; font-weight: 700; color: var(--tinta); letter-spacing: -.01em;
}
.titulo-seccion .coletilla { font-size: 0.8125rem; }
.cabecera-acciones { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ---- rejillas ---- */

.rejilla { display: grid; gap: 20px; }
.rejilla--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.rejilla--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rejilla--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rejilla--2-1 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.rejilla--1-1 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* Cada tarjeta mide lo que ocupa, en vez de estirarse hasta la altura de su
   vecina. Se pide donde el desnivel es grande —el mapa anatómico terminaba a
   584 px dentro de una tarjeta estirada a 1.140 px por la leyenda: 556 px de
   blanco que se leían como algo a medio cargar (hallazgo C18-1)—; no se cambia
   el estiramiento por defecto, que es lo que mantiene alineadas las parejas de
   tarjetas del resto de pantallas. */
.rejilla--arriba { align-items: start; }

/* --------------------------------------------------------------- tarjeta -- */

.tarjeta {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--sombra-tarjeta);
  display: flex; flex-direction: column;
  min-width: 0;
}
/* La cabecera ENVUELVE, no desborda: con la letra del navegador al 150 % el
   grupo de acciones de la derecha se salía de la tarjeta (medido el 12-ago-2026
   en la cola de validación, 99 px fuera). Envolver es lo que ya hace el pie de
   la tarjeta por la misma razón. */
.tarjeta-cab {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; row-gap: 8px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--borde);
}
.tarjeta-cab.sin-linea { border-bottom: 0; padding-bottom: 4px; }
.rotulo {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--texto-mudo);
}
/* El grupo de la derecha también envuelve: se arregló el padre `.tarjeta-cab` y
   se quedó sin arreglar el hijo que lleva los pills, que es quien empujaba la
   página a scroll horizontal (el recuento «9 hechos · 0 para incorporar · 9 sin
   decisión · 3 de revisión ineludible» llegaba a 1506 px en un viewport de
   1440). Sin `min-width: 0` un hijo flex no puede encogerse por debajo de su
   contenido, y sin `flex-wrap` no tiene dónde ir. */
.tarjeta-cab .der {
  margin-left: auto; min-width: 0;
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; row-gap: 6px; justify-content: flex-end;
}
.tarjeta-cuerpo { padding: 18px; }
.tarjeta-cuerpo.compacto { padding: 12px 18px; }
.tarjeta-pie {
  margin-top: auto;
  /* El pie envuelve en vez de truncar: a 1280px se leía «vs. …», «sin revi…». */
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; row-gap: 6px;
  padding: 12px 18px;
  border-top: 1px solid var(--borde);
  font-size: 0.78125rem; color: var(--texto-suave);
}
.pie-txt { min-width: 0; }
.tarjeta--plana { box-shadow: none; }
.tarjeta--suave { background: var(--superficie-suave); }

/* ------------------------------------------------------------------ KPI --- */

.kpi { padding: 16px 18px 0; }
.kpi-cab { display: flex; align-items: center; gap: 10px; }
.kpi-chip {
  width: 36px; height: 36px; flex: 0 0 36px;
  border-radius: var(--radio-control);
  display: grid; place-items: center; color: #fff;
}
.kpi-chip--verde { background: var(--verde); }
.kpi-chip--azul { background: var(--azul); }
.kpi-chip--ambar { background: var(--ambar); }
.kpi-chip--violeta { background: var(--violeta); }
/* min-height = dos líneas: así las 4 tarjetas KPI alinean cifra y pie aunque
   un rótulo ocupe una sola línea. */
.kpi-rotulo { flex: 1 1 auto; min-width: 0; min-height: 2rem; display: flex; flex-wrap: wrap; align-items: center; overflow-wrap: break-word; }
.kpi-cuerpo { display: flex; align-items: flex-end; gap: 12px; padding: 14px 0 16px; }
.kpi-cifra { font-size: 1.875rem; font-weight: 700; color: var(--tinta); line-height: 1; letter-spacing: -.02em; }
.kpi-denominador { font-size: 0.78125rem; color: var(--texto-suave); padding-bottom: 2px; }

.chispa { margin-left: auto; display: flex; align-items: flex-end; gap: 3px; height: 34px; }
.chispa i { display: block; width: 3px; border-radius: 2px; background: var(--borde-fuerte); }
.chispa i.acento--verde { background: var(--verde); }
.chispa i.acento--azul { background: var(--azul); }
.chispa i.acento--ambar { background: var(--ambar); }
.chispa i.acento--violeta { background: var(--violeta); }

/* ------------------------------------------------- pills, badges, chips --- */

/* El pill NO va en `nowrap`. Lo estuvo, y como aquí un pill no siempre es una
   etiqueta corta —«Ubicación confirmada por un profesional junto al original»
   son 454 px—, con la letra al 200 % sacaba la página entera a desplazamiento
   horizontal (145 px en la galería). Envolver solo ocurre cuando NO cabe: con la
   letra de fábrica el pill mide lo mismo que antes, y cuando el hueco se estrecha
   prefiere partirse a empujar la página. */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; min-width: 0;
  padding: 4px 10px 4px 7px;
  border-radius: var(--radio-pill);
  font-size: 0.75rem; font-weight: 600; line-height: 1.3;
  border: 1px solid transparent;
  white-space: normal; overflow-wrap: break-word;
}
.pill .ico { flex: 0 0 auto; }
.pill--verde   { background: var(--verde-suave);   color: var(--verde-texto); border-color: var(--verde-borde); }
.pill--azul    { background: var(--azul-suave);    color: var(--azul-texto); border-color: var(--azul-borde); }
.pill--ambar   { background: var(--ambar-suave);   color: var(--ambar-texto); border-color: var(--ambar-borde); }
.pill--rojo    { background: var(--rojo-suave);    color: var(--rojo-texto); border-color: var(--rojo-borde); }
.pill--violeta { background: var(--violeta-suave); color: var(--violeta-texto); border-color: var(--violeta-borde); }
.pill--gris    { background: var(--gris-suave);    color: var(--texto-suave); border-color: var(--borde-fuerte); }
.pill--contorno { background: var(--superficie); color: var(--texto-suave); border-color: var(--borde-fuerte); }
.pill--mini { font-size: 0.6875rem; padding: 2px 8px; }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--radio-pill);
  font-size: 0.75rem; font-weight: 600; white-space: nowrap;
}
.badge--verde   { background: var(--verde-suave);   color: var(--verde-hondo); }  /* 4,84:1 */
.badge--rojo    { background: var(--rojo-suave);    color: var(--rojo-icono); }   /* 5,30:1 */
.badge--ambar   { background: var(--ambar-suave);   color: var(--ambar-texto); }  /* 6,37:1 */
/* Medido en el DOM el 12-ago-2026: con `--azul-fuerte` este badge daba 4,24:1 a
   12 px —por debajo del 4,5:1 de texto normal—, y era el único de los cuatro que
   no usaba la tinta documentada de su acento. Con `--azul-texto`, 7,15:1. */
.badge--azul    { background: var(--azul-suave);    color: var(--azul-texto); }   /* 7,15:1 */
.badge .flecha { font-size: 0.625rem; line-height: 1; }

.etiqueta-mini {
  display: inline-block; padding: 2px 8px;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-pill);
  background: var(--superficie-suave);
  font-size: 0.6875rem; color: var(--texto-suave); font-weight: 600;
}

/* --------------------------------------------------------------- botones -- */

.boton {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 9px 14px;
  background: var(--superficie); color: var(--texto);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-control);
  font-size: 0.84375rem; font-weight: 600; text-decoration: none;
  cursor: pointer;
}
.boton:hover { background: var(--superficie-suave); color: var(--tinta); }
.boton--primario { background: var(--tinta); color: #fff; border-color: var(--tinta); }
.boton--primario:hover { background: #000; color: #fff; }
.boton--suave { background: var(--superficie-suave); }
.boton--fantasma { background: transparent; border-color: transparent; color: var(--texto-suave); }
.boton--fantasma:hover { background: var(--superficie-suave); }
.boton--mini { min-height: 34px; padding: 6px 11px; font-size: 0.78125rem; }
/* Donde el botón mini ES el control principal (decisiones de validación y
   barra de cierre), sube a los 40px de hit-área del design system. */
.hecho-acciones .boton--mini,
.barra-cierre .boton--mini,
.acciones-vinculacion .boton--mini { min-height: 40px; padding: 9px 13px; }
/* Dentro de una tabla el botón se queda en 30px para no engordar la fila
   (48-52px), pero su área pulsable llega a 40px. */
table.tabla .boton--mini { min-height: 30px; padding: 4px 11px; }
table.tabla .boton--mini::after { content: ''; position: absolute; inset: -5px 0; }
.boton[aria-disabled='true'], .boton:disabled { opacity: .55; cursor: not-allowed; }
.boton--bloque { width: 100%; }

.segmentado {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
}
.segmentado button {
  position: relative;
  border: 0; background: transparent; cursor: pointer;
  min-height: 30px; padding: 6px 13px; border-radius: var(--radio-pill);
  font-size: 0.78125rem; font-weight: 600; color: var(--texto-suave);
}
/* área pulsable de 40px sin engordar el control (design system: hit-área) */
.segmentado button::after { content: ''; position: absolute; inset: -5px 0; }
.segmentado button[aria-pressed='true'] {
  background: var(--superficie); color: var(--tinta);
  box-shadow: var(--sombra-tarjeta);
}

.selector, input[type='text'], input[type='search'], textarea, select {
  min-height: 40px; padding: 8px 12px;
  background: var(--superficie); color: var(--texto);
  border: 1px solid var(--borde); border-radius: var(--radio-control);
  font-size: 0.84375rem; font-family: inherit;
}
/* Un chip INFORMATIVO no es un control (bajo del c42): los dos usos vivos de
   `.selector` (#chip-fecha, #ambito-cola) son texto derivado de los datos, y el
   cursor de mano con realce al pasar prometía un desplegable que no existe. Si
   algún día un control real usa esta caja, que lo haga con <button class="selector">
   y recupere ahí su afordancia. */
.selector { display: inline-flex; align-items: center; gap: 8px; cursor: default; }
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--azul);
  box-shadow: 0 0 0 3px var(--azul-suave);
}
/* …pero con teclado el anillo suave no basta (≈1,2:1 sobre blanco): el foco
   tiene que verse SIEMPRE, y estos son los campos donde se corrige el OCR.
   Va después de la regla anterior a propósito: misma especificidad, gana. */
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--azul);
  outline-offset: 1px;
  border-color: var(--azul);
}
.campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.campo > label { font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--texto-mudo); }
.campo input { min-height: 36px; font-size: 0.84375rem; }
.campo input[readonly] { background: var(--superficie-suave); color: var(--texto-suave); }

/* --------------------------------------------------------------- tablas --- */

/* Una tabla clínica puede no caber a lo ancho, y entonces hay que DECIRLO: en
   macOS la barra de desplazamiento es efímera, así que una tabla cortada por el
   borde derecho se lee como una tabla que acaba ahí — y lo que queda fuera suele
   ser la última columna, la del documento del que sale el dato. La sombra del
   borde aparece solo cuando hay contenido más allá (dos degradados fijos al
   contenido y dos anclados al scroll: donde no hay nada que desplazar, el blanco
   tapa la sombra) y no depende de JavaScript ni de que la barra esté visible. */
.tabla-envoltorio {
  overflow-x: auto;
  background:
    linear-gradient(to right, var(--superficie) 30%, rgba(255, 255, 255, 0)),
    linear-gradient(to right, rgba(255, 255, 255, 0), var(--superficie) 70%) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(15, 23, 42, .13), rgba(15, 23, 42, 0)),
    radial-gradient(farthest-side at 100% 50%, rgba(15, 23, 42, .13), rgba(15, 23, 42, 0)) 100% 0;
  background-repeat: no-repeat;
  background-size: 42px 100%, 42px 100%, 13px 100%, 13px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* Tabla con desplazamiento propio: aquí la cabecera SÍ se pega, y lo hace
   respecto de este contenedor, no de la ventana. */
.tabla-envoltorio--alta { max-height: 60vh; overflow: auto; }
.tabla-envoltorio--alta table.tabla thead th { position: sticky; top: 0; z-index: 1; }
table.tabla { width: 100%; border-collapse: collapse; font-size: 0.84375rem; }
/* NO hay cabecera pegajosa por defecto. La había (`position:sticky; top:0`) y
   era un error: el scrollport real de estas tablas es `.tabla-envoltorio`, que
   no tiene alto propio, así que la cabecera acababa pegándose a y=0 —debajo de
   la topbar, que mide --alto-superior y va en z-index 30— y se veía una banda
   gris con las letras cortadas. Las tablas de la maqueta tienen 2-9 filas y no
   la necesitan. Cuando una tabla sí deba desplazarse por dentro, se usa el
   envoltorio alto de abajo, donde el sticky sí tiene sentido (top:0 respecto
   de SU scrollport).                                                          */
table.tabla thead th {
  background: var(--superficie-suave);
  padding: 10px 14px; text-align: left;
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo);
  border-bottom: 1px solid var(--borde); border-top: 1px solid var(--borde);
  white-space: nowrap;
}
.nota-th {
  display: block; margin-top: 2px;
  font-size: 0.625rem; font-weight: 600; text-transform: none; letter-spacing: 0;
  color: var(--ambar-texto);
}
table.tabla tbody td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--borde);
  vertical-align: middle;
}
.celda-chip { display: block; margin-top: 4px; }
/* Celda de una línea (tabla de actividad, filas de 48-52px): el texto completo
   queda en el title y, entero, en la pantalla de la cola. */
/* La celda ANCHA no es la celda RECORTADA: acota su anchura (en rem, para que
   crezca con la letra) y deja que el texto pase de línea. Recortaba con puntos
   suspensivos y guardaba el resto en un `title`: del tipo de documento —«Anatomía
   patológica · informe ampliado (versión 2)»— se leía el 65 % con la letra de
   fábrica y el 35 % al 200 %, y lo que faltaba solo aparecía si alguien dejaba
   quieto el ratón encima. El `title` se queda como refuerzo, no como único canal. */
.celda-truncada { min-width: 11rem; max-width: 16.25rem; overflow-wrap: break-word; }
.celda-parametro { min-width: 190px; }

/* Cabecera de un grupo de filas: separa la historia validada de la propuesta
   pendiente dentro de la misma tabla. */
tr.fila-grupo td {
  background: var(--superficie-suave);
  padding: 10px 14px;
  border-top: 1px solid var(--borde-fuerte);
}
tr.fila-grupo td > * { vertical-align: middle; margin-right: 8px; }
tr.fila-grupo:hover td { background: var(--superficie-suave); }
tr.fila-grupo--pendiente td { background: var(--ambar-suave); border-top-color: var(--ambar-borde); }
tr.fila-grupo--pendiente:hover td { background: var(--ambar-suave); }
tr.fila-grupo--pendiente .rotulo { color: var(--ambar-texto); }
tr.fila-grupo--pendiente .nota-pie { color: var(--ambar-texto); }
/* Una propuesta sin validar NO se ve como la historia. */
tr.fila-propuesta td { background: var(--ambar-tenue); }
tr.fila-propuesta:hover td { background: var(--ambar-suave); }
/* Y un dato NO COMPARABLE tampoco se ve como una propuesta: su documento está
   validado y no espera a nadie —lo que lo deja fuera de la serie es la unidad o
   el rango de origen—, así que lleva el violeta tenue de su propio estado y no
   el ámbar de lo pendiente. Dos cosas distintas, dos colores distintos. */
tr.fila-fuera-de-serie td { background: var(--violeta-tenue); }
tr.fila-fuera-de-serie:hover td { background: var(--violeta-suave); }
table.tabla tbody tr:last-child td { border-bottom: 0; }
table.tabla tbody tr:hover { background: var(--superficie-suave); }
table.tabla tbody tr.fila-activa { background: var(--azul-suave); }
table.tabla tbody tr.fila-activa:hover { background: var(--azul-suave); }
/* Sobre un fondo de acento, el gris mudo pierde contraste: el pie de la fila
   activa daba 4,02:1 (medido en el DOM el 12-ago-2026) porque el fondo ya no es
   blanco. En la fila resaltada, las notas y las celdas mudas pasan a la tinta
   honda del propio acento —8,49:1— y siguen leyéndose como secundarias por su
   tamaño, que es como manda la jerarquía este sistema. */
table.tabla tbody tr.fila-activa .nota-pie,
table.tabla tbody tr.fila-activa .celda-muda,
table.tabla tbody tr.fila-activa.atenuada td { color: var(--azul-hondo); }
table.tabla tbody tr.atenuada td { color: var(--texto-mudo); }
.celda-fuerte { color: var(--tinta); font-weight: 600; }
.celda-muda { color: var(--texto-suave); }
.celda-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla-nota { padding: 10px 18px; font-size: 0.75rem; color: var(--texto-suave); background: var(--superficie-suave); border-top: 1px solid var(--borde); }

/* --------------------------------------------------------------- ranking -- */

/* El panel de ranking ocupa la altura de la tarjeta y reparte sus filas: sin
   esto quedaba un hueco blanco entre la última fila y el pie. */
.ranking { display: flex; flex-direction: column; flex: 1 1 auto; justify-content: space-evenly; }
.ranking-fila {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--borde);
  text-decoration: none; color: inherit;
}
.ranking-fila:last-child { border-bottom: 0; }
.ranking-fila:hover { background: var(--superficie-suave); }
.ranking-pos {
  width: 22px; height: 22px; flex: 0 0 22px;
  border-radius: 50%; display: grid; place-items: center;
  font-size: 0.6875rem; font-weight: 700;
  background: var(--superficie-suave); color: var(--texto-suave);
  border: 1px solid var(--borde);
}
/* El chip de la primera posición va relleno de ámbar como en la referencia, pero
   con tinta oscura encima: el blanco sobre `--ambar` daba 2,15:1 (medido en el
   DOM el 12-ago-2026) y esa cifra es información, no adorno. Con `--tinta`,
   8,26:1 sin tocar el relleno. */
.ranking-fila:first-child .ranking-pos { background: var(--ambar); color: var(--tinta); border-color: var(--ambar); }
.ranking-txt { min-width: 0; flex: 1 1 auto; }
/* El nombre del paciente y su subtítulo ENVUELVEN: truncarlos con puntos
   suspensivos deja media identidad («Aurelia Bosch…»), y la identidad es
   justamente lo que esta fila existe para decir. */
.ranking-nombre {
  display: block; font-size: 0.84375rem; font-weight: 600; color: var(--tinta);
  overflow-wrap: break-word;
}
.ranking-sub {
  display: block; font-size: 0.75rem; color: var(--texto-mudo);
  overflow-wrap: break-word;
}
.nowrap { white-space: nowrap; }
.ranking-valor { font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- gráficas -- */

.grafica { position: relative; }
.grafica svg { display: block; width: 100%; height: auto; }
.tooltip {
  position: absolute; z-index: 10; pointer-events: none;
  min-width: 150px; padding: 10px 12px;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  box-shadow: var(--sombra-flotante);
  font-size: 0.78125rem; color: var(--texto);
  opacity: 0; transform: translate(-50%, -108%);
  transition: opacity .12s ease;
}
.tooltip.visible { opacity: 1; }
.tooltip-fecha { font-weight: 600; color: var(--tinta); padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px solid var(--borde); }
.tooltip-fila { display: flex; align-items: center; gap: 8px; }
.tooltip-fila .punto { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
.tooltip-fila .valor { margin-left: auto; font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }

/* El donut se dibuja a su tamaño natural (no se estira con la tarjeta), para
   que la cifra centrada mantenga los 27px del design system. */
.donut svg { max-width: 264px; margin: 0 auto 4px; }
.donut-cifra { font-size: 27px; font-weight: 700; fill: var(--tinta); letter-spacing: -.02em; }
.donut-unidad { font-size: 11.5px; fill: var(--texto-mudo); }

.leyenda { display: flex; flex-direction: column; gap: 2px; padding: 6px 0 0; }
.leyenda-fila { display: flex; align-items: center; gap: 10px; padding: 6px 2px; font-size: 0.8125rem; }
.leyenda-fila .punto { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px; }
/* El nombre de la categoría pasa de línea antes que perder letras: es lo que dice
   qué está contando el anillo, y sin él la cifra no significa nada («Imagen y
   anatomía patológica» se quedaba en «Imagen y anatomía patológi…» a 1280 px). */
.leyenda-nombre { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; color: var(--texto); }
.leyenda-valor { color: var(--texto-suave); font-variant-numeric: tabular-nums; }
.leyenda-pct { min-width: 42px; text-align: right; font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }

.leyenda-series { display: flex; flex-wrap: wrap; gap: 6px 16px; padding-top: 4px; }
.leyenda-series span { display: inline-flex; align-items: center; gap: 7px; font-size: 0.78125rem; color: var(--texto-suave); }
.leyenda-series i { width: 14px; height: 3px; border-radius: 2px; flex: 0 0 14px; }

/* ------------------------------------------------- fuente (trazabilidad) -- */

/* El chip de fuente lleva la etiqueta del documento, que es texto del propio
   archivo y puede ser largo («Hoja de enfermería · sesión 14 de hipertermia…»,
   556 px). Con `white-space: nowrap` no había forma de que cupiera y empujaba la
   página entera a scroll horizontal; envolviendo, el chip crece hacia abajo y la
   trazabilidad se sigue leyendo completa. */
.fuente {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%;
  padding: 3px 9px 3px 7px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  font-size: 0.71875rem; font-weight: 600; color: var(--texto-suave);
  cursor: pointer; text-align: left; overflow-wrap: break-word;
}
.fuente:hover { background: var(--azul-suave); border-color: var(--azul-borde); color: var(--azul-texto); }
.fuente .ico { flex: 0 0 auto; }

/* -------------------------------------------------------- bloques de texto */

.cita {
  margin: 0; padding: 10px 14px;
  background: var(--superficie-suave);
  border-left: 3px solid var(--borde-fuerte);
  border-radius: 0 10px 10px 0;
  color: var(--tinta); font-size: 0.84375rem;
  /* La cita es texto literal del documento: nombres de archivo y códigos de
     estudio sin espacios incluidos. Sin punto de corte, uno de esos «palabros»
     sacaba la página a desplazamiento horizontal en la leyenda del mapa. */
  overflow-wrap: break-word;
}
.cita-marca { display: block; margin-top: 6px; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--texto-mudo); overflow-wrap: break-word; }

.aviso {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px;
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
  font-size: 0.8125rem; color: var(--texto);
}
.aviso .ico { flex: 0 0 auto; margin-top: 1px; color: var(--texto-suave); }
/* Cita literal DENTRO de un aviso (p. ej. el valor citado por otro documento):
   bloque propio bajo el texto, nunca metida en la misma línea. */
.aviso .cita { display: block; margin: 9px 0 0; font-size: 0.78125rem; background: var(--superficie); }
.aviso--rojo    { background: var(--rojo-suave);    border-color: var(--rojo-borde); color: var(--rojo-hondo); }
.aviso--rojo .ico { color: var(--rojo-icono); }
.aviso--ambar   { background: var(--ambar-suave);   border-color: var(--ambar-borde); color: var(--ambar-hondo); }
.aviso--ambar .ico { color: var(--ambar-icono); }
.aviso--violeta { background: var(--violeta-suave); border-color: var(--violeta-borde); color: var(--violeta-hondo); }
.aviso--violeta .ico { color: var(--violeta-icono); }
.aviso--azul    { background: var(--azul-suave);    border-color: var(--azul-borde); color: var(--azul-hondo); }
.aviso--azul .ico { color: var(--azul-fuerte); }
/* LOS SEIS TONOS DE §4.1, TAMBIÉN AQUÍ (ciclo 26, hallazgo C26-2). Faltaban el
   verde y el gris, y la ficha del paciente escapaba del gris pintándolo de
   ámbar: con la doctrina de C2.4 —el gris es el tono de lo resuelto— eso teñía
   una decisión humana terminal con el color de lo que falta por hacer. El aviso
   lleva el tono que el estado declara; si un tono no tiene regla, la pantalla se
   inventa una. */
.aviso--verde   { background: var(--verde-suave);   border-color: var(--verde-borde); color: var(--verde-hondo); }
.aviso--verde .ico { color: var(--verde-hondo); }
.aviso--gris    { background: var(--gris-suave);    border-color: var(--borde-fuerte); color: var(--texto); }
.aviso--gris .ico { color: var(--texto-suave); }

.nota-pie { font-size: 0.75rem; color: var(--texto-mudo); }

/* ---- PANEL DE ALCANCE (ciclo 23) ------------------------------------------
   Afordancia persistente para las frases que sostienen una garantía y hasta hoy
   solo vivían en un `title` (que no aparece con el foco del teclado, no existe
   en pantalla táctil y exige mantener el puntero quieto). Se abre con clic o con
   Enter y se queda hasta que se cierra: nunca se cierra al mover el ratón. */
.alcance { position: relative; display: inline-flex; }
.alcance-boton {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: none; border: 1px solid transparent; border-radius: var(--radio-control);
  color: var(--texto-mudo); cursor: pointer;
}
.alcance-boton:hover { background: var(--superficie-suave); color: var(--texto); }
.alcance-boton[aria-expanded="true"] {
  background: var(--superficie-suave); border-color: var(--borde-fuerte); color: var(--tinta);
}
.alcance-panel {
  position: absolute; z-index: 30; top: calc(100% + 6px); left: -6px;
  display: flex; align-items: flex-start; gap: 8px;
  width: max-content; max-width: min(340px, 78vw); padding: 10px 10px 10px 12px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
  box-shadow: var(--sombra-flotante);
  font-size: 0.78125rem; line-height: 1.45; color: var(--texto);
  text-align: left; text-transform: none; letter-spacing: normal; font-weight: 400;
}
.alcance-panel[hidden] { display: none; }
.alcance-txt { flex: 1 1 auto; }
.alcance-cerrar {
  flex: 0 0 auto; display: inline-flex; padding: 0;
  background: none; border: 0; color: var(--texto-mudo); cursor: pointer;
}
.alcance-cerrar:hover { color: var(--tinta); }
/* Pegado al borde derecho del lienzo, el panel se sale: cuando el componente
   lo pide, se ancla por la derecha. */
.alcance--der .alcance-panel { left: auto; right: -6px; }

/* Pie de una casilla de cálculo (porcentaje, días, contra qué documento). El
   tope de ancho es lo que le obliga a partirse en varias líneas: sin él, la
   línea entera es el ancho «natural» de la columna y una sola casilla se lleva
   400 px, empujando fuera de la pantalla las columnas de la derecha —que en
   estas tablas son el estado del dato y su documento. */
.nota-pie--calculo {
  max-width: 170px;
  /* La casilla de una cifra va en `nowrap` (una cifra no se parte); su pie sí
     tiene que poder partirse, o el chip del documento se sale de la columna y se
     dibuja encima de la de al lado. */
  white-space: normal;
  margin-left: auto;
}

/* ------------------------------------------------ ficha de paciente ------ */

.ficha-paciente { display: flex; align-items: flex-start; gap: 18px; padding: 18px; flex-wrap: wrap; }
.ficha-id { display: flex; align-items: center; gap: 14px; min-width: 0; }
.ficha-nombre { font-size: 1.25rem; }
.ficha-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.8125rem; color: var(--texto-suave); margin-top: 4px; }
.ficha-meta .sep { color: var(--borde-fuerte); }
.ficha-datos { display: flex; gap: 26px; flex-wrap: wrap; margin-left: auto; }
.dato-mini .rotulo { display: block; margin-bottom: 3px; }
.dato-mini .valor { font-size: 0.875rem; font-weight: 600; color: var(--tinta); font-variant-numeric: tabular-nums; }
.ficha-acciones { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.lista-hechos { display: flex; flex-direction: column; gap: 14px; }
.hecho { display: flex; flex-direction: column; gap: 6px; }
.hecho-rotulo { display: flex; align-items: center; gap: 8px; }
.hecho-rotulo .ico { color: var(--texto-mudo); }
.hecho-item { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; font-size: 0.84375rem; color: var(--texto); }
.hecho-item .txt { flex: 1 1 260px; min-width: 0; }
.hecho-item .literal { color: var(--tinta); }

.rejilla-situacion { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 26px; }
.rejilla-situacion > .hecho { padding-bottom: 14px; border-bottom: 1px solid var(--borde); }

/* ------------------------------------------------------------ novedades -- */

.novedad {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--borde);
}
.novedad:last-child { border-bottom: 0; }
.novedad.revisada { background: var(--superficie-suave); }
.novedad.revisada .novedad-txt { color: var(--texto-suave); }
.novedad-fecha { flex: 0 0 92px; font-size: 0.78125rem; font-weight: 600; color: var(--tinta); font-variant-numeric: tabular-nums; }
.novedad-cuerpo { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.novedad-cab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.novedad-tipo { font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.novedad-txt { font-size: 0.84375rem; }
.novedad-acciones { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }

/* ----------------------------------------------------------- cronología -- */

.cronologia { display: flex; flex-direction: column; padding: 4px 18px 4px; }
.crono-item {
  position: relative;
  display: flex; gap: 16px;
  padding: 14px 0 14px 0;
}
.crono-item::before {
  /* 90px de fechas + 16px de gap + 9px de margen + 7px (medio punto) = 122px */
  content: ''; position: absolute; left: 121px; top: 0; bottom: 0;
  width: 1px; background: var(--borde);
}
.crono-item:first-child::before { top: 22px; }
.crono-item:last-child::before { bottom: calc(100% - 22px); }
.crono-fechas { flex: 0 0 90px; text-align: right; }
.crono-fecha { font-size: 0.8125rem; font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }
.crono-incorporado { font-size: 0.6875rem; color: var(--texto-mudo); font-variant-numeric: tabular-nums; }
.crono-punto {
  position: relative; z-index: 1;
  flex: 0 0 14px; width: 14px; height: 14px; margin-top: 4px; margin-left: 9px;
  border-radius: 50%; background: var(--superficie);
  border: 3px solid var(--borde-fuerte);
}
.crono-punto.tono--verde { border-color: var(--verde); }
.crono-punto.tono--ambar { border-color: var(--ambar); }
.crono-punto.tono--rojo { border-color: var(--rojo); }
.crono-punto.tono--azul { border-color: var(--azul); }
.crono-punto.tono--violeta { border-color: var(--violeta); }
.crono-punto.tono--gris { border-color: var(--borde-fuerte); }
.crono-cuerpo { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; padding-left: 4px; }
.crono-cab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.crono-titulo { font-size: 0.875rem; font-weight: 600; color: var(--tinta); }
.crono-detalle { font-size: 0.84375rem; color: var(--texto); }

/* ------------------------------------------------------------- lesiones -- */

.lesion { display: flex; flex-direction: column; gap: 14px; padding: 18px; border-top: 1px solid var(--borde); }
.lesion:first-of-type { border-top: 0; }
.lesion-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lesion-id {
  font-size: 0.75rem; font-weight: 700; color: var(--tinta);
  background: var(--superficie-suave); border: 1px solid var(--borde);
  padding: 3px 9px; border-radius: var(--radio-pill);
}
.lesion-titulo { font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }
.lesion-atributos { display: flex; gap: 8px 22px; flex-wrap: wrap; }
.atributo .rotulo { display: block; }
.atributo .valor { font-size: 0.84375rem; color: var(--texto); }

/* Mediciones candidatas: viven FUERA de la serie hasta que alguien decida. El
   bloque se distingue por su marco, no por un color que valore nada. */
.sin-vincular {
  display: flex; flex-direction: column; gap: 12px;
  padding: 14px; border: 1px dashed var(--ambar-borde);
  border-radius: var(--radio-caja); background: var(--ambar-tenue);
}
.sin-vincular .rotulo { color: var(--ambar-texto); }
.sin-vincular table.tabla thead th { background: var(--superficie); }
.sin-vincular .tabla-envoltorio {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); overflow: auto;
}
.sin-vincular .literal { color: var(--tinta); }
.acciones-vinculacion { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.acciones-vinculacion .nota-pie { flex: 1 1 260px; }

/* --------------------------------------------- pantalla lado a lado ------ */

.lado-a-lado { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
/* La barra de cierre flota pegada al pie de la columna derecha: se le reserva
   su altura para que ningún hecho quede nunca debajo, y se separa del borde
   para que se lea como barra de acción y no como dos tarjetas superpuestas. */
.columna-hechos { padding-bottom: 96px; }

.visor { display: flex; flex-direction: column; }
.visor-barra {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--borde);
  background: var(--superficie-suave);
  border-radius: var(--radio-tarjeta) var(--radio-tarjeta) 0 0;
  font-size: 0.78125rem; color: var(--texto-suave);
}
.visor-barra .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.visor-lienzo {
  padding: 22px;
  background: #eceef1;
  display: flex; justify-content: center;
  /* Con el documento ampliado (ciclo 42) el papel es más ancho que la mesa: el
     lienzo desplaza en vez de recortar, y deja de centrar para que el borde
     izquierdo siga siendo alcanzable —un centrado con desbordamiento esconde
     ese lado en cualquier navegador—. */
  overflow: auto;
}
.visor-lienzo--ampliado { justify-content: flex-start; }

/* El original ANCLADO mientras se recorren los hechos (§4: se decide junto al
   documento). Con nueve hechos, el papel y la tarjeta no caben en la misma
   pantalla si ambos desplazan la página: el panel se queda fijo bajo la topbar
   y el lienzo desplaza solo el documento, de forma que el fragmento resaltado y
   el hecho al que pertenece pueden verse a la vez. En una columna (≤1180 px) no
   se ancla nada: el papel va encima de la lista, como antes. */
@media (min-width: 73.8125em) {
  .lado-a-lado > .visor {
    position: sticky; top: calc(var(--alto-cabecera-total) + 0.75rem);
    max-height: calc(100vh - var(--alto-cabecera-total) - 2.25rem);
  }
  .lado-a-lado > .visor > .visor-lienzo { overflow: auto; min-height: 0; }
}

/* El "papel": documento escaneado recreado en HTML/CSS (analítica impresa u
   hoja de enfermería manuscrita).
   ⚠️ EXCEPCIÓN DELIBERADA AL SISTEMA DE DISEÑO: los colores de este bloque
   (#eceef1 de mesa, #fdfcf8 de papel, tintas #1f2937/#4b5563/#d1d5db, y la
   tinta de bolígrafo #26406b del manuscrito) NO son tokens ni deben serlo —
   imitan un documento ajeno a la aplicación. Que se distinga del resto de la
   interfaz es justamente el objetivo: a la izquierda está el original, a la
   derecha lo que el sistema propone. */
.papel {
  position: relative;
  width: 100%; max-width: 460px;
  padding: 26px 28px 30px;
  background: #fdfcf8;
  color: #1f2937;
  box-shadow: 0 1px 1px rgb(16 24 40 / .10), 0 10px 26px rgb(16 24 40 / .12);
  /* EL TAMAÑO DE LECTURA DEL DOCUMENTO (ciclo 42). `--papel-zoom` lo pone el
     control del visor (`validacion.js`) y AQUÍ es donde agranda de verdad: la
     escala entra en el MISMO `transform` que el giro del escaneo —dos reglas
     `transform` sobre el mismo elemento se pisan, y el giro es distinto en el
     impreso y en el manuscrito, así que el giro va en su propia variable—.
     Se escala el papel entero, no su tipografía: lo que crece es el documento
     tal cual, con sus proporciones, que es lo que hace un zoom de visor.
     El origen es la esquina superior izquierda para que lo que se sale caiga
     hacia donde el lienzo puede desplazarse; con el origen en el centro, el
     borde izquierdo quedaría fuera de alcance. */
  --papel-zoom: 1;
  --papel-giro: -.3deg;
  transform: rotate(var(--papel-giro)) scale(var(--papel-zoom));
  transform-origin: top left;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
  font-size: 0.6875rem; line-height: 1.5;
}
.papel::after {                     /* sombreado de escaneo + grano */
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(100deg, rgb(0 0 0 / .07) 0%, rgb(0 0 0 / 0) 14%, rgb(0 0 0 / 0) 86%, rgb(0 0 0 / .06) 100%),
    repeating-linear-gradient(96deg, rgb(0 0 0 / .012) 0 2px, rgb(0 0 0 / 0) 2px 5px);
  mix-blend-mode: multiply;
}
.papel-cab { text-align: center; border-bottom: 2px solid #1f2937; padding-bottom: 8px; }
.papel-lab { font-size: 0.8125rem; font-weight: 700; letter-spacing: .08em; }
.papel-lab2 { font-size: 0.625rem; color: #4b5563; letter-spacing: .04em; }
.papel-datos { display: flex; flex-wrap: wrap; gap: 2px 18px; padding: 10px 0; border-bottom: 1px dashed #9ca3af; font-size: 0.65625rem; }
.papel-datos div { flex: 1 1 100%; }
.papel-bloque { padding-top: 12px; }
.papel-bloque h4 { font-size: 0.65625rem; letter-spacing: .1em; color: #1f2937; font-weight: 700; padding-bottom: 4px; border-bottom: 1px solid #d1d5db; font-family: inherit; }
.papel-tabla { width: 100%; border-collapse: collapse; font-size: 0.65625rem; }
.papel-tabla td { padding: 4px 2px; border-bottom: 1px dotted #d1d5db; vertical-align: baseline; }
.papel-tabla .p-res { text-align: right; font-weight: 700; white-space: nowrap; }
.papel-tabla .p-uni { color: #4b5563; padding-left: 8px; white-space: nowrap; }
.papel-tabla .p-ran { color: #4b5563; text-align: right; white-space: nowrap; }
.papel-tabla .p-marca { width: 10px; color: #1f2937; font-weight: 700; }
.papel-pie { padding-top: 14px; font-size: 0.59375rem; color: #4b5563; border-top: 1px solid #d1d5db; margin-top: 12px; }
.papel-firma { padding-top: 16px; font-size: 0.625rem; color: #374151; }
.papel-firma .linea { margin-top: 14px; border-top: 1px solid #9ca3af; width: 150px; }
.papel-sello {
  position: absolute; right: 16px; bottom: 44px;
  transform: rotate(-9deg);
  border: 2px solid #6b7280; color: #6b7280;
  padding: 4px 8px; border-radius: 4px;
  font-size: 0.5625rem; font-weight: 700; letter-spacing: .1em;
  opacity: .65; text-align: center; line-height: 1.3;
}
.papel-borroso { filter: blur(.7px); opacity: .75; letter-spacing: .04em; }

/* fila resaltada = fragmento de origen del hecho seleccionado */
.papel-tabla tr.frag { transition: background .15s ease; }
.papel-tabla tr.frag.resaltado td {
  background: var(--ambar-suave);
  box-shadow: inset 0 0 0 1px var(--ambar-borde);
}

/* ---------------------------------------------------------------------------
   HOJA MANUSCRITA (§10.3, §10.4): formulario impreso relleno a mano.
   El papel se distingue del impreso en tres cosas, y las tres son las que hacen
   difícil la lectura automática: la RE JILLA del formulario, la LETRA ligada
   (familia cursiva del sistema, con inclinación y desplazamiento por línea) y
   los ACCIDENTES del original — una cifra escrita encima de otra tachada y una
   casilla cubierta por un borrón de tinta. Nada de esto decora: es el techo del
   reconocimiento de manuscrito, puesto donde se pueda ver.
   --------------------------------------------------------------------------- */
.papel--manuscrito {
  background:
    /* rejilla tenue del formulario impreso */
    repeating-linear-gradient(#fdfcf8 0 21px, #e7e3d8 21px 22px),
    #fdfcf8;
  --papel-giro: .45deg;                /* al escanear, la hoja nunca entra recta */
}
.papel--manuscrito .papel-cab { border-bottom-width: 1px; }
.papel-tabla--rejilla td { border-bottom: 1px solid #ddd8c9; padding: 6px 2px 3px; }
.papel-tabla--rejilla .p-eti {
  width: 42%; font-size: 0.59375rem; letter-spacing: .04em; color: #4b5563;
  text-transform: uppercase; vertical-align: bottom;
}
.papel-tabla--rejilla .p-val { vertical-align: bottom; }
.papel-tabla--rejilla .p-uni { vertical-align: bottom; width: 14%; }

/* La «letra» (c99): Caveat, fuente de escritura RÁPIDA e informal (OFL 1.1,
   fuentes/OFL-Caveat.txt al lado, como manda la licencia). La pila anterior
   abría con Snell Roundhand —caligrafía inglesa formal— y una hoja de
   enfermería no se rellena a plumilla: la elegancia era el delator. La pila
   del sistema queda de fallback. */
@font-face {
  font-family: 'Caveat';
  src: url('fuentes/Caveat-variable.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
.mano {
  font-family: 'Caveat', 'Bradley Hand', 'Segoe Script', 'Comic Sans MS', cursive;
  color: #26406b;
  font-size: 1.05rem; line-height: 1.2;
  display: inline-block;
  transform: rotate(-1.1deg);
}

/* Grano de escaneo (c99, contrato del c98): SOLO en las vistas de papel cuyo
   documento DECLARA escaneo (la clase la pone el visor derivándola del tipo
   declarado — nunca a mano). Es un filtro feTurbulence en un SVG de datos:
   código, no imagen. Los informes «PDF digital» van limpios a propósito:
   darles grano sería el delator inverso. Bajo `print` no se imprime (el papel
   real no lleva el ruido de su propia copia). */
@media screen {
  .papel--escaneado { position: relative; }
  .papel--escaneado::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='280' height='280'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='280' height='280' filter='url(%23g)'/></svg>");
    background-size: 280px 280px;
    opacity: 0.10; mix-blend-mode: multiply;
  }
}
.mano-marca { margin-right: 6px; font-weight: 700; transform: rotate(-8deg); }
.mano-linea { margin: 3px 0; transform: rotate(-.7deg); }
.mano-linea:nth-child(odd) { transform: rotate(.5deg) translateX(2px); }
.mano-firma { margin-top: -6px; font-size: 1rem; opacity: .85; }
.papel-libre { cursor: pointer; padding-bottom: 4px; }

/* Cifra corregida sobre la propia hoja: se conserva tachada (el original no se
   altera nunca, §3.2). */
.papel-tachon { position: relative; margin-right: 8px; opacity: .75; }
.papel-tachon::after {
  content: ''; position: absolute; left: -2px; right: -2px; top: 52%;
  border-top: 1.5px solid #26406b; transform: rotate(-4deg);
}

/* Zona ILEGIBLE: borrón de tinta. Va con `aria-hidden` y su explicación en
   texto para lector de pantalla: un aviso solo visual no existe para quien no
   lo ve, y aquí lo que se anuncia es que hay que transcribir a mano. */
.papel-mancha {
  display: inline-block; width: 62px; height: 16px; vertical-align: middle;
  border-radius: 46% 58% 52% 44% / 62% 44% 58% 40%;
  background:
    radial-gradient(closest-side at 34% 52%, rgb(38 64 107 / .92) 0 46%, rgb(38 64 107 / .5) 70%, rgb(38 64 107 / .12) 88%, transparent 100%),
    radial-gradient(closest-side at 74% 46%, rgb(38 64 107 / .8) 0 38%, rgb(38 64 107 / .35) 72%, transparent 100%);
  filter: blur(1.1px);
  transform: rotate(-2deg);
}

/* Fragmento resaltado en la hoja manuscrita (filas de rejilla y texto libre). */
.papel--manuscrito .frag { transition: background .15s ease; }
.papel--manuscrito .papel-tabla--rejilla tr.frag.resaltado td,
.papel--manuscrito .papel-libre.frag.resaltado,
.papel--manuscrito .papel-firma--frag.resaltado {
  background: var(--ambar-suave);
  box-shadow: inset 0 0 0 1px var(--ambar-borde);
}

/* FIRMA DEL PROFESIONAL (§10.3, ciclo 39). Era una rúbrica decorativa y ahora es
   un fragmento del papel con su hecho: la rúbrica va escrita a mano sobre la
   línea impresa y debajo queda el rótulo del formulario. `--parcial` es el trazo
   que el reconocimiento no resuelve del todo: se difumina un poco, como el
   escaneo, y lo que se dice de él vive en el hecho, no en un color. */
.papel-firma--frag { cursor: pointer; display: block; padding-bottom: 4px; }
.papel-firma-eti { display: block; font-size: 0.5625rem; letter-spacing: .06em; color: #4b5563; }
.papel-firma .mano-firma { display: inline-block; transform: rotate(-2.2deg); }
.mano-firma--parcial { filter: blur(.35px); opacity: .9; letter-spacing: .01em; }
/* Firma NO manuscrita (formulario impreso o cumplimentado a máquina): el mismo
   dato `mano` que gobierna las casillas gobierna la rúbrica, así que la pantalla
   tiene dónde caer cuando no hay trazo que imitar. */
.papel-firma-nombre { display: inline-block; font-weight: 600; }

/* DIVERGENCIA DENTRO DEL DOCUMENTO (§8.6): la casilla y lo que resume no dicen lo
   mismo. Se enseña donde está escrita, con texto y no solo con color, y sin
   proponer cuál vale: la marca solo dice «aquí hay dos lecturas». */
.papel-divergencia {
  display: block; margin-top: 2px;
  font-family: 'InterVariable', Inter, sans-serif; font-size: 0.5625rem; line-height: 1.35;
  color: #92400e;
}
.papel-divergencia .ico { vertical-align: -2px; }

/* Cuadro de los DOCE atributos de §10.3: qué campo de la hoja cumple cada uno. */
.tabla-atributos th[scope="row"] { vertical-align: top; }
.tabla-atributos .at-eti { display: block; font-weight: 700; }
.tabla-atributos .nota-pie { display: block; margin: 2px 0 0; font-weight: 400; white-space: normal; }
.tabla-atributos td { vertical-align: top; }
.at-campo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 4px; }
.at-campo:last-child { margin-bottom: 0; }
.at-sin-lectura { color: var(--texto-suave); font-style: italic; }
.at-ausente { display: inline-flex; align-items: center; gap: 6px; color: var(--texto-suave); }

/* ---------------------------------------------------------------------------
   ZONA DE ARRASTRE (§10.4). Maqueta VISUAL del paso de entrada: no sube nada,
   y por eso el botón va inhabilitado y la nota lo dice. El borde discontinuo es
   la convención del oficio para «suelta aquí»; el aspecto no promete proceso.
   --------------------------------------------------------------------------- */
.zona-arrastre {
  border: 2px dashed var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
  padding: 22px 18px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: var(--texto-suave);
}
.zona-arrastre .ico { color: var(--texto-mudo); }
.zona-arrastre-titulo { margin: 2px 0 0; font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }
.zona-arrastre-detalle { margin: 0; font-size: 0.8125rem; max-width: 46ch; }
.zona-arrastre .boton { margin-top: 8px; }

/* Los cinco pasos del flujo de §10.4, como recorrido y no como promesa. */
.pasos-flujo { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 8px; }
.pasos-flujo li {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 0.8125rem; color: var(--texto);
}
/* El número del paso es TEXTO dentro de una caja redonda: sus dos medidas van en
   rem (mínimos, no alturas clavadas) para que la caja crezca con la cifra en vez
   de recortarla al subir la letra. */
.paso-n {
  flex: 0 0 auto; min-width: 1.25rem; min-height: 1.25rem; border-radius: var(--radio-pill);
  background: var(--superficie-suave); border: 1px solid var(--borde);
  font-size: 0.6875rem; font-weight: 700; color: var(--texto-suave);
  display: inline-flex; align-items: center; justify-content: center;
}

/* Aviso del techo del manuscrito, dentro de la barra de confianza. Sangra hasta
   los bordes de la barra (compensa su padding) para leerse como una franja y no
   como un párrafo suelto. */
.bc-fila--techo {
  align-items: flex-start;
  background: var(--ambar-tenue);
  border-top: 1px solid var(--borde);
  margin: 9px -16px -11px; padding: 10px 16px;
  font-size: 0.78125rem; line-height: 1.5;
}
.bc-fila--techo .ico { color: var(--ambar-icono); flex: 0 0 auto; margin-top: 2px; }

/* panel de hechos extraídos */
.hecho-tarjeta {
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie);
  display: flex; flex-direction: column;
}
.hecho-tarjeta + .hecho-tarjeta { margin-top: 12px; }
.hecho-tarjeta.seleccionada { border-color: var(--azul); box-shadow: 0 0 0 3px var(--azul-suave); }
.hecho-tarjeta.resuelta--validado { border-left: 3px solid var(--verde); }
.hecho-tarjeta.resuelta--corregido { border-left: 3px solid var(--azul); }
.hecho-tarjeta.resuelta--rechazado { border-left: 3px solid var(--borde-fuerte); background: var(--superficie-suave); }
.hecho-tarjeta.resuelta--rechazado .hecho-campos { opacity: .55; }
.hecho-cab { display: flex; align-items: center; gap: 8px; padding: 11px 14px; border-bottom: 1px solid var(--borde); flex-wrap: wrap; }
.hecho-nombre { font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.hecho-cab .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
/* align-items:end evita que un rótulo de dos líneas descuelgue su campo. */
.hecho-campos { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; padding: 12px 14px; align-items: end; }
.hecho-literal { padding: 0 14px 12px; }
.hecho-extra { padding: 0 14px 12px; display: flex; flex-direction: column; gap: 8px; }
.hecho-acciones { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--borde); background: var(--superficie-suave); border-radius: 0 0 var(--radio-caja) var(--radio-caja); flex-wrap: wrap; }
.hecho-acciones .der { margin-left: auto; }
.panel-fusion { padding: 12px 14px; border-top: 1px dashed var(--borde-fuerte); background: var(--violeta-suave); display: none; flex-direction: column; gap: 10px; }
.panel-fusion.abierto { display: flex; }

/* Corrección a mano: lo teclado es un BORRADOR hasta que se pulsa guardar, y
   el panel enseña el «valor del OCR → nuevo» de §14.2 antes de registrar nada.
   El azul es el mismo tono con el que la maqueta marca «Corregido», no una
   valoración del dato. */
.panel-correccion {
  padding: 12px 14px; border-top: 1px dashed var(--azul-borde);
  background: var(--azul-suave);
  display: flex; flex-direction: column; gap: 10px;
}

.barra-cierre {
  position: sticky; bottom: 16px; z-index: 5;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 16px;
  padding: 14px 18px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-tarjeta);
  box-shadow: var(--sombra-flotante);
}
.barra-cierre .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; row-gap: 8px; justify-content: flex-end; }

/* ----------------------------------------------------------------- modal -- */

.modal {
  position: fixed; inset: 0; z-index: 100;
  display: none; align-items: center; justify-content: center;
  padding: 24px;
  background: rgb(17 24 39 / .38);
}
.modal.abierto { display: flex; }
.modal-caja {
  width: min(620px, 100%); max-height: 84vh; overflow: auto;
  background: var(--superficie);
  border-radius: var(--radio-tarjeta);
  box-shadow: var(--sombra-flotante);
}
.modal-cab { display: flex; align-items: flex-start; gap: 12px; padding: 18px; border-bottom: 1px solid var(--borde); }
.modal-cab .txt { min-width: 0; }
.modal-titulo { font-size: 1rem; }
.modal-cuerpo { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.modal-pie { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--borde); background: var(--superficie-suave); border-radius: 0 0 var(--radio-tarjeta) var(--radio-tarjeta); }
.modal-pie .der { margin-left: auto; }
.datos-fuente { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 8px 14px; font-size: 0.8125rem; }
.datos-fuente dt { color: var(--texto-mudo); font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; padding-top: 2px; }
.datos-fuente dd { margin: 0; color: var(--texto); word-break: break-word; }
/* Relación de versión en el visor común: una línea por emisión, para que el
   estado de la otra emisión no se lea pegado al resto de la frase. Sin color de
   juicio: no hay una emisión buena y otra mala. */
.datos-fuente .linea-version { display: block; }
.datos-fuente .linea-version + .linea-version { margin-top: 3px; }
/* El señalamiento del par, igual: una línea con el hecho y otra con el otro
   documento, que se abre. Tinta de dato, sin tono de juicio. */
.datos-fuente .linea-senal { display: block; }
.datos-fuente .linea-senal-otro {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 5px;
  font-size: 0.75rem; color: var(--texto-suave);
}

/* ------------------------------------------ confianza del reconocimiento -- */
/* Cifra del SISTEMA sobre su propia lectura (idea 5 del ciclo 1). El ámbar
   marca «revisión ineludible» = atención del sistema, nunca una valoración
   del paciente; y nunca va solo el color: siempre lleva cifra y pill.       */

.barra-confianza {
  display: flex; flex-direction: column; gap: 10px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--borde);
  background: var(--superficie-suave);
  font-size: 0.78125rem; color: var(--texto-suave);
}
.bc-fila { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.bc-fila .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.atajo {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; font-size: 0.71875rem; color: var(--texto-suave);
  background: var(--superficie); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-pill); white-space: nowrap;
}
.confianza { display: inline-flex; align-items: center; gap: 7px; font-size: 0.71875rem; color: var(--texto-suave); }
.confianza-cifra { font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }
.confianza-barra {
  width: 54px; height: 6px; flex: 0 0 54px;
  background: var(--gris-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-pill); overflow: hidden;
}
.confianza-barra i { display: block; height: 100%; background: var(--texto-suave); }
.confianza--baja .confianza-barra i { background: var(--ambar); }
.confianza--baja .confianza-cifra { color: var(--ambar-texto); }
.hecho-tarjeta.ineludible { border-color: var(--ambar-borde); }
.hecho-tarjeta.ineludible > .hecho-cab { background: var(--ambar-tenue); }

/* ------------------------------------- adjudicación de contradicciones --- */
/* El rojo suave de la cabecera es estado del SISTEMA (contradicción). Las
   cuatro salidas van SIN color: ninguna se presenta como la correcta.       */

.adj-caras { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
.adj-cara {
  border: 1px solid var(--borde); border-radius: var(--radio-tarjeta);
  background: var(--superficie); box-shadow: var(--sombra-tarjeta);
  display: flex; flex-direction: column;
}
.adj-cara-cab {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid var(--borde);
  background: var(--superficie-suave);
  border-radius: var(--radio-tarjeta) var(--radio-tarjeta) 0 0;
}
.adj-cara-letra {
  width: 24px; height: 24px; flex: 0 0 24px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.75rem; font-weight: 700; color: var(--tinta);
  background: var(--superficie); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-pill);
}
.adj-cara-titulo { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }
.adj-cara-cab .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.adj-cara-cuerpo { padding: 16px; display: flex; flex-direction: column; gap: 13px; }
.adj-valor { font-size: 1.1875rem; font-weight: 700; color: var(--tinta); margin-top: 4px; }
.adj-datos { display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 7px 14px; font-size: 0.8125rem; }
.adj-datos--ancha { grid-template-columns: 168px minmax(0, 1fr); }
.adj-datos dt {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo); padding-top: 2px;
}
.adj-datos dd { margin: 0; color: var(--texto); word-break: break-word; }

.adj-fieldset { border: 0; padding: 0; margin: 0; }
.adj-salidas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.adj-salida {
  display: flex; gap: 11px; padding: 14px;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie); cursor: pointer;
}
.adj-salida:hover { background: var(--superficie-suave); }
.adj-salida:focus-within { box-shadow: 0 0 0 3px var(--azul-suave); }
.adj-salida.elegida { border-color: var(--tinta); background: var(--superficie-suave); }
.adj-salida.bloqueada { cursor: default; opacity: .78; }
.adj-salida.bloqueada.elegida { opacity: 1; }
.adj-salida input { flex: 0 0 auto; width: 16px; height: 16px; margin-top: 3px; accent-color: var(--tinta); }
.adj-salida-txt { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.adj-salida-titulo { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.adj-salida-titulo .ico { color: var(--texto-suave); }
.adj-salida-letra { font-weight: 600; color: var(--texto-suave); }
.adj-salida-detalle { font-size: 0.8125rem; color: var(--texto); }
.adj-salida-efecto { display: flex; gap: 7px; font-size: 0.75rem; color: var(--texto-suave); }
.adj-salida-efecto .ico { flex: 0 0 auto; margin-top: 2px; color: var(--texto-mudo); }
.adj-salida-estados { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding-top: 2px; }

.adj-tercero {
  margin-top: 14px; padding: 14px;
  border: 1px dashed var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.adj-tercero .campo input { max-width: 340px; }
/* El valor y su ATRIBUCIÓN (fecha clínica) se piden juntos: un dato sin fecha
   clínica no tiene sitio en la historia (§4, §14.2). */
.adj-tercero-campos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 18px; }
.adj-tercero-campos .campo select { max-width: 340px; min-height: 36px; font-size: 0.84375rem; }
.adj-cierre { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.adj-cierre .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; row-gap: 8px; justify-content: flex-end; }
.adj-cierre .nota-pie { flex: 1 1 320px; }

.adj-resultado {
  display: flex; flex-direction: column; gap: 13px;
  padding: 16px; border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja); background: var(--superficie-suave);
}
.adj-resultado-cab { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.adj-resultado-cab .ico { color: var(--texto-suave); }
.adj-resultado-cab .der { margin-left: auto; }
.adj-resultado-titulo { font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }
.adj-resultado-estados { display: flex; flex-direction: column; gap: 7px; }
.adj-resultado-pills { display: flex; flex-direction: column; gap: 6px; font-size: 0.8125rem; color: var(--texto); }
.adj-resultado-pills span { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }

/* Cotejo del posible duplicado (§3.2, §4.1). Las frases de la especificación se
   presentan como CITAS —no como opciones—: sin casilla, sin borde de control y
   sin ningún tono que sugiera que una es preferible a otra.                  */
.dup-citas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* ------------------------------------------------ pasarela Chi Pro (§7) --- */
/* El color aquí solo distingue ESTADOS DEL SISTEMA (validado / pendiente,
   confirmada / fallida / duplicada). Ninguna casilla de selección lleva color:
   la elección es del profesional y el sistema no empuja hacia ninguna.       */

.cp-columna { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

.cp-flujo { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--borde); }
.cp-pasos {
  margin: 8px 0 0; padding-left: 22px;
  display: flex; flex-direction: column; gap: 5px;
  font-size: 0.8125rem; color: var(--texto);
}
.cp-pasos li::marker { color: var(--texto-mudo); font-variant-numeric: tabular-nums; }

.cp-elementos { display: flex; flex-direction: column; gap: 12px; }
.cp-elemento {
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie); overflow: hidden;
}
.cp-elemento.elegido { border-color: var(--tinta); }
/* Sin validar: se ve, se explica y no hay casilla ninguna (§7.2). */
.cp-elemento.bloqueado { border-style: dashed; border-color: var(--borde-fuerte); background: var(--superficie-suave); }
.cp-elemento-cab {
  display: flex; align-items: flex-start; gap: 11px; flex-wrap: wrap;
  padding: 12px 14px; border-bottom: 1px solid var(--borde);
  background: var(--superficie-suave);
}
.cp-elemento.elegido > .cp-elemento-cab { background: var(--superficie); }
label.cp-elemento-cab { cursor: pointer; }
label.cp-elemento-cab:hover { background: var(--gris-suave); }
.cp-elemento-cab input { flex: 0 0 auto; width: 17px; height: 17px; margin-top: 2px; accent-color: var(--tinta); }
.cp-elemento-cab:focus-within { box-shadow: inset 0 0 0 3px var(--azul-suave); }
.cp-elemento-cab .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.cp-elemento-candado { flex: 0 0 auto; margin-top: 2px; color: var(--texto-mudo); }
.cp-elemento-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cp-elemento-titulo { font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.cp-elemento-meta { font-size: 0.71875rem; color: var(--texto-mudo); }
.cp-elemento-cuerpo { padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.cp-elemento-pie { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cp-elemento-pie .nota-pie { flex: 1 1 240px; }

.cp-no-cruza, .cp-vias, .cp-versiones, .cp-lista-ausentes { list-style: none; margin: 0; padding: 0; }
.cp-no-cruza { display: flex; flex-direction: column; gap: 10px; }
.cp-no-cruza li { display: flex; gap: 9px; font-size: 0.8125rem; color: var(--texto); }
.cp-no-cruza li .ico { flex: 0 0 auto; margin-top: 2px; color: var(--texto-mudo); }
.cp-no-cruza li span span { display: block; }

.cp-vias { display: flex; flex-direction: column; gap: 10px; font-size: 0.8125rem; color: var(--texto); }
.cp-vias li { padding-left: 12px; border-left: 2px solid var(--borde-fuerte); }
.cp-vias li .nota-pie { display: block; margin: 2px 0 0; }

/* SELLO del documento: identifica lo que cruza (paciente, clave, versión y
   fecha) y NO se edita, para que la versión que declara el documento sea la
   misma que se registra (§7.6). */
.cp-sello {
  display: flex; flex-direction: column; gap: 7px;
  margin-bottom: 14px; padding: 12px 14px;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.cp-sello-texto {
  margin: 0; white-space: pre-wrap; word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78125rem; line-height: 1.55; color: var(--tinta);
}

.cp-campo-texto textarea {
  width: 100%; min-height: 300px; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78125rem; line-height: 1.55; color: var(--texto);
}
.cp-texto-pie { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.cp-texto-pie .der { margin-left: auto; }
.cp-texto-pie .nota-pie { flex: 1 1 300px; }

/* El texto revisado a mano dejó de corresponder a la selección: mientras esto
   se vea, la pantalla no transfiere. El ámbar avisa; no juzga a nadie. */
.cp-divergencia { margin-top: 12px; }
.cp-lista-divergencia {
  list-style: none; margin: 9px 0 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
  font-size: 0.78125rem; color: inherit;
}
.cp-lista-divergencia li { display: flex; gap: 9px; align-items: baseline; }
.cp-lista-divergencia .num { flex: 0 0 auto; color: var(--texto-mudo); }

.cp-ausentes {
  margin-top: 14px; padding: 12px 14px;
  border: 1px dashed var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.cp-lista-ausentes { display: flex; flex-direction: column; gap: 4px; font-size: 0.78125rem; color: var(--texto-suave); }
.cp-lista-ausentes li::before { content: '—'; color: var(--texto-mudo); margin-right: 7px; }

/* Emparejamiento: dos lados y la CLAVE en medio. La clave es el número de
   historia; el nombre queda debajo, como dato para el ojo humano (§7.6). */
.cp-emparejamiento {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 14px; align-items: center;
}
.cp-lado {
  display: flex; flex-direction: column; gap: 5px;
  padding: 14px; border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.cp-lado-valor { font-size: 1.1875rem; font-weight: 700; color: var(--tinta); }
.cp-clave {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 0 6px; font-size: 0.6875rem; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--texto-mudo); text-align: center;
}
.cp-clave .ico { color: var(--texto-suave); }

.cp-verificacion {
  display: flex; align-items: flex-start; gap: 10px; margin-top: 14px;
  padding: 13px 14px; font-size: 0.84375rem; color: var(--tinta); cursor: pointer;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.cp-verificacion:hover { background: var(--gris-suave); }
/* Sin clave coincidente no hay nada legítimo que verificar (§7.6). */
.cp-verificacion.bloqueado { cursor: not-allowed; color: var(--texto-mudo); border-style: dashed; }
.cp-verificacion.bloqueado:hover { background: var(--superficie-suave); }
.cp-verificacion:focus-within { box-shadow: 0 0 0 3px var(--azul-suave); }
.cp-verificacion input { width: 17px; height: 17px; margin-top: 1px; accent-color: var(--tinta); }

/* Control que NO existe en la aplicación real: se marca con el mismo lenguaje
   del banner de maqueta, para que nadie lo lea como una función del producto. */
.cp-simulacion {
  padding: 14px; border: 1px dashed var(--ambar-borde); border-radius: var(--radio-caja);
  background: var(--ambar-tenue);
}
.cp-simulacion-cab { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cp-simulacion-cab .ico { color: var(--ambar-icono); }
.cp-simulacion-aviso {
  font-size: 0.6875rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ambar-hondo);
}
.cp-simulacion .campo select { max-width: 420px; min-height: 36px; font-size: 0.84375rem; }

.cp-cierre { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.cp-cierre .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; row-gap: 8px; justify-content: flex-end; }
.cp-cierre .nota-pie { flex: 1 1 300px; }

.cp-resultado {
  display: flex; flex-direction: column; gap: 13px;
  padding: 16px; border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja); background: var(--superficie-suave);
}
.cp-resultado--verde { border-color: var(--verde-borde); background: var(--verde-suave); }
.cp-resultado--rojo { border-color: var(--rojo-borde); background: var(--rojo-suave); }
.cp-resultado--violeta { border-color: var(--violeta-borde); background: var(--violeta-suave); }
.cp-resultado .aviso { background: var(--superficie); }
.cp-resultado-cab { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.cp-resultado-cab .ico { color: var(--texto-suave); }
.cp-resultado-cab .der { margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; row-gap: 6px; justify-content: flex-end; }
.cp-resultado-titulo { font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }
.cp-resultado--verde .cp-resultado-cab .ico { color: var(--verde-hondo); }
.cp-resultado--rojo .cp-resultado-cab .ico { color: var(--rojo-icono); }
.cp-resultado--violeta .cp-resultado-cab .ico { color: var(--violeta-icono); }

.cp-versiones { display: flex; flex-direction: column; gap: 10px; }
.cp-version {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie);
}
.cp-version--curso { border-style: dashed; border-color: var(--borde-fuerte); background: var(--superficie-suave); }
.cp-version-num {
  flex: 0 0 auto; min-width: 34px; text-align: center;
  padding: 3px 8px; font-size: 0.75rem; font-weight: 700; color: var(--tinta);
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-pill);
}
.cp-version--curso .cp-version-num { background: var(--superficie); }
.cp-version-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cp-version-titulo { font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.cp-version-elementos { font-size: 0.71875rem; color: var(--texto-suave); }
.cp-version .der { margin-left: auto; }

/* ==========================================================================
   BUSCADOR FACTUAL (§13) — la consulta, su interpretación y las filas de hechos
   La interpretación se ve: los chips de filtro son la traducción de la frase a
   filtros estructurados, y el término literal que no se ha traducido va con
   otro fondo para que se distinga de un filtro aplicado.
   ========================================================================== */

.bs-forma { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.bs-campo {
  display: flex; align-items: center; gap: 9px;
  flex: 1 1 380px; min-width: 220px; padding: 8px 16px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  color: var(--texto-mudo);
}
.bs-campo:focus-within { border-color: var(--azul); box-shadow: 0 0 0 3px var(--azul-suave); }
.bs-campo input {
  border: 0; background: transparent; outline: none; min-height: 26px;
  width: 100%; font-size: 0.875rem; color: var(--texto); font-family: inherit;
}
.bs-campo input::placeholder { color: var(--texto-mudo); }

.bs-inicio {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 16px; padding: 14px 16px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.bs-inicio-titulo { font-size: 0.875rem; font-weight: 600; color: var(--tinta); }

.bs-interpretacion {
  display: flex; flex-direction: column; gap: 9px;
  margin-top: 16px; padding: 14px 16px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.bs-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.bs-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-pill);
  font-size: 0.75rem;
}
.bs-chip-clave { color: var(--texto-mudo); text-transform: uppercase; letter-spacing: .05em; font-size: 0.65625rem; font-weight: 600; }
.bs-chip-valor { color: var(--tinta); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Lo que el buscador NO ha traducido a filtro: se ve distinto de un filtro. */
.bs-chip--literal { background: var(--ambar-tenue); border-color: var(--ambar-borde); border-style: dashed; }
.bs-chip--literal .bs-chip-valor { color: var(--ambar-texto); }

.bs-hecho { display: block; font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.bs-meta { display: block; margin-top: 3px; font-size: 0.75rem; color: var(--texto-suave); }
.bs-carril { display: inline-flex; margin-top: 5px; }
.bs-rango { display: inline-flex; margin-left: 6px; }
.bs-notas { display: block; margin-top: 10px; }
.bs-notas .nota-pie { display: block; margin-top: 5px; }
/* El texto literal es un BLOQUE dentro de la celda: en línea, su caja se
   monta encima de la línea de meta y la marca «Texto del documento» cae sobre
   lo que viene después. */
#tabla-filas td .cita { display: block; margin: 8px 0 0; font-size: 0.78125rem; }
#tabla-filas td .nota-pie { display: block; margin-top: 6px; }
#tabla-filas td { vertical-align: top; }
#tabla-filas td:first-child { padding-top: 16px; }
#tabla-filas { table-layout: fixed; }
#tabla-filas td { overflow-wrap: break-word; }
#tabla-filas td:last-child .fuente { white-space: normal; text-align: left; max-width: 100%; }
#tabla-filas th:nth-child(1) { width: 6.875rem; }
#tabla-filas th:nth-child(2) { width: auto; }
/* La columna del estado tiene que caber las pills más largas del catálogo
   («Discrepancia entre documentos», «Fuera del rango de origen»): con
   `table-layout: fixed` lo que no cabe NO se recorta, se sale y se monta sobre
   el chip del documento de al lado. Se le da ancho suficiente y, además, la
   celda apila sus pills en cuanto no caben en una línea. */
#tabla-filas th:nth-child(3) { width: 14.5rem; }
#tabla-filas th:nth-child(4) { width: 12.25rem; }
#tabla-filas td.bs-celda-estado {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px;
}
#tabla-filas td.bs-celda-estado .bs-rango { margin-left: 0; }

.bs-disponibles { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; padding: 0; list-style: none; }
.bs-ejemplo {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 34px; padding: 6px 12px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-pill);
  font-size: 0.78125rem; font-weight: 600; color: var(--texto); font-family: inherit;
  cursor: pointer;
}
.bs-ejemplo:hover { background: var(--azul-suave); border-color: var(--azul-borde); color: var(--azul-texto); }

.bs-catalogo { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.bs-consulta {
  display: flex; flex-direction: column; gap: 9px;
  padding: 14px 16px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.bs-consulta-titulo { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }
.bs-consulta-ejemplos { display: flex; flex-wrap: wrap; gap: 8px; }

/* ==========================================================================
   VISTA DE AUDITORÍA (§6.4) — quién, cuándo, qué, valor anterior → nuevo
   El valor anterior no se tacha ni se pinta de rojo: no es un error, es lo que
   la historia decía antes y se conserva (§14.2).
   ========================================================================== */

.au-cobertura { margin-top: 16px; }
.au-tipos {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 10px; margin: 10px 0 0; padding: 0; list-style: none;
}
.au-tipos li {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}

/* Prestador, vocabularios cerrados y cita del anexo II (ciclo 51).
   Sin un solo color de estado: identificar quién entró, decir a qué categoría de
   datos llegó y de dónde venía el dato no es valorar nada (§6.4, §1.2). */
.au-prestador { margin: 8px 0 0; font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.au-vocabulario {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 10px; margin: 10px 0 0; padding: 0; list-style: none;
}
.au-vocabulario li {
  display: flex; flex-direction: column; gap: 3px;
  padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.au-voc-termino { font-size: 0.8125rem; font-weight: 700; color: var(--tinta); }

.au-norma-cabeza { margin: 8px 0 12px; font-size: 0.8125rem; font-weight: 600; color: var(--tinta); }
.au-norma-punto { margin-bottom: 12px; }
.au-letras { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 0; padding: 0; list-style: none; }
.au-letras li {
  display: grid; grid-template-columns: 2rem minmax(0, 1fr); gap: 4px 10px;
  padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.au-letra { font-size: 0.8125rem; font-weight: 700; color: var(--tinta); }
.au-letra-txt { display: flex; flex-direction: column; gap: 3px; }
.au-letra-exige { font-size: 0.78125rem; color: var(--texto); }

/* Los dos campos del anexo II en una línea del registro: rótulo pequeño y valor
   legible, sin pill ni color, para que la fila no crezca a lo alto ni parezca
   que el registro clasifica en categorías «buenas» y «malas». */
.au-anexo { display: flex; flex-direction: column; gap: 4px; }
.au-anexo-par { display: flex; flex-wrap: wrap; gap: 2px 8px; align-items: baseline; }
.au-anexo-rot {
  font-size: 0.6875rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--texto-mudo);
}
.au-anexo-val { font-size: 0.78125rem; color: var(--texto); overflow-wrap: break-word; }

.au-filtro { display: flex; flex-direction: column; gap: 9px; margin-bottom: 16px; }
.au-botones { display: flex; flex-wrap: wrap; gap: 8px; }
.au-chip {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 34px; padding: 5px 12px;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio-pill);
  font-size: 0.78125rem; font-weight: 600; color: var(--texto-suave); font-family: inherit;
  cursor: pointer;
}
.au-chip:hover { background: var(--superficie-suave); color: var(--tinta); }
.au-chip[aria-pressed='true'] {
  background: var(--tinta); border-color: var(--tinta); color: #fff;
}
.au-chip[aria-pressed='true'] .au-chip-n { background: var(--superficie); color: var(--tinta); }
.au-chip-n {
  padding: 1px 7px; border-radius: var(--radio-pill);
  background: var(--superficie-suave); color: var(--texto-mudo);
  font-size: 0.6875rem; font-variant-numeric: tabular-nums;
}
/* «sin líneas» en palabras, no un 0 pelado: una historia sin accesos es una
   respuesta del informe, y un cero se lee como si faltara el dato. */
.au-chip-n--cero { font-variant-numeric: normal; font-style: italic; }
.au-chip .avatar { width: 22px; height: 22px; font-size: 0.59375rem; }

.au-actor { display: flex; align-items: center; gap: 9px; }
.au-actor .avatar { width: 30px; height: 30px; font-size: 0.6875rem; flex: 0 0 auto; }
.au-actor-txt { display: flex; flex-direction: column; gap: 1px; }
.au-actor-nombre { font-size: 0.8125rem; font-weight: 600; color: var(--tinta); }

.au-que { display: flex; flex-direction: column; gap: 6px; }
.au-que .pill { align-self: flex-start; }
/* De quién es la línea, primero: el registro mezcla historias a propósito. */
.au-quien-historia { display: block; font-size: 0.8125rem; }
.au-objeto { font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.au-extras { font-size: 0.75rem; color: var(--texto-suave); }
.au-motivo {
  display: inline-flex; align-items: flex-start; gap: 6px;
  padding: 7px 10px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
  font-size: 0.78125rem; color: var(--texto);
}
.au-motivo .ico { flex: 0 0 auto; margin-top: 2px; color: var(--texto-mudo); }

.au-valores { display: flex; flex-direction: column; gap: 4px; }
.au-valor { font-size: 0.78125rem; }
.au-valor--antes { color: var(--texto-suave); }
.au-valor--despues { color: var(--tinta); font-weight: 600; }
.au-flecha { color: var(--texto-mudo); font-size: 0.75rem; }
.au-docs { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.au-docs .fuente { text-decoration: none; white-space: normal; text-align: left; max-width: 100%; }

#tabla-auditoria td { vertical-align: top; }
#tabla-auditoria td:first-child { padding-top: 18px; }
/* Anchos declarados: sin ellos la columna «Qué» —que lleva el objeto, el
   contexto y el motivo— se queda estrecha y la fila crece a lo alto, mientras
   las dos últimas columnas se quedan vacías. */
/* Reparto FIJO: con reparto automático, un chip de documento que no parte
   («Analítica completa · 24 jul 2026 · p. 1») se lleva el ancho de la fila y
   deja la columna del qué en un hilo. */
#tabla-auditoria { table-layout: fixed; }
#tabla-auditoria td { overflow-wrap: break-word; }
#tabla-auditoria th { white-space: normal; }
#tabla-auditoria th:nth-child(1) { width: 8.875rem; }
#tabla-auditoria th:nth-child(2) { width: 10.5rem; }
#tabla-auditoria th:nth-child(3) { width: 38%; }
#tabla-auditoria th:nth-child(4) { width: 21%; }
#tabla-auditoria th:nth-child(5) { width: 18%; }
.au-motivo { display: flex; }

.au-perfiles { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.au-perfil {
  display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 6px 16px;
  padding: 12px 14px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.au-perfil-nombre { font-size: 0.8125rem; font-weight: 700; color: var(--tinta); }
.au-perfil-permisos { font-size: 0.78125rem; color: var(--texto); }
.au-perfil-tipos { grid-column: 2; display: flex; flex-wrap: wrap; gap: 6px; }

/* ------------- INFORME DE ACCESOS DE UN PACIENTE (derecho de acceso, §6.4) --
   Documento que se entrega: sobrio, sin chips de color y con el pie normativo
   como parte del papel. En pantalla vive dentro de la tarjeta; al imprimir, la
   hoja de estilos deja en el papel esta sección y nada más. */
.au-informe { border-color: var(--borde-fuerte); }
.au-informe-acciones { display: flex; flex-wrap: wrap; gap: 8px; }
.au-informe-cab { margin-bottom: 14px; }
.au-informe-titulo { margin: 0; font-size: 1.0625rem; font-weight: 700; color: var(--tinta); }
.au-informe-datos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px 18px; margin: 0 0 14px;
  padding: 13px 15px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.au-informe-datos dt {
  font-size: 0.65625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo);
}
.au-informe-datos dd { margin: 3px 0 0; font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.au-informe-pie { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--borde); }
.au-informe-pie p { margin: 0 0 9px; font-size: 0.78125rem; color: var(--texto); }
#tabla-informe th:nth-child(1) { width: 9.375rem; }
#tabla-informe th:nth-child(2) { width: 13.125rem; }

/* ==========================================================================
   EL PAPEL · UN SOLO MECANISMO DE IMPRESIÓN (generalizado en el ciclo 30)
   Antes vivía aquí un `@media print` clavado a `#seccion-informe`, el id del
   informe de accesos: la segunda pantalla que quisiera papel tenía que copiar
   el bloque entero, y dos copias de la regla de qué sale por la impresora son
   dos ocasiones de que una de las dos deje de cumplirla. Ahora el mecanismo es
   de clases y sirve a cualquier pantalla:

     · `body.solo-papel`  — el cuerpo en modo papel;
     · `.hoja-papel`      — la sección imprimible, hija directa de `.lienzo`;
     · `.no-en-papel`     — lo que en pantalla es botón y en papel sería tinta
                            sin destino.

   Las dos CORRIENTES viven en el `thead` y el `tfoot` de la tabla `.papel-armazon`
   que envuelve el documento: ese es el mecanismo que el navegador pagina de
   verdad —repite las dos filas en TODAS las hojas y reserva su alto, así que no
   pisan el texto—. Medido sobre el PDF paginado en el ciclo 31: con
   `position: fixed` la cabecera se perdía en la última página, el pie en la
   primera, y ambos se imprimían encima del contenido (ver `app.js`).

   EN PANTALLA el armazón es transparente: sus filas se pintan como bloques y
   las corrientes no se ven, de modo que la hoja se lee antes de imprimirla
   exactamente igual que antes de existir la tabla.
   ========================================================================== */

.papel-corriente { display: none; }
.papel-armazon, .papel-armazon > tbody, .papel-armazon > tbody > tr,
.papel-armazon > tbody > tr > td { display: block; }
.papel-armazon > thead, .papel-armazon > tfoot { display: none; }

/* El documento en sí: sobrio, sin chips de color, con la jerarquía hecha con
   peso tipográfico. Se ve igual en pantalla (antes de imprimir) que en papel,
   que es lo que permite comprobar qué lleva antes de gastar una hoja. */
.papel-acciones { display: flex; flex-wrap: wrap; gap: 8px; }
.papel-doc { font-size: 0.84375rem; color: var(--texto); }
.papel-titulo { margin: 0; font-size: 1.0625rem; font-weight: 700; color: var(--tinta); }
.papel-coletilla { margin: 3px 0 0; font-size: 0.78125rem; color: var(--texto-suave); }
.papel-datos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px 18px; margin: 14px 0 0; padding: 13px 15px;
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.papel-datos dt {
  font-size: 0.65625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo);
}
.papel-datos dd { margin: 3px 0 0; font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.papel-bloque { margin-top: 20px; }
.papel-bloque-titulo {
  margin: 0 0 8px; padding-bottom: 5px; font-size: 0.9375rem; font-weight: 700;
  color: var(--tinta); border-bottom: 1px solid var(--borde);
}
.papel-lista { margin: 0; padding: 0; list-style: none; }
.papel-lista > li { margin: 0 0 9px; }
.papel-lista .papel-lista { margin: 4px 0 0 14px; }
.papel-fuente { display: block; font-size: 0.71875rem; color: var(--texto-suave); }
.papel-nota { margin: 8px 0 0; font-size: 0.75rem; color: var(--texto-suave); }
.papel-vacio { margin: 0; font-size: 0.78125rem; color: var(--texto-suave); }
.papel-lesion { margin: 0 0 14px; }
.papel-lesion-cab { margin: 0 0 6px; font-size: 0.84375rem; color: var(--tinta); }
.papel-cierre { margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--borde); }
.papel-excluidos { margin: 0; font-size: 0.78125rem; color: var(--texto); }
.tabla--papel { font-size: 0.78125rem; }
.tabla--papel em { font-style: normal; color: var(--texto-suave); }

@media print {
  /* El botón del modo producción jamás se imprime (es herramienta de revisión). */
  .boton-produccion { display: none !important; }

  /* Con la hoja compuesta, el papel lleva SOLO esa hoja: ni menú, ni filtros,
     ni el resto de la pantalla — sacar por la impresora líneas de otras
     historias sería exactamente lo que este documento no puede hacer. */
  body.solo-papel .barra-lateral,
  body.solo-papel .barra-superior,
  body.solo-papel .banda-paciente,
  body.solo-papel .lienzo > *:not(.hoja-papel),
  body.solo-papel .no-en-papel { display: none !important; }
  body.solo-papel .hoja-papel { border: 0; box-shadow: none; padding: 0; }
  body.solo-papel .lienzo { padding: 0; }

  /* NINGÚN COLOR JUZGA EN EL PAPEL — y ningún texto se vuelve invisible al
     imprimir sin gráficos de fondo, que es el defecto que `imagenes.js` (129)
     dejó documentado: texto blanco sobre fondo de color se convierte en texto
     blanco sobre papel blanco. Dentro de la hoja todo va en tinta sobre blanco;
     lo que distinguía por color se dice con palabras, que es como se lee en
     papel. En evolución tumoral esto es además la regla del proyecto: números y
     comparación matemática, sin color semántico. */
  body.solo-papel .hoja-papel,
  body.solo-papel .hoja-papel * {
    background: transparent !important;
    color: #111827 !important;
    /* Los BORDES también son tinta: sin esto, un chip conserva su trazo azul
       (--azul-borde) en el PDF real y la garantía de tinta única es falsa
       (hallazgo C30-1, medido sobre paciente.pdf/auditoria.pdf p.1). */
    border-color: #111827 !important;
    outline-color: #111827 !important;
  }

  /* CADA PÁGINA dice de quién es, de cuándo es y qué es. El mecanismo es el
     armazón de tabla: el navegador REPITE `thead` y `tfoot` en todas las hojas
     y les reserva sitio, que es lo que `position: fixed` no hace (se pintaba
     encima del texto y faltaba en una hoja de cada documento). */
  body.solo-papel .papel-armazon { display: table; width: 100%; border-collapse: collapse; }
  body.solo-papel .papel-armazon > thead { display: table-header-group; }
  body.solo-papel .papel-armazon > tfoot { display: table-footer-group; }
  body.solo-papel .papel-armazon > tbody { display: table-row-group; }
  body.solo-papel .papel-armazon > * > tr { display: table-row; }
  body.solo-papel .papel-armazon > * > tr > td { display: table-cell; padding: 0; }
  /* El documento entero es UNA fila: la regla general de no partir filas la
     dejaría sin poder repartirse entre páginas, y el papel saldría de una hoja. */
  body.solo-papel .papel-armazon > tbody > tr { break-inside: auto; }
  body.solo-papel .papel-armazon > thead > tr > td { padding-bottom: 5mm; }
  body.solo-papel .papel-armazon > tfoot > tr > td { padding-top: 5mm; }
  body.solo-papel .papel-corriente {
    display: flex; gap: 12px; align-items: baseline;
    font-size: 0.65625rem; color: #111827;
  }
  body.solo-papel .papel-corriente--cabecera {
    border-bottom: 1px solid #111827; padding-bottom: 2mm;
  }
  body.solo-papel .papel-corriente--pie {
    border-top: 1px solid #111827; padding-top: 2mm;
  }
  .papel-corriente .papel-hc { font-weight: 700; }
  .papel-corriente .papel-emision { margin-left: auto; }

  body { background: #fff; }
  .tabla-envoltorio { overflow: visible; }
  tr { break-inside: avoid; }
  /* Las corrientes ya no viven en el margen, sino dentro de la caja de texto
     como primera y última fila: el margen vuelve a ser solo margen. */
  @page { margin: 16mm 14mm; }
}

/* ==========================================================================
   ARCHIVO DOCUMENTAL DE NIVEL 4 (§5.4) sobre la organización de §3
   Una tarjeta por subcarpeta, plegable, con su tabla dentro. La subcarpeta
   VACÍA no se esconde: se ve apagada y dice que está vacía, porque que una
   historia no tenga ninguna fotografía es un dato. El nombre de archivo va en
   cifra tabular: es un identificador, se lee carácter a carácter.
   ========================================================================== */

.ar-datos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px 18px; margin: 0;
  padding: 13px 15px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.ar-datos dt {
  font-size: 0.65625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo);
}
.ar-datos dd { margin: 3px 0 0; font-size: 0.8125rem; font-weight: 600; color: var(--tinta); overflow-wrap: break-word; }

/* ---- filtros y búsqueda ---- */
.ar-busqueda { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ar-filtros {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 12px 16px; margin-top: 16px;
}
.ar-campo { display: flex; flex-direction: column; gap: 5px; }
.ar-campo select { width: 100%; min-height: 38px; font-size: 0.8125rem; }
/* El rango ocupa dos columnas de la retícula: sus dos campos se leen juntos
   («desde … hasta …») y apilados parecerían dos filtros distintos. */
.ar-rango {
  display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end;
  grid-column: span 2; margin: 0; padding: 0; border: 0;
}
.ar-rango legend + .ar-fecha { margin-right: 4px; }
.ar-rango legend { padding: 0; margin-bottom: 5px; }
.ar-fecha { display: flex; flex-direction: column; gap: 5px; font-size: 0.75rem; color: var(--texto-suave); }
.ar-fecha input[type='date'] {
  min-height: 38px; padding: 8px 11px;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio-control);
  font-family: inherit; font-size: 0.8125rem; color: var(--texto);
  font-variant-numeric: tabular-nums;
}
.ar-fecha input[type='date']:focus { border-color: var(--azul); box-shadow: 0 0 0 3px var(--azul-suave); outline: none; }

/* ---- una subcarpeta ---- */
.ar-carpeta { margin-bottom: 16px; }
.ar-carpeta--vacia { background: var(--superficie-suave); }
/* El cajón de las rutas que no corresponden a ninguna subcarpeta de §3.1 no es
   una carpeta: se distingue por el trazo del borde, no por color, y lo que hay
   que leer (que la ruta no corresponde) ya lo dice su aviso. */
.ar-carpeta--fuera { border-style: dashed; }
.ar-carpeta--fuera .ar-carpeta-id { font-style: italic; color: var(--texto-suave); }
.ar-toggle {
  display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 9px;
  min-width: 0; max-width: 100%;
  min-height: 2.5rem; padding: 4px 6px 4px 2px;
  background: transparent; border: 0; border-radius: var(--radio-control);
  font-family: inherit; color: var(--tinta); cursor: pointer; text-align: left;
}
.ar-toggle:hover { background: var(--superficie-suave); }
.ar-carpeta-id { font-size: 0.75rem; font-weight: 700; color: var(--texto-suave); letter-spacing: .02em; }
.ar-carpeta-nombre { font-size: 0.90625rem; font-weight: 700; color: var(--tinta); min-width: 0; overflow-wrap: break-word; }
.ar-carpeta-cuerpo[hidden] { display: none; }

/* ---- una fila de documento ---- */
/* Los anchos de columna van en rem: son columnas de TEXTO, y clavadas en píxeles
   dejaban la fecha y el nombre del archivo sin sitio en cuanto subía la letra
   (medido a 200 %: la tabla del archivo sacaba la página 46 px). Lo vigila C19.5. */
.tabla-archivo th:nth-child(1) { width: 8.25rem; }
/* Ancho para la pill de estado más larga del catálogo de §4.1 («Discrepancia
   entre documentos»): un pill recortado deja de decir el estado del dato. */
.tabla-archivo th:nth-child(3) { width: 14rem; }
.tabla-archivo th:nth-child(4) { width: 12.25rem; }
.tabla-archivo th:nth-child(5) { width: 14.5rem; }
.tabla-archivo td { vertical-align: top; }
.tabla-archivo td:first-child { padding-top: 15px; }
.tabla-archivo, .tabla-versiones { table-layout: fixed; }
.tabla-archivo td, .tabla-versiones td { overflow-wrap: break-word; }
.tabla-archivo td:last-child .fuente,
.tabla-versiones td:last-child .fuente { white-space: normal; text-align: left; max-width: 100%; }
.tabla-archivo td:last-child .fuente + .fuente { margin-top: 6px; }

.ar-titulo { display: block; font-size: 0.84375rem; font-weight: 600; color: var(--tinta); }
.ar-nombre { display: block; margin-top: 3px; font-size: 0.78125rem; font-weight: 600; color: var(--texto); }
.ar-meta { display: block; margin-top: 3px; font-size: 0.75rem; color: var(--texto-suave); white-space: normal; }
/* La celda de la fecha va en `nowrap` (una fecha no se parte), pero la línea de
   la hora puede ser una frase —«Sin hora en el documento»— y sin permitirle
   volver de línea se salía de su columna y se montaba sobre la de al lado. */
.ar-hora { display: block; margin-top: 4px; font-size: 0.71875rem; color: var(--texto-mudo); white-space: normal; }
.ar-huella { display: block; margin-bottom: 6px; font-size: 0.75rem; color: var(--texto-suave); }

/* La relación entre versiones: azul de dato, nunca verde/rojo — no hay una
   versión buena y otra mala, hay dos emisiones con su fecha. */
.ar-version {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 9px; padding: 9px 11px;
  background: var(--azul-suave); border: 1px solid var(--azul-borde);
  border-radius: var(--radio-caja);
}
.ar-version-txt { display: block; font-size: 0.75rem; color: var(--azul-texto); font-weight: 600; }

/* CUSTODIA DEL ORIGINAL EN PAPEL (ciclo 45). Va en tinta neutra y sin color de
   estado: no es un juicio sobre el documento ni un aviso, es lo que hay que
   saber antes de archivar. La misma caja sirve en la fila del archivo y en el
   panel del documento de la cola, porque el texto es el mismo. */
.custodia {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 9px; padding: 9px 11px;
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja);
}
.custodia-nota, .custodia-ref { display: block; }
.custodia-ref { word-break: break-word; }

/* LA CLASE DEL DOCUMENTO FIRMADO (ciclo 46). Misma caja neutra que la custodia:
   tampoco es un aviso ni un juicio, es de qué clase de documento firmado se
   trata y con qué plazo, dicho donde ya se pinta la conservación. */
.clase-firmada {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 9px; padding: 9px 11px;
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja);
}
.clase-nota, .clase-ref { display: block; }
.clase-ref { word-break: break-word; }

/* Un señalamiento del sistema, que NO es el estado del documento. */
.ar-senal {
  display: flex; flex-direction: column; gap: 5px;
  margin-top: 9px; padding: 9px 11px;
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja);
}
/* El otro documento del par señalado, dentro de la misma caja: envuelve porque
   el rótulo es una frase y el chip lleva el nombre del archivo. */
.ar-senal-otro { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ar-coincidencia { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 9px; }
.tabla-archivo td .cita { display: block; margin: 8px 0 0; font-size: 0.78125rem; }
.tabla-versiones td .cita { display: block; margin: 8px 0 0; font-size: 0.78125rem; }

/* ---- historial de versiones ---- */
.ar-cadena { margin-top: 16px; }
.ar-cadena-cab { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; }
/* Los rótulos de esta tabla son frases («Fecha clínica e incorporación»,
   «Huella propia»): con el `nowrap` de la cabecera general se salían de su
   columna y se montaban sobre la de al lado. Aquí vuelven de línea. */
table.tabla-archivo thead th, table.tabla-versiones thead th { white-space: normal; }
.tabla-versiones th:nth-child(1) { width: 7rem; }
.tabla-versiones th:nth-child(3) { width: 9.25rem; }
.tabla-versiones th:nth-child(4) { width: 7.25rem; }
.tabla-versiones th:nth-child(5) { width: 11rem; }
.tabla-versiones th:nth-child(6) { width: 13rem; }
.tabla-versiones td { vertical-align: top; }
.tabla-versiones td:first-child { padding-top: 15px; }

/* ---- deduplicación por huella ---- */
.ar-capas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px; margin: 14px 0 0; padding: 0; list-style: none;
}
.ar-capa {
  display: flex; flex-direction: column; gap: 7px;
  padding: 12px 14px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.ar-capa-cab { display: flex; flex-wrap: wrap; gap: 6px; }
.ar-caso {
  margin-top: 14px; padding: 14px 15px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
}
.ar-caso-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 11px; }
.ar-caso-doc { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }

/* ==========================================================================
   IMÁGENES Y MAPA ANATÓMICO (§11)
   Tres piezas y una regla común: nada de esta pantalla puede parecer una
   imagen clínica ni valorar una lesión. Las miniaturas son figuras abstractas
   con su sello encima; las regiones del mapa se dibujan todas iguales, en gris
   y con trazo discontinuo; y las marcas van en tinta —el color no juzga—,
   distinguiendo por el TRAZO (continuo / discontinuo) la ubicación confirmada
   de la que sigue siendo una propuesta.
   ========================================================================== */

.im-datos {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 9px 18px; margin: 0;
}
.im-datos dt {
  font-size: 0.65625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  color: var(--texto-mudo);
}
.im-datos dd { margin: 3px 0 0; font-size: 0.8125rem; color: var(--texto); overflow-wrap: break-word; }
.im-datos dd.num { font-weight: 600; color: var(--tinta); }
/* Donde el valor es una frase y no una cifra, el rótulo va ENCIMA: en dos
   columnas, un dato de una palabra y otro de tres líneas dejan al rótulo
   colgando a media altura, lejos de lo que nombra. */
.im-puerta .im-datos, .im-datos--via, .im-capa .im-datos { grid-template-columns: minmax(0, 1fr); }
.im-datos--via { margin-top: 10px; }

/* ---- las dos puertas de entrada ---- */
.im-puertas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
}
.im-puerta {
  display: flex; flex-direction: column; gap: 9px;
  padding: 13px 15px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.im-puerta-cab { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.im-puerta-cab .ico { color: var(--texto-suave); }
.im-puerta-titulo { font-size: 0.90625rem; font-weight: 700; color: var(--tinta); }
.im-puerta-txt { margin: 0; font-size: 0.8125rem; color: var(--texto); }

/* ---- un estudio de la galería ---- */
.im-estudio { margin-bottom: 16px; }
.im-estudio-titulo { font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }
.im-estudio-cuerpo {
  display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 20px; align-items: start;
}
.im-estudio-datos { min-width: 0; }
.im-estudio-pie { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }

/* ---- miniatura SIMULADA (nunca una imagen clínica) ---- */
.im-mini { margin: 0; }
.im-mini-svg {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.im-mini-fondo { fill: var(--superficie-suave); }
.im-mini-cuerpo { fill: var(--superficie); stroke: var(--borde-fuerte); stroke-width: 1.4; }
.im-mini-forma { fill: var(--texto-mudo); }
.im-mini-eje { stroke: var(--borde); stroke-width: 1; stroke-dasharray: 3 4; }
.im-mini-rotulo { display: block; margin-bottom: 6px; }
.im-mini-pie { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; margin-top: 9px; }
/* EL SELLO DENTRO DE LA FIGURA (hallazgo C18-3): es dibujo, no fondo, así que
   se imprime, se exporta y se recorta junto con la imagen que sella. */
.im-mini-sello-fondo { fill: var(--tinta); }
.im-mini-sello-texto {
  fill: var(--superficie);
  font-family: inherit; font-size: 6.1px; font-weight: 700; letter-spacing: .04em;
}
/* El sello va en tinta plena: tiene que leerse antes que la figura. El
   `print-color-adjust` conserva el contraste al imprimir; sin él, con los
   gráficos de fondo desactivados quedaba texto blanco sobre papel blanco. */
.im-sello {
  display: inline-block; padding: 3px 9px;
  background: var(--tinta); color: var(--superficie);
  border-radius: var(--radio-pill);
  font-size: 0.625rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}

/* ---- bloque interior de una tarjeta de estudio ---- */
.im-bloque {
  margin-top: 14px; padding: 12px 14px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.im-mediciones { list-style: none; margin: 9px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.im-medicion { display: flex; flex-direction: column; gap: 6px; font-size: 0.8125rem; }
.im-medicion-linea { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
/* Una medición candidata trae debajo el literal del informe y el motivo por el
   que no se vincula. El marco discontinuo la separa de las de la serie sin
   valorarla: es el mismo recurso de `.sin-vincular` en la ficha del paciente. */
.im-medicion--sin-vincular {
  padding: 10px 12px; border: 1px dashed var(--ambar-borde);
  border-radius: var(--radio-caja); background: var(--ambar-tenue);
}
.im-medicion--sin-vincular .cita { margin: 0; font-size: 0.78125rem; }
.im-medicion--sin-vincular p { margin: 0; }
.im-medicion-lesion { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
.im-medicion-lesion:hover .im-medicion-organo { text-decoration: underline; }
.im-medicion-organo { font-size: 0.8125rem; font-weight: 600; color: var(--tinta); }
.im-medicion-valor { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }

/* ---- mapa anatómico ---- */
.im-mapa { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 22px; align-items: start; }
.im-figura { display: block; width: 100%; height: auto; }
.im-silueta { fill: var(--superficie-suave); stroke: var(--borde-fuerte); stroke-width: 1.5; }
/* Todas las regiones iguales: el mapa sitúa, no clasifica. */
.im-region-forma { fill: var(--superficie); stroke: var(--borde-fuerte); stroke-width: 1.2; stroke-dasharray: 4 3; }
.im-marca { cursor: pointer; }
.im-marca-halo { fill: none; stroke: var(--tinta); stroke-width: 2; }
/* Ubicación aún sin confirmar: se distingue por el TRAZO, no por el color. */
.im-marca-halo--propuesta { stroke-dasharray: 3 3; }
.im-marca-punto { fill: var(--tinta); }
.im-marca:hover .im-marca-halo, .im-marca:focus-visible .im-marca-halo { stroke-width: 3.2; }
.im-marca:focus-visible { outline: none; }

.im-leyenda { list-style: none; margin: 0; padding: 0; }
.im-leyenda-item {
  display: flex; flex-direction: column; gap: 8px; min-width: 0;
  padding: 14px 18px; border-bottom: 1px solid var(--borde);
}
.im-leyenda-item:last-child { border-bottom: 0; }
/* Las tres filas de la leyenda pueden encoger: sin `min-width: 0` un hijo flex
   se niega a bajar del ancho de su contenido, y un pill de los suyos (que va en
   `nowrap` a propósito, para no partir «12 × 9 mm») sacaba la página entera a
   scroll horizontal con la letra grande. */
.im-leyenda-cab { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.im-leyenda-titulo { font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.im-leyenda-meta { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }
.im-leyenda-item .cita { font-size: 0.78125rem; }
.im-leyenda-pie { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-width: 0; }

/* ---- selección para casos clínicos ---- */
.im-candidato {
  margin-top: 14px; padding: 14px 16px;
  background: var(--superficie);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja);
}
.im-candidato-cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.im-capas {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px; margin-top: 10px;
}
.im-capa {
  display: flex; flex-direction: column; gap: 9px;
  padding: 13px 15px; border: 1px solid var(--borde); border-radius: var(--radio-caja);
  background: var(--superficie-suave);
}
.im-capa--azul { background: var(--azul-suave); border-color: var(--azul-borde); }
.im-capa--ambar { background: var(--ambar-suave); border-color: var(--ambar-borde); }
.im-capa-cab { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.im-capa-cab .ico { color: var(--texto-suave); }
.im-capa-titulo { font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.im-capa-txt { margin: 0; font-size: 0.8125rem; color: var(--texto); }
.im-capa-accion { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.im-capa-accion .nota-pie { flex: 1 1 200px; }
.im-capa .im-datos dd { color: var(--tinta); }

.im-disponibles { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.im-disponible {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.im-disponible-txt {
  display: inline-flex; align-items: center; gap: 10px;
  min-width: 0; font-size: 0.84375rem; color: var(--tinta); font-weight: 600; text-decoration: none;
}
.im-disponible-txt:hover { text-decoration: underline; }
.im-disponible-txt .num { color: var(--texto-suave); font-weight: 600; }
.im-disponible .boton { margin-left: auto; }

/* -------------------------------------------------- pantalla de pacientes -- */
/* Selección de historia (§5.5, §6). La fila de una historia con nombre parecido
   a otra se marca con el ÁMBAR de aviso del sistema —el mismo de «pendiente» y
   «fecha dudosa»— y nunca con verde ni rojo: no hay una historia buena y otra
   mala, hay dos que se pueden confundir. La marca no sustituye al texto: la fila
   lleva además su pill con palabras, porque el color solo no es un estado. */

.pa-ejemplos { margin-top: 14px; }
.pa-ejemplos .rotulo { display: block; margin-bottom: 2px; }

.pa-fila-parecida > td:first-child { box-shadow: inset 3px 0 0 var(--ambar); }
.pa-fila-parecida > td { background: var(--ambar-tenue); }

.pa-docs {
  display: flex; flex-direction: column; gap: 8px;
  margin: 0; padding: 0; list-style: none;
}
/* Declaraciones de una identificación, una por línea y agrupadas: en lista se
   distingue de un golpe cuántas fuentes hay y cuál se sale (hallazgo C21-6). */
.pa-declaraciones {
  display: flex; flex-direction: column; gap: 3px;
  margin: 0; padding: 0; list-style: none;
}
.pa-doc {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px;
  background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.pa-doc-txt {
  display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  flex: 1 1 auto; min-width: 0; font-size: 0.84375rem; color: var(--tinta); font-weight: 600;
}
.pa-doc-txt .num { color: var(--texto-suave); font-weight: 600; }
.pa-doc .boton { margin-left: auto; }

/* ==========================================================================
   TRATAMIENTOS, MEDICACIÓN, SUPLEMENTACIÓN Y SESIONES (§10) · prefijo `tr-`
   --------------------------------------------------------------------------
   Dos piezas nuevas y ninguna con color de juicio: la BARRA DE INTERVALO de una
   pauta (tramos aplicados, huecos de pausa y extremo abierto si sigue en curso)
   y la rejilla de los catorce campos, donde la casilla sin dato tiene que
   distinguirse de un vacío por descuido. Todas las medidas de texto van en rem;
   las alturas que sí están en píxeles son figuras con anchura propia o barras,
   nunca cajas de contenido (C19.5).
   ========================================================================== */

.tr-enlace {
  color: var(--azul-fuerte); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid var(--azul-borde); margin-left: 6px;
}
.tr-enlace:hover, .tr-enlace:focus-visible { border-bottom-color: var(--azul-fuerte); }

/* ---- barra de intervalo de una pauta ---- */
.tr-barra {
  position: relative; margin: 12px 0 6px; min-height: 1.125rem;
  padding: 0.375rem 0; overflow: visible;
}
.tr-barra-eje {
  position: absolute; left: 0; right: 0; top: 50%;
  border-top: 1px dashed var(--borde-fuerte);
}
.tr-barra-tramo {
  position: absolute; top: 50%; height: 0.5rem; transform: translateY(-0.25rem);
  background: var(--borde-fuerte); border: 1px solid var(--texto-suave);
  border-radius: 3px; min-width: 3px;
}
/* El hueco de una pausa se dibuja como hueco: línea de puntos entre dos tramos,
   no un tramo de otro color —un color distinto se leería como otra cosa que se
   está aplicando—. */
.tr-barra-pausa {
  position: absolute; top: 50%; height: 0; transform: translateY(-1px);
  border-top: 2px dotted var(--texto-suave); min-width: 3px;
}
/* La punta del extremo abierto la coloca el armazón con `left` calculado (el final
   del último tramo dibujado). Anclada al borde derecho señalaba el final de la
   línea temporal, no el último día que la pauta declara. */
.tr-barra-abierto {
  position: absolute; left: 0; top: 50%; width: 0; height: 0;
  transform: translateY(-5px);
  border-top: 5px solid transparent; border-bottom: 5px solid transparent;
  border-left: 7px solid var(--texto-suave);
}
.tr-barra-txt {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0 0 4px; font-size: 0.8125rem; color: var(--texto);
}
.tr-barra-txt .num { color: var(--tinta); font-weight: 600; }
.tr-sin-barra {
  display: flex; align-items: center; gap: 8px; margin: 12px 0 6px;
}

/* ---- los catorce campos ---- */
.tr-campos {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px;
  margin-top: 10px;
}
.tr-campo {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
/* La casilla sin dato se distingue por TRAZO, no por color: es información, no
   un aviso, y el ámbar de esta maqueta significa «pendiente de validación». */
.tr-campo--sin { border-style: dashed; background: var(--superficie); }
.tr-campo-valor { font-size: 0.84375rem; color: var(--tinta); font-weight: 600; }
.tr-campo-marcas {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}

/* ---- catálogo de campos ---- */
.tr-catalogo { display: flex; flex-direction: column; gap: 2px; }
.tr-catalogo-fila {
  display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) minmax(0, 12rem);
  gap: 10px; align-items: baseline; padding: 7px 2px;
  border-bottom: 1px solid var(--borde);
}
.tr-catalogo-fila:last-child { border-bottom: 0; }
.tr-catalogo-eti { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }
.tr-catalogo-ayuda { font-size: 0.8125rem; color: var(--texto); }
.tr-catalogo-marcas { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

/* ---- versión vigente e historial ---- */
.tr-vigente {
  margin-top: 12px; padding: 12px; border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja); background: var(--superficie);
}
.tr-historial { margin-top: 14px; }
.tr-version {
  margin-top: 10px; padding: 12px; border: 1px solid var(--borde);
  border-radius: var(--radio-caja); background: var(--superficie-suave);
}
.tr-version--vigente { border-color: var(--borde-fuerte); background: var(--superficie); }
.tr-version-cab {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.tr-version-n { font-size: 0.875rem; font-weight: 700; color: var(--tinta); }
.tr-version-cadena { margin: 6px 0 8px; }
.tr-detalle { margin-top: 8px; }
.tr-detalle > summary {
  cursor: pointer; font-size: 0.8125rem; color: var(--texto-suave); font-weight: 600;
  padding: 4px 0;
}
.tr-detalle > summary:focus-visible { outline: 2px solid var(--azul); outline-offset: 2px; }

/* ---- valor anterior → valor nuevo (§14.2) ---- */
.tr-difs {
  margin-top: 10px; padding: 10px; background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio-caja);
}
.tr-dif {
  display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 8px; align-items: baseline; padding: 5px 0; font-size: 0.8125rem;
}
.tr-dif + .tr-dif { border-top: 1px solid var(--borde); }
.tr-dif-campo { color: var(--texto-suave); font-weight: 600; }
.tr-dif-antes { color: var(--texto-suave); }
.tr-dif-ahora { color: var(--tinta); font-weight: 700; }
.tr-dif-flecha { color: var(--texto-mudo); }

/* ---- texto literal dentro de una celda de la tabla de sesiones ---- */
.tr-literal {
  margin-top: 4px; font-size: 0.78125rem; color: var(--texto); font-style: italic;
  max-width: 34ch;
}
/* Cuando la columna del escalado no compara —corte de ciclo o pausa documentada—
   enseña el documento que reanuda la pauta debajo del motivo. */
.tr-escalado-doc { margin-top: 5px; }
/* Al llegar por un ancla, la tarjeta de destino se marca: la página es larga. */
.tr-destacada { box-shadow: 0 0 0 2px var(--azul-borde), var(--sombra-tarjeta); }

/* ----------------------------------------------------------- responsive -- */
/* LOS CORTES VAN EN «em», NO EN PÍXELES. En una media query, `em` es el tamaño de
   letra por defecto del navegador, así que 73.75em son los 1180 px de siempre con
   la letra de fábrica y se estrechan solos cuando el usuario la sube: la maqueta
   pasa a una columna cuando de verdad hace falta. Con los cortes en píxeles el
   diseño se quedaba en dos y tres columnas al 200 % —cada una demasiado estrecha
   para su texto—, que es lo que sacaba la portada a desplazamiento horizontal.
   Es el «reflow» del SC 1.4.10, y lo vigila C19.5. */


/* ==========================================================================
   PRE-VISITA (§5.1, §5.5) · la plantilla de diferencias
   --------------------------------------------------------------------------
   Densidad de lectura de pie: la línea es una rejilla de cuatro columnas
   —fecha, hecho, estado y documento— y no una tarjeta con prosa. El color no
   aparece por ninguna parte salvo en el pill del estado, que ya es el de §4.1.
   ========================================================================== */

.pv-plantilla { margin-top: 12px; padding: 12px 14px; background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.pv-categorias { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px;
  grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pv-categorias li { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.pv-cat-nombre { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }
.pv-cat-ayuda { font-size: 0.78125rem; color: var(--texto-suave); }

/* La lista del día: chips con la identidad derivada y su botón de quitar. */
.pv-lista { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pv-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 6px 5px 10px;
  background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-pill); }
.pv-anadir { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.pv-anadir select { min-width: 18rem; }

/* Una historia por tarjeta; dentro, un bloque por categoría. */
.pv-historia { margin-bottom: 16px; }
.pv-quien { display: inline-flex; align-items: center; gap: 8px; }
.pv-bloque { padding: 10px 0 4px; border-top: 1px solid var(--borde); }
.pv-bloque:first-child { border-top: 0; padding-top: 2px; }
.pv-bloque-cab { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.pv-vacio { margin: 2px 2px 8px; }
/* La categoría que NO SE HA COMPROBADO no puede leerse igual que la comprobada y
   vacía: lleva el ámbar de la espera —que no juzga nada, dice «falta hacer»— y
   su propio borde, para que a un metro de distancia se vea que ahí no hay un
   visto bueno sino un hueco declarado. */
.pv-vacio.pv-sin-comprobar { padding: 7px 10px; border-left: 3px solid var(--ambar-borde);
  background: var(--ambar-tenue); color: var(--ambar-texto); border-radius: var(--radio-caja); }

.pv-linea { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr) 10rem minmax(0, 16rem);
  gap: 10px; align-items: start; padding: 8px 2px; border-top: 1px dashed var(--borde); }
.pv-linea:first-of-type { border-top: 0; }
.pv-fecha { font-size: 0.8125rem; font-weight: 600; color: var(--tinta); }
.pv-cuerpo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pv-texto { font-size: 0.84375rem; color: var(--tinta); font-weight: 600; }
.pv-datos { font-size: 0.78125rem; color: var(--texto-suave); }
.pv-estado, .pv-docs { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }

/* ==========================================================================
   INGESTA DOCUMENTAL (§3, §4, §4.1)
   --------------------------------------------------------------------------
   Una tarjeta por documento y un rastro de pasos: ni una barra de porcentaje en
   toda la pantalla, porque el sistema no puede medir lo que prometería.
   ========================================================================== */

.ing-pasos { margin-top: 12px; padding: 12px 14px; background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.ing-pasos-lista { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.ing-pasos-lista li { display: flex; align-items: flex-start; gap: 10px; padding: 8px 10px;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.ing-paso-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ing-paso-nombre { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }
.ing-paso-est { font-size: 0.78125rem; color: var(--texto-suave); }

.ing-acciones { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 8px; }
.zona-arrastre--activa { border-color: var(--azul); background: var(--azul-suave); }

.ing-destino { margin-top: 14px; padding: 12px 14px; background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.ing-destino-fila { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 8px; }
.ing-destino-fila select { min-width: 18rem; }
.ing-destino-quien { display: inline-flex; align-items: center; }

.ing-doc { margin-bottom: 16px; }
.ing-archivo { display: inline-flex; align-items: center; gap: 8px; font-size: 0.84375rem;
  font-weight: 700; color: var(--tinta); min-width: 0; overflow-wrap: anywhere; }
.ing-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 0.78125rem;
  color: var(--texto-suave); }
.ing-quien { margin: 8px 0; }
.ing-paso-actual { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px;
  padding: 8px 10px; background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }
.ing-paso-n { font-size: 0.78125rem; font-weight: 700; color: var(--texto-suave); }

/* El rastro de pasos: forma y texto, nunca solo color. */
.ing-rastro { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap;
  gap: 6px 10px; font-size: 0.78125rem; }
.ing-rastro li { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
  border: 1px solid var(--borde); border-radius: var(--radio-pill); color: var(--texto-suave);
  background: var(--superficie); }
.ing-rastro-marca { font-weight: 700; }
.ing-rastro-hecho { color: var(--verde-hondo); border-color: var(--verde-borde); background: var(--verde-suave); }
.ing-rastro-curso { color: var(--tinta); border-color: var(--borde-fuerte); font-weight: 600; }
.ing-rastro-detenido { color: var(--ambar-hondo); border-color: var(--ambar-borde); background: var(--ambar-suave); }
.ing-rastro-futuro { color: var(--texto-mudo); border-style: dashed; }

.ing-reintento { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 8px; }
.ing-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

/* «Paciente no confirmado»: candidatos con sus dos identificadores. */
.ing-atencion { margin-top: 12px; padding: 12px 14px; background: var(--superficie-suave);
  border: 1px solid var(--borde-fuerte); border-radius: var(--radio-caja); }
.ing-atencion-cab { display: flex; align-items: flex-start; gap: 8px; font-size: 0.84375rem;
  color: var(--texto); }
.ing-doc-nombre { display: flex; flex-direction: column; gap: 2px; margin: 10px 0; }
.ing-candidatos { list-style: none; margin: 8px 0 10px; padding: 0; display: grid; gap: 8px; }
.ing-candidato { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.ing-candidato-nac { font-size: 0.78125rem; color: var(--texto-suave); }
.ing-comprobar { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; }
.ing-atencion-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ing-equivalente { display: flex; flex-direction: column; gap: 6px; margin-top: 12px;
  padding: 10px 12px; background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }

/* ==========================================================================
   MÓDULOS COMPLEMENTARIOS (§12.2)
   --------------------------------------------------------------------------
   COMPONENTES PROPIOS a propósito: nada de esto puede parecerse a un dato
   clínico validado. No hay pills de estado de §4.1, no hay acentos de la escala
   clínica y el bloque entero va dentro de un marco de trazo distinto, con su
   rótulo de «evaluación complementaria» a la vista.
   ========================================================================== */

.cm-separacion { border-style: dashed; }
.cm-bloque { border-style: dashed; margin-bottom: 16px; }
.cm-bloque > .tarjeta-cab { background: var(--superficie-suave); }

.cm-aviso { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px;
  font-size: 0.8125rem; color: var(--texto); background: var(--superficie-suave);
  border: 1px dashed var(--borde-fuerte); border-radius: var(--radio-caja); }
.cm-aviso .ico { flex: 0 0 auto; margin-top: 1px; color: var(--texto-suave); }
.cm-aviso--fuerte { background: var(--superficie); border-color: var(--texto-mudo); }

.cm-referencia { display: flex; flex-direction: column; gap: 4px; margin-top: 12px;
  padding: 10px 12px; background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }
.cm-literales { list-style: none; margin: 4px 0; padding: 0; display: grid; gap: 4px; }
.cm-literales li { font-size: 0.8125rem; color: var(--tinta); font-style: italic; }

.cm-exploraciones { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px;
  margin: 12px 0; }
.cm-exploracion { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  background: var(--superficie); border: 1px dashed var(--borde-fuerte);
  border-radius: var(--radio-caja); }
.cm-exploracion-cab { display: flex; flex-direction: column; gap: 2px; }
.cm-exploracion-nombre { font-size: 0.9375rem; font-weight: 700; color: var(--tinta); }

.cm-cita { margin: 0; padding: 10px 12px; font-size: 0.84375rem; color: var(--tinta);
  background: var(--superficie-suave); border-left: 3px solid var(--borde-fuerte);
  border-radius: 0 var(--radio-caja) var(--radio-caja) 0; }
.cm-cita--corta { font-size: 0.8125rem; }
.cm-cita--cuaderno { background: var(--superficie); border-left-style: dashed; }
.cm-cita--norma { font-size: 0.8125rem; color: var(--texto); }
.cm-cita-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 8px; }

.cm-firma { display: inline-flex; align-items: center; gap: 8px; }
.cm-firma-txt { display: flex; flex-direction: column; }
.cm-firma-nombre { font-size: 0.8125rem; font-weight: 600; color: var(--tinta); }

.cm-patron { display: flex; flex-direction: column; gap: 8px; margin: 12px 0;
  padding: 12px 14px; background: var(--superficie-suave); border: 1px dashed var(--borde-fuerte);
  border-radius: var(--radio-caja); }

.cm-insumos, .cm-pilares, .cm-interpretacion { display: flex; flex-direction: column; gap: 8px;
  margin-top: 12px; padding: 12px 14px; background: var(--superficie-suave);
  border: 1px solid var(--borde); border-radius: var(--radio-caja); }
.cm-datos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0; }
.cm-datos dt { font-size: 0.6875rem; text-transform: uppercase; letter-spacing: .06em;
  font-weight: 600; color: var(--texto-mudo); }
.cm-datos dd { margin: 4px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 0.875rem; color: var(--tinta); }
.cm-pilar { display: flex; flex-direction: column; gap: 4px; }
.cm-pilar-nombre { font-size: 0.78125rem; font-weight: 700; color: var(--texto-suave); }

.cm-clases { margin: 12px 0; }
.cm-clases-lista { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 8px;
  grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cm-clases-lista li { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
  background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }
.cm-clase-nombre { font-size: 0.84375rem; font-weight: 700; color: var(--tinta); }

.cm-entradas { display: grid; gap: 12px; margin: 12px 0; }
.cm-entrada { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px;
  background: var(--superficie); border: 1px dashed var(--borde-fuerte);
  border-radius: var(--radio-caja); }
/* La entrada reservada se distingue por TRAZO y por texto, nunca por un color
   que la valore: reservar no es un señalamiento del sistema. */
.cm-entrada--reservada { border-style: solid; border-color: var(--texto-mudo); }
.cm-entrada-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.cm-entrada-cab .der { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px; min-width: 0; }

.cm-reserva { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px;
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-radius: var(--radio-caja); }
.cm-reserva-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cm-reserva-rotulo { font-size: 0.8125rem; font-weight: 700; color: var(--tinta); }
.cm-reserva-motivo { display: flex; flex-direction: column; gap: 2px; }
.cm-motivo-txt { font-size: 0.84375rem; color: var(--tinta); }
.cm-reserva-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

.cm-salida { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }

.cm-norma { display: flex; flex-direction: column; gap: 8px; margin-top: 12px;
  padding: 12px 14px; background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: var(--radio-caja); }
.cm-norma-cabeza { margin: 0; font-size: 0.8125rem; color: var(--texto); display: flex;
  flex-direction: column; gap: 2px; }
.cm-reglas { display: flex; flex-direction: column; gap: 5px; margin-top: 12px; }

/* La línea reservada del informe de accesos: sin objeto, sin fecha del objeto y
   sin motivo. Solo el texto neutro, en la tinta muda de lo que no se detalla. */
.au-linea-reservada td { font-style: italic; }

@media (max-width: 73.75em) {
  .pv-categorias { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pv-linea { grid-template-columns: 7rem minmax(0, 1fr); }
  .pv-estado, .pv-docs { grid-column: 2; }
  .cm-exploraciones, .cm-clases-lista, .cm-datos { grid-template-columns: minmax(0, 1fr); }
  .tr-campos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tr-catalogo-fila { grid-template-columns: minmax(0, 1fr); }
  .tr-catalogo-marcas { justify-content: flex-start; }
  .im-estudio-cuerpo, .im-mapa { grid-template-columns: minmax(0, 1fr); }
  .im-mini-svg { max-width: 320px; }
  .im-figura { max-width: 240px; }
  .rejilla--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rejilla--2-1, .rejilla--1-1, .lado-a-lado, .rejilla--3 { grid-template-columns: minmax(0, 1fr); }
  .hecho-campos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .adj-caras, .adj-salidas, .adj-tercero-campos, .dup-citas { grid-template-columns: minmax(0, 1fr); }
  .cp-emparejamiento { grid-template-columns: minmax(0, 1fr); }
  .cp-clave { flex-direction: row; justify-content: center; padding: 4px 0; }
}
@media (max-width: 56.25em) {
  .pv-categorias { grid-template-columns: minmax(0, 1fr); }
  .pv-linea { grid-template-columns: minmax(0, 1fr); }
  .pv-estado, .pv-docs { grid-column: 1; }
  .pv-anadir select, .ing-destino-fila select { min-width: 0; flex: 1 1 12rem; }
  .tr-campos { grid-template-columns: minmax(0, 1fr); }
  .tr-dif { grid-template-columns: minmax(0, 1fr); }
  .capa { grid-template-columns: 1fr; }
  .barra-lateral { position: static; height: auto; }
  .rejilla--4, .rejilla--2, .rejilla-situacion { grid-template-columns: minmax(0, 1fr); }
  .buscador { width: auto; flex: 1 1 140px; }
  .adj-datos, .adj-datos--ancha { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .au-perfil { grid-template-columns: minmax(0, 1fr); }
  .au-perfil-tipos { grid-column: 1; }
  .bs-campo { flex: 1 1 100%; }
  .adj-datos dd { padding-bottom: 6px; }
  .ar-filtros { grid-template-columns: minmax(0, 1fr); }
  .ar-rango { grid-column: span 1; }
  .ar-capas { grid-template-columns: minmax(0, 1fr); }
  .im-puertas, .im-capas { grid-template-columns: minmax(0, 1fr); }
  .im-disponible .boton { margin-left: 0; }
}

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

/* ==========================================================================
   VISITA GUIADA (tour.js + tour.html) — capa de demo, no una pantalla
   --------------------------------------------------------------------------
   La barra vive ENCIMA de la maqueta: fija abajo, con la superficie y el
   borde del sistema. El hueco que abre al pie no está clavado en píxeles:
   tour.js mide la barra y publica --alto-tour, porque el texto envuelve
   distinto según el ancho y la letra del usuario.                          */
body.con-tour { padding-bottom: calc(var(--alto-tour, 0px) + 16px); }

.barra-tour {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 400;
  background: var(--superficie); border-top: 1px solid var(--borde-fuerte);
  box-shadow: 0 -8px 28px rgba(17, 24, 39, .10);
  padding: 10px 22px 12px;
}
/* Plegada, la barra no puede seguir tapando ni interceptando la maqueta:
   solo queda vivo su botón. */
.barra-tour--oculta {
  background: transparent; border-top: 0; box-shadow: none;
  padding: 0 22px 12px; display: flex; justify-content: flex-end;
  pointer-events: none;
}
.barra-tour--oculta .boton { pointer-events: auto; box-shadow: 0 4px 14px rgba(17, 24, 39, .18); }

.tour-cabeza { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tour-cuenta { white-space: nowrap; }
.tour-pantalla { font-weight: 650; font-size: 0.9375rem; }
.tour-cabeza .der, .tour-pasos .der {
  margin-left: auto; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.tour-medio { display: flex; gap: 28px; align-items: flex-start; flex-wrap: wrap; margin-top: 4px; }
.tour-texto { margin: 2px 0 0; max-width: 66ch; color: var(--texto); }
.tour-toca .rotulo { margin: 0 0 2px; }
.tour-lista { margin: 0; padding: 0 0 0 4px; list-style: none; display: flex; flex-wrap: wrap; gap: 6px 10px; }
.tour-lista li {
  background: var(--superficie-suave); border: 1px solid var(--borde);
  border-radius: 999px; padding: 2px 10px; font-size: 0.75rem; white-space: nowrap;
}
.tour-pasos { display: flex; align-items: center; margin-top: 8px; gap: 10px; }
.tour-puntos { display: inline-flex; gap: 5px; align-items: center; }
.tour-punto { width: 7px; height: 7px; border-radius: 50%; background: var(--borde-fuerte); display: inline-block; }
.tour-punto--aqui { background: var(--azul-fuerte); }

/* ---- portada (tour.html) ---- */
.tour-portada { max-width: 860px; margin: 0 auto; padding: 48px 24px 64px; }
.tour-portada h1 { margin: 10px 0 12px; font-size: 1.875rem; letter-spacing: -.02em; }
.tour-portada .tour-intro { font-size: 1rem; line-height: 1.6; max-width: 60ch; margin: 0 0 8px; }
.tour-fin {
  margin: 14px 0 0; padding: 10px 14px; border-radius: 10px;
  background: var(--azul-suave); border: 1px solid var(--azul-borde); color: var(--azul-texto);
}
.tour-arranque { margin: 22px 0 34px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.tour-tarjetas { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.tour-tarjeta {
  width: 100%; text-align: left; cursor: pointer;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: 12px;
  padding: 14px 16px; font: inherit; color: inherit; display: block;
}
.tour-tarjeta:hover { border-color: var(--azul-fuerte); box-shadow: 0 4px 16px rgba(17, 24, 39, .08); }
.tour-tarjeta .num { color: var(--texto-suave); font-size: 0.75rem; }
.tour-tarjeta strong { display: block; margin: 2px 0 4px; }
.tour-tarjeta span { color: var(--texto-suave); font-size: 0.8125rem; line-height: 1.45; display: block; }

/* ==========================================================================
   PLANOS DE LECTURA (docs/diseno/CAPAS-DE-LECTURA.md, ciclo 57)
   --------------------------------------------------------------------------
   El plano de garantía (P3) se pliega por defecto SIN salir del DOM: la
   garantía sigue entera en la página —los linters estáticos la leen y el modo
   garantía o su «¿por qué?» la abren—, pero no compite con el dato clínico.
   El selector impone `none` SOLO en el estado plegado: en los estados visibles
   cada bloque conserva el display que su propia clase le dé.               */
@media screen { body:not(.modo-garantia) [data-plano="garantia"]:not(.plano-abierto) { display: none !important; } }
/* EL PAPEL NO PLIEGA (ciclo 60): los planos son de LECTURA EN PANTALLA. Al
   imprimir, toda garantía plegada vuelve a estar donde estaba — un documento
   entregado no puede depender de qué tenía abierto quien lo imprimió. */

/* El afordance «¿por qué?»: discreto y SIEMPRE el mismo. */
.porque {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: 0; padding: 2px 4px; margin: 6px 0 0;
  font: inherit; font-size: 0.75rem; color: var(--texto-suave);
  cursor: pointer; border-radius: 6px;
}
.porque:hover { color: var(--texto); background: var(--superficie-suave); }
.porque[aria-expanded="true"] { color: var(--texto); }

/* CON EL MODO GARANTÍA ABIERTO, el «¿por qué?» por bloque es un mando muerto
   (todo está ya a la vista) y pulsarlo conmutaría el estado del bloque EN
   SILENCIO: al apagar el modo, el bloque aparecería abierto por sorpresa con
   el botón diciendo «Plegar» (defecto A59-1, verificado en Chrome). Mientras
   el modo dure, el mando por bloque se retira. */
body.modo-garantia .porque { display: none; }

/* El conmutador global de la topbar dice su estado con tinta, no solo con el
   atributo: activo = tinta plena sobre superficie suave. */
#modo-garantia-boton.modo-on { background: var(--superficie-suave); color: var(--texto); }

/* EL ESTADO POR DEFECTO, EN TEXTO SIN FONDO (catálogo c62 · doctrina GDS):
   la cápsula marca la excepción; la normalidad no compite por la mirada. */
.estado-texto {
  display: inline-flex; align-items: center;
  color: var(--texto-suave); font-size: 0.8125rem; white-space: nowrap;
}
.estado-texto--mini { font-size: 0.75rem; }

/* ÍNDICE DE SECCIONES DE LA FICHA (c66): enlaces en voz baja, sin cápsulas
   (catálogo c62 — el índice navega, no señala estados). */
.indice-ficha {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: 12px; padding: 9px 16px;
}
.indice-ficha .rotulo { margin-right: 4px; }
.indice-ficha a {
  color: var(--texto-suave); text-decoration: none;
  font-size: 0.8125rem; white-space: nowrap;
}
.indice-ficha a:hover { color: var(--texto); text-decoration: underline; }

/* MEDIDA DE LECTURA (auditoría c71 · vara Butterick 45–90 del c70): la prosa
   no corre a todo el ancho de la tarjeta — a 1440 px había líneas de hasta 200
   caracteres, más del doble del techo legible. El límite va en `ch` (relativo
   a la fuente de CADA bloque): sube la letra y la medida se conserva. Las
   celdas y columnas estrechas no llegan al límite y no cambian. */
/* La unidad `ch` mide el ancho del «0», más ancho que la letra media de una
   fuente proporcional: medido en Chrome, 92ch equivalían a ~123 caracteres
   reales por línea. 66ch ≈ 88 caracteres reales — dentro de la vara. */
.aviso > span, .cm-aviso > span { max-width: 66ch; }
p.nota-pie { max-width: 66ch; }
.tabla-nota { max-width: 66ch; }

/* CHULETA DE ATAJOS (ciclo 72): derivada del mapa de los datos. Oculta por
   defecto; se abre con «?» y se cierra con Esc, el botón o el fondo. */
.atajos-panel {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(17, 24, 39, .35);
  display: flex; align-items: center; justify-content: center;
}
.atajos-caja {
  background: var(--superficie); border: 1px solid var(--borde-fuerte);
  border-radius: 14px; padding: 6px 18px 14px; width: min(430px, 92vw);
  box-shadow: 0 18px 50px rgba(17, 24, 39, .22);
}
.atajos-lista { list-style: none; margin: 8px 0 10px; padding: 0; display: grid; gap: 7px; }
.atajos-lista li { display: flex; align-items: center; gap: 12px; font-size: 0.8125rem; }
.atajos-lista li > span { min-width: 64px; display: inline-flex; gap: 4px; }
.atajos-caja kbd {
  font: 600 0.75rem ui-monospace, monospace; color: var(--texto);
  background: var(--superficie-suave); border: 1px solid var(--borde-fuerte);
  border-bottom-width: 2px; border-radius: 6px; padding: 1px 7px;
}

/* Método analítico del bloque del documento recreado (c83): letra de informe. */
.papel-metodo { font-weight: 400; font-size: 0.6875rem; color: var(--texto-suave); text-transform: none; }

/* INFORME RECREADO DE IMPRENTA en el visor de fuente (c87): papel dentro del
   modal — borde de documento, secciones ESR, firma al pie. */
.informe-doc {
  margin-top: 14px; border: 1px solid var(--borde-fuerte); border-radius: 10px;
  padding: 16px 18px; background: #fffdf9;
  box-shadow: inset 0 1px 4px rgba(17, 24, 39, .04);
}
.informe-doc-cab { display: flex; flex-direction: column; gap: 2px; border-bottom: 1px solid var(--borde); padding-bottom: 10px; margin-bottom: 10px; }
.informe-doc-centro { font-weight: 700; letter-spacing: .02em; }
.informe-doc-sec { margin: 8px 0; }
.informe-doc-sec p { margin: 2px 0 0; max-width: 66ch; }
.informe-doc-reco { margin: 10px 0; }
.informe-doc-firma { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--borde); padding-top: 8px; margin-top: 10px; font-style: italic; }

/* ---------------------------------------------------------------------------
   MODO PRODUCCIÓN (volátil · revisión de Mario, 15-ago-2026).
   Un botón flotante oculta los RÓTULOS DE MAQUETA — lo que en producción no
   existiría: avisos «MAQUETA · datos ficticios», sellos de simulación, notas
   «en la aplicación real…», controles de simulación. NO toca ninguna garantía
   del producto (esas existirían en producción). VOLÁTIL a propósito: el estado
   vive solo en memoria — recargar la página devuelve la maqueta honesta, y no
   se persiste en sessionStorage ni en ninguna parte. Solo pantalla: al
   imprimir, los sellos van SIEMPRE (la honestidad impresa no se apaga). */
@media screen {
  body.modo-produccion [data-maqueta],
  body.modo-produccion .aviso-maqueta,
  body.modo-produccion .papel-sello,
  body.modo-produccion .im-mini-sello-fondo,
  body.modo-produccion .im-mini-sello-texto,
  body.modo-produccion .im-sello { display: none !important; }
}
.boton-produccion {
  position: fixed; left: 14px; bottom: 14px; z-index: 400;
  font: inherit; font-size: 0.71rem; letter-spacing: .02em;
  padding: 6px 10px; border-radius: 999px; cursor: pointer;
  border: 1px dashed var(--texto-mudo); color: var(--texto-mudo);
  background: var(--fondo, #fff); opacity: .75;
}
.boton-produccion:hover { opacity: 1; }
body.modo-produccion .boton-produccion {
  border-style: solid; color: var(--tinta); opacity: .95;
}
/* La regla de impresión del botón vive en el ÚNICO bloque @media print (C24.3). */
