/*
 * Hoja de estilo común de las pantallas de sistema/ (la misma en las dos raíces web; una prueba lo exige).
 *
 * Dirección «carta clínica» (spec de diseño del 28-oct): papel sobre una cuadrícula de líneas finas que se enciende bajo el
 * puntero, tinta para el texto y un solo acento cálido (el de la clínica) para lo que importa: el estado verificado, el foco,
 * la página actual. Líneas de 1 px en lugar de sombras pesadas, superficies planas y ninguna tarjeta dentro de otra.
 *
 * Neutra: sin marca, sin fuentes ni direcciones externas (la CSP solo permite 'self'). Todo color sale de los cuatro de la
 * clínica que llegan en /tema.css (--tema-primario, --tema-acento, --tema-fondo y --tema-texto) y se deriva con color-mix(),
 * así cualquier clínica hereda una paleta coherente cambiando solo sus colores. Cada uno trae aquí su neutro por omisión (los
 * mismos de Vistas: tinta #1b1e22, oro #8a6229 y blanco), de modo que la página se ve bien aunque /tema.css falle. El modo
 * oscuro del aparato tiene su propia paleta, derivada también de la clínica pero con la luz al revés: los colores de una clínica
 * se eligen para fondo claro y aquí se aclaran o se mezclan con la noche para que conserven su contraste.
 *
 * Contraste AA en los dos modos (texto 4,5:1; bordes, iconos y foco 3:1: una prueba lo mide con varias paletas), foco siempre
 * visible, objetivos táctiles de al menos 44 px, campos de 16 px o más (iOS no acerca la página), adaptable desde 320 px y sin
 * animación si la persona lo pide.
 */

/* ------------------------------------------------------------------------------------------------------------------
 * 0. Las letras: dos familias propias, autoalojadas (SIL OFL 1.1; ver assets/fonts/LICENCIA-fuentes.txt y docs/procedencia.md)
 *
 * Outfit, geométrica y redonda, para los títulos y las cifras; IBM Plex Sans, para el texto, con cifras tabulares. Variables,
 * un archivo cada una. `font-display: swap`: el texto se lee de inmediato con la letra del sistema y cambia cuando llega la
 * propia. La CSP las admite porque son del mismo sitio (font-src 'self').
 * ------------------------------------------------------------------------------------------------------------------ */

@font-face {
  font-family: "Outfit";
  src: url("/assets/fonts/outfit-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("/assets/fonts/plex-sans-variable.woff2") format("woff2");
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 1. Las fichas del diseño (modo claro)
 * ------------------------------------------------------------------------------------------------------------------ */

:root {
  color-scheme: light;

  /* Los cuatro de la clínica, con sus neutros; y el rojo de lo que falla (el único color que no es de la clínica). */
  --c-primario: var(--tema-primario, #1b1e22);
  --c-acento: var(--tema-acento, #8a6229);
  --c-fondo: var(--tema-fondo, #ffffff);
  --c-texto: var(--tema-texto, #1b1e22);
  --c-rojo: #b42318;

  /* Papel y tinta. */
  --papel: var(--c-fondo);
  --lienzo: color-mix(in srgb, var(--c-texto) 3%, var(--c-fondo));
  --papel-2: color-mix(in srgb, var(--c-texto) 5%, var(--c-fondo));
  --campo: var(--c-fondo);
  --texto: var(--c-texto);
  --silenciado: color-mix(in srgb, var(--c-texto) 70%, var(--c-fondo));
  --linea: color-mix(in srgb, var(--c-texto) 12%, var(--c-fondo));
  --borde: color-mix(in srgb, var(--c-texto) 56%, var(--c-fondo));

  /* La acción principal (tinta) y el acento (oro). */
  --primario: var(--c-primario);
  --primario-hover: color-mix(in srgb, var(--c-primario) 84%, var(--c-fondo));
  --sobre-primario: var(--c-fondo);
  /* El texto sobre un relleno de acento: en la noche el acento se aclara, así que el texto pasa a ser el papel oscuro. */
  --sobre-acento: var(--c-fondo);
  --acento: var(--c-acento);
  --acento-tinta: color-mix(in srgb, var(--c-acento) 75%, var(--c-texto));
  --acento-suave: color-mix(in srgb, var(--c-acento) 10%, var(--c-fondo));
  --acento-linea: color-mix(in srgb, var(--c-acento) 45%, var(--c-fondo));
  --anillo: var(--c-acento);
  --seleccion: color-mix(in srgb, var(--c-acento) 22%, var(--c-fondo));

  /* Avisos (del oro de la clínica) y errores. */
  --aviso-fondo: color-mix(in srgb, var(--c-acento) 9%, var(--c-fondo));
  --aviso-texto: color-mix(in srgb, var(--c-acento) 50%, var(--c-texto));
  --aviso-linea: color-mix(in srgb, var(--c-acento) 30%, var(--c-fondo));
  --error-fondo: color-mix(in srgb, var(--c-rojo) 7%, var(--c-fondo));
  --error-texto: color-mix(in srgb, var(--c-rojo) 88%, var(--c-texto));
  --error-borde: var(--c-rojo);
  --error-linea: color-mix(in srgb, var(--c-rojo) 30%, var(--c-fondo));

  /* La sombra de una hoja: un filo y una caída larga y suave, con desplazamiento (la luz viene de arriba). */
  --sombra: 0 1px 2px color-mix(in srgb, var(--c-texto) 6%, transparent), 0 18px 40px -28px color-mix(in srgb, var(--c-texto) 35%, transparent);
  /* La constelación de fondo (constelacion.js): puntos de oro y de plata. El oro es el de la clínica aclarado hacia el dorado
     claro (en un fondo blanco el oro de texto sería sucio); la plata, la tinta aclarada. Solo se dibujan con poca opacidad. */
  --constelacion-oro: color-mix(in srgb, var(--c-acento) 62%, #e5ca7b);
  --constelacion-plata: color-mix(in srgb, var(--c-primario) 36%, #ffffff);

  /* La sombra de un borde que se desplaza (hay más a ese lado) y las líneas de la portada y del carnet: del texto y del acento,
     así siguen al modo (se resuelven con el --texto, el --acento y el --papel de cada uno). */
  --sombra-borde: color-mix(in srgb, var(--texto) 13%, transparent);
  --portada: color-mix(in srgb, var(--acento) 5%, var(--papel));
  --portada-linea: color-mix(in srgb, var(--acento) 16%, var(--papel));

  /*
   * El vidrio (enmienda del 29-oct, §1): los paneles son vidrio esmerilado sobre la cuadrícula y el color líquido. Cada uno es lo
   * bastante opaco para el contraste AA SIN contar con el desenfoque (la prueba lo mide sobre lo más oscuro y lo más claro que
   * puede tener detrás: el color líquido con una celda encendida y su línea); el desenfoque es lo de más. --vidrio-2 tiñe las
   * zonas de dentro de un panel (el margen de un tablero), --brillo es la luz que sigue al puntero y --frente, el frente de una
   * carpeta, sobre su ilustración.
   */
  --plata: color-mix(in srgb, var(--c-primario) 24%, var(--c-fondo));
  --vidrio: color-mix(in srgb, var(--papel) 80%, transparent);
  --vidrio-macizo: color-mix(in srgb, var(--papel) 94%, transparent);
  --vidrio-2: color-mix(in srgb, var(--texto) 3%, transparent);
  --vidrio-borde: color-mix(in srgb, var(--texto) 13%, transparent);
  --vidrio-luz: color-mix(in srgb, #ffffff 95%, transparent);
  --vidrio-sombra: 0 1px 2px color-mix(in srgb, var(--c-texto) 7%, transparent), 0 22px 44px -26px color-mix(in srgb, var(--c-texto) 38%, transparent);
  --brillo: color-mix(in srgb, #ffffff 70%, transparent);
  --frente: color-mix(in srgb, var(--papel) 80%, transparent);

  /*
   * El color líquido del fondo, muy suave: el lienzo con la plata, el oro y la tinta de la clínica, y sus brillos. liquido.js lo
   * pinta mezclando solo estos cinco (nada de lo que pinta sale de entre ellos: la prueba del contraste mide sus extremos). Las
   * ilustraciones de las carpetas y de la portada usan la misma paleta, con más color.
   */
  --liquido-1: var(--lienzo);
  --liquido-2: color-mix(in srgb, var(--plata) 42%, var(--lienzo));
  --liquido-3: color-mix(in srgb, var(--c-acento) 16%, var(--lienzo));
  --liquido-4: color-mix(in srgb, var(--c-primario) 10%, var(--lienzo));
  --liquido-brillo: var(--c-fondo);
  /* Oro, plata y perla (29-oct): las portadas y las carpetas se ven como metal pulido, no como mármol gris. */
  --ilustracion-1: color-mix(in srgb, var(--c-acento) 46%, #e5ca7b);
  --ilustracion-2: color-mix(in srgb, var(--c-primario) 26%, #ffffff);
  --ilustracion-3: color-mix(in srgb, var(--c-primario) 9%, #ffffff);
  --ilustracion-4: color-mix(in srgb, var(--c-acento) 24%, #fff3cf);
  --ilustracion-brillo: #ffffff;
  --carnet-velo-1: color-mix(in srgb, var(--ilustracion-1) 16%, transparent);
  --carnet-velo-2: color-mix(in srgb, var(--ilustracion-2) 12%, transparent);

  /*
   * El destello (§3): luz suave que nunca es opaca y que solo pasa por el borde de un panel (no por su texto). En el modo claro la
   * luz blanca no se vería sobre el papel: el frente lleva el acento, y la dispersión, el acento y la plata.
   */
  --destello-nucleo: color-mix(in srgb, #ffffff 70%, transparent);
  --destello-calido: color-mix(in srgb, var(--c-acento) 70%, transparent);
  --destello-frio: color-mix(in srgb, var(--plata) 70%, transparent);
  --destello-velo: color-mix(in srgb, var(--c-acento) 12%, transparent);

  /* El pie con la identidad de la clínica (logo y contacto): un bloque oscuro, de la tinta de la clínica, con el dorado aclarado
     para lo que va marcado. Es oscuro en los dos modos; una prueba mide su texto sobre él con varias paletas. */
  --pie-fondo: color-mix(in srgb, var(--c-primario) 90%, #000000);
  --pie-texto: color-mix(in srgb, #ffffff 88%, var(--pie-fondo));
  --pie-silencio: color-mix(in srgb, #ffffff 68%, var(--pie-fondo));
  --pie-acento: color-mix(in srgb, var(--c-acento) 12%, #f5e3a8);

  /* El vidrio líquido de los botones (30-oct): la luz de sus bordes (blanca; en el modo oscuro, más tenue) y la curva con resorte
     que los hace «blandos» al acercarse. */
  --r-boton: 1.25rem;
  --boton-luz: rgba(255, 255, 255, 0.8);
  --resorte: cubic-bezier(0.175, 0.885, 0.32, 1.8);

  /* Letra: la del sistema (no hay archivos de fuente que la CSP admita). */
  --letra: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --letra-titulo: "Outfit", "Segoe UI Variable Display", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --letra-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /* Escala tipográfica fija (razón ~1,2) y espacios sobre una base de 4 px. */
  --t-xs: 0.8125rem;
  --t-s: 0.875rem;
  --t-m: 1rem;
  --t-l: 1.1875rem;
  --t-xl: 1.4375rem;
  --t-2xl: 1.75rem;
  --t-3xl: 2.125rem;
  --r-control: 6px;
  --r-hoja: 10px;

  /* Movimiento: salida exponencial, corto. */
  --salida: cubic-bezier(0.16, 1, 0.3, 1);
  --rapido: 160ms;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 2. El modo oscuro del aparato: la noche tintada de la clínica, la tinta clara y el oro aclarado
 * ------------------------------------------------------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --papel: color-mix(in srgb, var(--c-primario) 14%, #131416);
    --lienzo: color-mix(in srgb, var(--c-primario) 10%, #0c0d0f);
    --papel-2: color-mix(in srgb, var(--texto) 5%, var(--papel));
    --campo: color-mix(in srgb, var(--texto) 3%, var(--papel));
    --texto: color-mix(in srgb, var(--c-fondo) 90%, var(--c-acento));
    --silenciado: color-mix(in srgb, var(--texto) 66%, var(--papel));
    --linea: color-mix(in srgb, var(--texto) 14%, var(--papel));
    --borde: color-mix(in srgb, var(--texto) 46%, var(--papel));
    --primario: var(--texto);
    --primario-hover: color-mix(in srgb, var(--texto) 84%, var(--papel));
    --sobre-primario: var(--papel);
    --sobre-acento: var(--papel);
    --acento: color-mix(in srgb, var(--c-acento) 62%, #ffffff);
    --acento-tinta: var(--acento);
    --acento-suave: color-mix(in srgb, var(--c-acento) 22%, var(--papel));
    --acento-linea: color-mix(in srgb, var(--c-acento) 55%, var(--papel));
    --anillo: var(--acento);
    --seleccion: color-mix(in srgb, var(--c-acento) 40%, var(--papel));
    --aviso-fondo: color-mix(in srgb, var(--c-acento) 16%, var(--papel));
    --aviso-texto: color-mix(in srgb, var(--c-acento) 35%, #ffffff);
    --aviso-linea: color-mix(in srgb, var(--c-acento) 40%, var(--papel));
    --error-fondo: color-mix(in srgb, var(--c-rojo) 18%, var(--papel));
    --error-texto: color-mix(in srgb, var(--c-rojo) 35%, #ffffff);
    --error-borde: color-mix(in srgb, var(--c-rojo) 55%, #ffffff);
    --error-linea: color-mix(in srgb, var(--c-rojo) 45%, var(--papel));
    --sombra: 0 1px 0 color-mix(in srgb, var(--texto) 6%, transparent), 0 24px 48px -32px #000000;
    /* En la noche los puntos son más apagados que el texto y que los bordes (que son claros): un punto brillante detrás de un
       panel le quitaría contraste. */
    --boton-luz: rgba(255, 255, 255, 0.2);
    --constelacion-oro: color-mix(in srgb, var(--c-acento) 50%, #8f7035);
    --constelacion-plata: color-mix(in srgb, var(--c-fondo) 20%, #737982);

    /* El vidrio de noche: la misma opacidad sobre la noche de la clínica; la luz del borde y el brillo, blancos y tenues. */
    --plata: color-mix(in srgb, var(--c-fondo) 64%, var(--c-primario));
    --vidrio: color-mix(in srgb, var(--papel) 84%, transparent);
    --vidrio-macizo: color-mix(in srgb, var(--papel) 95%, transparent);
    --vidrio-borde: color-mix(in srgb, var(--texto) 14%, transparent);
    --vidrio-luz: color-mix(in srgb, #ffffff 34%, transparent);
    --vidrio-sombra: 0 1px 0 color-mix(in srgb, #ffffff 5%, transparent), 0 26px 52px -30px #000000;
    --brillo: color-mix(in srgb, #ffffff 5%, transparent);
    --frente: color-mix(in srgb, var(--papel) 72%, transparent);
    --liquido-1: var(--lienzo);
    --liquido-2: color-mix(in srgb, var(--plata) 10%, var(--lienzo));
    --liquido-3: color-mix(in srgb, var(--c-acento) 26%, var(--lienzo));
    --liquido-4: color-mix(in srgb, var(--c-primario) 55%, var(--lienzo));
    --liquido-brillo: color-mix(in srgb, var(--texto) 17%, var(--lienzo));
    --ilustracion-1: color-mix(in srgb, var(--c-acento) 60%, var(--papel));
    --ilustracion-2: color-mix(in srgb, var(--plata) 34%, var(--papel));
    --ilustracion-3: color-mix(in srgb, var(--c-primario) 60%, var(--papel));
    --ilustracion-4: color-mix(in srgb, var(--c-acento) 32%, var(--papel));
    --ilustracion-brillo: color-mix(in srgb, var(--texto) 40%, var(--papel));
    --destello-nucleo: color-mix(in srgb, #ffffff 62%, transparent);
    --destello-calido: color-mix(in srgb, var(--acento) 58%, transparent);
    --destello-frio: color-mix(in srgb, var(--plata) 48%, transparent);
    --destello-velo: color-mix(in srgb, #ffffff 6%, transparent);
  }
}

/* Más contraste si la persona lo pide: las líneas finas pasan a ser bordes. */
@media (prefers-contrast: more) {
  :root {
    --linea: var(--borde);
    --borde: var(--texto);
    --silenciado: var(--texto);
    --vidrio: var(--papel);
    --vidrio-macizo: var(--papel);
    --frente: var(--papel);
    --vidrio-borde: var(--borde);
  }
}

/* Menos transparencia si la persona lo pide: el vidrio pasa a papel (sin desenfoque: sección 16). */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --vidrio: var(--papel);
    --vidrio-macizo: var(--papel);
    --frente: var(--papel);
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 3. La base: la caja, el documento y lo que el navegador dibuja solo (selección, cursor, barras, subrayados, cifras)
 * ------------------------------------------------------------------------------------------------------------------ */

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

/* Lo que lleva el atributo hidden (el campo del código que oculta enlace.js) se oculta siempre, aunque otra regla le dé un display. */
[hidden] {
  display: none !important;
}

/*
 * Lo que solo oye un lector de pantalla (el estado de cada paso del riel): fuera de la vista con clip-path, en su sitio y sin
 * overflow que recorte un texto que se ve.
 */
.solo-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

html {
  font-family: var(--letra);
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scrollbar-color: var(--borde) var(--lienzo);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-m);
  line-height: 1.55;
  font-optical-sizing: auto;
}

::selection {
  background: var(--seleccion);
  color: var(--texto);
}

input,
textarea {
  caret-color: var(--acento);
}

a {
  color: var(--texto);
  text-decoration-line: underline;
  text-decoration-color: var(--acento-linea);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-color var(--rapido) var(--salida);
}

a:hover {
  text-decoration-color: var(--acento);
  text-decoration-thickness: 2px;
}

a,
button,
summary,
label,
input[type="checkbox"],
input[type="radio"] {
  touch-action: manipulation;
}

:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

code,
kbd {
  font-family: var(--letra-mono);
  font-size: 0.9em;
  font-variant-numeric: tabular-nums;
  padding: 0.1em 0.35em;
  background: var(--papel-2);
  border: 1px solid var(--linea);
  border-radius: 4px;
  overflow-wrap: anywhere;
}

/* Las cifras que se comparan o se dictan (cédulas, fechas, códigos, tablas) van con dígitos de ancho fijo. */
td,
time,
.cifras,
.datos dd {
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 4. El armazón: saltar al contenido, la franja de datos de prueba, la cabecera con la marca y la navegación, y el fondo
 * ------------------------------------------------------------------------------------------------------------------ */

/* Enlace para saltar al contenido: fuera de la vista hasta que recibe el foco con el teclado. */
.saltar {
  position: absolute;
  left: 0.5rem;
  top: 0.5rem;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.5rem 1rem;
  background: var(--primario);
  color: var(--sobre-primario);
  border-radius: var(--r-control);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(calc(-100% - 1rem));
}

.saltar:focus,
.saltar:focus-visible {
  transform: none;
}

/* La franja de datos de prueba: discreta, pero siempre arriba y en todas las páginas. */
.banner-prueba {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.375rem 1rem;
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  border-bottom: 1px solid var(--aviso-linea);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
}

.banner-prueba p {
  margin: 0;
}

.banner-prueba::before {
  content: "";
  flex: none;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--acento);
}

.cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: 1.5rem;
  padding: 0 clamp(1rem, 4vw, 2rem);
  background: var(--vidrio);
  border-bottom: 1px solid var(--vidrio-borde);
}

/* La marca de la clínica: su monograma (las iniciales de su nombre) y su nombre, de su configuración. */
.marca {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  min-height: 3.5rem;
  margin: 0;
  color: var(--texto);
  font-size: var(--t-m);
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.marca-monograma {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-control);
  background: var(--primario);
  color: var(--sobre-primario);
  box-shadow: inset 0 -2px 0 var(--acento);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* El nombre baja de línea si no cabe (nunca se corta: es el de la clínica); en el teléfono, un punto más chico. */
.marca-con-logo {
  flex: none;
  min-height: 4rem;
}

.marca-con-logo picture {
  display: block;
}

/* El logo de la clínica en la cabecera (CLINICA_LOGO): la altura manda y el ancho sigue a la imagen. */
.marca-logo {
  display: block;
  width: auto;
  height: 2.5rem;
  max-width: 12rem;
  object-fit: contain;
}

@media (min-width: 48rem) {
  .marca-logo {
    height: 2.875rem;
    max-width: 14rem;
  }
}

.marca-nombre {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 0.9375rem;
}

@media (min-width: 48rem) {
  .marca-nombre {
    font-size: var(--t-m);
  }
}

/*
 * La navegación (enmienda del 29-oct): una píldora de vidrio y, en ella, la página actual como una gota de agua. En el teléfono, una
 * fila propia con el icono sobre el nombre; desde 48rem, a la derecha de la marca. La gota (--gota-fondo y --gota-sombra: un
 * brillo arriba a la izquierda, un filo de luz y un poco de sombra del color del acento) es, sin JS, el fondo del enlace de la
 * página actual; con JS (cabecera.js pone data-gota en el <nav>), una sola gota compartida (el ::before de la lista) que sigue
 * al puntero o al foco y se estira al moverse: el borde que va delante llega antes que el de atrás (data-hacia). Al pulsar, una
 * onda sale de ella (data-onda). Un brillo de menisco sigue al puntero por la píldora (--gx). Sin movimiento, la gota salta.
 */
.cabecera nav {
  --gota-fondo: radial-gradient(120% 140% at 30% 0%, var(--vidrio-luz), transparent 58%), color-mix(in srgb, var(--papel) 88%, transparent);
  --gota-sombra: inset 0 1px 1px var(--vidrio-luz), inset 0 -2px 6px color-mix(in srgb, var(--acento) 20%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--acento) 28%, transparent), 0 6px 14px -8px color-mix(in srgb, var(--c-texto) 45%, transparent);
  flex: 1 1 100%;
  min-width: 0;
  margin: 0 0 0.625rem;
}

/* Si las pestañas no caben (once para administración en un teléfono), la píldora se desplaza a lo ancho, sin barra, como la del portal;
   cabecera.js deja la actual a la vista. */
.cabecera nav ul {
  position: relative;
  display: flex;
  gap: 0.125rem;
  margin: 0;
  padding: 0.25rem;
  overflow: auto hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  list-style: none;
  border-radius: 999px;
  background:
    radial-gradient(6rem 2.75rem at var(--gx, -20rem) 0, color-mix(in srgb, var(--vidrio-luz) 70%, transparent), transparent 75%),
    color-mix(in srgb, var(--texto) 4%, transparent);
  box-shadow: inset 0 1px 1px var(--vidrio-luz), inset 0 0 0 1px var(--vidrio-borde);
}

.cabecera nav ul::-webkit-scrollbar {
  display: none;
}

.cabecera nav li {
  flex: 1 0 auto;
}

.cabecera nav a {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  min-height: 3.25rem;
  min-width: 44px;
  padding: 0.375rem 0.5rem;
  border-radius: 999px;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: color var(--rapido) var(--salida);
}

.cabecera nav a .icono {
  width: 1.25rem;
  height: 1.25rem;
  transition: transform 420ms var(--resorte);
}

@media (hover: hover) and (pointer: fine) {
  .cabecera nav a:hover {
    color: var(--texto);
  }

  .cabecera nav a:hover .icono {
    transform: translateY(-1px) scale(1.12);
  }
}

/* La página actual: en negrita, con la tinta, el icono en el acento y la gota de agua (no solo de otro color). */
.cabecera nav a[aria-current="page"] {
  color: var(--texto);
  font-weight: 700;
  background: var(--gota-fondo);
  box-shadow: var(--gota-sombra);
}

.cabecera nav a[aria-current="page"] .icono {
  color: var(--acento);
}

.cabecera nav a:focus-visible {
  outline-offset: -2px;
}

/* Con JS, la gota es una sola y la lleva el ::before de la lista: los enlaces ya no pintan la suya. */
.cabecera nav[data-gota] a[aria-current="page"] {
  background: none;
  box-shadow: none;
}

.cabecera nav[data-gota] ul::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 0.25rem;
  bottom: 0.25rem;
  left: var(--gota-l, 0px);
  right: var(--gota-r, 0px);
  border-radius: 999px;
  background: var(--gota-fondo);
  box-shadow: var(--gota-sombra);
  transition: left 440ms cubic-bezier(0.3, 0.8, 0.3, 1), right 440ms cubic-bezier(0.3, 0.8, 0.3, 1), opacity 200ms var(--salida);
}

.cabecera nav[data-gota="oculta"] ul::before {
  opacity: 0;
}

/* Hacia la derecha manda el borde derecho (llega antes) y el izquierdo se queda un momento atrás: la gota se estira; hacia la
   izquierda, al revés. */
.cabecera nav[data-hacia="derecha"] ul::before {
  transition: left 540ms 70ms cubic-bezier(0.3, 0.8, 0.3, 1), right 380ms cubic-bezier(0.2, 1, 0.3, 1.18), opacity 200ms var(--salida);
}

.cabecera nav[data-hacia="izquierda"] ul::before {
  transition: left 380ms cubic-bezier(0.2, 1, 0.3, 1.18), right 540ms 70ms cubic-bezier(0.3, 0.8, 0.3, 1), opacity 200ms var(--salida);
}

/* La onda que sale de la gota al pulsar: un anillo que crece y se apaga (dos animaciones iguales que se alternan). */
.cabecera nav[data-onda] ul::after {
  content: "";
  position: absolute;
  z-index: 0;
  top: 50%;
  left: calc(var(--gota-l, 0px) + (100% - var(--gota-l, 0px) - var(--gota-r, 0px)) / 2);
  width: 2.5rem;
  height: 2.5rem;
  margin: -1.25rem 0 0 -1.25rem;
  border: 1px solid color-mix(in srgb, var(--acento) 60%, transparent);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.cabecera nav[data-onda="a"] ul::after {
  animation: gota-onda-a 720ms var(--salida);
}

.cabecera nav[data-onda="b"] ul::after {
  animation: gota-onda-b 720ms var(--salida);
}

@keyframes gota-onda-a {
  from {
    opacity: 0.8;
    transform: scale(0.4);
  }

  to {
    opacity: 0;
    transform: scale(3.4);
  }
}

@keyframes gota-onda-b {
  from {
    opacity: 0.8;
    transform: scale(0.4);
  }

  to {
    opacity: 0;
    transform: scale(3.4);
  }
}

@media (min-width: 48rem) {
  .cabecera {
    flex-wrap: nowrap;
  }

  /* La marca no cede ancho: lo que falte lo cede la píldora, que se desplaza (doce pestañas en administración no caben a 1440 px, y
     encogible la marca partía «Clínica» en dos líneas). Un nombre largo baja de línea por sus espacios pasado el 40 % de la fila. */
  .marca {
    flex: none;
    max-width: 40%;
  }

  .cabecera nav {
    flex: 0 1 auto;
    margin: 0;
  }

  .cabecera nav li {
    flex: 0 0 auto;
  }

  .cabecera nav a {
    flex-direction: row;
    gap: 0.5rem;
    min-height: 2.75rem;
    padding: 0 1rem;
    font-size: var(--t-s);
  }
}

/* El fondo: una capa fija del tamaño de la ventana, detrás de todo y que no recibe el puntero; constelacion.js dibuja dentro. */
.fondo {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.constelacion {
  display: block;
  width: 100%;
  height: 100%;
}

/* Los dos colores de la constelación, para que constelacion.js los lea ya resueltos del navegador (un elemento de prueba). */
.constelacion-oro {
  color: var(--constelacion-oro);
}

.constelacion-plata {
  color: var(--constelacion-plata);
}

/*
 * El color líquido (liquido.js, enmienda del 29-oct): un lienzo pintado a baja resolución que el navegador agranda suave; se
 * funde al terminar de pintarse. La clase de su paleta le da sus cinco colores como `color` y colores de borde (sin borde
 * visible): así liquido.js los lee ya resueltos, en este orden: el color, arriba, a la derecha, abajo y a la izquierda (el brillo).
 * El del fondo va debajo de la cuadrícula, en su propia capa (el puntero que enciende una celda no lo vuelve a pintar).
 */
.liquido {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0 solid;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms var(--salida);
}

.liquido.pintado {
  opacity: 1;
}

.liquido-fondo {
  /* El fondo de la página es blanco con la constelación encima (29-oct): el color líquido queda para las portadas y las carpetas. */
  display: none;
  color: var(--liquido-1);
  border-color: var(--liquido-2) var(--liquido-3) var(--liquido-4) var(--liquido-brillo);
}

.liquido-ilustracion {
  color: var(--ilustracion-1);
  border-color: var(--ilustracion-2) var(--ilustracion-3) var(--ilustracion-4) var(--ilustracion-brillo);
}

/*
 * El pie (Vistas::pie): el logo para fondo oscuro, el descriptor y lo que la clínica tenga de contacto: dónde está, cómo llamarla o
 * escribirle y su horario. Un bloque de tinta al final de la página, como el pie de la academia, con los títulos de columna en
 * Outfit, en versalitas y en dorado claro. Nada de esto está si la clínica no configuró nada.
 */
.pie {
  margin-top: 3rem;
  background: var(--pie-fondo);
  border-top: 1px solid color-mix(in srgb, var(--pie-acento) 35%, transparent);
  color: var(--pie-texto);
  font-size: var(--t-s);
}

.pie-contenido {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 2rem 2.5rem;
  max-width: 72rem;
  margin: 0 auto;
  padding: 2.5rem 1rem 2.75rem;
}

@media (min-width: 48rem) {
  .pie-contenido {
    padding: 3rem 2rem 3.25rem;
  }
}

.pie p,
.pie ul {
  margin: 0;
}

.pie ul {
  display: grid;
  gap: 0.375rem;
  padding: 0;
  list-style: none;
}

.pie-logo {
  display: block;
  width: auto;
  height: 3.25rem;
  max-width: 100%;
  object-fit: contain;
}

.pie-nombre {
  font-family: var(--letra-titulo);
  font-size: var(--t-xl);
  font-weight: 650;
  letter-spacing: -0.01em;
}

.pie-descriptor {
  margin-top: 0.625rem !important;
  color: var(--pie-silencio);
}

.pie-titulo {
  margin-bottom: 0.625rem !important;
  color: var(--pie-acento);
  font-family: var(--letra-titulo);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.pie a {
  color: var(--pie-texto);
  text-decoration-color: color-mix(in srgb, var(--pie-acento) 55%, transparent);
}

.pie :focus-visible {
  outline: 2px solid var(--pie-acento);
  outline-offset: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .pie a:hover {
    color: var(--pie-acento);
  }
}

main {
  flex: 1 0 auto;
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

main:focus {
  outline: none;
}

@media (min-width: 48rem) {
  main {
    padding: 2.5rem 2rem 5rem;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 5. El texto
 * ------------------------------------------------------------------------------------------------------------------ */

h1,
h2,
h3 {
  margin: 1.75rem 0 0.625rem;
  color: var(--texto);
  font-family: var(--letra-titulo);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 {
  margin-top: 0;
  font-size: var(--t-2xl);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

h2 {
  font-size: var(--t-l);
}

h3 {
  font-size: var(--t-m);
}

@media (min-width: 48rem) {
  h1 {
    font-size: var(--t-3xl);
  }

  h2 {
    font-size: var(--t-xl);
  }
}

p,
ul,
ol {
  margin: 0 0 1rem;
}

p,
li,
dd {
  text-wrap: pretty;
}

strong {
  font-weight: 650;
}

.silenciado {
  color: var(--silenciado);
}

.entradilla {
  margin: 0;
  max-width: 40rem;
  color: var(--silenciado);
  font-size: var(--t-m);
}

.nota {
  margin: 0.75rem 0 0;
  font-size: var(--t-s);
  line-height: 1.5;
}

.enlace-aparte {
  margin: 1rem 0 0;
}

.texto-libre {
  white-space: pre-line;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 6. Los formularios: etiqueta arriba, ayuda y error debajo de ella, campos de 48 px y casillas dibujadas
 * ------------------------------------------------------------------------------------------------------------------ */

form {
  max-width: 36rem;
}

label {
  display: block;
  margin: 0 0 0.375rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
}

.campo {
  margin: 0 0 1.25rem;
}

.ayuda {
  margin: 0 0 0.5rem;
  font-size: var(--t-s);
  line-height: 1.45;
}

.campo > .silenciado:not(.ayuda) {
  margin: 0.375rem 0 0;
  font-size: var(--t-s);
  line-height: 1.45;
}

.error-campo {
  margin: 0 0 0.5rem;
  color: var(--error-texto);
  font-size: var(--t-s);
  font-weight: 600;
  line-height: 1.45;
}

input:not([type="checkbox"]):not([type="radio"]),
select,
textarea {
  display: block;
  width: 100%;
  min-height: 3rem;
  padding: 0.625rem 0.875rem;
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
  color: var(--texto);
  background-color: var(--campo);
  border: 1px solid var(--borde);
  border-radius: var(--r-control);
  transition: border-color var(--rapido) var(--salida), box-shadow var(--rapido) var(--salida);
}

textarea {
  min-height: 7rem;
  resize: vertical;
}

select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.5rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--silenciado) 50%), linear-gradient(135deg, var(--silenciado) 50%, transparent 50%);
  background-position: calc(100% - 1.25rem) 52%, calc(100% - 0.9375rem) 52%;
  background-size: 0.3125rem 0.3125rem;
  background-repeat: no-repeat;
}

input[type="date"] {
  text-align: left;
}

input::-webkit-date-and-time-value {
  text-align: left;
}

::placeholder {
  color: var(--silenciado);
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  input:not([type="checkbox"]):not([type="radio"]):hover,
  select:hover,
  textarea:hover {
    border-color: var(--texto);
  }
}

input:not([type="checkbox"]):not([type="radio"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 0;
  border-color: var(--anillo);
}

/* Un campo con error: el borde en rojo y del doble (el mensaje, con texto, va arriba del campo: no solo el color). */
[aria-invalid="true"] {
  border-color: var(--error-borde);
}

input[aria-invalid="true"]:not([type="checkbox"]):not([type="radio"]),
textarea[aria-invalid="true"],
select[aria-invalid="true"] {
  box-shadow: inset 0 0 0 1px var(--error-borde);
}

input:disabled,
select:disabled,
textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background-color: var(--papel-2);
}

/* Casillas y botones de opción dibujados: un cuadro (o un círculo) de borde fino que se rellena de tinta al marcarlo. */
input[type="checkbox"],
input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  display: inline-grid;
  place-content: center;
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
  margin: 0;
  background: var(--campo);
  border: 1px solid var(--borde);
  border-radius: 5px;
  color: var(--sobre-primario);
  cursor: pointer;
  transition: background-color var(--rapido) var(--salida), border-color var(--rapido) var(--salida), box-shadow var(--rapido) var(--salida);
}

input[type="radio"] {
  border-radius: 50%;
}

input[type="checkbox"]::before {
  content: "";
  width: 0.6875rem;
  height: 0.375rem;
  margin-top: -0.125rem;
  border: solid currentColor;
  border-width: 0 0 2px 2px;
  transform: rotate(-45deg) scale(0);
  transition: transform var(--rapido) var(--salida);
}

input[type="checkbox"]:checked {
  background: var(--primario);
  border-color: var(--primario);
}

input[type="checkbox"]:checked::before {
  transform: rotate(-45deg) scale(1);
}

input[type="radio"]:checked {
  background: var(--primario);
  border-color: var(--primario);
  box-shadow: inset 0 0 0 0.3125rem var(--campo);
}

@media (hover: hover) and (pointer: fine) {
  input[type="checkbox"]:hover,
  input[type="radio"]:hover {
    border-color: var(--texto);
  }
}

input[type="checkbox"][aria-invalid="true"],
input[type="radio"][aria-invalid="true"] {
  border-color: var(--error-borde);
  box-shadow: 0 0 0 1px var(--error-borde);
}

input[type="radio"][aria-invalid="true"]:checked {
  box-shadow: inset 0 0 0 0.3125rem var(--campo), 0 0 0 1px var(--error-borde);
}

input[type="checkbox"]:disabled,
input[type="radio"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.opcion {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 44px;
}

.opcion label {
  margin: 0;
  font-size: var(--t-m);
  font-weight: 400;
  cursor: pointer;
}

.opcion-larga {
  align-items: flex-start;
  padding: 0.5rem 0;
}

.opcion-larga input[type="checkbox"] {
  margin-top: 0.0625rem;
}

.ayuda-casilla {
  margin: -0.375rem 0 1rem 2.125rem;
}

fieldset {
  min-width: 0;
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
}

legend {
  margin: 0 0 0.5rem;
  padding: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.resumen-errores ul {
  margin: 0;
  padding-left: 1.125rem;
}

.resumen-errores p:last-child {
  margin-bottom: 0;
}

.resumen-errores a {
  color: inherit;
  font-weight: 600;
  text-decoration-color: currentColor;
}

/*
 * El campo trampa del registro: recortado a nada en su sitio (no desplazado fuera de la página), para nadie: ni la vista, ni
 * el teclado (tabindex -1) ni un lector de pantalla (aria-hidden).
 */
.trampa {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 7. Los botones: primario (tinta), secundario (contorno) y peligro (solo lo irreversible); todos con sus estados
 * ------------------------------------------------------------------------------------------------------------------ */

/*
 * Vidrio líquido (30-oct, pedido de Gabriel): cada botón es una pieza de vidrio en tres capas, de atrás hacia delante: el cristal
 * (::before: la tinta del botón translúcida sobre el desenfoque de lo que hay detrás, que un filtro SVG, #vidrio-liquido, deforma
 * como un lente), el brillo y la luz de los bordes (::after: un destello en la esquina y dos filos de luz, arriba a la izquierda
 * y abajo a la derecha) y el contenido. Al acercarse el puntero el botón se hincha y se redondea con un resorte; al pulsarlo se
 * hunde. El cristal es más grande que el botón (lo recorta `contain: paint`, no `overflow`: la comprobación de texto recortado de las
 * pruebas de navegador, con razón, desconfía de un `overflow` que oculta algo). El texto nunca depende del desenfoque: la tinta es lo bastante opaca para el AA sobre lo más claro que puede tener
 * detrás (lo mide una prueba) y, sin backdrop-filter, el botón es la tinta sólida de siempre.
 */
button,
.boton {
  position: relative;
  isolation: isolate;
  contain: paint;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  min-width: 44px;
  padding: 0.5rem 1.25rem;
  font: inherit;
  font-size: var(--t-m);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
  text-align: center;
  text-decoration: none;
  color: var(--sobre-primario);
  background: var(--primario);
  border: 1px solid var(--primario);
  border-radius: var(--r-boton);
  box-shadow: 0 10px 20px -12px color-mix(in srgb, var(--primario) 70%, transparent), 0 1px 2px color-mix(in srgb, var(--texto) 18%, transparent);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  --boton-vidrio: linear-gradient(180deg, color-mix(in srgb, var(--primario) 88%, transparent), color-mix(in srgb, var(--primario) 96%, transparent));
  --boton-brillo: linear-gradient(155deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0) 48%);
  --boton-filos: inset 2px 2px 1px 0 rgba(255, 255, 255, 0.42), inset -1px -1px 1px 1px rgba(255, 255, 255, 0.22);
  transition: transform 520ms var(--resorte), border-radius 520ms var(--resorte), box-shadow 300ms var(--salida), background-color var(--rapido) var(--salida), border-color var(--rapido) var(--salida), color var(--rapido) var(--salida);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  button,
  .boton {
    background: transparent;
    border-color: transparent;
  }

  button::before,
  .boton::before {
    content: "";
    position: absolute;
    /* Más grande que el botón: el filtro empuja los píxeles hacia dentro en los bordes, y si el cristal acabara justo en el borde
       se vería roto; así el borde lo pone el botón (overflow: hidden) y el cristal solo se deforma por dentro. */
    inset: -10px;
    z-index: -2;
    border-radius: inherit;
    background: var(--boton-vidrio);
    -webkit-backdrop-filter: blur(3px) saturate(1.35);
    backdrop-filter: blur(3px) saturate(1.35);
    filter: url(#vidrio-liquido);
  }

  button::after,
  .boton::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--boton-brillo);
    box-shadow: var(--boton-filos);
    pointer-events: none;
  }
}

@media (hover: hover) and (pointer: fine) {
  button:hover,
  .boton:hover {
    border-radius: calc(var(--r-boton) + 0.375rem);
    box-shadow: 0 14px 26px -12px color-mix(in srgb, var(--primario) 75%, transparent), 0 1px 2px color-mix(in srgb, var(--texto) 22%, transparent);
    transform: scale(1.035);
  }
}

button:active,
.boton:active {
  transform: scale(0.97);
  transition-duration: 160ms;
}

button[disabled],
.boton[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.boton-secundario {
  color: var(--texto);
  background: var(--papel);
  border-color: var(--borde);
  box-shadow: 0 8px 18px -14px color-mix(in srgb, var(--texto) 55%, transparent), 0 1px 2px color-mix(in srgb, var(--texto) 12%, transparent);
  --boton-vidrio: color-mix(in srgb, var(--papel) 58%, transparent);
  --boton-brillo: linear-gradient(155deg, rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 50%);
  --boton-filos: inset 2px 2px 1px 0 var(--boton-luz), inset -1px -1px 1px 1px color-mix(in srgb, var(--texto) 9%, transparent);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .boton-secundario {
    background: transparent;
    border-color: var(--borde);
  }
}

@media (hover: hover) and (pointer: fine) {
  .boton-secundario:hover {
    color: var(--texto);
    border-color: var(--texto);
    box-shadow: 0 14px 24px -14px color-mix(in srgb, var(--texto) 60%, transparent), 0 1px 2px color-mix(in srgb, var(--texto) 16%, transparent);
  }
}

/* El botón de lo que no se deshace («Borrar mi perfil», «Descartar este perfil»): con el par de error, que mide el contraste AA. */
.boton-peligro {
  color: var(--error-texto);
  background: var(--error-fondo);
  border-color: var(--error-borde);
  box-shadow: 0 8px 18px -14px color-mix(in srgb, var(--error-borde) 60%, transparent), 0 1px 2px color-mix(in srgb, var(--error-borde) 16%, transparent);
  --boton-vidrio: color-mix(in srgb, var(--error-fondo) 78%, transparent);
  --boton-brillo: linear-gradient(155deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 50%);
  --boton-filos: inset 2px 2px 1px 0 var(--boton-luz), inset -1px -1px 1px 1px color-mix(in srgb, var(--error-borde) 14%, transparent);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .boton-peligro {
    background: transparent;
    border-color: var(--error-borde);
  }
}

@media (hover: hover) and (pointer: fine) {
  .boton-peligro:hover {
    color: var(--error-texto);
    border-color: var(--error-texto);
  }
}

/* El filtro SVG del vidrio (Vistas::pagina lo pone una vez en cada página): sin tamaño y fuera del flujo. */
.filtros-vidrio {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

.boton-chico {
  min-height: 44px;
  margin: 0.25rem 0 0 0.5rem;
  padding: 0.375rem 0.875rem;
  font-size: 0.9375rem;
}

.acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}

/* Sin el campo del código (enlace.js lo ocultó), el botón queda arriba de la hoja. */
.campo[hidden] + .acciones {
  margin-top: 0;
}

.acciones + p {
  margin-top: 1rem;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 8. Los avisos: un bloque tintado con su icono dibujado (nunca una raya lateral gruesa)
 * ------------------------------------------------------------------------------------------------------------------ */

.aviso,
.error,
.aviso-ok {
  position: relative;
  margin: 0 0 1.25rem;
  padding: 0.875rem 1rem 0.875rem 2.875rem;
  border: 1px solid;
  border-radius: var(--r-control);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.aviso {
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  border-color: var(--aviso-linea);
}

.error {
  background: var(--error-fondo);
  color: var(--error-texto);
  border-color: var(--error-linea);
}

.aviso-ok {
  background: var(--acento-suave);
  color: var(--acento-tinta);
  border-color: var(--acento-linea);
  font-weight: 600;
}

/* El icono del aviso y del error: un círculo con su signo, dibujado con el color del texto del bloque. */
.aviso::before,
.error::before {
  content: "";
  position: absolute;
  left: 1rem;
  top: 0.9375rem;
  width: 1.125rem;
  height: 1.125rem;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  background:
    linear-gradient(currentColor, currentColor) 50% 3px / 1.5px 6px no-repeat,
    linear-gradient(currentColor, currentColor) 50% 10.5px / 1.5px 1.75px no-repeat;
}

/* El de lo que salió bien: una marca de hecho. */
.aviso-ok::before {
  content: "";
  position: absolute;
  left: 1.125rem;
  top: 1.0625rem;
  width: 0.75rem;
  height: 0.4375rem;
  border: solid currentColor;
  border-width: 0 0 2px 2px;
  transform: rotate(-45deg);
}

.aviso a,
.error a {
  color: inherit;
  text-decoration-color: currentColor;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 9. Los sellos de estado: verificado (oro), sin verificar (neutro con aviso), descartado y error
 * ------------------------------------------------------------------------------------------------------------------ */

.sello,
.etiqueta {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--linea);
  border-radius: 4px;
  background: var(--papel-2);
  color: var(--texto);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

.sello .icono,
.etiqueta .icono {
  width: 1rem;
  height: 1rem;
}

.sello-verificado,
.etiqueta-ok {
  border-color: var(--acento-linea);
  background: var(--acento-suave);
  color: var(--acento-tinta);
}

.sello-pendiente,
.etiqueta-pendiente {
  border-color: var(--aviso-linea);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

.sello-descartado {
  border-style: dashed;
  border-color: var(--borde);
  background: transparent;
  color: var(--silenciado);
}

.sello-error {
  border-color: var(--error-linea);
  background: var(--error-fondo);
  color: var(--error-texto);
}

.etiqueta-campo {
  display: inline-block;
  margin-left: 0.25rem;
  padding: 0 0.375rem;
  border: 1px solid var(--linea);
  border-radius: 4px;
  background: var(--papel-2);
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
  vertical-align: 0.1em;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 10. Las piezas: iconos, tablas, listas de datos, pasos, pestañas, estados vacíos, plegables, zona de peligro y carnet
 * ------------------------------------------------------------------------------------------------------------------ */

.icono {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

/* Tablas: líneas finas, la cabecera fija y la fila bajo el puntero resaltada; se desplazan a lo ancho en lo angosto. */
.tabla {
  overflow-x: auto;
  margin: 0 0 1rem;
  scrollbar-width: thin;
  scrollbar-color: var(--borde) transparent;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 0.75rem 0.875rem;
  text-align: left;
  vertical-align: middle;
  border-bottom: 1px solid var(--linea);
}

th {
  position: sticky;
  top: 0;
  background: var(--papel-2);
  color: var(--silenciado);
  font-size: var(--t-s);
  font-weight: 600;
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
  tbody tr:hover {
    background: var(--acento-suave);
  }
}

/* La primera columna de una tabla de perfiles es el nombre, con el enlace al perfil: encabezado de fila, sin el fondo de los de columna. */
.tabla th[scope="row"] {
  position: static;
  background: transparent;
  color: var(--texto);
  font-size: var(--t-m);
  font-weight: 600;
  white-space: normal;
}

.tabla th[scope="row"] a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* «Mis datos» y los datos del perfil: nombre y valor; en el teléfono, uno debajo del otro (un correo largo cabe entero). */
.datos {
  margin: 1rem 0 0;
}

.datos div {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.125rem 1rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--linea);
}

.datos div:last-child {
  border-bottom: 0;
}

.datos dt {
  color: var(--silenciado);
  font-size: var(--t-s);
  font-weight: 600;
}

.datos dd {
  margin: 0;
  overflow-wrap: anywhere;
}

@media (min-width: 40rem) {
  .datos div {
    grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr);
    align-items: baseline;
  }
}

/* Pasos numerados dibujados, donde la secuencia importa (verificar, activar): un círculo con el número y un hilo al siguiente. */
.pasos,
.pasos-verificacion {
  counter-reset: paso;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.pasos > li,
.pasos-verificacion > li {
  counter-increment: paso;
  position: relative;
  min-height: 2.25rem;
  padding: 0.125rem 0 1rem 2.75rem;
}

.pasos > li::before,
.pasos-verificacion > li::before {
  content: counter(paso);
  position: absolute;
  left: 0;
  top: -0.0625rem;
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.875rem;
  border: 1px solid var(--borde);
  border-radius: 50%;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pasos > li::after,
.pasos-verificacion > li::after {
  content: "";
  position: absolute;
  left: 0.9375rem;
  top: 2rem;
  bottom: 0.125rem;
  width: 1px;
  background: var(--linea);
}

.pasos > li:last-child,
.pasos-verificacion > li:last-child {
  padding-bottom: 0;
}

.pasos > li:last-child::after,
.pasos-verificacion > li:last-child::after {
  display: none;
}

.pasos > li.paso-listo::before {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.pasos > li.paso-actual::before {
  border-color: var(--acento);
  box-shadow: 0 0 0 3px var(--acento-suave);
}

/*
 * Las pestañas del portal: una barra de una sola línea al pie de la cabecera del perfil, con el icono y el nombre de cada una.
 * En una pantalla angosta se desplaza a lo ancho (pestanas.js la corre hasta la actual) y una sombra suave en cada borde dice
 * que hay más (la sombra va fija a la barra y el papel que la tapa va con el contenido: en cada punta, la tapa). La actual va en
 * negrita, en tinta, con su icono en el acento y una barra debajo (no solo de otro color); las que todavía no se abren llevan su
 * candado. Cada una es un objetivo de al menos 44 × 44 px; el anillo del foco va por dentro, para que la barra no lo recorte.
 */
.pestanas {
  border-top: 1px solid var(--linea);
}

.pestanas ul {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.125rem;
  margin: 0;
  padding: 0 clamp(0.25rem, 1.5vw, 1rem);
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-padding-inline: 2rem;
  scrollbar-width: none;
  background:
    linear-gradient(90deg, var(--vidrio-macizo) 45%, transparent) 0 0 / 2.5rem 100% no-repeat local,
    linear-gradient(270deg, var(--vidrio-macizo) 45%, transparent) 100% 0 / 2.5rem 100% no-repeat local,
    linear-gradient(90deg, var(--sombra-borde), transparent) 0 0 / 1rem 100% no-repeat scroll,
    linear-gradient(270deg, var(--sombra-borde), transparent) 100% 0 / 1rem 100% no-repeat scroll,
    var(--vidrio-macizo);
}

.pestanas ul::-webkit-scrollbar {
  display: none;
}

.pestanas li {
  flex: none;
}

.pestanas a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  min-width: 44px;
  height: 3.25rem;
  padding: 0 0.75rem;
  color: var(--silenciado);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  transition: color var(--rapido) var(--salida), box-shadow var(--rapido) var(--salida);
}

.pestanas a .icono {
  width: 1.125rem;
  height: 1.125rem;
}

/* El candado de una pestaña que todavía no se abre: más chico que el icono, detrás del nombre. */
.pestanas a .icono-candado {
  width: 0.875rem;
  height: 0.875rem;
  margin-left: -0.125rem;
}

@media (hover: hover) and (pointer: fine) {
  .pestanas a:hover {
    color: var(--texto);
    box-shadow: inset 0 -2px 0 var(--linea);
  }
}

.pestanas a[aria-current="page"] {
  color: var(--texto);
  font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--acento);
}

.pestanas a[aria-current="page"] .icono:not(.icono-candado) {
  color: var(--acento);
}

.pestanas a:focus-visible {
  outline-offset: -3px;
  border-radius: var(--r-control);
}

.pestana-descripcion {
  color: var(--silenciado);
}

/*
 * El estado vacío de una pestaña: su dibujo (Sis\Ilustraciones), su título, lo que va a aparecer en ella y cuándo. Sin recuadro ni
 * hueco punteado: la hoja ya es el contenedor. Bloqueada (nivel 1), el dibujo pierde su detalle en el acento y el cuándo lleva su
 * candado en una pieza propia; abierta (nivel 2), el cuándo es una línea tranquila.
 */
.vacio {
  display: grid;
  justify-items: center;
  padding: 0.75rem 0 0.25rem;
  text-align: center;
}

.ilustracion {
  display: block;
  width: 7.5rem;
  height: auto;
  color: var(--borde);
}

.ilustracion * {
  vector-effect: non-scaling-stroke;
}

.ilustracion .acento {
  stroke: var(--acento);
}

.vacio .ilustracion {
  margin: 0 0 1.5rem;
}

.vacio-bloqueado .ilustracion {
  color: color-mix(in srgb, var(--borde) 70%, var(--papel));
}

.vacio-bloqueado .ilustracion .acento {
  stroke: currentColor;
}

.vacio h2 {
  margin: 0 0 0.375rem;
}

.vacio .pestana-descripcion {
  max-width: 32rem;
  margin: 0 0 1.25rem;
}

.vacio-estado {
  max-width: 30rem;
  margin: 0;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.vacio-bloqueado .vacio-estado {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--papel-2);
  font-weight: 600;
  text-align: left;
}

.vacio-estado .icono {
  width: 1rem;
  height: 1rem;
  color: var(--acento);
}

/* Un bloque plegable: el triángulo dice si está abierto (el propio se pierde con display: flex). */
.plegable > summary,
.zona-peligro > summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 44px;
  cursor: pointer;
  font-size: var(--t-m);
  font-weight: 650;
  list-style: none;
}

.plegable > summary::-webkit-details-marker,
.zona-peligro > summary::-webkit-details-marker {
  display: none;
}

.plegable > summary::before,
.zona-peligro > summary::after {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--rapido) var(--salida);
}

.plegable[open] > summary::before,
.zona-peligro[open] > summary::after {
  transform: rotate(45deg);
}

.plegable[open] > summary {
  margin-bottom: 0.75rem;
}

/* La zona de peligro: lo irreversible, al final, aparte y plegado; se abre a propósito. */
.zona-peligro {
  margin: 1.5rem 0 0;
  border: 1px solid var(--error-linea);
  border-radius: var(--r-hoja);
  background: var(--papel);
}

.zona-peligro > summary {
  justify-content: space-between;
  padding: 0.5rem 1.25rem;
  color: var(--error-texto);
}

.zona-peligro[open] > summary {
  border-bottom: 1px solid var(--error-linea);
}

.zona-peligro > :not(summary) {
  margin: 1rem 1.25rem;
}

/*
 * El carnet: la credencial del paciente verificado, con la proporción de una tarjeta de identidad (85,6 × 54). Arriba quien la
 * emite (el monograma y el nombre de la clínica); al centro la persona (sus iniciales en el lugar de la foto, su nombre y su
 * cédula tapada); abajo el número de historia, en monoespaciada tabular (es un dato que se dicta), y el sello «Verificado en
 * persona» en el acento. Un filo del acento arriba y, en la esquina, un velo de la ilustración de la clínica que se apaga, como el
 * holograma de una credencial. Es de vidrio (enmienda del 29-oct): translúcido, con la luz del borde y el destello (sección 16).
 * Sin recortar: si el nombre de la clínica o el de la persona son largos (en 320 px), la tarjeta crece.
 */
.carnet {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 0.875rem;
  width: 100%;
  max-width: 22rem;
  aspect-ratio: 85.6 / 54;
  padding: 0.875rem 1rem 1rem;
  border: 1px solid var(--vidrio-borde);
  border-radius: 14px;
  background:
    radial-gradient(70% 90% at 100% 0, var(--carnet-velo-1), transparent 70%),
    radial-gradient(60% 70% at 88% 12%, var(--carnet-velo-2), transparent 75%),
    var(--vidrio);
  box-shadow: var(--vidrio-sombra), inset 0 3px 0 var(--acento);
}

.carnet p {
  margin: 0;
}

.carnet-emisor {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.carnet-monograma {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.625rem;
  height: 1.625rem;
  border-radius: 5px;
  background: var(--primario);
  color: var(--sobre-primario);
  box-shadow: inset 0 -2px 0 var(--acento);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.carnet-persona {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.875rem;
}

.carnet-foto {
  display: grid;
  place-items: center;
  width: clamp(2.5rem, 13vw, 3.25rem);
  height: clamp(2.5rem, 13vw, 3.25rem);
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--papel-2);
  color: var(--texto);
  font-size: var(--t-l);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.carnet-nombre {
  font-size: var(--t-l);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.carnet .carnet-cedula {
  margin-top: 0.25rem;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.carnet-cedula .cifras,
.carnet-historia {
  font-family: var(--letra-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}

.carnet-cedula .cifras {
  color: var(--texto);
}

.carnet-pie {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
}

.carnet-historia {
  font-size: 0.9375rem;
  font-weight: 500;
}

/* Lo que se copia una sola vez: la clave de la aplicación de autenticación y los códigos de recuperación. */
.clave {
  display: inline-block;
  padding: 0.625rem 0.875rem;
  font-size: var(--t-l);
  font-weight: 600;
  letter-spacing: 0.06em;
  word-spacing: 0.2em;
  user-select: all;
  -webkit-user-select: all;
}

.codigos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.5rem 1rem;
  margin: 0 0 1.25rem;
  padding: 0 0 0 1.5rem;
  font-variant-numeric: tabular-nums;
}

.codigos li::marker {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.codigos code {
  font-size: var(--t-m);
  letter-spacing: 0.04em;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 11. Las hojas: el papel sobre la cuadrícula. Las pantallas de entrada son una hoja centrada; las que todavía no tienen su
 *     armazón propio (las rediseñan los cortes B y C) tienen su hoja en `main`, para que ningún texto quede sobre las líneas.
 * ------------------------------------------------------------------------------------------------------------------ */

/* El papel ahora es vidrio (enmienda del 29-oct): translúcido, con su borde fino y su sombra; la luz del borde, en la sección 16. */
.hoja,
.tarjeta {
  background: var(--vidrio);
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--r-hoja);
  box-shadow: var(--vidrio-sombra);
}

.hoja {
  padding: 1.5rem 1.25rem 1.75rem;
}

.hoja > :first-child,
.tarjeta > :first-child,
.hoja-cuerpo > :first-child,
.hoja-margen > :first-child {
  margin-top: 0;
}

.hoja > :last-child,
.tarjeta > :last-child,
.hoja-cuerpo > :last-child,
.hoja-margen > :last-child {
  margin-bottom: 0;
}

.hoja form {
  max-width: none;
}

main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
  flex: 0 0 auto;
  width: calc(100% - 2rem);
  max-width: 60rem;
  margin: 1.5rem auto 4rem;
  padding: 1.5rem 1.25rem 2rem;
  background: var(--vidrio);
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--r-hoja);
  box-shadow: var(--vidrio-sombra);
}

main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) > :last-child {
  margin-bottom: 0;
}

/* La entrada: una hoja centrada, angosta, con el título, el formulario y debajo las salidas. */
.entrada {
  display: grid;
  justify-items: center;
  align-content: start;
  padding-top: 0.5rem;
}

.entrada > .hoja {
  width: 100%;
  max-width: 29rem;
}

.entrada-media > .hoja {
  max-width: 38rem;
}

.hoja-encabezado {
  margin: 0 0 1.5rem;
}

.hoja-encabezado h1 {
  margin: 0 0 0.5rem;
}

/* El icono de una hoja de un solo mensaje («Correo confirmado», «Este enlace ya no sirve»…): en su pieza, arriba del título. */
.hoja-icono {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin: 0 0 1.25rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel-2);
  color: var(--texto);
}

.hoja-icono .icono {
  width: 1.5rem;
  height: 1.5rem;
}

.hoja-icono-bien {
  border-color: var(--acento-linea);
  background: var(--acento-suave);
  color: var(--acento-tinta);
}

/* Lo de abajo de la hoja: otro camino («¿Primera vez en el portal?»), separado por un filo. */
.hoja-pie {
  margin: 1.75rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--linea);
}

.hoja-pie h2 {
  margin: 0 0 0.25rem;
  font-size: var(--t-m);
}

.hoja-pie p {
  color: var(--silenciado);
  font-size: 0.9375rem;
}

.hoja-pie .acciones {
  margin-top: 0.75rem;
}

.invitado-paciente {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px dashed var(--linea);
}

.invitado-paciente > h3 {
  margin: 0 0 0.25rem;
}

.hoja-seccion + .hoja-seccion {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--linea);
}

.hoja-seccion > h2:first-child {
  margin-top: 0;
  font-size: var(--t-l);
}

/* En la hoja, el botón principal va a lo ancho: se ve y se toca sin buscarlo. */
.entrada .acciones > button,
.entrada .acciones > .boton,
.entrada .acciones > form {
  flex: 1 1 100%;
}

.entrada .acciones > form {
  display: flex;
  margin: 0;
}

.entrada .acciones > form > button {
  flex: 1 1 auto;
}

/* La hoja doble: el cuerpo y, al lado (en una pantalla ancha) o debajo, su margen con lo que conviene saber. */
.hoja-doble {
  display: grid;
  padding: 0;
}

.hoja-doble > .hoja-cuerpo {
  padding: 1.5rem 1.25rem 1.75rem;
}

.hoja-doble > .hoja-margen {
  padding: 1.5rem 1.25rem 1.75rem;
  background: var(--vidrio-2);
  border-top: 1px solid var(--linea);
  border-radius: 0 0 calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px);
}

.entrada > .hoja-doble {
  max-width: 29rem;
}

.entrada-ancha > .hoja-doble {
  max-width: 40rem;
}

.hoja-margen h2 {
  margin: 0 0 1rem;
  font-size: var(--t-m);
}

.hoja-margen > p {
  color: var(--silenciado);
  font-size: var(--t-s);
}

/* Lo que ofrece el portal: sus siete pestañas, cada una con su icono y lo que va a traer. */
.lista-portal {
  display: grid;
  gap: 0.625rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.lista-portal li {
  display: grid;
  grid-template-columns: 2.125rem minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
  font-size: var(--t-s);
  line-height: 1.45;
}

.lista-portal .icono {
  box-sizing: content-box;
  width: 1.125rem;
  height: 1.125rem;
  padding: 0.4375rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--papel);
}

.lista-portal strong {
  display: block;
  color: var(--texto);
  font-size: 0.9375rem;
}

.lista-portal span span {
  color: var(--silenciado);
}

.nota-candado {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

.nota-candado .icono {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.0625rem;
  color: var(--acento);
}

@media (min-width: 40rem) {
  .entrada {
    padding-top: 1.5rem;
  }

  .hoja {
    padding: 2.25rem 2.5rem 2.5rem;
  }

  .hoja-doble {
    padding: 0;
  }

  .hoja-doble > .hoja-cuerpo {
    padding: 2.25rem 2.5rem 2.5rem;
  }

  .hoja-doble > .hoja-margen {
    padding: 2rem 2.5rem 2.25rem;
  }

  main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
    margin-top: 2.5rem;
    padding: 2.5rem 3rem 3rem;
  }
}

@media (min-width: 60rem) {
  .entrada > .hoja-doble {
    max-width: 56rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 21rem);
  }

  .entrada-ancha > .hoja-doble {
    max-width: 66rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
  }

  .hoja-doble > .hoja-margen {
    border-top: 0;
    border-left: 1px solid var(--linea);
    border-radius: 0 calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px) 0;
  }

  .hoja-margen-fija > :first-child {
    position: sticky;
    top: 1.5rem;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 12. El portal sin sesión: el registro (sus secciones numeradas y sus textos legales) y las páginas de un mensaje
 * ------------------------------------------------------------------------------------------------------------------ */

.publico {
  max-width: 34rem;
  margin: 0 auto;
}

.publico form {
  max-width: none;
}

.encabezado {
  margin: 0 0 1.5rem;
}

.encabezado h1 {
  margin: 0 0 0.5rem;
}

.tarjeta {
  margin: 0 0 1rem;
  padding: 1.5rem 1.25rem;
}

.tarjeta h2 {
  margin: 0 0 1rem;
  font-size: var(--t-l);
}

.tarjeta-suave {
  background: var(--vidrio-2);
  box-shadow: none;
}

.tarjetas {
  display: grid;
  gap: 1rem;
}

.tarjetas .tarjeta {
  margin: 0;
}

/* Dentro de una hoja, las secciones son zonas del mismo papel, separadas por un filo: nunca una tarjeta dentro de otra. */
.hoja .tarjeta {
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.hoja .tarjeta + .tarjeta {
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
}

/* Las secciones numeradas del registro. */
.paso h2 {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.paso-numero {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.875rem;
  height: 1.875rem;
  border: 1px solid var(--borde);
  border-radius: 50%;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Los textos legales: completos y legibles sin JS, en un recuadro que se desplaza y se enfoca con el teclado. */
.texto-legal-bloque {
  margin: 0 0 1.25rem;
  padding: 0 0 1.25rem;
  border-bottom: 1px solid var(--linea);
}

.texto-legal-bloque h3 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

/* La versión de un texto legal, como un sello chico junto a su nombre: se lee qué versión se acepta. */
.version {
  display: inline-block;
  margin-left: 0.25rem;
  padding: 0 0.375rem;
  border: 1px solid var(--linea);
  border-radius: 4px;
  background: var(--papel-2);
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  vertical-align: 0.1em;
  white-space: nowrap;
}

/* El texto, en su caja que se desplaza; una sombra arriba o abajo dice que hay más (la tapa el papel cuando se llega a la punta). */
.texto-legal {
  max-height: 12rem;
  overflow: auto;
  overscroll-behavior: contain;
  margin: 0 0 0.75rem;
  padding: 0.75rem 1rem;
  background:
    linear-gradient(var(--papel-2) 40%, transparent) 0 0 / 100% 1.5rem no-repeat local,
    linear-gradient(transparent, var(--papel-2) 60%) 0 100% / 100% 1.5rem no-repeat local,
    linear-gradient(var(--sombra-borde), transparent) 0 0 / 100% 0.625rem no-repeat scroll,
    linear-gradient(transparent, var(--sombra-borde)) 0 100% / 100% 0.625rem no-repeat scroll,
    var(--papel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  font-size: 0.9375rem;
  line-height: 1.55;
  white-space: pre-line;
  scrollbar-width: thin;
  scrollbar-color: var(--borde) transparent;
}

/* «Obligatorio» y «Opcional» junto a cada casilla: el obligatorio, en tinta; el opcional, en silencio y con el borde punteado. */
.etiqueta-obligatorio {
  border-color: var(--borde);
  color: var(--texto);
}

.etiqueta-opcional {
  border-style: dashed;
  background: transparent;
}

/*
 * El registro (corte B): un riel vertical de pasos. Cada sección es un paso: en el teléfono, su título numerado y debajo lo suyo;
 * desde 60rem, el título en la columna del riel (fijo mientras se llenan sus campos, con el hilo que baja al siguiente) y lo
 * suyo a la derecha, con el filo entre pasos solo de ese lado. El número se pone en el acento mientras se escribe en su paso
 * (:focus-within) y pasa a la marca de hecho cuando todo lo obligatorio del paso está completo (nada :invalid ni con error); el
 * último, «Qué pasa después», lleva una flecha en lugar del número.
 */
.entrada-registro > .hoja {
  width: 100%;
  max-width: 64rem;
}

.registro .hoja-encabezado {
  margin-bottom: 1.75rem;
}

.registro .paso {
  position: relative;
}

.registro .paso > h2 {
  margin: 0 0 1rem;
  font-size: var(--t-l);
}

.registro .paso-cuerpo > :first-child {
  margin-top: 0;
}

.registro .paso-cuerpo > :last-child {
  margin-bottom: 0;
}

.registro .paso-numero {
  position: relative;
  transition: border-color var(--rapido) var(--salida), background-color var(--rapido) var(--salida), box-shadow var(--rapido) var(--salida), color var(--rapido) var(--salida);
}

.registro .paso-numero .icono {
  width: 1rem;
  height: 1rem;
}

.registro .paso:focus-within .paso-numero {
  border-color: var(--acento);
  color: var(--acento-tinta);
  box-shadow: 0 0 0 4px var(--acento-suave);
}

.registro .paso:has(input:not([type="hidden"])):not(:has(:invalid, [aria-invalid="true"])) .paso-numero {
  border-color: var(--primario);
  background: var(--primario);
  color: transparent;
}

.registro .paso:has(input:not([type="hidden"])):not(:has(:invalid, [aria-invalid="true"])) .paso-numero::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0.625rem;
  height: 0.3125rem;
  border: solid var(--sobre-primario);
  border-width: 0 0 2px 2px;
  transform: translate(-50%, -65%) rotate(-45deg);
}

.registro .paso-despues .pasos {
  margin-bottom: 0.75rem;
}

.registro .paso-enviar {
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
}

.registro .paso-enviar .acciones {
  margin-top: 0;
}

.registro .paso-enviar .acciones > button {
  flex: 1 1 100%;
}

@media (min-width: 60rem) {
  .registro .paso,
  .registro .paso-enviar {
    display: grid;
    grid-template-columns: 14rem minmax(0, 1fr);
    column-gap: 3rem;
  }

  .registro .paso > h2 {
    position: sticky;
    top: 1.5rem;
    align-self: start;
    align-items: flex-start;
    margin: 0;
    font-size: var(--t-m);
    line-height: 1.35;
  }

  .registro .paso > h2 .paso-numero {
    margin-top: -0.25rem;
  }

  .registro .paso-cuerpo,
  .registro .paso-enviar > * {
    grid-column: 2;
  }

  .registro .paso-enviar > * + * {
    margin-top: 0.75rem;
  }

  /* El filo entre pasos, solo sobre lo suyo (el riel sigue entero a la izquierda): 14rem del riel y 3rem de aire. */
  .hoja.registro .paso + .paso,
  .hoja.registro .paso-enviar {
    margin-top: 2.25rem;
    padding-top: 2.25rem;
    border-top: 0;
    background: linear-gradient(var(--linea), var(--linea)) 17rem 0 / calc(100% - 17rem) 1px no-repeat;
  }

  /*
   * El hilo del riel: del número de cada paso al del siguiente, a través del aire y del filo de entre los dos (2,25 + 2,25 rem);
   * `--arriba` es lo que el paso tiene encima de su número (nada el primero).
   */
  .hoja.registro .paso::before {
    content: "";
    position: absolute;
    left: calc(0.9375rem - 0.5px);
    top: calc(var(--arriba, 0rem) + 2rem);
    bottom: -3.875rem;
    width: 1px;
    background: var(--linea);
  }

  .hoja.registro .paso + .paso {
    --arriba: 2.25rem;
  }

  .hoja.registro .paso-despues::before {
    display: none;
  }

  .registro .paso-enviar .acciones > button {
    flex: 0 0 auto;
    min-width: 16rem;
  }
}

.publico .acciones .boton,
.publico .acciones button {
  flex: 1 1 100%;
}

@media (min-width: 40rem) {
  .tarjeta {
    padding: 2rem;
  }

  .publico .acciones .boton,
  .publico .acciones button {
    flex: 0 0 auto;
    min-width: 12rem;
  }
}

@media (min-width: 56rem) {
  .tarjetas {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    align-items: start;
    gap: 1.5rem;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 13. El portal con sesión (corte B): la cabecera del perfil con sus pestañas, el tablero de Mi portal (el riel de pasos del
 *     nivel 1 o el carnet del nivel 2, al lado de la pestaña), la hoja de cada pestaña, Mis datos, el código vivo y la encuesta
 * ------------------------------------------------------------------------------------------------------------------ */

/* Una columna de piezas separadas por el mismo aire; lo que solo muestra un fragmento (:target) no deja hueco si no se ve. */
.portal {
  display: grid;
  gap: 1rem;
  max-width: 68rem;
  margin: 0 auto;
}

.portal > * {
  min-width: 0;
  margin: 0;
}

/*
 * La cabecera del perfil, como la de una red social pero privada: la portada (un trozo de la cuadrícula, tibio del acento), las
 * iniciales grandes que la montan, «Hola, <nombres>» y los sellos del perfil; al pie, la barra de pestañas.
 */
.perfil {
  overflow: hidden;
  background: var(--vidrio);
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--r-hoja);
  box-shadow: var(--vidrio-sombra);
}

/*
 * La portada: el color líquido de la clínica, como la foto de portada de una red social (liquido.js pinta dentro su ilustración,
 * la receta «portada»); mientras tanto, y sin JS, un degradado de la misma paleta. Decorativa: sin texto encima.
 */
.perfil-portada {
  position: relative;
  height: 3.5rem;
  overflow: hidden;
  background-color: var(--ilustracion-4);
  background-image:
    radial-gradient(60% 140% at 18% 0, var(--ilustracion-1), transparent 70%),
    radial-gradient(50% 160% at 78% 100%, var(--ilustracion-3), transparent 72%),
    linear-gradient(100deg, var(--ilustracion-2), var(--ilustracion-4) 55%, var(--ilustracion-2));
  border-bottom: 1px solid var(--vidrio-borde);
}

.perfil-cuerpo {
  display: flex;
  align-items: flex-end;
  gap: 0.875rem;
  padding: 0 1rem 1rem;
}

/* Las iniciales montan la portada: van por encima de ella (que ahora es una capa con su lienzo). */
.perfil-avatar {
  position: relative;
  z-index: 2;
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 4.5rem;
  height: 4.5rem;
  margin-top: -2.25rem;
  border: 3px solid var(--papel);
  border-radius: 16px;
  background: var(--primario);
  color: var(--sobre-primario);
  box-shadow: inset 0 -3px 0 var(--acento), 0 6px 14px -8px color-mix(in srgb, var(--c-texto) 45%, transparent);
  font-size: var(--t-xl);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.perfil-texto {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 0.625rem;
}

.perfil h1 {
  margin: 0 0 0.375rem;
  font-size: var(--t-xl);
  overflow-wrap: anywhere;
}

.perfil-etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Un sello de la cabecera baja de línea si no cabe (un número de historia largo en 320 px): la cabecera recorta lo que sale. */
.perfil-etiquetas .sello {
  max-width: 100%;
  white-space: normal;
}

.sello-historia {
  font-variant-numeric: tabular-nums;
}

/*
 * El tablero de Mi portal: una sola hoja con su margen. En el margen, lo que es de la persona (el riel de pasos para abrir el
 * portal, en el nivel 1; el carnet, en el nivel 2); en el cuerpo, la pestaña Resumen. En el teléfono el margen va primero, arriba;
 * desde 60rem, a la izquierda.
 */
.tablero {
  display: grid;
  padding: 0;
}

.tablero-lado {
  padding: 1.25rem 1rem 1.5rem;
  background: var(--vidrio-2);
  border-bottom: 1px solid var(--linea);
  border-radius: calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px) 0 0;
}

.tablero-lado > h2 {
  margin: 0 0 1.125rem;
  font-size: var(--t-m);
}

.tablero-principal {
  min-width: 0;
  padding: 1.75rem 1.25rem 1.75rem;
}

.tablero-nota {
  margin: 0.875rem 0 0;
  max-width: 22rem;
  color: var(--silenciado);
  font-size: var(--t-s);
}

/*
 * El riel de pasos: el número (o la marca de hecho) en su círculo y un hilo al siguiente, que va en el acento donde ya se
 * avanzó. El paso actual (aria-current="step") lleva el anillo del acento, su explicación y su acción; los que vienen, en
 * silencio. Cada paso dice su estado también en palabras, para el lector de pantalla.
 */
.riel {
  margin: 0;
  padding: 0;
  list-style: none;
}

.riel-paso {
  position: relative;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  column-gap: 0.875rem;
  padding: 0 0 1.375rem;
}

.riel-paso:last-child {
  padding-bottom: 0;
}

.riel-paso::before {
  content: "";
  position: absolute;
  left: calc(1rem - 0.5px);
  top: 2.375rem;
  bottom: 0.375rem;
  width: 1px;
  background: var(--borde);
  opacity: 0.45;
}

.riel-paso:last-child::before {
  display: none;
}

.riel-hecho::before {
  background: var(--acento);
  opacity: 1;
}

.riel-marca {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--borde);
  border-radius: 50%;
  background: var(--papel);
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.riel-marca .icono {
  width: 1rem;
  height: 1rem;
}

.riel-hecho .riel-marca {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.riel-actual .riel-marca {
  border-color: var(--acento);
  background: var(--papel);
  color: var(--acento-tinta);
  box-shadow: 0 0 0 4px var(--acento-suave);
}

.riel-texto {
  min-width: 0;
  padding-top: 0.3125rem;
}

.riel-texto h3 {
  margin: 0;
  font-size: var(--t-m);
  font-weight: 650;
  line-height: 1.35;
}

.riel-paso:not(.riel-hecho):not(.riel-actual) h3 {
  color: var(--silenciado);
  font-weight: 600;
}

.riel-detalle {
  margin: 0.375rem 0 0;
  color: var(--silenciado);
  font-size: var(--t-s);
  line-height: 1.55;
}

.riel-detalle strong {
  color: var(--texto);
  font-weight: 650;
}

/* El paso que viene se lee entero, pero en silencio: lo que pide no es para ahora. */
.riel-paso:not(.riel-hecho):not(.riel-actual) .riel-detalle strong {
  color: inherit;
  font-weight: 600;
}

.riel .acciones {
  margin-top: 0.875rem;
  gap: 0.5rem;
}

/* El mensaje de «Reenviar el enlace»: lo muestra el fragmento #reenviado (sin JS). */
.reenviado {
  display: none;
}

.reenviado:target {
  display: block;
  margin: 0.75rem 0 0;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-control);
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-size: var(--t-s);
  font-weight: 600;
}

/* La invitación a la encuesta: al pie de la pestaña, tras un filo, con su acción secundaria (la principal está en el riel). */
.invitacion {
  margin: 2rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--linea);
}

.invitacion h2 {
  margin: 0 0 0.25rem;
  font-size: var(--t-m);
}

.invitacion p {
  margin: 0;
  color: var(--silenciado);
  font-size: 0.9375rem;
}

.invitacion .acciones {
  margin-top: 1rem;
}

/* La hoja de una pestaña (y de Mis datos, la encuesta, el código y los mensajes): el papel, con su título y lo suyo. */
.hoja-pestana > h2:first-child,
.hoja-pestana > .hoja-seccion > h2:first-child {
  margin-top: 0;
}

.hoja-pestana .pestana-descripcion {
  max-width: 40rem;
}

/* Mis datos: lo que la clínica tiene, la sesión y, al final y aparte, lo que no se deshace (con el filo y el título del error). */
.hoja-seccion > h2 {
  margin: 0 0 0.375rem;
  font-size: var(--t-l);
}

.hoja-seccion.borrar-perfil {
  border-top-color: var(--error-linea);
}

.borrar-perfil > h2 {
  color: var(--error-texto);
}

.borrar-perfil form {
  max-width: 26rem;
}

/* Una página de un solo mensaje con sesión (las esperas y los 409): el icono de lo que pasó, el título y la salida. */
.hoja-mensaje .hoja-icono {
  margin-bottom: 1rem;
}

/* «Todavía no te verifican»: lo muestra el fragmento #todavia, adonde vuelve «Ya me verificaron» (sin JS). */
.todavia {
  display: none;
}

.todavia:target {
  display: block;
}

/* «Tu perfil se borró»: lo muestra el fragmento #borrado en la entrada, adonde va «Borrar mi perfil» (sin JS). */
.borrado {
  display: none;
}

.borrado:target {
  display: block;
}

/* El agradecimiento de la encuesta guardada: lo muestra el fragmento #gracias (sin JS). */
.gracias {
  display: none;
}

.gracias:target {
  display: block;
  padding: 1rem 1.25rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-hoja);
  background: var(--acento-suave);
}

.gracias h2 {
  margin: 0 0 0.25rem;
  font-size: var(--t-m);
}

.gracias p {
  margin: 0;
}

.gracias .urgencia {
  margin: 0.75rem 0 0;
}

/* La encuesta: el aviso de urgencia a la vista, preguntas en piezas de opción. */
.urgencia {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  margin: 0 0 1.5rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--error-linea);
  border-radius: var(--r-control);
  background: var(--error-fondo);
  color: var(--error-texto);
  font-size: 0.9375rem;
}

.urgencia .icono {
  margin-top: 0.125rem;
}

.pregunta {
  min-width: 0;
  margin: 0 0 1.75rem;
  padding: 0;
  border: 0;
}

.pregunta legend {
  margin: 0 0 0.625rem;
  padding: 0;
  font-size: var(--t-m);
  font-weight: 650;
}

.opciones {
  display: grid;
  gap: 0.5rem;
}

.opcion-tarjeta {
  padding: 0 0.875rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-control);
  background: var(--campo);
  transition: border-color var(--rapido) var(--salida), background-color var(--rapido) var(--salida);
}

.opcion-tarjeta label {
  flex: 1;
  padding: 0.625rem 0;
}

@media (hover: hover) and (pointer: fine) {
  .opcion-tarjeta:hover {
    border-color: var(--texto);
  }
}

.opcion-tarjeta:has(input:checked) {
  border-color: var(--primario);
  background: var(--acento-suave);
  box-shadow: inset 0 0 0 1px var(--primario);
}

.opcion-tarjeta:has(input:focus-visible) {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.campo-texto {
  margin-top: 1rem;
}

/* Donde el navegador lo admite, las preguntas que no tocan se ocultan; si no (sin :has), se ven todas y el servidor las ignora. */
.encuesta:has(#encuesta-busca-tratamiento:checked) .si-molestia,
.encuesta:has(#encuesta-busca-control:checked) .si-molestia,
.encuesta:has(#encuesta-busca-conocer:checked) .si-molestia,
.encuesta:has(#encuesta-busca-molestia:checked) .si-tratamiento,
.encuesta:has(#encuesta-busca-control:checked) .si-tratamiento,
.encuesta:has(#encuesta-busca-conocer:checked) .si-tratamiento {
  display: none;
}

.portal .acciones .boton,
.portal .acciones button {
  flex: 1 1 100%;
}

/* Un formulario de un solo botón dentro de .acciones del portal («Ya me verificaron», «Salir», «Reenviar»): una fila más de botones. */
.portal .acciones form {
  display: flex;
  flex: 1 1 100%;
  margin: 0;
}

/*
 * La página del código vivo (/verificacion): el código es lo que se ve. Seis dígitos muy grandes, tabulares, en dos grupos (el
 * espacio entre ellos, más ancho), en una sola línea; debajo, una barra fina en el acento que se vacía hasta que el código vence
 * y la hora en que vence. Al vencer, sin JS: el código se apaga y tachado, y la hora cede su lugar a «ya venció» (las animaciones
 * solo esperan su momento: data-queda, los segundos que le quedan en tramos de 5, da la espera). Con movimiento reducido la barra
 * no se mueve: se queda en lo que quedaba al abrir la página, y el aviso de vencido llega igual, a su hora.
 */
.codigo-vivo {
  display: grid;
  justify-items: center;
  margin: 1.5rem 0;
  padding: 1.5rem 0.75rem 1.25rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel-2);
  text-align: center;
}

.codigo-vivo p {
  margin: 0;
}

.codigo-vivo-etiqueta {
  color: var(--silenciado);
  font-size: var(--t-s);
  font-weight: 600;
}

.codigo-vivo-numero {
  margin: 0.25rem 0 0;
  color: var(--texto);
  font-size: clamp(2.75rem, 0.5rem + 11vw, 5.5rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  word-spacing: 0.18em;
  line-height: 1.05;
  white-space: nowrap;
  text-decoration-color: var(--borde);
  text-decoration-thickness: 0.05em;
}

.codigo-vivo-barra {
  width: min(100%, 15rem);
  height: 0.25rem;
  margin: 1rem 0 0.75rem;
  border-radius: 999px;
  background: var(--linea);
  overflow: hidden;
}

.codigo-vivo-barra::after {
  content: "";
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--acento);
  transform-origin: left center;
}

.codigo-vivo-plazo {
  display: grid;
  font-size: 0.9375rem;
  font-weight: 600;
}

.codigo-vivo-plazo > p {
  grid-area: 1 / 1;
}

.codigo-vivo-vencido {
  visibility: hidden;
  color: var(--aviso-texto);
}

.codigo-vivo .boton-chico {
  margin: 1rem 0 0;
}

.codigo-vivo[data-queda] .codigo-vivo-barra::after {
  animation: codigo-queda 120s linear var(--pasado) forwards;
}

.codigo-vivo[data-queda] .codigo-vivo-numero {
  animation: codigo-apagado 1ms step-end var(--queda) forwards;
}

.codigo-vivo[data-queda] .codigo-vivo-vence {
  animation: codigo-oculto 1ms step-end var(--queda) forwards;
}

.codigo-vivo[data-queda] .codigo-vivo-vencido {
  animation: codigo-visible 1ms step-end var(--queda) forwards;
}

@keyframes codigo-queda {
  from {
    transform: scaleX(1);
  }

  to {
    transform: scaleX(0);
  }
}

@keyframes codigo-apagado {
  to {
    color: var(--silenciado);
    text-decoration-line: line-through;
  }
}

@keyframes codigo-oculto {
  to {
    visibility: hidden;
  }
}

@keyframes codigo-visible {
  to {
    visibility: visible;
  }
}

/* Los segundos que le quedan al código (de 60 a 120: vale el paso actual y el siguiente), en tramos de 5, hacia abajo. */
.codigo-vivo[data-queda="120"] { --queda: 120s; --pasado: 0s; }
.codigo-vivo[data-queda="115"] { --queda: 115s; --pasado: -5s; }
.codigo-vivo[data-queda="110"] { --queda: 110s; --pasado: -10s; }
.codigo-vivo[data-queda="105"] { --queda: 105s; --pasado: -15s; }
.codigo-vivo[data-queda="100"] { --queda: 100s; --pasado: -20s; }
.codigo-vivo[data-queda="95"] { --queda: 95s; --pasado: -25s; }
.codigo-vivo[data-queda="90"] { --queda: 90s; --pasado: -30s; }
.codigo-vivo[data-queda="85"] { --queda: 85s; --pasado: -35s; }
.codigo-vivo[data-queda="80"] { --queda: 80s; --pasado: -40s; }
.codigo-vivo[data-queda="75"] { --queda: 75s; --pasado: -45s; }
.codigo-vivo[data-queda="70"] { --queda: 70s; --pasado: -50s; }
.codigo-vivo[data-queda="65"] { --queda: 65s; --pasado: -55s; }
.codigo-vivo[data-queda="60"] { --queda: 60s; --pasado: -60s; }

.verificacion .pasos-verificacion {
  margin-top: 0.5rem;
}

/* Sin el correo confirmado, en el lugar del código, el recuadro cerrado: qué falta y su acción (ningún código). */
.codigo-cerrado {
  display: grid;
  justify-items: center;
  margin: 1.5rem 0 1rem;
  padding: 1.75rem 1.25rem 1.5rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel-2);
  text-align: center;
}

.codigo-cerrado .hoja-icono {
  margin: 0 0 1rem;
  background: var(--papel);
}

.codigo-cerrado p {
  max-width: 30rem;
  margin: 0;
  color: var(--silenciado);
}

.codigo-cerrado .codigo-cerrado-titulo {
  margin: 0 0 0.375rem;
  color: var(--texto);
  font-size: var(--t-l);
  font-weight: 650;
}

.codigo-cerrado .acciones {
  justify-content: center;
  margin-top: 1.25rem;
}

@media (min-width: 40rem) {
  .portal .acciones form {
    flex: 0 0 auto;
  }

  .opciones {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .portal .acciones .boton,
  .portal .acciones button {
    flex: 0 0 auto;
    min-width: 12rem;
  }

  .codigo-vivo {
    padding: 2rem 1.5rem 1.5rem;
  }
}

@media (min-width: 48rem) {
  .portal {
    gap: 1.25rem;
  }

  /* El código vivo y los mensajes son una sola tarea: su hoja, más angosta y al centro, bajo la cabecera. */
  .portal > .verificacion,
  .portal > .hoja-mensaje {
    justify-self: center;
    width: 100%;
    max-width: 46rem;
  }

  .perfil-portada {
    height: 5.5rem;
  }

  .perfil-cuerpo {
    gap: 1.25rem;
    padding: 0 2rem 1.25rem;
  }

  .perfil-avatar {
    width: 6rem;
    height: 6rem;
    margin-top: -3rem;
    border-width: 4px;
    border-radius: 20px;
    font-size: var(--t-3xl);
  }

  .perfil-texto {
    padding-top: 0.875rem;
  }

  .perfil h1 {
    font-size: var(--t-3xl);
  }
}

@media (min-width: 60rem) {
  .tablero {
    grid-template-columns: minmax(0, 23rem) minmax(0, 1fr);
  }

  .tablero-lado {
    padding: 2rem 1.75rem 2.25rem;
    border-bottom: 0;
    border-right: 1px solid var(--linea);
    border-radius: calc(var(--r-hoja) - 1px) 0 0 calc(var(--r-hoja) - 1px);
  }

  .tablero-principal {
    padding: 2.25rem 2.5rem 2.5rem;
  }

  /* En el margen angosto, cada botón del riel va a lo ancho de su paso. */
  .riel .acciones .boton,
  .riel .acciones button,
  .riel .acciones form {
    flex: 1 1 100%;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 14. El panel del personal (corte C): la misma carta clínica que el portal, del otro lado del mostrador. Cada página es una
 *     columna de hojas: la cabeza (el título, su entradilla y lo que se hace ahí: el buscador, en Pacientes), lo suyo en una
 *     sola hoja con sus secciones separadas por un filo y, al final, lo que no se deshace, en su zona tintada y plegada. El
 *     perfil del paciente lleva la cabecera del portal (la portada, las iniciales y sus sellos) y una hoja con dos zonas: la
 *     verificación como pasos dibujados y, al margen, sus datos. El aviso de lo que se acaba de hacer (#creado, #verificado,
 *     #reiniciado, #descartado) lo muestra el fragmento (:target).
 * ------------------------------------------------------------------------------------------------------------------ */

.panel {
  display: grid;
  gap: 1rem;
  max-width: 72rem;
  margin: 0 auto;
}

.panel > * {
  min-width: 0;
  margin: 0;
}

.panel h1 {
  overflow-wrap: anywhere;
}

/* Una página de una sola tarea (el enlace que se ve una vez, el equipo registrado, un mensaje): su hoja, angosta y al centro. */
.panel > .hoja-tarea,
.panel > .volver-tarea {
  justify-self: center;
  width: 100%;
  max-width: 46rem;
}

.hoja-tarea .hoja-icono {
  margin-bottom: 1rem;
}

.hoja-tarea > h2 {
  margin: 1.75rem 0 0.5rem;
  font-size: var(--t-l);
}

.hoja-tarea > h1 + p:not([class]) {
  color: var(--silenciado);
}

/* El aviso de un mensaje del panel: tintado, sin su propio icono (el de la hoja ya dice lo que pasó). */
.hoja-mensaje > .aviso,
.hoja-mensaje > .error {
  padding-left: 1rem;
}

.hoja-mensaje > .aviso::before,
.hoja-mensaje > .error::before {
  display: none;
}

/* «Volver a …»: un camino de vuelta corto, con su flecha (la del juego, al revés), encima de la hoja. */
.volver a {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 44px;
  color: var(--silenciado);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  transition: color var(--rapido) var(--salida);
}

.volver .icono {
  width: 1rem;
  height: 1rem;
  transform: scaleX(-1);
}

@media (hover: hover) and (pointer: fine) {
  .volver a:hover {
    color: var(--texto);
  }
}

/* La cabeza de una página del panel: el título y su entradilla, y lo que se hace en ella. */
.panel-cabeza > h1 {
  margin: 0;
}

.panel-cabeza > .entradilla {
  margin-top: 0.375rem;
}

.panel-cabeza > .aviso {
  margin: 1.25rem 0 0;
}

.panel .entradilla {
  max-width: 44rem;
}

/* Un sello con el número de lo que hay en una lista, junto a su título; varias piezas en fila (los roles, lo que dijo un perfil). */
.sello-cuenta {
  font-variant-numeric: tabular-nums;
}

.sellos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sellos .sello {
  max-width: 100%;
  white-space: normal;
}

.sin-dato {
  color: var(--silenciado);
}

.boton .icono,
button .icono {
  width: 1.125rem;
  height: 1.125rem;
}

/* ---- Pacientes: el buscador como protagonista y, debajo, una sola hoja con las dos listas -------------------------------- */

.buscador-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem 1rem;
  margin: 1.5rem 0 0;
}

.buscador {
  flex: 1 1 24rem;
  min-width: 0;
  max-width: none;
  margin: 0;
}

.buscador label {
  margin-bottom: 0.5rem;
}

/* La barra de búsqueda: un campo de 56 px con su lupa y el botón dentro, como una barra de comandos; el anillo del foco, en la barra. */
.buscador-campo {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 3.5rem;
  padding: 0.25rem;
  background: var(--campo);
  border: 1px solid var(--borde);
  border-radius: var(--r-hoja);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--c-texto) 6%, transparent);
  transition: border-color var(--rapido) var(--salida);
}

.buscador-campo > .icono {
  margin-left: 0.75rem;
  color: var(--silenciado);
}

.buscador-campo input:not([type="checkbox"]):not([type="radio"]) {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  min-height: 3rem;
  padding: 0.5rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font-size: 1.125rem;
}

.buscador-campo input:not([type="checkbox"]):not([type="radio"]):focus-visible {
  outline: none;
}

.buscador-campo:focus-within {
  border-color: var(--anillo);
  outline: 2px solid var(--anillo);
  outline-offset: 0;
}

.buscador-campo button {
  flex: none;
  min-height: 44px;
  padding: 0.5rem 1.125rem;
  border-radius: calc(var(--r-hoja) - 4px);
}

.buscador-campo button:focus-visible {
  outline-offset: 1px;
}

@media (hover: hover) and (pointer: fine) {
  .buscador-campo:hover {
    border-color: var(--texto);
  }
}

.buscador-barra > .boton {
  flex: 1 1 100%;
  min-height: 3.5rem;
}

/* Las listas: una sola hoja; cada sección con su título, su número y su tabla (o su lista, en el teléfono), separadas por un filo. */
.listas > section + section {
  margin-top: 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
}

.lista-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.75rem;
}

.lista-cabeza h2 {
  margin: 0;
  font-size: var(--t-l);
}

.lista-explica {
  max-width: 46rem;
  margin: 0.375rem 0 1.125rem;
  color: var(--silenciado);
  font-size: 0.9375rem;
}

.lista-vacia {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin: 1rem 0 0;
  padding: 1rem 1.125rem;
  border: 1px dashed var(--borde);
  border-radius: var(--r-control);
  color: var(--silenciado);
  font-size: 0.9375rem;
}

.lista-tope {
  margin: 0.75rem 0 0;
  color: var(--silenciado);
  font-size: var(--t-s);
}

/*
 * La tabla de una lista: la caja con su filo, la cabecera sutil y fija (una lista larga se desplaza dentro de su caja), la fila bajo
 * el puntero resaltada, el nombre como un enlace claro y las cifras tabulares.
 */
.listas .tabla,
.apilada .tabla {
  margin: 0;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

.listas thead th,
.apilada thead th {
  padding-block: 0.625rem;
  background: var(--papel);
  border-bottom-color: color-mix(in srgb, var(--texto) 20%, var(--papel));
  font-size: var(--t-xs);
  font-weight: 650;
  letter-spacing: 0.01em;
}

.listas tbody tr:last-child > *,
.apilada tbody tr:last-child > * {
  border-bottom: 0;
}

.listas .tabla th[scope="row"] a {
  font-weight: 650;
}

.cifras-tapadas {
  font-family: var(--letra-mono);
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
}

/*
 * Las listas de perfiles en el teléfono: cada fila, una pieza apilada (el nombre y, debajo, cada columna con su nombre), en lugar
 * de una tabla que se desplaza a lo ancho sin que se note. Desde 40rem, la tabla.
 */
.lista-perfiles {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--linea);
}

.lista-perfiles > li {
  padding: 0.625rem 0 0.875rem;
  border-bottom: 1px solid var(--linea);
}

.lista-perfiles a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.lista-perfiles dl {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.25rem 0.75rem;
  margin: 0;
  font-size: 0.9375rem;
}

.lista-perfiles dl div {
  display: contents;
}

.lista-perfiles dt {
  color: var(--silenciado);
  font-weight: 600;
}

.lista-perfiles dd {
  margin: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

.tabla-perfiles {
  display: none;
}

/* ---- El perfil del paciente: la cabecera del portal, y una hoja con la verificación y los datos al margen ----------------- */

/* La cabecera de una persona en el panel (el perfil del paciente, el inicio): sin pestañas al pie; con un nombre largo que baja de
   línea, las iniciales se quedan arriba, montadas en la portada, y el texto crece hacia abajo. */
.perfil-panel .perfil-cuerpo {
  align-items: flex-start;
  padding-bottom: 1.25rem;
}

.ficha-cuerpo {
  display: grid;
  padding: 0;
}

.ficha-acciones {
  min-width: 0;
  padding: 1.5rem 1.25rem 1.75rem;
}

.hoja .ficha-acciones > .tarjeta + .tarjeta {
  margin-top: 2rem;
  padding-top: 1.75rem;
}

.ficha-acciones > .tarjeta > h2 {
  margin: 0 0 0.375rem;
  font-size: var(--t-xl);
}

.ficha-acciones > .tarjeta > h2 + p {
  max-width: 40rem;
  color: var(--silenciado);
}

.ficha-cuerpo > .ficha-datos {
  min-width: 0;
  padding: 1.5rem 1.25rem 1.75rem;
  background: var(--vidrio-2);
  border-top: 1px solid var(--linea);
  border-radius: 0 0 calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px);
}

/* Sin nada que hacer con la persona (odontología ante un verificado), los datos son toda la hoja. */
.ficha-cuerpo > .ficha-datos:first-child {
  background: transparent;
  border-top: 0;
  border-radius: inherit;
}

.ficha-datos h2 {
  margin: 0;
  font-size: var(--t-m);
}

.ficha-datos .datos {
  margin-top: 0.5rem;
}

.ficha-datos .boton-chico {
  display: flex;
  width: fit-content;
  margin: 0.5rem 0 0;
}

.ficha-datos .datos dd .sello {
  margin-left: 0.25rem;
  vertical-align: 0.05em;
}

.ficha-datos .nota {
  margin-top: 1rem;
}

/*
 * La verificación: un riel de pasos dentro del formulario (el riel del portal). El número se pone en el acento mientras se escribe
 * en su paso y pasa a la marca de hecho cuando lo obligatorio del paso está completo (nada :invalid ni con error); el botón va al
 * final del último paso.
 */
.riel-formulario {
  margin: 1.5rem 0 0;
}

.riel-formulario > .riel-paso {
  padding-bottom: 1.75rem;
}

.riel-formulario > .riel-paso:last-child {
  padding-bottom: 0;
}

.riel-formulario .riel-texto {
  padding-top: 0.25rem;
}

/* Todos los pasos de la verificación son de ahora (no los del riel del portal, que vienen después): su título, en tinta. */
.riel.riel-formulario .riel-paso .riel-texto > h3 {
  margin: 0 0 1rem;
  color: var(--texto);
  font-size: var(--t-m);
  font-weight: 650;
  line-height: 1.4;
}

.riel-formulario .riel-marca {
  position: relative;
  color: var(--texto);
  transition: border-color var(--rapido) var(--salida), background-color var(--rapido) var(--salida), box-shadow var(--rapido) var(--salida), color var(--rapido) var(--salida);
}

.riel-formulario .riel-paso:focus-within .riel-marca {
  border-color: var(--acento);
  color: var(--acento-tinta);
  box-shadow: 0 0 0 4px var(--acento-suave);
}

.riel-formulario .riel-paso:has(input:not([type="hidden"])):not(:has(:invalid, [aria-invalid="true"])) .riel-marca {
  border-color: var(--primario);
  background: var(--primario);
  color: transparent;
}

.riel-formulario .riel-paso:has(input:not([type="hidden"])):not(:has(:invalid, [aria-invalid="true"])) .riel-marca::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0.625rem;
  height: 0.3125rem;
  border: solid var(--sobre-primario);
  border-width: 0 0 2px 2px;
  transform: translate(-50%, -65%) rotate(-45deg);
}

.riel-formulario .acciones {
  margin-top: 1.25rem;
}

/* La cédula y la fecha de la cédula física, una al lado de la otra en una pantalla ancha: se teclean mirándola. */
.campos-dobles {
  display: grid;
  column-gap: 1rem;
}

.campos-dobles > .campo {
  min-width: 0;
}

.campo-cifras {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}

/* El código del teléfono de la persona: grande y tabular, como lo muestra su portal. */
input.campo-codigo:not([type="checkbox"]):not([type="radio"]) {
  max-width: 14rem;
  min-height: 3.5rem;
  font-family: var(--letra-mono);
  font-size: 1.625rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.2em;
  text-align: center;
}

/* El contacto que se confirma con la persona: el celular y el correo que trae el perfil, y la casilla. */
.contacto-confirmado {
  min-width: 0;
  margin: 0 0 1rem;
  padding: 1rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

.contacto-confirmado legend {
  padding: 0 0.375rem;
  font-weight: 650;
}

.contacto-confirmado .campo:last-of-type {
  margin-bottom: 0.5rem;
}

/* En el riel, el título del paso ya nombra el contacto a la vista: sin recuadro, y la leyenda queda para el lector de pantalla. */
.riel-formulario .contacto-confirmado {
  margin: 0;
  padding: 0;
  border: 0;
}

.riel-formulario .contacto-confirmado > legend {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  /* Que baje de línea dentro de su píxel: en una línea, su texto saldría por la derecha y la página se desplazaría a lo ancho. */
  white-space: normal;
}

/* El enlace de activación: dos caminos lado a lado, el presencial (el principal) y el remoto, cada uno con lo que hace. */
.enlaces-activacion {
  display: grid;
  gap: 0.75rem;
  margin: 1.25rem 0 0;
}

.enlace-opcion {
  display: flex;
  flex-direction: column;
  max-width: none;
  margin: 0;
  padding: 1.125rem 1.125rem 1.25rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel);
}

.enlace-opcion h3 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.375rem;
  font-size: var(--t-m);
}

.enlace-opcion h3 .icono {
  color: var(--acento);
}

.enlace-opcion p {
  flex: 1 1 auto;
  margin: 0 0 1rem;
  color: var(--silenciado);
  font-size: 0.9375rem;
}

/* Lo que se hace con el perfil cuando algo no está bien, al final: un bloque tintado del error con su icono y, dentro, cada acción
   plegada en su propio recuadro (se abre a propósito; abierta si vuelve con su aviso). */
.zona-riesgo {
  padding: 1.25rem 1rem 1rem;
  border: 1px solid var(--error-linea);
  border-radius: var(--r-hoja);
  background: var(--error-fondo);
}

.zona-riesgo > h2 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.25rem;
  color: var(--error-texto);
  font-size: var(--t-m);
}

.zona-riesgo > p {
  margin: 0 0 1rem;
  color: var(--error-texto);
  font-size: 0.9375rem;
}

.zona-riesgo .zona-peligro {
  margin: 0;
  border-radius: var(--r-control);
}

.zona-riesgo .zona-peligro + .zona-peligro {
  margin-top: 0.5rem;
}

.zona-riesgo .zona-peligro > summary {
  min-height: 3rem;
  padding: 0.5rem 1rem;
  font-size: 0.9375rem;
}

.zona-riesgo .zona-peligro > :not(summary) {
  margin: 1rem;
}

.zona-peligro form {
  max-width: 36rem;
}

/* ---- Lo que se ve una sola vez: el enlace de enrolamiento y el de activación, en una pieza que dice que es única ------------- */

.secreto {
  margin: 1.25rem 0;
  padding: 0.875rem;
  border: 1px dashed var(--acento-linea);
  border-radius: var(--r-hoja);
  background: var(--acento-suave);
}

.secreto-aviso {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  color: var(--acento-tinta);
  font-size: 0.9375rem;
}

.secreto-aviso .icono {
  margin-top: 0.0625rem;
}

.secreto-valor {
  margin: 0;
}

.secreto-valor code {
  display: block;
  padding: 0.875rem 1rem;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  font-size: var(--t-m);
  line-height: 1.5;
  overflow-wrap: anywhere;
  user-select: all;
  -webkit-user-select: all;
}

.secreto-pie {
  margin: 0.75rem 0 0;
  color: var(--acento-tinta);
  font-size: var(--t-s);
}

/* ---- Inicio: la persona de la sesión, el estado de su sesión y lo que se hace a diario -------------------------------------- */

.sesion-de {
  margin: 0 0 0.75rem;
}

.tablero-lado .datos {
  margin-top: 0;
}

.sesion-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
}

.sesion-acciones form {
  display: flex;
  flex: 1 1 auto;
  max-width: none;
  margin: 0;
}

.sesion-acciones button {
  flex: 1 1 auto;
}

.cambiar-persona {
  margin: 1.75rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--linea);
}

.cambiar-persona h3 {
  margin: 0 0 0.25rem;
  font-size: var(--t-m);
}

.cambiar-persona > p {
  margin: 0 0 1rem;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.tablero-principal > h2 {
  margin: 0 0 1rem;
  font-size: var(--t-l);
}

/* Lo que hay ahora (el inicio del personal): números de la base, como las filas del resumen del portal: el nombre a un lado y la
   cifra al otro. */
.cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 0.625rem;
  margin: 0 0 1.75rem;
}

.cifras > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
}

.cifras dt {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.cifras dd {
  margin: 0;
  color: var(--texto);
  font-size: var(--t-l);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* El estante del inicio: sus carpetas, con aire arriba para que los archivos se abaniquen sin tapar el título. */
.tablero-principal > h2 + .estante {
  padding-top: 1.25rem;
}

/*
 * El inicio (enmienda del 29-oct): lo que se hace a diario primero, a lo ancho de la hoja (las carpetas, más altas: sus archivos
 * se abanican dentro), y la sesión debajo, como una franja: de quién es y con qué entró a un lado, y sus botones al otro.
 */
.tablero-inicio .carpeta {
  --arriba: 6.5rem;
  --perspectiva: 80rem;
}

.tablero-inicio .estante {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.tablero-inicio .tablero-lado {
  border-top: 1px solid var(--linea);
  border-bottom: 0;
  border-radius: 0 0 calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px);
}

@media (min-width: 60rem) {
  .tablero.tablero-inicio {
    grid-template-columns: minmax(0, 1fr);
  }

  .tablero-inicio .tablero-lado {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 2.5rem;
    align-items: start;
    padding: 1.75rem 2.5rem 2rem;
    border-top: 1px solid var(--linea);
    border-right: 0;
    border-radius: 0 0 calc(var(--r-hoja) - 1px) calc(var(--r-hoja) - 1px);
  }

  .tablero-inicio .tablero-lado > :not(.sesion-acciones) {
    grid-column: 1;
  }

  .tablero-inicio .sesion-acciones {
    grid-column: 2;
    grid-row: 1 / span 3;
    align-self: center;
    margin: 0;
  }

  .tablero-inicio .tablero-lado .datos {
    display: flex;
    flex-wrap: wrap;
    gap: 0 2.5rem;
  }

  .tablero-inicio .tablero-lado .datos div {
    border-bottom: 0;
  }

  .tablero-inicio .cambiar-persona {
    grid-column: 1 / -1;
    max-width: 40rem;
  }
}

.sin-tareas {
  color: var(--silenciado);
}

/* ---- Personal y Equipos: tablas con sellos (en el teléfono, cada fila apilada), y el alta como una hoja ---------------------- */

.persona-celda strong,
.equipo-celda strong {
  display: block;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.persona-celda code {
  display: inline-block;
  margin-top: 0.25rem;
  font-size: var(--t-s);
}

.equipo-celda > span {
  display: block;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.fecha-fin {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.hoja > .apilada {
  margin-top: 1.75rem;
}

.hoja > .aviso,
.hoja > .error {
  margin: 1.25rem 0 0;
}

/* Lo que va apilado en una celda (el estado y la fecha de fin): uno debajo del otro, cada uno de su ancho. */
.pila {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
}

.apilada td > .sello {
  justify-self: start;
}

/* Los ajustes de la agenda: la ayuda debajo del nombre y el campo del ancho de su fila. */
.ajustes-agenda .ayuda {
  display: block;
  margin-top: 0.25rem;
}

.ajustes-agenda .campo {
  margin: 0;
}

/* El alta de una persona o de un equipo: más angosta que su hoja, para que ningún campo quede estirado (gana a `.hoja form`). */
.hoja form.formulario-alta {
  max-width: 46rem;
}

.accion-celda form {
  max-width: none;
  margin: 0;
}

.accion-celda .boton-chico {
  margin: 0;
  white-space: nowrap;
}

.campos-alta {
  display: grid;
  column-gap: 1rem;
}

.campos-alta > .campo {
  min-width: 0;
}

.roles .opciones {
  margin-top: 0.25rem;
}

.roles legend {
  margin-bottom: 0.25rem;
}

.roles > .silenciado {
  margin: 0 0 0.625rem;
  font-size: var(--t-s);
}

.alta-acciones {
  margin-top: 1.75rem;
}

/* En el teléfono, una tabla del personal o de los equipos es una fila apilada por persona o equipo, cada celda con su nombre. */
.apilada table,
.apilada tbody,
.apilada tr,
.apilada td {
  display: block;
}

.apilada thead {
  display: none;
}

.apilada tr {
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--linea);
}

.apilada tbody tr:last-child {
  border-bottom: 0;
}

.apilada td {
  display: grid;
  grid-template-columns: minmax(6rem, 32%) minmax(0, 1fr);
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.25rem 0;
  border: 0;
}

.apilada td::before {
  content: attr(data-etiqueta);
  color: var(--silenciado);
  font-size: var(--t-s);
  font-weight: 600;
}

.apilada td:first-child {
  display: block;
  padding-bottom: 0.5rem;
}

.apilada td:first-child::before,
.apilada td.accion-celda::before {
  content: none;
}

.apilada td.accion-celda {
  display: block;
  padding-top: 0.625rem;
}

.apilada td.accion-celda:empty {
  display: none;
}

.panel .formulario-largo,
.panel .resumen-errores {
  max-width: none;
}

.panel .error .acciones {
  margin-top: 0.75rem;
}

.panel .error > p:last-child {
  margin-bottom: 0;
}

.enlace-activacion {
  display: block;
  padding: 0.75rem 1rem;
  font-size: var(--t-m);
  overflow-wrap: anywhere;
  user-select: all;
  -webkit-user-select: all;
}

.hecho {
  display: none;
}

.hecho:target {
  position: relative;
  display: block;
  margin: 0;
  padding: 0.875rem 1.25rem 0.875rem 2.875rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-hoja);
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-weight: 600;
}

.hecho:target::before {
  content: "";
  position: absolute;
  left: 1.125rem;
  top: 1.0625rem;
  width: 0.75rem;
  height: 0.4375rem;
  border: solid currentColor;
  border-width: 0 0 2px 2px;
  transform: rotate(-45deg);
}

/* Los botones: a lo ancho en el teléfono, de su tamaño desde 40rem (los de un formulario de un botón, también: el del enlace). */
.panel .acciones .boton,
.panel .acciones button {
  flex: 1 1 100%;
}

.panel .acciones form {
  display: flex;
  flex: 1 1 100%;
  margin: 0;
}

@media (min-width: 40rem) {
  .buscador-barra > .boton {
    flex: 0 0 auto;
  }

  .panel .acciones .boton,
  .panel .acciones button {
    flex: 0 0 auto;
    min-width: 12rem;
  }

  .panel .acciones form {
    flex: 0 0 auto;
  }

  .campos-dobles,
  .campos-alta,
  .enlaces-activacion {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .zona-riesgo {
    padding: 1.5rem 1.5rem 1.25rem;
  }

  .sesion-acciones form,
  .sesion-acciones button {
    flex: 0 0 auto;
  }

  .sesion-acciones button {
    min-width: 9rem;
  }

  .tablero-lado .datos div {
    grid-template-columns: minmax(0, 5.5rem) minmax(0, 1fr);
  }

  .listas .tabla {
    max-height: 32rem;
    overflow: auto;
    overscroll-behavior: contain;
  }

  .lista-perfiles {
    display: none;
  }

  .tabla-perfiles {
    display: block;
  }
}

@media (min-width: 48rem) {
  .panel {
    gap: 1.25rem;
  }

  .ficha-acciones,
  .ficha-cuerpo > .ficha-datos {
    padding: 2rem 2.25rem 2.25rem;
  }

  .apilada table {
    display: table;
  }

  .apilada thead {
    display: table-header-group;
  }

  .apilada tbody {
    display: table-row-group;
  }

  .apilada tr {
    display: table-row;
    padding: 0;
  }

  .apilada td,
  .apilada td:first-child,
  .apilada td.accion-celda {
    display: table-cell;
    padding: 0.75rem 0.875rem;
    border-bottom: 1px solid var(--linea);
  }

  .apilada td::before {
    content: none;
  }

  .apilada td:first-child {
    min-width: 13rem;
  }
}

/* En una pantalla ancha, los datos al margen, a la izquierda, y lo que se hace con la persona a la derecha (en el orden de la
   página van primero las acciones: en el teléfono, arriba). */
@media (min-width: 64rem) {
  .ficha-cuerpo:has(> .ficha-acciones) {
    grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  }

  .ficha-cuerpo:has(> .ficha-acciones) > .ficha-datos {
    grid-column: 1;
    grid-row: 1;
    border-top: 0;
    border-right: 1px solid var(--linea);
    border-radius: calc(var(--r-hoja) - 1px) 0 0 calc(var(--r-hoja) - 1px);
  }

  .ficha-cuerpo:has(> .ficha-acciones) > .ficha-datos .datos div {
    grid-template-columns: minmax(0, 1fr);
  }

  .ficha-acciones {
    grid-column: 2;
    grid-row: 1;
    padding: 2.25rem 2.5rem 2.5rem;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 15. El movimiento y la impresión
 * ------------------------------------------------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  .saltar {
    transition: transform var(--rapido) var(--salida);
  }
}

/* Con movimiento reducido no se anima nada: tampoco la cuadrícula, que se enciende y se apaga sin transición. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .celda {
    transition: none;
  }

  /* La barra del código vivo no se mueve: se queda en lo que le quedaba al abrir la página (y el aviso de vencido llega igual). */
  .codigo-vivo[data-queda] .codigo-vivo-barra::after {
    animation-duration: 120s !important;
    animation-play-state: paused !important;
  }
}

/* En papel: sin el fondo ni la navegación, y la hoja sin sombra. La franja de datos de prueba se imprime. */
@media print {
  .fondo,
  .pie,
  .cabecera nav,
  .saltar {
    display: none;
  }

  body {
    background: #ffffff;
  }

  .hoja,
  .tarjeta,
  .perfil,
  main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
    box-shadow: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 16. El vidrio, la luz del borde y el destello (enmienda del 29-oct, §1 y §3). Los paneles (la hoja, la cabecera de una persona,
 *     el carnet, la barra superior y la hoja de main) desenfocan lo que tienen detrás y lo saturan un poco; su texto no depende de
 *     eso (cada uno ya es lo bastante opaco: sección 1). Llevan una luz fina en el borde, intensa arriba y tenue abajo (::before),
 *     un velo tenue por dentro (la sombra interior) y, con JS, el brillo que sigue al puntero (data-brillo) y el destello
 *     (data-destello, en su versión CSS: ::after). La luz va solo por el borde, dentro del margen del panel: nunca sobre el texto.
 * ------------------------------------------------------------------------------------------------------------------ */

.hoja,
.tarjeta:not(.hoja .tarjeta),
.perfil,
.carnet,
.cabecera,
main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
  position: relative;
  isolation: isolate;
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
}

.hoja,
.tarjeta:not(.hoja .tarjeta),
.perfil,
main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
  box-shadow: var(--vidrio-sombra), inset 0 0 1.5rem -0.75rem var(--destello-velo);
}

/* Donde el navegador no desenfoca, el vidrio es casi macizo: el texto se lee igual. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .hoja,
  .tarjeta:not(.hoja .tarjeta),
  .perfil,
  .carnet,
  .cabecera,
  main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
    background-color: var(--vidrio-macizo);
  }
}

/* La luz del borde: una línea de 1 px por dentro, intensa arriba y que se apaga hacia abajo (la luz viene de arriba). */
.hoja::before,
.tarjeta:not(.hoja .tarjeta)::before,
.perfil::before,
.carnet::before,
.cabecera::before,
main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja))::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg, var(--vidrio-luz), color-mix(in srgb, var(--vidrio-luz) 30%, transparent) 2.5rem, transparent 70%);
  -webkit-mask: linear-gradient(#000000 0 0) content-box, linear-gradient(#000000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000000 0 0) content-box exclude, linear-gradient(#000000 0 0);
  pointer-events: none;
}

/* El brillo que sigue al puntero (destello.js pone data-brillo y la posición, con un puntero fino): luz difusa debajo del texto. */
[data-brillo] {
  background-image: radial-gradient(22rem circle at var(--brillo-x, 50%) var(--brillo-y, 0), var(--brillo), transparent 70%);
}

.carnet[data-brillo] {
  background-image:
    radial-gradient(16rem circle at var(--brillo-x, 50%) var(--brillo-y, 0), var(--brillo), transparent 70%),
    radial-gradient(70% 90% at 100% 0, var(--carnet-velo-1), transparent 70%),
    radial-gradient(60% 70% at 88% 12%, var(--carnet-velo-2), transparent 75%);
}

/*
 * El destello, versión CSS (la que se ve sin WebGL; destello.js elige hasta tres paneles a la vista y les pone data-destello 1, 2 o
 * 3, cada uno desfasado): una banda de luz que cruza el panel de un borde al otro, con el acento delante y la plata detrás (la
 * dispersión), vista solo en el borde: el anillo de 1,5 px, la cresta de arriba (más ancha) y una cinta tenue por los otros
 * lados; un velo constante muy tenue en esas mismas cintas. Va y vuelve (un sentido y el otro), con una pausa larga entre barridos.
 */
[data-destello]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  padding: 2px;
  background:
    linear-gradient(var(--destello-angulo, 104deg), transparent 42%, var(--destello-calido) 47.5%, var(--destello-nucleo) 50%, var(--destello-frio) 52.5%, transparent 58%) 100% 0 / 280% 100% no-repeat,
    linear-gradient(var(--destello-velo), var(--destello-velo));
  -webkit-mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.85), transparent 0.875rem),
    linear-gradient(0deg, rgba(0, 0, 0, 0.42), transparent 0.5rem),
    linear-gradient(90deg, rgba(0, 0, 0, 0.42), transparent 0.5rem),
    linear-gradient(270deg, rgba(0, 0, 0, 0.42), transparent 0.5rem),
    linear-gradient(#000000 0 0) content-box,
    linear-gradient(#000000 0 0);
  -webkit-mask-composite: source-over, source-over, source-over, source-over, xor;
  mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.85), transparent 0.875rem) add,
    linear-gradient(0deg, rgba(0, 0, 0, 0.42), transparent 0.5rem) add,
    linear-gradient(90deg, rgba(0, 0, 0, 0.42), transparent 0.5rem) add,
    linear-gradient(270deg, rgba(0, 0, 0, 0.42), transparent 0.5rem) add,
    linear-gradient(#000000 0 0) content-box exclude,
    linear-gradient(#000000 0 0);
  pointer-events: none;
  animation: destello-barrido var(--destello-ciclo, 10s) linear var(--destello-retraso, 0s) infinite alternate both;
}

[data-destello="2"]::after {
  --destello-retraso: -3.4s;
  --destello-angulo: 98deg;
}

[data-destello="3"]::after {
  --destello-retraso: -6.8s;
  --destello-angulo: 110deg;
}

/* El barrido ocupa del 43 % al 57 % de cada vuelta (1,4 s de 10); lo demás es la pausa, con la banda fuera del panel. */
@keyframes destello-barrido {
  0%,
  43% {
    background-position: 100% 0, 0 0;
  }

  57%,
  100% {
    background-position: 0 0, 0 0;
  }
}

/* En un panel chico (el carnet), las cintas son más angostas: nunca llegan a su texto. */
.carnet[data-destello]::after {
  -webkit-mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.62), transparent 0.5rem),
    linear-gradient(0deg, rgba(0, 0, 0, 0.3), transparent 0.375rem),
    linear-gradient(90deg, rgba(0, 0, 0, 0.3), transparent 0.375rem),
    linear-gradient(270deg, rgba(0, 0, 0, 0.3), transparent 0.375rem),
    linear-gradient(#000000 0 0) content-box,
    linear-gradient(#000000 0 0);
  -webkit-mask-composite: source-over, source-over, source-over, source-over, xor;
  mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.62), transparent 0.5rem) add,
    linear-gradient(0deg, rgba(0, 0, 0, 0.3), transparent 0.375rem) add,
    linear-gradient(90deg, rgba(0, 0, 0, 0.3), transparent 0.375rem) add,
    linear-gradient(270deg, rgba(0, 0, 0, 0.3), transparent 0.375rem) add,
    linear-gradient(#000000 0 0) content-box exclude,
    linear-gradient(#000000 0 0);
}

/*
 * El destello con WebGL: un solo lienzo fijo para toda la página, encima del contenido y sin recibir el puntero (destello.js). Sus
 * colores son los del destello CSS: el lienzo los recibe como color y colores de borde (sin borde visible) y destello.js los lee.
 * --destello-banda es el ancho de las cintas de luz de cada panel: menos que su margen interior (la luz no llega al texto).
 */
.destello-lienzo {
  position: fixed;
  inset: 0;
  z-index: 20;
  width: 100%;
  height: 100%;
  border: 0 solid;
  pointer-events: none;
  color: var(--destello-nucleo);
  border-color: var(--destello-calido) var(--destello-frio) var(--destello-velo) transparent;
}

.hoja,
.perfil,
main {
  --destello-banda: 12px;
}

.carnet {
  --destello-banda: 7px;
}

/*
 * Vidrio ligero: sin WebGL suele no haber aceleración gráfica, y desenfocar los paneles grandes cada vez que la cuadrícula
 * enciende una celda detrás traba la página (medido: de 60 a 20 cuadros por segundo). destello.js pone data-vidrio="ligero" en la
 * raíz y los paneles grandes quedan translúcidos sin desenfoque (el texto se lee igual: es lo que mide la prueba del contraste);
 * los chicos (la barra superior, el carnet, el frente de una carpeta) lo conservan.
 */
[data-vidrio="ligero"] .hoja,
[data-vidrio="ligero"] .tarjeta,
[data-vidrio="ligero"] .perfil,
[data-vidrio="ligero"] main {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* La pestaña oculta pausa el destello CSS (destello.js pone data-destello-pausa en la raíz). */
[data-destello-pausa] [data-destello]::after {
  animation-play-state: paused;
}

/* Con movimiento reducido: sin barrido, solo el borde fijo y el velo. */
@media (prefers-reduced-motion: reduce) {
  [data-destello]::after {
    animation: none;
    background: linear-gradient(var(--destello-velo), var(--destello-velo));
  }
}

/* Menos transparencia: sin desenfoque. */
@media (prefers-reduced-transparency: reduce) {
  .hoja,
  .tarjeta:not(.hoja .tarjeta),
  .perfil,
  .carnet,
  .cabecera,
  main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* Con los colores forzados del sistema (alto contraste de Windows): sin luces ni lienzos; los bordes los pone el sistema. */
@media (forced-colors: active) {
  .hoja::before,
  .tarjeta::before,
  .perfil::before,
  .carnet::before,
  .cabecera::before,
  main::before,
  [data-destello]::after,
  .destello-lienzo {
    display: none;
  }
}

/* En papel: el vidrio es papel, sin desenfoque ni luces. */
@media print {
  .hoja,
  .tarjeta,
  .perfil,
  .carnet,
  .cabecera,
  main:not(:has(> .entrada, > .publico, > .portal, > .panel, > .hoja)) {
    background: #ffffff;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .hoja::before,
  .tarjeta::before,
  .perfil::before,
  .carnet::before,
  .cabecera::before,
  main::before,
  [data-destello]::after,
  .destello-lienzo {
    display: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 17. Las carpetas de vidrio (enmienda del 29-oct, §2): en lugar de los menús grandes. Cada carpeta es un <details> con su
 *     <summary>, que es el objeto: el panel trasero con su ilustración (liquido.js; mientras tanto, un degradado de la paleta), las
 *     hojas que asoman (decorativas) y el frente de vidrio, con el icono, el nombre y lo que reúne. Sus archivos son enlaces reales.
 *     Sin JS, al abrirla, los archivos van debajo, en filas de vidrio (la versión plana). Con JS (carpetas.js pone data-viva y
 *     data-estado), los archivos suben desde detrás del frente y se abanican, y el frente cae sobre su bisagra. El puntero que se
 *     acerca la inclina hacia quien mira y sube un poco las hojas; con un puntero fino, el paralaje (--px, --py). Con movimiento
 *     reducido, solo los estados.
 * ------------------------------------------------------------------------------------------------------------------ */

.estante {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 12rem), 1fr));
  align-items: end;
  gap: 1.75rem 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.estante > li {
  min-width: 0;
}

.carpeta {
  /* Lo que se ve del panel trasero por encima del frente, lo que asoma cada hoja y el paralaje que pone carpetas.js. */
  --arriba: 5rem;
  --perspectiva: 34rem;
  --inclina: 0deg;
  --px: 0;
  --py: 0;
  position: relative;
  isolation: isolate;
  margin: 0;
  transition: margin-top 440ms var(--salida);
}

.carpeta[open] {
  z-index: 5;
}

.carpeta-resumen {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 44px;
  padding-top: var(--arriba);
  border-radius: 0.875rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.carpeta-resumen::-webkit-details-marker {
  display: none;
}

.carpeta-resumen::marker {
  content: "";
}

.carpeta-resumen:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 4px;
}

/*
 * El panel trasero: de arriba abajo, con su pestaña arriba a la izquierda (un recorte en ángulo, como el de una carpeta de
 * oficina) y la ilustración dentro, que se mueve un poco a contraluz con el puntero. Bloqueada (el portal del nivel 1), apagada.
 */
.carpeta-trasera {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  border-radius: 0.875rem;
  background-color: var(--ilustracion-4);
  background-image:
    radial-gradient(80% 70% at 22% 18%, var(--ilustracion-1), transparent 70%),
    radial-gradient(70% 80% at 85% 70%, var(--ilustracion-3), transparent 72%),
    linear-gradient(125deg, var(--ilustracion-2), var(--ilustracion-4) 60%);
  clip-path: polygon(0 0, calc(40% - 0.625rem) 0, calc(40% + 0.25rem) 0.875rem, calc(100% - 0.625rem) 0.875rem, calc(100% - 0.18rem) 1.06rem, 100% 1.5rem, 100% 100%, 0 100%);
}

.carpeta-trasera .liquido {
  transform: scale(1.1) translate(calc(var(--px) * -3%), calc(var(--py) * -3%));
  transition: transform 500ms var(--salida), opacity 700ms var(--salida);
}

/* La luz que entra por detrás: sigue al puntero (el paralaje). */
.carpeta-trasera::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 60% at calc(35% + var(--px) * 30%) calc(25% + var(--py) * 25%), color-mix(in srgb, #ffffff 38%, transparent), transparent 70%);
  pointer-events: none;
}

.carpeta-bloqueada .carpeta-trasera {
  filter: saturate(0.3) brightness(1.04);
}

/* Las hojas que asoman por encima del frente (decorativas: los archivos de verdad están en la lista, que se ve al abrir). */
.carpeta-hojas {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.carpeta-hojas > span {
  position: absolute;
  left: 10%;
  right: 10%;
  top: calc(var(--arriba) - 0.875rem);
  height: 4rem;
  border-radius: 0.5rem;
  background: var(--papel);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-texto) 8%, transparent), 0 -4px 10px -6px color-mix(in srgb, var(--c-texto) 30%, transparent);
  transform: translateY(var(--sube, 0)) rotate(var(--giro, 0deg));
  transition: transform 380ms var(--salida), opacity 160ms var(--salida);
}

.carpeta-hojas > span:nth-child(2) {
  left: 14%;
  right: 7%;
  top: calc(var(--arriba) - 0.5rem);
  --giro: 1.5deg;
}

.carpeta-hojas > span:nth-child(3) {
  left: 7%;
  right: 15%;
  top: calc(var(--arriba) - 0.25rem);
  --giro: -1.25deg;
}

/* El frente de vidrio: el nombre de la carpeta y lo que reúne; cae sobre su bisagra de abajo, hacia quien mira. */
.carpeta-frente {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr) auto;
  column-gap: 0.625rem;
  row-gap: 0.0625rem;
  align-items: center;
  min-height: 4.75rem;
  padding: 0.75rem 0.875rem 0.8125rem;
  border: 1px solid var(--vidrio-borde);
  border-radius: 0.875rem;
  background: var(--frente);
  -webkit-backdrop-filter: blur(14px) saturate(1.5);
  backdrop-filter: blur(14px) saturate(1.5);
  box-shadow: 0 -1px 0 var(--vidrio-luz) inset, 0 12px 24px -16px color-mix(in srgb, var(--c-texto) 55%, transparent);
  --destello-banda: 6px;
  transform-origin: 50% 100%;
  transform: perspective(var(--perspectiva)) rotateX(var(--inclina)) rotateY(calc(var(--px) * 3deg));
  transition: transform 420ms var(--salida), box-shadow 420ms var(--salida);
}

.carpeta-frente::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg, var(--vidrio-luz), transparent 60%);
  -webkit-mask: linear-gradient(#000000 0 0) content-box, linear-gradient(#000000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000000 0 0) content-box exclude, linear-gradient(#000000 0 0);
  pointer-events: none;
}

.carpeta-frente[data-destello]::after {
  -webkit-mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.85), transparent 0.375rem),
    linear-gradient(0deg, rgba(0, 0, 0, 0.42), transparent 0.25rem),
    linear-gradient(90deg, rgba(0, 0, 0, 0.42), transparent 0.25rem),
    linear-gradient(270deg, rgba(0, 0, 0, 0.42), transparent 0.25rem),
    linear-gradient(#000000 0 0) content-box,
    linear-gradient(#000000 0 0);
  -webkit-mask-composite: source-over, source-over, source-over, source-over, xor;
  mask:
    linear-gradient(180deg, rgba(0, 0, 0, 0.85), transparent 0.375rem) add,
    linear-gradient(0deg, rgba(0, 0, 0, 0.42), transparent 0.25rem) add,
    linear-gradient(90deg, rgba(0, 0, 0, 0.42), transparent 0.25rem) add,
    linear-gradient(270deg, rgba(0, 0, 0, 0.42), transparent 0.25rem) add,
    linear-gradient(#000000 0 0) content-box exclude,
    linear-gradient(#000000 0 0);
}

.carpeta-icono {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--linea);
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
}

.carpeta-icono .icono {
  width: 1.25rem;
  height: 1.25rem;
}

.carpeta-nombre {
  min-width: 0;
  color: var(--texto);
  font-size: var(--t-m);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.carpeta-detalle {
  grid-column: 2 / -1;
  min-width: 0;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 500;
  line-height: 1.35;
}

/*
 * Las carpetas que vienen (Agenda, Historia clínica): el mismo objeto de vidrio, quieto. Sin <details>, sin archivos y sin enlaces
 * (no hay a dónde ir): ni el puntero ni el teclado las inclinan, el fondo va apagado y un sello dice «Próximamente».
 */
.carpeta-proxima .carpeta-resumen {
  cursor: default;
}

.carpeta-proxima .carpeta-trasera {
  filter: saturate(0.35) brightness(1.04);
}

.estante-ancho .carpeta-proxima .carpeta-detalle::after {
  content: none;
}

/* El sello va a caballo sobre el borde de arriba del frente (no le quita sitio al nombre). */
.carpeta-aviso {
  position: absolute;
  top: 0;
  right: 0.875rem;
  z-index: 2;
  transform: translateY(-50%);
  padding: 0.0625rem 0.5rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: color-mix(in srgb, var(--papel) 72%, transparent);
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
}

/* Un chevrón que dice que la carpeta se abre (hacia arriba, de donde salen los archivos) y que se cierra (hacia abajo). */
.estante-ancho .carpeta-frente {
  padding-right: 2.75rem;
}

.estante-ancho .carpeta-detalle::after {
  content: "";
  position: absolute;
  right: 1.25rem;
  top: 50%;
  width: 0.5rem;
  height: 0.5rem;
  margin-top: -0.375rem;
  border: solid var(--silenciado);
  border-width: 0 2px 2px 0;
  transform: rotate(-135deg);
  transition: transform 300ms var(--salida);
}

.estante-ancho .carpeta[open] .carpeta-detalle::after {
  transform: rotate(45deg);
}

.carpeta-frente .icono-candado {
  grid-row: 1;
  grid-column: 3;
  width: 1rem;
  height: 1rem;
  color: var(--acento);
}

/* Los archivos: hojas de papel con su icono, su nombre y una segunda línea; cada uno un objetivo grande. */
.carpeta-archivos {
  margin: 0;
  padding: 0;
  list-style: none;
}

.carpeta-archivo {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  column-gap: 0.625rem;
  min-height: 44px;
  padding: 0.5625rem 0.8125rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--texto) 11%, transparent);
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
  text-decoration: none;
  box-shadow: 0 1px 1px color-mix(in srgb, var(--c-texto) 6%, transparent), 0 10px 20px -14px color-mix(in srgb, var(--c-texto) 45%, transparent);
  transition: transform 420ms var(--salida), translate 160ms var(--salida), border-color var(--rapido) var(--salida), box-shadow 420ms var(--salida);
}

.carpeta-archivo > .icono {
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.125rem;
  color: var(--acento);
}

.carpeta-archivo > .icono-candado {
  width: 0.875rem;
  height: 0.875rem;
  margin-top: 0.25rem;
}

.archivo-texto {
  min-width: 0;
}

.archivo-nombre {
  display: block;
  font-size: 0.9375rem;
  font-weight: 650;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.archivo-detalle {
  display: block;
  margin-top: 0.0625rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
  line-height: 1.35;
}

@media (hover: hover) and (pointer: fine) {
  .carpeta-resumen:hover {
    --inclina: -12deg;
  }

  /* Las que vienen no se inclinan: no hay nada que abrir. */
  .carpeta-proxima .carpeta-resumen:hover {
    --inclina: 0deg;
  }

  .carpeta-resumen:hover .carpeta-hojas > span {
    --sube: -0.375rem;
  }

  .carpeta-resumen:hover .carpeta-hojas > span:nth-child(2) {
    --sube: -0.25rem;
  }

  .carpeta-resumen:hover .carpeta-hojas > span:nth-child(3) {
    --sube: -0.125rem;
  }

  .carpeta-archivo:hover {
    translate: 0 -2px;
    border-color: var(--acento-linea);
  }
}

/* Con el foco del teclado, como con el puntero encima: el frente se inclina y las hojas suben un poco. */
.carpeta-resumen:focus-visible {
  --inclina: -12deg;
}

.carpeta-resumen:focus-visible .carpeta-hojas > span {
  --sube: -0.375rem;
}

.carpeta-resumen:active .carpeta-frente {
  scale: 0.985;
}

.carpeta-archivo:active {
  scale: 0.985;
}

/* Abierta sin JS: el frente cae un poco más y los archivos van debajo, en filas (la versión plana del vidrio). */
.carpeta[open] {
  --inclina: -22deg;
}

.carpeta[open] .carpeta-hojas > span {
  --sube: -0.5rem;
}

.carpeta:not([data-viva])[open] > .carpeta-archivos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 0.5rem 0.75rem;
  margin-top: 0.75rem;
}

/*
 * Con JS (data-viva): los archivos van detrás del frente y suben desde ahí (data-estado="abierta"), en una rejilla que reparte el
 * ancho de la carpeta: una carpeta ancha los pone en una fila, uno al lado del otro, y una angosta, en una columna, siempre con su
 * título entero a la vista (ninguno tapa a otro). Al cerrarse vuelven a meterse antes de que el <details> se cierre. Las hojas
 * decorativas se apagan mientras tanto. Lo que ocupa el abanico lo mide carpetas.js (--abanico): el hueco que no cabe en lo que
 * asoma del panel trasero (--arriba) se reserva sobre la carpeta, para que no tape lo que hay encima.
 */
.carpeta[data-viva] > .carpeta-archivos {
  position: absolute;
  z-index: 2;
  left: 0.5rem;
  right: 0.5rem;
  bottom: calc(100% - var(--arriba) - 0.75rem);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 0.5rem 0.75rem;
  transform: translateY(calc(100% - 1rem));
  opacity: 0;
  transition: transform 440ms var(--salida), opacity 200ms var(--salida);
}

.carpeta[data-viva][open] .carpeta-hojas > span {
  opacity: 0;
}

.carpeta[data-viva][data-estado="abierta"] {
  --inclina: -30deg;
  margin-top: max(0px, calc(var(--abanico, 0px) - var(--arriba) + 0.5rem));
}

.carpeta[data-viva][data-estado="abierta"] > .carpeta-archivos {
  transform: translateY(-0.25rem);
  opacity: 1;
}

/* Abanicados: los de los extremos, inclinados hacia fuera; los de en medio, casi rectos. */
.carpeta[data-viva][data-estado="abierta"] > .carpeta-archivos > li:only-child > .carpeta-archivo {
  transform: rotate(-1deg);
}

.carpeta[data-viva][data-estado="abierta"] > .carpeta-archivos > li:first-child:not(:only-child) > .carpeta-archivo {
  transform: rotate(-1.5deg);
  transition-delay: 40ms;
}

.carpeta[data-viva][data-estado="abierta"] > .carpeta-archivos > li:not(:first-child):not(:last-child) > .carpeta-archivo {
  transform: rotate(0.5deg);
  transition-delay: 20ms;
}

.carpeta[data-viva][data-estado="abierta"] > .carpeta-archivos > li:last-child:not(:only-child) > .carpeta-archivo {
  transform: rotate(1.5deg);
  transition-delay: 60ms;
}

/* En el teléfono (una columna angosta de dos), las carpetas son más bajas. */
@media (max-width: 30rem) {
  .estante {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.5rem 0.75rem;
  }

  .carpeta {
    --arriba: 4.25rem;
  }

  .carpeta-frente {
    grid-template-columns: minmax(0, 1fr) auto;
    padding: 0.625rem 0.6875rem 0.6875rem;
  }

  .carpeta-icono {
    display: none;
  }

  .carpeta-detalle {
    grid-column: 1 / -1;
  }

  .carpeta-frente .icono-candado {
    grid-column: 2;
  }
}

/* Las carpetas con varios archivos (el inicio del personal) van a lo ancho en el teléfono, con su icono. */
@media (max-width: 30rem) {
  .estante-ancho {
    grid-template-columns: minmax(0, 1fr);
  }

  .estante-ancho .carpeta-frente {
    grid-template-columns: 2.25rem minmax(0, 1fr) auto;
  }

  .estante-ancho .carpeta-icono {
    display: grid;
  }

  .estante-ancho .carpeta-detalle {
    grid-column: 2 / -1;
  }
}

/* El estante de Mi portal: arriba de la pestaña Resumen, que va después, compacta (su dibujo al lado, más chico). */
.estante-portal > h2 {
  margin: 0 0 1.5rem;
  font-size: var(--t-l);
}

.estante-portal + .pestana {
  margin-top: 2.25rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--linea);
}

.estante-portal + .pestana .vacio {
  grid-template-columns: auto minmax(0, 1fr);
  justify-items: start;
  align-items: start;
  column-gap: 1.25rem;
  padding: 0;
  text-align: left;
}

.estante-portal + .pestana .vacio .ilustracion {
  grid-row: span 3;
  width: 4.5rem;
  margin: 0.25rem 0 0;
}

.estante-portal + .pestana .vacio h2 {
  font-size: var(--t-l);
}

.estante-portal + .pestana .vacio .pestana-descripcion {
  margin-bottom: 0.5rem;
}

/*
 * Fuera de Mi portal, la barra de pestañas es compacta (las migas): primero el regreso al estante (Resumen, con la flecha de
 * volver), un filo, y las demás, más chicas; la actual, como siempre, en tinta, en negrita y con la barra del acento.
 */
.pestanas-compactas a {
  height: 2.875rem;
  padding: 0 0.625rem;
  font-size: var(--t-s);
}

.pestanas-compactas .pestanas-estante {
  position: sticky;
  left: 0;
  z-index: 1;
  margin-right: 0;
  padding-right: 0.5rem;
  border-right: 1px solid var(--linea);
  background: var(--papel);
  box-shadow: -1rem 0 0 var(--papel), 0.25rem 0 0 var(--papel);
}

.pestanas-compactas .pestanas-estante a {
  color: var(--texto);
}

.pestanas-compactas .pestanas-estante .icono {
  transform: scaleX(-1);
}

@media (prefers-reduced-motion: reduce) {
  .carpeta,
  .carpeta-trasera .liquido,
  .carpeta-hojas > span,
  .estante-ancho .carpeta-detalle::after,
  .carpeta-frente,
  .carpeta-archivo,
  .carpeta[data-viva] > .carpeta-archivos {
    transition: none;
  }

  .carpeta-trasera .liquido {
    transform: scale(1.1);
  }

  .carpeta-frente {
    transform: perspective(var(--perspectiva)) rotateX(var(--inclina));
  }
}

@media (prefers-reduced-transparency: reduce) {
  .carpeta-frente {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@media (forced-colors: active) {
  .carpeta-trasera,
  .carpeta-hojas {
    display: none;
  }

  .carpeta-frente {
    transform: none;
  }
}

/* La gota de la cabecera, quieta con movimiento reducido (la regla de las transiciones va con la de todos: arriba). */
@media (prefers-reduced-motion: reduce) {
  .cabecera nav a .icono,
  .cabecera nav[data-gota] ul::before,
  .cabecera nav[data-hacia] ul::before {
    transition: none;
  }

  .cabecera nav[data-onda] ul::after {
    animation: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 18. La agenda (corte 2a, 29-oct): el calendario del día del personal, sus citas y las horas libres para elegir. Una cita es una
 *     fila de vidrio con su hora, su nombre y su sala; una hora libre, una pastilla que se marca como una opción (un radio, con su
 *     foco y su estado marcado visibles). Sin la hora en un color solo: la marcada lleva el fondo de tinta.
 * ------------------------------------------------------------------------------------------------------------------ */

.agenda-dias {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 1rem 0 1.25rem;
}

.agenda-fecha {
  flex: 1 1 14rem;
  margin: 0;
  font-size: var(--t-l);
  text-align: center;
}

.agenda-dias a:first-child .icono {
  transform: scaleX(-1);
}

.agenda-ir {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.75rem;
  margin: 0 0 1.75rem;
}

.agenda-ir .campo {
  margin: 0;
}

.agenda-doctor + .agenda-doctor {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--linea);
}

.citas {
  display: grid;
  gap: 0.5rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.cita {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
}

.cita-hora {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cita-texto {
  display: grid;
  gap: 0.125rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.cita-texto > span:last-child {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.cita-accion {
  margin: 0;
}

.cita-acciones {
  display: grid;
  justify-items: start;
  gap: 0.375rem;
}

.formulario-horas fieldset {
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
}

.horas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.horas legend {
  margin: 0 0 0.5rem;
  padding: 0;
  font-weight: 650;
}

.hora {
  position: relative;
  display: inline-block;
}

.hora input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.hora span {
  display: inline-grid;
  place-items: center;
  min-width: 4.5rem;
  min-height: 2.75rem;
  padding: 0 0.75rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--papel);
  color: var(--texto);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  transition: background-color var(--rapido) var(--salida), border-color var(--rapido) var(--salida), color var(--rapido) var(--salida);
}

.hora input:checked + span {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.hora input:focus-visible + span {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

/* La hora sugerida de «Agendar mi cita»: la misma opción de radio, pero con la frase entera (varias líneas en el celular) y arriba, sola. */
.hora-sugerida {
  display: block;
  margin: 0 0 1rem;
}

/* Un día de horas libres por plegable (el primero abierto): el nombre del grupo para el lector de pantalla es la <legend>, que no se ve porque el resumen ya dice el día. */
.dia-horas {
  border-top: 1px solid var(--linea);
}

.dia-horas > summary {
  font-size: var(--t-m);
}

.dia-horas > summary > span:first-child {
  font-weight: 650;
}

.dia-horas > summary .silenciado {
  font-weight: 500;
  white-space: nowrap;
}

.dia-horas legend {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

.dia-horas > fieldset {
  position: relative;
  margin: 0 0 0.75rem;
}

.mover-doctor {
  margin: 0 0 1.25rem;
}

.hora-sugerida span {
  padding: 0.5rem 1rem;
  border-radius: 1rem;
  text-align: center;
}

@media (hover: hover) and (pointer: fine) {
  .hora:hover span {
    border-color: var(--texto);
  }
}

@media (max-width: 30rem) {
  .cita {
    grid-template-columns: minmax(0, 1fr);
  }

  .cita-hora {
    grid-column: 1 / -1;
    white-space: normal;
  }

  /* Los botones debajo del texto, a todo el ancho de la tarjeta. */
  .cita-acciones {
    justify-items: stretch;
  }

  .cita-acciones .boton,
  .cita-acciones button {
    width: 100%;
    margin: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hora span {
    transition: none;
  }
}

/* «Tu próxima cita» del Resumen (nivel 2) y los avisos de «Mis citas»: una losa de tinta con la fecha en grande, o, sin cita, la
   invitación a agendar en vidrio. El texto es el de la tinta sobre la tinta (el par AA de los botones), sin opacidades. */
.proxima-cita {
  margin: 0 0 1.5rem;
  padding: 1.25rem 1.5rem;
  border-radius: 1rem;
  background: var(--primario);
  color: var(--sobre-primario);
}

.proxima-cita h2 {
  margin: 0 0 0.5rem;
  color: inherit;
  font-size: var(--t-m);
}

.proxima-cita p {
  margin: 0;
}

.proxima-fecha {
  font-size: var(--t-l);
  font-weight: 700;
}

.proxima-detalle {
  margin-top: 0.25rem;
}

.proxima-cita .acciones {
  margin-top: 1rem;
}

.proxima-vacia {
  border: 1px solid var(--linea);
  background: color-mix(in srgb, var(--papel) 70%, transparent);
  color: var(--texto);
}

.cita-aviso {
  max-width: 14rem;
  color: var(--silenciado);
  font-size: var(--t-s);
}

/* El aviso de que la agenda cambió en otro lado (agenda.js lo descubre; sin JS no aparece, porque lleva `hidden`). */
.aviso-cambios {
  margin: 0 0 1rem;
  padding: 0.625rem 1rem;
  border: 1px solid var(--acento-linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--acento) 10%, var(--papel));
  color: var(--texto);
  font-weight: 600;
}

.aviso-cambios[hidden] {
  display: none;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 19. El calendario del inicio (29-oct, pedido de Gabriel): la cuadrícula del mes (cada día, un enlace con cuántas citas tiene) y, del
 *     día elegido, sus horas por doctor (una hora libre, un enlace que agenda). El día elegido, el de hoy y los que tienen citas se
 *     distinguen por algo más que el color: un fondo de tinta, un anillo y el número de citas.
 * ------------------------------------------------------------------------------------------------------------------ */

.calendario {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--linea);
}

.mes-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0.75rem 0 1rem;
}

.mes-titulo {
  flex: 1 1 12rem;
  margin: 0;
  font-size: var(--t-l);
  text-align: center;
}

.mes-titulo::first-letter,
.dia-panel h3::first-letter {
  text-transform: uppercase;
}

.mes-nav a:first-child .icono {
  transform: scaleX(-1);
}

.mes {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0.25rem;
  table-layout: fixed;
}

.mes th {
  padding: 0.25rem 0;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 650;
  text-align: center;
}

.mes td {
  padding: 0;
}

.dia {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 3rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
  color: var(--texto);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: background-color var(--rapido) var(--salida), border-color var(--rapido) var(--salida);
}

.dia-numero {
  font-weight: 600;
}

.dia-citas {
  position: absolute;
  top: 0.1875rem;
  right: 0.3125rem;
  min-width: 1.125rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--acento);
  color: var(--sobre-acento, var(--papel));
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.125rem;
  text-align: center;
}

.dia[aria-current="date"] {
  box-shadow: inset 0 0 0 2px var(--acento);
}

.dia-elegido {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.dia:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .dia:hover {
    border-color: var(--texto);
  }
}

.dia-panel {
  margin-top: 1.5rem;
}

.dia-panel h3 {
  margin: 0 0 0.25rem;
  font-size: var(--t-l);
}

.franjas-doctor + .franjas-doctor {
  margin-top: 1.25rem;
}

.franjas-doctor h4 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

.franjas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.franja {
  display: grid;
  gap: 0.125rem;
  min-height: 3.25rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
  color: var(--texto);
  text-decoration: none;
}

.franja-hora {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.franja-texto {
  min-width: 0;
  color: var(--silenciado);
  font-size: var(--t-s);
  overflow-wrap: anywhere;
}

a.franja.libre {
  border-color: var(--borde);
  background: var(--papel);
}

a.franja.libre .franja-texto {
  color: var(--texto);
  font-weight: 600;
}

.franja.ocupada {
  background: color-mix(in srgb, var(--acento) 10%, var(--papel));
  border-color: var(--acento-linea);
}

.franja.ocupada .franja-texto {
  color: var(--texto);
}

.franja.pasada {
  opacity: 0.78;
}

a.franja:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  a.franja.libre:hover {
    border-color: var(--texto);
    background: color-mix(in srgb, var(--primario) 6%, var(--papel));
  }
}

.personas {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
}

.personas legend {
  margin: 0 0 0.5rem;
  padding: 0;
  font-weight: 650;
}

.personas ul {
  display: grid;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.opcion-persona label {
  display: flex;
  align-items: start;
  gap: 0.625rem;
  min-height: 2.75rem;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
  cursor: pointer;
}

.opcion-persona input {
  margin-top: 0.1875rem;
}

.opcion-persona:has(input:checked) label {
  border-color: var(--primario);
  box-shadow: inset 0 0 0 1px var(--primario);
}

.opcion-persona:has(input:focus-visible) label {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.opcion-persona:has(input:disabled) label {
  cursor: not-allowed;
  color: var(--silenciado);
}

@media (max-width: 30rem) {
  .dia {
    min-height: 2.5rem;
  }

  .franjas {
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 20. El odontograma del personal (corte 3a, plan O2; spec del 17-oct §8.1). Un SVG por cuadrante, en la cruz de siempre; cada pieza
 *     es un cuadrado de cinco caras que son enlaces. El color dice qué es (rojo, lo que hay que tratar; azul, lo restaurado) y la forma
 *     dice el estado (rayado, por tratar; rayado con borde de rayas, planificado; relleno, realizado): se lee igual en blanco y negro.
 *     Lo de la pieza entera lleva su signo encima (X, círculo, I, raya). Nada de esto lleva estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.odo {
  --odo-tratar: var(--c-rojo);
  --odo-hecho: #1f4eb4;
  --odo-trazo: color-mix(in srgb, var(--c-texto) 62%, var(--c-fondo));
  --odo-vacio: var(--c-fondo);
}

.odo-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.odo-patron-fondo {
  fill: var(--odo-vacio);
}

.odo-patron-tratar {
  stroke: var(--odo-tratar);
  stroke-width: 2.4;
}

.odo-patron-hecho {
  stroke: var(--odo-hecho);
  stroke-width: 2.4;
}

.odo-fecha {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 0 0 1rem;
}

.odo-fecha label {
  font-weight: 600;
}

.odo-leyenda {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: 0.375rem 1rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.odo-leyenda li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.odo-muestra {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
}

.odo-zona {
  margin: 0 0 1.25rem;
}

.odo-cruz {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem 1.5rem;
  margin: 0 0 0.75rem;
}

.odo-cuadrante {
  margin: 0;
  padding: 0.5rem 0.5rem 0.25rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
}

.odo-cuadrante figcaption {
  margin: 0 0 0.25rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--silenciado);
}

.odo-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.odo-temporales {
  margin: 0 0 1rem;
}

.odo-temporales > summary {
  cursor: pointer;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  font-weight: 600;
}

.cara polygon {
  fill: var(--odo-vacio);
  stroke: var(--odo-trazo);
  stroke-width: 1.25;
  stroke-linejoin: round;
  cursor: pointer;
}

.cara-caries-diagnosticado polygon {
  fill: url(#odo-rayado-tratar);
}

.cara-caries-planificado polygon {
  fill: url(#odo-rayado-tratar);
  stroke: var(--odo-tratar);
  stroke-width: 2.25;
  stroke-dasharray: 4 3;
}

.cara-caries-realizado polygon {
  fill: var(--odo-tratar);
}

.cara-restauracion-diagnosticado polygon {
  fill: url(#odo-rayado-hecho);
}

.cara-restauracion-planificado polygon {
  fill: url(#odo-rayado-hecho);
  stroke: var(--odo-hecho);
  stroke-width: 2.25;
  stroke-dasharray: 4 3;
}

.cara-restauracion-realizado polygon {
  fill: var(--odo-hecho);
}

.cara:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 1px;
}

.cara.cara-elegida polygon {
  stroke: var(--anillo);
  stroke-width: 4;
  stroke-dasharray: none;
}

.pieza-numero rect {
  fill: transparent;
  stroke: transparent;
  stroke-width: 1.5;
}

.pieza-numero text {
  fill: var(--texto);
  font-size: 13px;
  font-weight: 600;
  text-anchor: middle;
  cursor: pointer;
}

.pieza-numero:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 1px;
}

.pieza-numero.cara-elegida rect {
  fill: var(--seleccion);
  stroke: var(--anillo);
}

.signo {
  fill: none;
  stroke: var(--odo-tratar);
  stroke-width: 4;
  stroke-linecap: round;
  pointer-events: none;
}

.signo-planificado {
  stroke-dasharray: 6 5;
}

.signo-realizado {
  stroke: var(--odo-hecho);
}

.diente-ausente .cara {
  opacity: 0.35;
}

.odo-seleccion {
  margin: 0 0 1.5rem;
  padding: 1.25rem;
  scroll-margin-top: 5rem;
}

.odo-seleccion h2 {
  margin: 0 0 0.25rem;
}

.odo-pieza-nombre {
  margin: 0 0 0.75rem;
  color: var(--silenciado);
}

.odo-ahora {
  margin: 0 0 1rem;
}

.odo-historia {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 0.9375rem;
}

.odo-lista {
  margin: 0 0 1rem;
}

.odo-fecha input[type="date"] {
  width: auto;
  min-width: 11rem;
}

/* Atajo a las publicaciones del portal: el dibujo trae unos 320 enlaces y los botones de confirmar quedan detrás. */
.atajo {
  margin: 0 0 1rem;
}

.odo .acciones + .odo-fecha {
  margin-top: 1rem;
}

.odo-leyenda-plegable {
  margin: 0 0 1rem;
}

.atajo a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

#titulo-publicaciones {
  scroll-margin-top: 5rem;
}

/* Una publicación del portal (Tratamiento): su nota y sus tres confirmaciones, una debajo de otra. */
.publicacion {
  margin: 0 0 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--linea);
}

.publicacion h4 {
  margin: 0 0 0.25rem;
  font-size: var(--t-m);
}

.publicacion-nota {
  max-width: 46rem;
  margin: 0 0 1rem;
}

.publicacion-confirma {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pieza-numero {
  text-decoration: none;
}

.odo-temporales > summary::before,
.odo-otra > summary::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  margin: 0 0.75rem 0 0.25rem;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}

.odo-temporales[open] > summary::before,
.odo-otra[open] > summary::before {
  transform: rotate(45deg);
}

.odo-nombre {
  display: block;
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--silenciado);
}

.odo-elegir {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.75rem;
  margin: 0 0 1rem;
}

.odo-elegir .campo {
  flex: 1 1 14rem;
  margin: 0;
}

.odo-otra {
  margin: 0 0 1rem;
}

.odo-otra > summary {
  cursor: pointer;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  font-weight: 600;
}

@media (hover: hover) and (pointer: fine) {
  .cara:hover polygon {
    stroke: var(--anillo);
    stroke-width: 2.5;
  }

  .cara.cara-elegida:hover polygon {
    stroke-width: 4;
  }

  .pieza-numero:hover rect {
    fill: var(--seleccion);
  }
}

@media (min-width: 48rem) {
  .odo-cruz {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 70rem) {
  .odo-cruz-temporal {
    max-width: 44rem;
  }
}

/* En papel: solo el dibujo, su leyenda y la lista pieza por pieza, en blanco y negro (el rayado y las rayas dicen el estado). */
@media print {
  .odo-aviso,
  .odo > .acciones,
  .odo-fecha,
  .odo-seleccion,
  .odo-temporales > summary {
    display: none;
  }

  .odo {
    --odo-tratar: #000000;
    --odo-hecho: #000000;
    --odo-trazo: #000000;
  }

  .odo-cuadrante {
    break-inside: avoid;
    background: #ffffff;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 21. Los documentos (corte 3b, plan D2): la lista, el formulario de cada tipo y la hoja, que es lo único que sale en papel. La hoja
 *     usa la tinta y el papel de la clínica (nunca colores fijos), con el membrete de su configuración arriba, la firma abajo y el
 *     código de comprobación al pie. Nada de esto lleva estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.doc-nuevos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
}

.doc-formulario .campos-alta {
  grid-template-columns: 1fr;
  max-width: 40rem;
}

.doc-formulario textarea {
  width: 100%;
}

.doc-formulario .doc-medicamento {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.75rem 1rem;
  margin: 0 0 1rem;
  padding: 0.75rem 1rem 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
}

.doc-formulario .doc-medicamento legend {
  padding: 0 0.5rem;
  font-weight: 600;
}

.doc-formulario .doc-medicamento .campo {
  margin: 0;
}

.doc-lista {
  display: grid;
  gap: 0.625rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.doc-enlace {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-height: 2.75rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
  color: var(--texto);
  text-decoration: none;
}

.doc-enlace span {
  color: var(--silenciado);
  font-size: 0.875rem;
}

.doc-enlace:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .doc-enlace:hover {
    border-color: var(--acento-linea);
  }
}

.doc-acciones {
  display: flex;
  justify-content: flex-end;
  max-width: 46rem;
  margin: 0 auto 0.75rem;
}

.doc-acciones:empty {
  display: none;
}

.hoja-documento {
  position: relative;
  max-width: 46rem;
  margin: 0 auto 1.5rem;
  padding: 2rem 1.5rem 1.5rem;
  /* Es un papel: siempre claro, también en la noche; sus tintas son las del modo claro (si no, el título y los datos salían en letra clara sobre blanco). */
  --texto: var(--c-texto);
  --silenciado: color-mix(in srgb, var(--c-texto) 70%, var(--c-fondo));
  --linea: color-mix(in srgb, var(--c-texto) 12%, var(--c-fondo));
  --borde: color-mix(in srgb, var(--c-texto) 56%, var(--c-fondo));
  background: var(--c-fondo);
  color: var(--c-texto);
  border: 1px solid var(--borde);
  border-radius: 0.5rem;
  line-height: 1.6;
}

.membrete {
  margin: 0 0 1.25rem;
  padding: 0 0 0.75rem;
  border-bottom: 1px solid var(--borde);
}

.membrete-logo {
  display: block;
  max-height: 3.5rem;
  width: auto;
}

.membrete-nombre {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
}

.membrete-descriptor,
.membrete-datos {
  margin: 0.125rem 0 0;
  font-size: 0.8125rem;
  color: var(--silenciado);
}

.doc-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  margin: 0 0 0.25rem;
}

.doc-titulo {
  margin: 0;
  font-size: 1.5rem;
}

.doc-numero {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.doc-fecha {
  margin: 0 0 1rem;
  text-align: right;
  color: var(--silenciado);
}

.doc-paciente {
  margin: 0 0 1rem;
}

.doc-paciente span {
  color: var(--silenciado);
}

.doc-subtitulo {
  margin: 1.25rem 0 0.5rem;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.doc-medicamentos {
  margin: 0 0 0.5rem;
  padding-left: 1.5rem;
}

.doc-medicamentos li {
  margin: 0 0 0.625rem;
}

.doc-medicamentos li span {
  display: block;
  color: var(--silenciado);
  font-size: 0.9375rem;
}

.doc-texto,
.doc-destinatario,
.doc-asunto {
  margin: 0 0 0.875rem;
}

.doc-firma {
  width: min(100%, 17rem);
  margin: 3.5rem 0 0;
}

.doc-firma-linea {
  margin: 0 0 0.375rem;
  border-top: 1px solid var(--c-texto);
}

.doc-firma p {
  margin: 0;
  font-size: 0.9375rem;
}

.doc-pie {
  margin: 2rem 0 0;
  padding: 0.625rem 0 0;
  border-top: 1px solid var(--borde);
  font-size: 0.75rem;
  color: var(--silenciado);
}

.doc-pie p {
  margin: 0 0 0.125rem;
}

.doc-url {
  overflow-wrap: anywhere;
}

.doc-sello {
  display: inline-block;
  margin: 0 0 1rem;
  padding: 0.25rem 0.75rem;
  border: 3px solid var(--c-rojo);
  border-radius: 0.375rem;
  color: var(--c-rojo);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transform: rotate(-3deg);
}

.doc-anular {
  max-width: 46rem;
  margin: 0 auto;
}

/* En papel: solo la hoja. Se va todo lo demás (la cabecera, el pie, el fondo, los avisos, «Imprimir» y «Anular») y ella pierde su borde. */
@media print {
  .panel > :not(.hoja-documento),
  .portal > .perfil,
  .doc-pagina > :not(.hoja-documento),
  body:has(.hoja-documento) .cabecera {
    display: none;
  }

  .hoja.doc-pagina {
    padding: 0;
    border: 0;
    box-shadow: none;
  }

  .hoja-documento {
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: #ffffff;
    color: #000000;
  }

  .hoja-documento .membrete,
  .hoja-documento .doc-pie {
    border-color: #000000;
  }

  .doc-firma-linea {
    border-color: #000000;
  }

  .doc-sello {
    color: #000000;
    border-color: #000000;
  }

  .doc-fecha,
  .doc-paciente span,
  .doc-medicamentos li span,
  .doc-pie,
  .membrete-descriptor,
  .membrete-datos {
    color: #000000;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 22. El calendario del personal (29-oct, pedido de Gabriel: «como el calendario del teléfono»). Una barra de vistas (Mes, Semana, Día y
 *     Lista), la tira de la semana con el día elegido en un círculo, la rejilla por horas (una fila cada 15 minutos, de 07:00 a 20:00)
 *     con la línea de «ahora», la cita como un bloque con su información y el botón «+». Los bloques no llevan estilos en línea: cada uno
 *     trae sus clases `c<columna>`, `f<fila de inicio>` y `l<filas que ocupa>` (y `min-<minutos>` la línea de ahora), que valen
 *     `grid-column` y `grid-row` (las generó un script: 52 filas, 10 columnas y 15 minutos).
 * ------------------------------------------------------------------------------------------------------------------ */

.calendario {
  --celda: 0.9375rem;
  --eje: 3.25rem;
  position: relative;
  margin: 1.5rem 0 0;
}

.hoja-calendario .calendario {
  margin-top: 0.5rem;
}

.cal-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0 0 0.75rem;
}

.cal-titulo {
  margin: 0;
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
}

.cal-nav {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.cal-flecha,
.cal-hoy {
  display: inline-grid;
  place-items: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  background: color-mix(in srgb, var(--papel) 75%, transparent);
  color: var(--texto);
  text-decoration: none;
}

.cal-hoy {
  padding: 0 1rem;
  font-weight: 600;
}

.cal-hoy[aria-current="date"] {
  border-color: var(--acento);
  color: var(--acento-tinta);
}

.cal-flecha span {
  width: 0.5625rem;
  height: 0.5625rem;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
}

.cal-ant span {
  transform: translateX(2px) rotate(135deg);
}

.cal-sig span {
  transform: translateX(-2px) rotate(-45deg);
}

.cal-flecha:focus-visible,
.cal-hoy:focus-visible,
.cal-vistas a:focus-visible,
.tira-dia:focus-visible,
.mes-dia:focus-visible,
.cal-cita:focus-visible,
.cal-hueco:focus-visible,
.lista-cita:focus-visible,
.cal-fab:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.cal-vistas {
  display: flex;
  gap: 0.25rem;
  margin: 0 0 1rem;
  padding: 0.25rem;
  border-radius: 999px;
  background: var(--papel-2);
}

.cal-vistas a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  border-radius: 999px;
  color: var(--silenciado);
  font-weight: 500;
  text-decoration: none;
}

.cal-vistas a[aria-current="true"] {
  background: var(--papel);
  color: var(--texto);
  font-weight: 700;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--c-texto) 18%, transparent);
}

.cal-doctor {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 0 0 0.75rem;
}

.cal-doctor label {
  font-weight: 600;
}

.cal-doctor select {
  width: auto;
  min-width: 14rem;
}

.cal-tira {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.25rem;
  margin: 0 0 0.75rem;
  text-align: center;
}

.tira-dia {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0;
  color: var(--texto);
  text-decoration: none;
}

.tira-letra {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--silenciado);
}

.tira-dia.finde .tira-letra {
  opacity: 0.75;
}

.tira-num {
  display: grid;
  place-items: center;
  width: 2.625rem;
  height: 2.625rem;
  border-radius: 50%;
  font-size: 1.0625rem;
  font-weight: 700;
}

.tira-dia.hoy .tira-num {
  box-shadow: inset 0 0 0 2px var(--acento);
}

.tira-dia.activo .tira-num {
  background: var(--acento);
  color: var(--sobre-acento);
  box-shadow: none;
}

.cal-cuerpo {
  overflow-x: auto;
}

.cal-cols,
.cal-rejilla {
  display: grid;
  min-width: 18rem;
}

.cal-cols {
  margin: 0 0 0.25rem;
}

.cal-colhead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
  padding: 0.25rem 0.25rem 0;
  min-width: 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--silenciado);
  text-align: center;
}

.cal-colhead span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cal-colhead b {
  display: grid;
  place-items: center;
  min-width: 2rem;
  height: 2rem;
  border-radius: 50%;
  font-size: 1rem;
  color: var(--texto);
}

.cal-colhead.hoy b {
  background: var(--acento);
  color: var(--sobre-acento);
}

.cal-colhead.finde {
  opacity: 0.8;
}

.cal-rejilla {
  position: relative;
  grid-template-rows: repeat(52, var(--celda));
  overflow: hidden;
  border: 1px solid var(--linea);
  border-radius: 1.25rem;
  background: var(--papel);
}

.cal-hora {
  grid-column: 1;
  align-self: start;
  justify-self: end;
  margin: -0.5em 0.5rem 0 0;
  font-size: 0.75rem;
  line-height: 1;
  color: var(--silenciado);
  font-variant-numeric: tabular-nums;
}

.cal-col {
  grid-row: 1 / -1;
  border-left: 1px solid var(--linea);
  background-color: var(--lienzo);
  background-image: repeating-linear-gradient(to bottom, transparent 0, transparent calc(var(--celda) * 4 - 1px), var(--linea) calc(var(--celda) * 4 - 1px), var(--linea) calc(var(--celda) * 4));
}

.cal-col.hoy {
  background-color: color-mix(in srgb, var(--acento) 5%, var(--lienzo));
}

.cal-jornada {
  background-color: var(--papel);
  background-image: repeating-linear-gradient(to bottom, transparent 0, transparent calc(var(--celda) * 4 - 1px), var(--linea) calc(var(--celda) * 4 - 1px), var(--linea) calc(var(--celda) * 4));
  background-position: 0 calc(var(--celda) * 0);
}

.cal-hueco {
  z-index: 1;
  display: grid;
  place-items: center;
  margin: 1px 2px;
  border-radius: 0.5rem;
  color: var(--acento-tinta);
  opacity: 0;
  text-decoration: none;
}

.cal-hueco span {
  position: relative;
  width: 0.875rem;
  height: 0.875rem;
}

.cal-hueco span::before,
.cal-hueco span::after {
  content: "";
  position: absolute;
  background: currentColor;
}

.cal-hueco span::before {
  left: 0;
  right: 0;
  top: calc(50% - 1px);
  height: 2px;
}

.cal-hueco span::after {
  top: 0;
  bottom: 0;
  left: calc(50% - 1px);
  width: 2px;
}

.cal-hueco:focus-visible {
  opacity: 1;
  background: var(--acento-suave);
}

.cal-cita {
  z-index: 2;
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin: 1px 2px;
  padding: 0.1875rem 0.4375rem;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--acento) 35%, var(--papel));
  border-radius: 0.5rem;
  background: color-mix(in srgb, var(--acento) 15%, var(--papel));
  color: var(--texto);
  font-size: 0.75rem;
  line-height: 1.25;
  text-decoration: none;
}

.cal-cita-hora {
  color: var(--silenciado);
  font-variant-numeric: tabular-nums;
}

.cal-cita-hora::before,
.lista-hora::before {
  content: "";
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.3125rem;
  border-radius: 50%;
  background: var(--acento);
}

.cal-cita-nombre {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cal-cita-tipo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--silenciado);
}

.cal-cita.l1 .cal-cita-hora,
.cal-cita.l1 .cal-cita-tipo,
.cal-cita.l2 .cal-cita-tipo {
  display: none;
}

.cal-cita.l1,
.cal-cita.l2 {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}

.cal-hora.f1 {
  margin-top: 0.25rem;
}

.cal-cita.e-atendida {
  border-color: var(--linea);
  background: color-mix(in srgb, var(--texto) 7%, var(--papel));
}

.cal-cita.e-atendida .cal-cita-hora::before,
.e-atendida .lista-hora::before {
  background: var(--silenciado);
}

.cal-cita.e-llego .cal-cita-hora::before,
.e-llego .lista-hora::before {
  background: var(--c-primario);
}

.cal-cita.e-no_asistio {
  border-color: var(--error-linea);
  background: var(--error-fondo);
}

.cal-cita.e-no_asistio .cal-cita-hora::before,
.e-no_asistio .lista-hora::before {
  background: var(--c-rojo);
}

.cal-cita.activa {
  outline: 2px solid var(--anillo);
  outline-offset: -1px;
}

.cal-ahora {
  z-index: 3;
  align-self: start;
  height: 2px;
  background: var(--c-rojo);
  pointer-events: none;
}

.cal-ahora-hora {
  z-index: 3;
  grid-column: 1;
  align-self: start;
  justify-self: end;
  margin: calc(-0.5em - 1px) 0.25rem 0 0;
  padding: 0.125rem 0.375rem;
  border-radius: 999px;
  background: var(--c-rojo);
  color: #ffffff;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* La hora de «ahora» (su chip) y la etiqueta de la hora en punto se tapan cuando están a menos de unos 15 minutos: se aparta la etiqueta (el chip ya dice la hora).
   Una regla por hora: el chip lleva la fila de su minuto (`f<fila>`) y la etiqueta, la de su hora en punto (`f1`, `f5`, `f9`…). */
.cal-rejilla:has(.cal-ahora-hora:is(.f1)) .cal-hora.f1,
.cal-rejilla:has(.cal-ahora-hora:is(.f4, .f5)) .cal-hora.f5,
.cal-rejilla:has(.cal-ahora-hora:is(.f8, .f9)) .cal-hora.f9,
.cal-rejilla:has(.cal-ahora-hora:is(.f12, .f13)) .cal-hora.f13,
.cal-rejilla:has(.cal-ahora-hora:is(.f16, .f17)) .cal-hora.f17,
.cal-rejilla:has(.cal-ahora-hora:is(.f20, .f21)) .cal-hora.f21,
.cal-rejilla:has(.cal-ahora-hora:is(.f24, .f25)) .cal-hora.f25,
.cal-rejilla:has(.cal-ahora-hora:is(.f28, .f29)) .cal-hora.f29,
.cal-rejilla:has(.cal-ahora-hora:is(.f32, .f33)) .cal-hora.f33,
.cal-rejilla:has(.cal-ahora-hora:is(.f36, .f37)) .cal-hora.f37,
.cal-rejilla:has(.cal-ahora-hora:is(.f40, .f41)) .cal-hora.f41,
.cal-rejilla:has(.cal-ahora-hora:is(.f44, .f45)) .cal-hora.f45,
.cal-rejilla:has(.cal-ahora-hora:is(.f48, .f49)) .cal-hora.f49 {
  visibility: hidden;
}

/* Con cinco columnas o más (Semana) una cita corta no tiene lugar para «10:00–10:30»: queda el punto de su estado y el nombre usa el resto (la hora la dicen el eje y la ventana; el
   lector de pantalla la sigue leyendo). */
:is(.cols-5, .cols-6, .cols-7) .cal-cita:is(.l1, .l2) .cal-cita-hora {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

:is(.cols-5, .cols-6, .cols-7) .cal-cita:is(.l1, .l2)::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.25rem;
  border-radius: 50%;
  background: var(--acento);
}

:is(.cols-5, .cols-6, .cols-7) .cal-cita.e-atendida:is(.l1, .l2)::before {
  background: var(--silenciado);
}

:is(.cols-5, .cols-6, .cols-7) .cal-cita.e-llego:is(.l1, .l2)::before {
  background: var(--c-primario);
}

:is(.cols-5, .cols-6, .cols-7) .cal-cita.e-no_asistio:is(.l1, .l2)::before {
  background: var(--c-rojo);
}

:is(.cols-5, .cols-6, .cols-7) .cal-cita:is(.l1, .l2) {
  gap: 0;
  padding-inline: 0.25rem;
}

.cc-todo {
  grid-column: 2 / -1;
}

.cal-mes {
  border: 1px solid var(--linea);
  border-radius: 1.25rem;
  background: var(--papel);
  overflow: hidden;
}

.mes-letras,
.mes-dias {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.mes-letras span {
  padding: 0.5rem 0;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--silenciado);
}

.mes-dia,
.mes-vacio {
  min-height: 3.5rem;
  border-top: 1px solid var(--linea);
}

.mes-dia {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
  padding: 0.25rem 0;
  color: var(--texto);
  text-decoration: none;
}

.mes-num {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  font-weight: 600;
}

.mes-dia.hoy .mes-num {
  box-shadow: inset 0 0 0 2px var(--acento);
}

.mes-dia.activo .mes-num {
  background: var(--acento);
  color: var(--sobre-acento);
  box-shadow: none;
}

.mes-citas {
  min-width: 1.25rem;
  padding: 0 0.3125rem;
  border-radius: 999px;
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-size: 0.75rem;
  font-weight: 700;
  text-align: center;
}

/* «Por confirmar mañana» (F1.3, B8): el bloque plegable sobre la rejilla, con aire debajo. */
.cal-confirmar {
  margin: 0 0 1rem;
}

.cal-lista {
  display: grid;
  gap: 1rem;
}

.lista-dia h3 {
  margin: 0 0 0.375rem;
  font-size: 1rem;
}

.lista-dia ul {
  display: grid;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lista-cita {
  display: flex;
  gap: 0.75rem;
  align-items: baseline;
  min-height: 2.75rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--papel) 75%, transparent);
  color: var(--texto);
  text-decoration: none;
}

.lista-hora {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

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

.lista-texto span {
  color: var(--silenciado);
  font-size: 0.875rem;
}

.calendario .cal-detalle {
  max-width: 34rem;
  margin: 1.25rem 0 0;
  padding: 1.25rem;
  scroll-margin-top: 5rem;
}

.cal-detalle h3 {
  margin: 0 0 0.5rem;
}

.cal-fab {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 20;
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: var(--papel);
  color: var(--acento-tinta);
  box-shadow: 0 6px 20px color-mix(in srgb, var(--c-texto) 22%, transparent), 0 0 0 1px var(--linea);
  text-decoration: none;
}

.cal-fab span {
  position: relative;
  width: 1.25rem;
  height: 1.25rem;
}

.cal-fab span::before,
.cal-fab span::after {
  content: "";
  position: absolute;
  background: currentColor;
}

.cal-fab span::before {
  left: 0;
  right: 0;
  top: calc(50% - 1.5px);
  height: 3px;
}

.cal-fab span::after {
  top: 0;
  bottom: 0;
  left: calc(50% - 1.5px);
  width: 3px;
}

@media (hover: hover) and (pointer: fine) {
  .cal-hueco:hover {
    opacity: 1;
    background: var(--acento-suave);
  }

  .cal-cita:hover {
    background: color-mix(in srgb, var(--acento) 26%, var(--papel));
  }

  /* Con el tinte más fuerte del puntero, la hora y el tipo (en gris) bajarían de 4,5:1 con algunas paletas: pasan a la tinta plena. */
  .cal-cita:hover .cal-cita-hora,
  .cal-cita:hover .cal-cita-tipo {
    color: var(--texto);
  }

  .mes-dia:hover .mes-num,
  .tira-dia:hover .tira-num {
    background: var(--acento-suave);
  }

  .lista-cita:hover {
    border-color: var(--acento-linea);
  }
}

@media (max-width: 40rem) {
  .calendario {
    --eje: 2.75rem;
    /* 23 px cada 15 minutos: un bloque de 30 minutos (una hora libre, una cita) mide 44 px con su margen, el objetivo táctil mínimo. */
    --celda: 1.4375rem;
  }

  .cal-cuerpo .cols-7 {
    min-width: 0;
  }

  .cols-7 .cal-cita {
    align-items: center;
    justify-content: center;
    padding-inline: 0;
  }

  .cols-7 .cal-cita::before {
    content: "";
    flex: none;
    width: 0.5rem;
    height: 0.5rem;
    margin: 0;
    border-radius: 50%;
    background: var(--acento);
  }

  .cols-7 .cal-cita.e-atendida::before {
    background: var(--silenciado);
  }

  .cols-7 .cal-cita.e-llego::before {
    background: var(--c-primario);
  }

  .cols-7 .cal-cita.e-no_asistio::before {
    background: var(--c-rojo);
  }

  .cols-7 .cal-cita-nombre {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: visible;
    clip-path: inset(50%);
    text-overflow: clip;
  }

  .cal-cuerpo .cols-3,
  .cal-cuerpo .cols-4,
  .cal-cuerpo .cols-5,
  .cal-cuerpo .cols-6 {
    min-width: 24rem;
  }

  .cal-cita-hora,
  .cal-cita-tipo {
    display: none;
  }

  .calendario .cal-detalle {
    max-width: none;
  }
}

@media print {
  .cal-fab,
  .cal-vistas,
  .cal-nav,
  .cal-doctor,
  .cal-hueco {
    display: none;
  }
}

.f1 {
  grid-row-start: 1;
}

.f2 {
  grid-row-start: 2;
}

.f3 {
  grid-row-start: 3;
}

.f4 {
  grid-row-start: 4;
}

.f5 {
  grid-row-start: 5;
}

.f6 {
  grid-row-start: 6;
}

.f7 {
  grid-row-start: 7;
}

.f8 {
  grid-row-start: 8;
}

.f9 {
  grid-row-start: 9;
}

.f10 {
  grid-row-start: 10;
}

.f11 {
  grid-row-start: 11;
}

.f12 {
  grid-row-start: 12;
}

.f13 {
  grid-row-start: 13;
}

.f14 {
  grid-row-start: 14;
}

.f15 {
  grid-row-start: 15;
}

.f16 {
  grid-row-start: 16;
}

.f17 {
  grid-row-start: 17;
}

.f18 {
  grid-row-start: 18;
}

.f19 {
  grid-row-start: 19;
}

.f20 {
  grid-row-start: 20;
}

.f21 {
  grid-row-start: 21;
}

.f22 {
  grid-row-start: 22;
}

.f23 {
  grid-row-start: 23;
}

.f24 {
  grid-row-start: 24;
}

.f25 {
  grid-row-start: 25;
}

.f26 {
  grid-row-start: 26;
}

.f27 {
  grid-row-start: 27;
}

.f28 {
  grid-row-start: 28;
}

.f29 {
  grid-row-start: 29;
}

.f30 {
  grid-row-start: 30;
}

.f31 {
  grid-row-start: 31;
}

.f32 {
  grid-row-start: 32;
}

.f33 {
  grid-row-start: 33;
}

.f34 {
  grid-row-start: 34;
}

.f35 {
  grid-row-start: 35;
}

.f36 {
  grid-row-start: 36;
}

.f37 {
  grid-row-start: 37;
}

.f38 {
  grid-row-start: 38;
}

.f39 {
  grid-row-start: 39;
}

.f40 {
  grid-row-start: 40;
}

.f41 {
  grid-row-start: 41;
}

.f42 {
  grid-row-start: 42;
}

.f43 {
  grid-row-start: 43;
}

.f44 {
  grid-row-start: 44;
}

.f45 {
  grid-row-start: 45;
}

.f46 {
  grid-row-start: 46;
}

.f47 {
  grid-row-start: 47;
}

.f48 {
  grid-row-start: 48;
}

.f49 {
  grid-row-start: 49;
}

.f50 {
  grid-row-start: 50;
}

.f51 {
  grid-row-start: 51;
}

.f52 {
  grid-row-start: 52;
}

.l1 {
  grid-row-end: span 1;
}

.l2 {
  grid-row-end: span 2;
}

.l3 {
  grid-row-end: span 3;
}

.l4 {
  grid-row-end: span 4;
}

.l5 {
  grid-row-end: span 5;
}

.l6 {
  grid-row-end: span 6;
}

.l7 {
  grid-row-end: span 7;
}

.l8 {
  grid-row-end: span 8;
}

.l9 {
  grid-row-end: span 9;
}

.l10 {
  grid-row-end: span 10;
}

.l11 {
  grid-row-end: span 11;
}

.l12 {
  grid-row-end: span 12;
}

.l13 {
  grid-row-end: span 13;
}

.l14 {
  grid-row-end: span 14;
}

.l15 {
  grid-row-end: span 15;
}

.l16 {
  grid-row-end: span 16;
}

.l17 {
  grid-row-end: span 17;
}

.l18 {
  grid-row-end: span 18;
}

.l19 {
  grid-row-end: span 19;
}

.l20 {
  grid-row-end: span 20;
}

.l21 {
  grid-row-end: span 21;
}

.l22 {
  grid-row-end: span 22;
}

.l23 {
  grid-row-end: span 23;
}

.l24 {
  grid-row-end: span 24;
}

.l25 {
  grid-row-end: span 25;
}

.l26 {
  grid-row-end: span 26;
}

.l27 {
  grid-row-end: span 27;
}

.l28 {
  grid-row-end: span 28;
}

.l29 {
  grid-row-end: span 29;
}

.l30 {
  grid-row-end: span 30;
}

.l31 {
  grid-row-end: span 31;
}

.l32 {
  grid-row-end: span 32;
}

.l33 {
  grid-row-end: span 33;
}

.l34 {
  grid-row-end: span 34;
}

.l35 {
  grid-row-end: span 35;
}

.l36 {
  grid-row-end: span 36;
}

.l37 {
  grid-row-end: span 37;
}

.l38 {
  grid-row-end: span 38;
}

.l39 {
  grid-row-end: span 39;
}

.l40 {
  grid-row-end: span 40;
}

.l41 {
  grid-row-end: span 41;
}

.l42 {
  grid-row-end: span 42;
}

.l43 {
  grid-row-end: span 43;
}

.l44 {
  grid-row-end: span 44;
}

.l45 {
  grid-row-end: span 45;
}

.l46 {
  grid-row-end: span 46;
}

.l47 {
  grid-row-end: span 47;
}

.l48 {
  grid-row-end: span 48;
}

.l49 {
  grid-row-end: span 49;
}

.l50 {
  grid-row-end: span 50;
}

.l51 {
  grid-row-end: span 51;
}

.l52 {
  grid-row-end: span 52;
}

.c1 {
  grid-column: 2;
}

.c2 {
  grid-column: 3;
}

.c3 {
  grid-column: 4;
}

.c4 {
  grid-column: 5;
}

.c5 {
  grid-column: 6;
}

.c6 {
  grid-column: 7;
}

.c7 {
  grid-column: 8;
}

.c8 {
  grid-column: 9;
}

.c9 {
  grid-column: 10;
}

.c10 {
  grid-column: 11;
}

.cols-1 {
  grid-template-columns: var(--eje) repeat(1, minmax(0, 1fr));
}

.cols-2 {
  grid-template-columns: var(--eje) repeat(2, minmax(0, 1fr));
}

.cols-3 {
  grid-template-columns: var(--eje) repeat(3, minmax(0, 1fr));
}

.cols-4 {
  grid-template-columns: var(--eje) repeat(4, minmax(0, 1fr));
}

.cols-5 {
  grid-template-columns: var(--eje) repeat(5, minmax(0, 1fr));
}

.cols-6 {
  grid-template-columns: var(--eje) repeat(6, minmax(0, 1fr));
}

.cols-7 {
  grid-template-columns: var(--eje) repeat(7, minmax(0, 1fr));
}

.cols-8 {
  grid-template-columns: var(--eje) repeat(8, minmax(0, 1fr));
}

.cols-9 {
  grid-template-columns: var(--eje) repeat(9, minmax(0, 1fr));
}

.cols-10 {
  grid-template-columns: var(--eje) repeat(10, minmax(0, 1fr));
}

.min-0 {
  margin-top: calc(var(--celda) * 0 / 15);
}

.min-1 {
  margin-top: calc(var(--celda) * 1 / 15);
}

.min-2 {
  margin-top: calc(var(--celda) * 2 / 15);
}

.min-3 {
  margin-top: calc(var(--celda) * 3 / 15);
}

.min-4 {
  margin-top: calc(var(--celda) * 4 / 15);
}

.min-5 {
  margin-top: calc(var(--celda) * 5 / 15);
}

.min-6 {
  margin-top: calc(var(--celda) * 6 / 15);
}

.min-7 {
  margin-top: calc(var(--celda) * 7 / 15);
}

.min-8 {
  margin-top: calc(var(--celda) * 8 / 15);
}

.min-9 {
  margin-top: calc(var(--celda) * 9 / 15);
}

.min-10 {
  margin-top: calc(var(--celda) * 10 / 15);
}

.min-11 {
  margin-top: calc(var(--celda) * 11 / 15);
}

.min-12 {
  margin-top: calc(var(--celda) * 12 / 15);
}

.min-13 {
  margin-top: calc(var(--celda) * 13 / 15);
}

.min-14 {
  margin-top: calc(var(--celda) * 14 / 15);
}

/* ------------------------------------------------------------------------------------------------------------------
 * 24. El acabado de lujo (29-oct, pedido de Gabriel, con una referencia visual de vidrio: un calendario translúcido de bordes finos, sombras largas y un día elegido
 *     en degradado). Solo la piel: oro pulido en los filos, sombras en capas con un reflejo cálido del acento, cristal en lo que se toca, y la ventana de la cita.
 *     Todo sale del acento y del texto de la clínica (color-mix), así sigue al modo claro y al oscuro y a cada paleta; el contraste del texto no cambia (los
 *     fondos de lo que lleva letra siguen siendo los de siempre, con más luz por los bordes). Nada de esto toca el contenido ni el orden de las cosas.
 * ------------------------------------------------------------------------------------------------------------------ */

:root {
  --lujo-1: color-mix(in srgb, var(--c-acento) 52%, #f6e7b4);
  --lujo-2: color-mix(in srgb, var(--c-acento) 100%, #ffffff);
  --lujo-3: color-mix(in srgb, var(--c-acento) 72%, #000000);
  --lujo-metal: linear-gradient(135deg, var(--lujo-3) 0%, var(--lujo-2) 34%, var(--lujo-1) 52%, var(--lujo-2) 70%, var(--lujo-3) 100%);
  --lujo-hilo: color-mix(in srgb, var(--lujo-2) 46%, transparent);
  --lujo-hilo-suave: color-mix(in srgb, var(--lujo-2) 26%, transparent);
  --lujo-resplandor: color-mix(in srgb, var(--lujo-2) 42%, transparent);
  --r-hoja: 1.5rem;
  --r-control: 0.75rem;
  --sombra:
    0 1px 1px color-mix(in srgb, var(--c-texto) 7%, transparent),
    0 4px 8px -2px color-mix(in srgb, var(--c-texto) 7%, transparent),
    0 18px 36px -14px color-mix(in srgb, var(--c-texto) 20%, transparent),
    0 42px 84px -38px color-mix(in srgb, var(--c-acento) 48%, transparent);
  --vidrio-sombra: var(--sombra);
  --vidrio-luz: color-mix(in srgb, #ffffff 92%, var(--lujo-1));
}

@media (prefers-color-scheme: dark) {
  :root {
    --sombra: 0 1px 0 color-mix(in srgb, #ffffff 7%, transparent), 0 22px 46px -22px #000000, 0 46px 92px -48px color-mix(in srgb, var(--c-acento) 50%, #000000);
    --vidrio-sombra: var(--sombra);
    --vidrio-luz: color-mix(in srgb, #ffffff 16%, var(--lujo-1));
  }
}

/* Los botones: la tinta de siempre con un filo de oro pulido, una luz que baja desde arriba y una sombra en capas con reflejo cálido. */
button,
.boton {
  --boton-vidrio: linear-gradient(180deg, color-mix(in srgb, var(--primario) 90%, var(--lujo-2)), color-mix(in srgb, var(--primario) 97%, transparent));
  --boton-brillo: linear-gradient(160deg, color-mix(in srgb, var(--lujo-1) 40%, transparent) 0%, rgba(255, 255, 255, 0) 46%);
  --boton-filos: inset 0 0 0 1px color-mix(in srgb, var(--lujo-2) 64%, transparent), inset 2px 2px 1px 0 rgba(255, 255, 255, 0.4), inset -1px -1px 1px 1px color-mix(in srgb, var(--lujo-1) 28%, transparent);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--texto) 24%, transparent),
    0 6px 10px -4px color-mix(in srgb, var(--primario) 55%, transparent),
    0 18px 30px -14px color-mix(in srgb, var(--primario) 70%, transparent),
    0 12px 26px -12px var(--lujo-resplandor);
}

@media (hover: hover) and (pointer: fine) {
  button:hover,
  .boton:hover {
    box-shadow:
      0 1px 2px color-mix(in srgb, var(--texto) 24%, transparent),
      0 8px 14px -4px color-mix(in srgb, var(--primario) 55%, transparent),
      0 24px 38px -14px color-mix(in srgb, var(--primario) 72%, transparent),
      0 14px 34px -10px var(--lujo-resplandor);
  }
}

.boton-secundario {
  border-color: color-mix(in srgb, var(--lujo-2) 58%, var(--borde));
  --boton-vidrio: linear-gradient(180deg, color-mix(in srgb, var(--lujo-1) 22%, var(--papel)), color-mix(in srgb, var(--lujo-2) 9%, var(--papel)));
  --boton-brillo: linear-gradient(160deg, rgba(255, 255, 255, 0.72) 0%, rgba(255, 255, 255, 0) 52%);
  --boton-filos: inset 0 0 0 1px var(--lujo-hilo), inset 2px 2px 1px 0 var(--boton-luz), inset -1px -1px 1px 1px color-mix(in srgb, var(--lujo-2) 16%, transparent);
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--texto) 10%, transparent),
    0 5px 9px -4px color-mix(in srgb, var(--texto) 16%, transparent),
    0 16px 26px -14px color-mix(in srgb, var(--lujo-2) 52%, transparent);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .boton-secundario {
    border-color: transparent;
  }
}

@media (hover: hover) and (pointer: fine) {
  .boton-secundario:hover {
    border-color: var(--lujo-2);
    box-shadow:
      0 1px 2px color-mix(in srgb, var(--texto) 12%, transparent),
      0 8px 14px -4px color-mix(in srgb, var(--texto) 18%, transparent),
      0 20px 32px -14px color-mix(in srgb, var(--lujo-2) 62%, transparent);
  }
}

/* Los campos: un borde de oro tenue, un hueco por dentro (la luz viene de arriba) y, al enfocar, un halo cálido. */
input:not([type="checkbox"], [type="radio"], [type="hidden"]),
select,
textarea {
  border-color: color-mix(in srgb, var(--lujo-2) 34%, var(--borde));
  box-shadow: inset 0 1px 2px color-mix(in srgb, var(--texto) 9%, transparent), 0 1px 0 color-mix(in srgb, #ffffff 70%, transparent), 0 8px 16px -12px var(--lujo-resplandor);
}

input:not([type="checkbox"], [type="radio"], [type="hidden"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--lujo-2);
  box-shadow: inset 0 1px 2px color-mix(in srgb, var(--texto) 9%, transparent), 0 0 0 4px color-mix(in srgb, var(--lujo-2) 26%, transparent), 0 12px 24px -12px var(--lujo-resplandor);
}

/* Los sellos de estado: un filo de oro y una luz arriba. */
.sello {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 60%, transparent), 0 0 0 1px var(--lujo-hilo-suave), 0 6px 12px -8px var(--lujo-resplandor);
}

/* El calendario: las vistas como un control de cristal con la elegida en relieve, los días elegidos en oro oscuro con halo, las citas como cristales con su luz. */
.cal-vistas {
  background: linear-gradient(180deg, color-mix(in srgb, var(--texto) 7%, transparent), color-mix(in srgb, var(--texto) 3%, transparent));
  box-shadow: inset 0 1px 3px color-mix(in srgb, var(--texto) 14%, transparent), 0 1px 0 color-mix(in srgb, #ffffff 60%, transparent), 0 0 0 1px var(--lujo-hilo-suave);
}

.cal-vistas a[aria-current="true"] {
  background: linear-gradient(180deg, color-mix(in srgb, var(--lujo-1) 30%, var(--papel)), color-mix(in srgb, var(--lujo-2) 10%, var(--papel)));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 80%, transparent), 0 0 0 1px var(--lujo-hilo), 0 8px 16px -8px var(--lujo-resplandor), 0 2px 4px color-mix(in srgb, var(--texto) 12%, transparent);
}

.cal-flecha,
.cal-hoy {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 70%, transparent), 0 0 0 1px var(--lujo-hilo-suave), 0 8px 14px -8px var(--lujo-resplandor);
}

.tira-dia.hoy .tira-num,
.tira-dia.activo .tira-num,
.mes-dia.hoy .mes-num,
.mes-dia.activo .mes-num,
.cal-colhead.hoy b {
  background-image: linear-gradient(145deg, color-mix(in srgb, var(--acento-tinta) 84%, var(--lujo-2)), var(--acento-tinta) 62%);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 34%, transparent), 0 0 0 2px color-mix(in srgb, var(--lujo-2) 42%, transparent), 0 10px 18px -6px var(--lujo-resplandor);
}

.cal-cita {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 55%, transparent), 0 0 0 1px var(--lujo-hilo-suave), 0 3px 6px -2px color-mix(in srgb, var(--texto) 14%, transparent), 0 12px 22px -12px var(--lujo-resplandor);
}

.cal-cita.activa {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 55%, transparent), 0 0 0 2px var(--lujo-2), 0 14px 26px -10px var(--lujo-resplandor);
}

.cal-fab {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 0 1px var(--lujo-hilo), 0 10px 20px -6px color-mix(in srgb, var(--primario) 60%, transparent), 0 18px 36px -12px var(--lujo-resplandor);
}

/* La ventana de una cita (popup.js): una pieza de cristal encima de todo, con el fondo oscurecido y desenfocado. Sin JavaScript queda como una ventana fija con su propia sombra grande. */
.cal-popup {
  width: min(30rem, calc(100vw - 2rem));
  max-width: none;
  max-height: calc(100dvh - 2rem);
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--texto);
  overflow: visible;
}

.cal-popup:not([open]) {
  display: none;
}

.cal-popup[open]:not(:modal) {
  position: fixed;
  inset: 0;
  z-index: 90;
  box-shadow: 0 0 0 100vmax color-mix(in srgb, #100904 50%, transparent);
}

.cal-popup::backdrop {
  background: color-mix(in srgb, #100904 48%, transparent);
  -webkit-backdrop-filter: blur(8px) saturate(1.2);
  backdrop-filter: blur(8px) saturate(1.2);
}

.cal-popup__caja {
  position: relative;
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: 1.75rem 1.75rem 1.5rem;
  border-radius: 1.75rem;
  background: linear-gradient(165deg, color-mix(in srgb, var(--lujo-1) 16%, var(--papel)), color-mix(in srgb, var(--papel) 96%, transparent) 38%);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #ffffff 75%, transparent),
    0 0 0 1px var(--lujo-hilo),
    0 4px 8px -2px color-mix(in srgb, #100904 30%, transparent),
    0 30px 64px -18px color-mix(in srgb, #100904 62%, transparent),
    0 40px 90px -40px var(--lujo-resplandor);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  backdrop-filter: blur(24px) saturate(1.5);
}

.cal-popup__cerrar {
  position: absolute;
  top: 0.875rem;
  right: 0.875rem;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  font-size: 1.5rem;
  line-height: 1;
  text-decoration: none;
  color: var(--texto);
  background: linear-gradient(180deg, color-mix(in srgb, var(--lujo-1) 20%, var(--papel)), color-mix(in srgb, var(--lujo-2) 8%, var(--papel)));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 70%, transparent), 0 0 0 1px var(--lujo-hilo-suave), 0 8px 14px -8px var(--lujo-resplandor);
}

.cal-popup__cerrar:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.cal-popup__estado {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--acento-tinta);
  background: var(--acento-suave);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 60%, transparent), 0 0 0 1px var(--lujo-hilo-suave);
}

.cal-popup__punto {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--lujo-metal);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--lujo-2) 30%, transparent);
}

/* Lo que se hace con la cita va ARRIBA de sus datos (en el marcado también: el foco y la lectura siguen ese orden): dos columnas de botones, que a 390 px caben sin desplazar la ventana. */
.cal-popup .acciones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.cal-popup .acciones form {
  display: grid;
  margin: 0;
}

.cal-popup .acciones .boton,
.cal-popup .acciones button {
  width: 100%;
  padding-inline: 0.75rem;
}

/* Los datos, compactos: el nombre y su valor en la misma fila también en el celular (nueve filas de dos líneas hacían una ventana de tres pantallas). */
.cal-popup .datos {
  margin: 0 0 0.5rem;
}

.cal-popup .datos div {
  grid-template-columns: minmax(4.5rem, 6.5rem) minmax(0, 1fr);
  align-items: baseline;
  padding: 0.4375rem 0;
}

@media (max-width: 40rem) {
  .cal-popup__caja {
    padding: 1.25rem 1.125rem 1rem;
  }

  .cal-popup h3 {
    margin-bottom: 0.75rem;
  }
}

.cal-popup h3 {
  margin: 0 3.5rem 1rem 0;
  font-family: var(--letra-titulo);
  font-size: var(--t-2xl);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

@keyframes cal-popup-entra {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.97);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.cal-popup[open] .cal-popup__caja {
  animation: cal-popup-entra 260ms var(--salida) both;
}

@media (prefers-reduced-motion: reduce) {
  .cal-popup[open] .cal-popup__caja {
    animation: none;
  }
}

@media print {
  .cal-popup {
    display: none;
  }
}

/* 25. Tarifario (F1.4, corte a): el cambio de precio en la misma fila de la lista. */
.accion-celda .en-linea {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
}

/* Las tablas de cada categoría comparten columnas, para que la lista se lea como una sola. */
.tabla-tarifa table {
  table-layout: fixed;
  width: 100%;
}

.tabla-tarifa .c-tratamiento {
  width: 28%;
}

.tabla-tarifa .c-aplica {
  width: 19%;
}

.tabla-tarifa .c-precio {
  width: 15%;
}

.tabla-tarifa .c-estado {
  width: 12%;
}

.tabla-tarifa .c-accion {
  width: 26%;
}

.tabla + .formulario-alta {
  margin-top: 1.75rem;
}

/* 27. Cuenta y caja (F1.4, corte b): el saldo grande y la anulación de un pago dentro de su fila. */
.saldo-cuenta {
  margin: 0 0 1.5rem;
  font-size: 1.125rem;
}

.saldo-cuenta strong {
  font-size: 1.75rem;
  letter-spacing: -0.01em;
}

.apilada .lista-cabeza + .formulario-alta {
  margin-top: 1rem;
}

.anular-pago {
  margin-top: 0.5rem;
}

.anular-pago summary {
  cursor: pointer;
  font-size: 0.875rem;
  text-decoration: underline;
}

.anular-pago[open] {
  padding: 0.75rem 0 0;
}

/* 26. Presupuesto (F1.4, corte a): las acciones de un borrador, con aire entre ellas. */
.quitar-lineas {
  margin: 0 0 1.5rem;
}

.quitar-lineas .en-linea {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 0.5rem;
}

.apilada .formulario-alta + .formulario-alta,
.apilada .lista-explica + .formulario-alta {
  margin-top: 1.5rem;
}

.accion-celda .en-linea:last-child {
  margin-bottom: 0;
}

.accion-celda .en-linea input[name="precio"] {
  width: 7rem;
  min-height: 2.5rem;
  margin: 0;
}

/* 28. El resumen del perfil del paciente y la ortodoncia (spec de equipo, ortodoncia, escáner y chat). */
.tablero-perfil .cifras {
  margin-bottom: 1rem;
}

.alertas-perfil {
  display: grid;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.alerta-perfil {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--linea, rgba(0, 0, 0, 0.12));
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
}

.alerta-perfil > span {
  flex: 1 1 14rem;
}

.alerta-perfil svg {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.linea-titulo {
  margin: 0.5rem 0;
  font-size: 1rem;
}

.linea-tiempo {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.linea-tiempo li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
}

.linea-tiempo svg {
  flex: none;
  width: 1rem;
  height: 1rem;
  align-self: center;
}

.linea-fecha {
  min-width: 8.5rem;
  color: var(--silenciado);
  font-size: 0.875rem;
}

.adendas {
  margin: 0.5rem 0 0;
  padding: 0 0 0 1rem;
  font-size: 0.875rem;
}

/* 29. El chat del equipo y la biblioteca «Aprender» (spec de equipo, ortodoncia, escáner y chat). */
.canales-chat {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.chat-mensajes {
  display: grid;
  gap: 0.625rem;
  max-height: min(30rem, 58vh);
  margin: 0 0 0.5rem;
  padding: 0.25rem 0.25rem 0.25rem 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
}

.chat-mensaje {
  display: grid;
  gap: 0.25rem;
  justify-self: start;
  max-width: min(40rem, 92%);
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem 0.875rem 0.875rem 0.25rem;
  background: var(--vidrio-macizo);
}

.chat-propio {
  justify-self: end;
  border-color: var(--acento-linea);
  border-radius: 0.875rem 0.875rem 0.25rem 0.875rem;
  background: var(--acento-suave);
}

.chat-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
  font-size: 0.875rem;
}

.chat-cuerpo {
  overflow-wrap: anywhere;
  white-space: pre-line;
}

.chat-mensaje .en-linea {
  justify-self: end;
}

.chat-vacio {
  padding: 1.25rem 1rem;
  color: var(--silenciado);
  text-align: center;
  list-style: none;
}

.chat-fin {
  margin: 0 0 1rem;
  font-size: 0.875rem;
  text-align: right;
}

.chat-envio textarea {
  width: 100%;
  min-height: 3.5rem;
  resize: vertical;
}

.video-equipo {
  display: block;
  width: 100%;
  max-height: 70vh;
  margin: 0 0 1.25rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--c-texto) 92%, var(--c-fondo));
}

.pasos-guia {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
  counter-reset: paso;
}

.pasos-guia li {
  position: relative;
  padding: 0.75rem 1rem 0.75rem 3.25rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: var(--vidrio-macizo);
  counter-increment: paso;
}

.pasos-guia li::before {
  content: counter(paso);
  position: absolute;
  top: 0.75rem;
  left: 0.875rem;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--acento-linea);
  border-radius: 50%;
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-size: 0.875rem;
  font-weight: 600;
}

/* 30. El visor de los escaneos 3D del escáner intraoral. */
.visor3d {
  margin: 0 0 0.75rem;
}

.visor3d-lienzo {
  display: block;
  width: 100%;
  height: min(32rem, 62vh);
  min-height: 18rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--c-texto) 7%, var(--c-fondo));
  cursor: grab;
  touch-action: none;
}

.visor3d-lienzo:active {
  cursor: grabbing;
}

.visor3d-lienzo:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.visor3d-estado {
  margin: 0.5rem 0 0;
  color: var(--silenciado);
  font-size: 0.875rem;
}

.visor3d-estado[hidden] {
  display: none;
}

.visor3d-botones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.visor3d-ayuda {
  margin: 0 0 1rem;
  font-size: 0.875rem;
}

.huella {
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

/* Una tabla o un aviso de «no hay nada» que sigue a la entradilla de una hoja, con aire arriba. */
.entradilla + .tabla,
.entradilla + .lista-vacia {
  margin-top: 1.25rem;
}

/* 31. Datos legales y plantillas de los documentos: la lista de marcadores permitidos de un tipo. */
.lista-marcadores {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lista-marcadores li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
}

/* 32. Documentos legales: el sello de borrador, las dos firmas del consentimiento, los datos legales bajo la firma y la nota de la hoja con la cédula completa. */
.doc-borrador {
  display: inline-block;
  margin: 0 0 1rem;
  padding: 0.25rem 0.75rem;
  border: 2px dashed var(--aviso-linea);
  border-radius: 0.375rem;
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.doc-firmas {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 3rem;
}

.doc-legales {
  margin: 1.25rem 0 0;
  font-size: 0.8125rem;
  color: var(--silenciado);
}

.doc-legales p {
  margin: 0 0 0.125rem;
}

.aviso-nota {
  margin: 0 0 1rem;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--aviso-linea);
  border-radius: 0.5rem;
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  font-size: 0.9375rem;
}

@media print {
  .doc-borrador {
    border-color: #000000;
    background: #ffffff;
    color: #000000;
  }

  .doc-legales {
    color: #000000;
  }
}

/* 33. El catálogo de tratamientos del portal: las categorías como enlaces y las tarjetas con su precio vigente. */
.catalogo-categorias ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
}

.catalogo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.875rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.catalogo-tarjeta {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel);
}

.catalogo-tarjeta p {
  margin: 0;
}

.catalogo-nombre {
  font-weight: 700;
}

.catalogo-texto {
  font-size: 0.9375rem;
  color: var(--silenciado);
}

.catalogo-tarjeta .catalogo-precio {
  margin-top: auto;
  padding-top: 0.5rem;
}

.catalogo-precio strong {
  font-size: 1.125rem;
  font-variant-numeric: tabular-nums;
}

/* 34. Lo que falta por cargar en el inicio de administración (documentos legales). */
.lista-simple-inicio {
  display: grid;
  gap: 0.375rem;
  margin: 0;
  padding: 0 0 0 1.125rem;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 35. El odontograma 3D del paciente (corte 5b, P5.3). El bloque nace oculto (atributo hidden) y lo muestra odonto3d.js solo si el equipo
 *     puede dibujarlo; el dibujo 2D de la sección 20 sigue debajo y es la vía accesible. El lienzo no se anuncia (aria-hidden): lo
 *     operable son los botones. El fundido existe solo si la persona no pidió menos movimiento. Nada de esto lleva estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.odo-3d {
  margin: 0 0 1.25rem;
  padding: 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--papel) 70%, transparent);
}

.odo-3d h3 {
  margin: 0 0 0.25rem;
}

.odo-3d-nota {
  max-width: 46rem;
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
}

.odo-3d-ver {
  margin: 0 0 1rem;
}

.odo-3d-barra {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0.5rem 0 0.75rem;
}

.odo-3d-grupo {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.odo-3d-grupo button {
  min-height: 2.75rem;
  padding: 0.375rem 0.875rem;
  font-size: var(--t-s);
}

/* Pulsado: fondo de selección, anillo y letra más gruesa (se nota también sin color). */
.odo-3d-grupo button[aria-pressed="true"] {
  --boton-vidrio: var(--seleccion);
  background: var(--seleccion);
  border-color: var(--anillo);
  box-shadow: 0 0 0 2px var(--anillo);
  font-weight: 700;
}

.odo-3d-lienzo {
  display: block;
  width: 100%;
  height: clamp(18rem, 56vh, 30rem);
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel-2);
  cursor: grab;
  touch-action: none;
}

.odo-3d-lienzo:active {
  cursor: grabbing;
}

.odo-3d-pie {
  min-height: 1.5rem;
  margin: 0.5rem 0 0.25rem;
  font-weight: 600;
}

/* El deslizador de fechas: etiqueta, control y valor a la vista; el control crece con el espacio y deja un blanco cómodo para el dedo. */
.odo-3d-fechas {
  display: grid;
  grid-template-columns: auto minmax(8rem, 1fr);
  gap: 0.25rem 0.75rem;
  align-items: center;
  margin: 0 0 0.75rem;
}

.odo-3d-fechas label {
  font-weight: 600;
}

.odo-3d-fechas input[type="range"] {
  width: 100%;
  min-height: 2.75rem;
  margin: 0;
  accent-color: var(--anillo);
}

.odo-3d-fechas output {
  grid-column: 1 / -1;
  font-weight: 700;
}

.odo-3d-fechas .odo-3d-nota {
  grid-column: 1 / -1;
  margin: 0;
}

/* «Ver su historial» (con un toque): un blanco cómodo para el dedo. */
.odo-3d-enlace {
  display: inline-block;
  padding: 0.5rem 0.25rem;
  font-weight: 700;
}

@keyframes odo-3d-entra {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .odo-3d {
    animation: odo-3d-entra 600ms var(--salida) both;
  }
}

@media print {
  .odo-3d,
  .odo-3d-ver {
    display: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 36. Fotos y radiografías del paciente (F1.2, A3b): la rejilla de miniaturas (lo pendiente de confirmar y lo guardado, por atención).
 *     Las miniaturas son `<img>` del propio servidor; la caja tiene tamaño fijo para que la página no salte mientras cargan. Dos columnas
 *     en el teléfono (390 px) y más en la pantalla ancha. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.imagenes-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.75rem;
  margin: 0.75rem 0 1.25rem;
  padding: 0;
  list-style: none;
}

.imagenes-rejilla li {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

.imagenes-rejilla img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--linea);
  border-radius: 0.5rem;
  background: var(--papel-2);
}

.imagenes-pie {
  font-size: var(--t-s);
  color: var(--silenciado);
  overflow-wrap: anywhere;
}

.imagenes-atencion + .imagenes-atencion {
  margin-top: 1.25rem;
}

.imagenes-atencion h3 {
  margin: 0.75rem 0 0;
}

/* Confirmar y descartar son dos formularios hermanos: el segundo se despega del primero. */
.apilada .imagenes-confirmacion + .imagenes-descarte {
  margin-top: 0.5rem;
}

@media print {
  .imagenes-rejilla img {
    border-color: #000;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 37. Una imagen del paciente y el visor de radiografías (F1.2, A5). La miniatura de la rejilla es un enlace (la imagen y su pie, un solo
 *     destino). La foto se ve entera. La radiografía va en un marco de desplazamiento nativo (overflow: auto) y sus controles (acercar,
 *     contraste, invertir) son CLASES del contenedor `.rx`, sin estilos en línea: la ampliación es el ancho de la imagen (`rx-z1` a
 *     `rx-z4`: 100, 150, 200 y 300 % del marco), el contraste y el invertido son dos variables que componen el mismo `filter`
 *     (`rx-c1` a `rx-c5`, `rx-inv`). Los controles nacen ocultos (atributo hidden) y los muestra `rx.js`: sin JavaScript se ve la imagen
 *     entera. No hay animación: nada que reducir con prefers-reduced-motion.
 * ------------------------------------------------------------------------------------------------------------------ */

.imagenes-enlace {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: inherit;
  text-decoration: none;
}

.imagenes-enlace:focus-visible .imagenes-pie {
  text-decoration: underline;
}

@media (hover: hover) and (pointer: fine) {
  .imagenes-enlace:hover .imagenes-pie {
    text-decoration: underline;
  }
}

.imagen-marco {
  margin: 1rem 0;
}

.imagen-grande {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel-2);
}

.imagen-acciones {
  margin: 1rem 0 0;
}

.rx {
  --rx-contraste: 1;
  --rx-inversion: 0;
  margin: 1rem 0;
}

.rx-controles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
}

.rx-controles[hidden] {
  display: none;
}

.rx-controles .boton-chico {
  margin: 0;
}

/* Pulsado: fondo de selección, anillo y letra más gruesa (se nota también sin color). */
.rx-controles button[aria-pressed="true"] {
  background: var(--seleccion);
  border-color: var(--anillo);
  box-shadow: 0 0 0 2px var(--anillo);
  font-weight: 700;
}

.rx-estado {
  flex: 1 1 100%;
  margin: 0;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.rx-marco {
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel-2);
}

.rx-marco:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.rx-imagen {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
  filter: contrast(var(--rx-contraste)) invert(var(--rx-inversion));
}

.rx-z2 .rx-imagen {
  width: 150%;
}

.rx-z3 .rx-imagen {
  width: 200%;
}

.rx-z4 .rx-imagen {
  width: 300%;
}

/* Ampliada, el marco se acota para que la imagen se desplace dentro de él y la página no se alargue. */
.rx-z2 .rx-marco,
.rx-z3 .rx-marco,
.rx-z4 .rx-marco {
  max-height: min(75vh, 48rem);
}

.rx-c1 {
  --rx-contraste: 0.6;
}

.rx-c2 {
  --rx-contraste: 0.8;
}

.rx-c3 {
  --rx-contraste: 1;
}

.rx-c4 {
  --rx-contraste: 1.35;
}

.rx-c5 {
  --rx-contraste: 1.8;
}

.rx-inv {
  --rx-inversion: 1;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 38. La foto de perfil del paciente (F1.2, A8): en la cabecera del perfil, en lugar de las iniciales; pequeña, al lado del nombre, en
 *     las confirmaciones; y grande en su propia pantalla. Son `<img>` del propio servidor, con `alt` vacío (la persona ya está nombrada
 *     al lado). Sin estilos en línea y sin animación.
 * ------------------------------------------------------------------------------------------------------------------ */

.perfil-foto {
  display: block;
  object-fit: cover;
  background: var(--papel-2);
}

.foto-perfil-mini {
  display: inline-block;
  width: 2.5rem;
  height: 2.5rem;
  margin-inline-end: 0.5rem;
  border: 1px solid var(--linea);
  border-radius: 50%;
  vertical-align: middle;
  object-fit: cover;
  background: var(--papel-2);
}

.foto-perfil-grande {
  display: block;
  width: 100%;
  max-width: 20rem;
  height: auto;
  margin: 0.75rem 0 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel-2);
}

/* El campo de archivo dentro de la lista de datos del perfil: sin la caja del formulario de alta, el botón debajo del campo. */
.foto-perfil-formulario {
  margin: 0;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 39. Corregir una imagen ya guardada (F1.2, A7): «Descartar» y «Mover» bajo cada imagen de la lista (solo con `mover_archivos`), la
 *     miniatura de la imagen que se corrige y las publicaciones retiradas. Enlaces de al menos 44 px de alto para el dedo.
 * ------------------------------------------------------------------------------------------------------------------ */

.imagenes-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.75rem;
  font-size: var(--t-s);
}

.imagenes-acciones a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

.imagen-vista {
  margin: 0.75rem 0;
}

.imagen-vista img {
  display: block;
  width: 10rem;
  max-width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--linea);
  border-radius: 0.5rem;
  background: var(--papel-2);
}

.imagenes-retiradas {
  margin: 0.5rem 0 1rem;
  padding-inline-start: 1.25rem;
}

@media print {
  .imagen-vista img {
    border-color: #000;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 40. La lista de tratamiento del personal (lista de tratamiento L6; spec del 31-oct §12.1, la Variante B): la tira de piezas como selector y el
 *     panel de la pieza elegida con sus filas y el formulario de añadir. El estado se dice con TEXTO y con FORMA (rayado, rayado con borde de rayas,
 *     relleno: la lengua del odontograma, sin color nuevo; el rojo de lo que hay que tratar y el azul de lo hecho salen de `.odo`), así que se lee
 *     igual en blanco y negro. Teléfono primero: cuatro piezas por fila a 390 px y las ocho de un cuadrante en pantallas anchas; todo objetivo de
 *     toque de 44 px como mínimo. Nada de esto lleva estilos en línea.
 *     R3 (rediseño según la Variante B del mockup): los chips de recuento por estado, la tarjeta «Elija una pieza» con su interruptor Permanentes / Temporales (enlaces `?dent=`), los cuadrantes por pares con su rótulo
 *     y las piezas como «tiles» (borde de 2 px, número, ícono del estado y «×N»): ocho por fila a 390 px (la tira sangra hasta el borde de la pantalla, como en el mockup) y, desde 46rem de ancho de la tarjeta, los dos cuadrantes de un arco lado a lado.
 *     R12: el campo «Diagnóstico (K)» del formulario de añadir (`.lt-dx`, con las opciones `.cb-op` del catálogo) y la pastilla del diagnóstico ligado (`.lt-dx-liga`).
 * ------------------------------------------------------------------------------------------------------------------ */

.lt [hidden] {
  display: none;
}

/* La lista sola (`/lista`) es una hoja con 1,25 rem de relleno; la tarjeta de la tira sangra esa medida en el celular. */
.hoja.lt {
  --lt-sangrado: 1.25rem;
}

.lt-faltan {
  margin: 0 0 1rem;
  padding: 0.625rem 0.875rem;
  border: 1px dashed var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  font-weight: 600;
}

.lt-forma {
  display: inline-block;
  flex: none;
  box-sizing: border-box;
  width: 0.9375rem;
  height: 0.9375rem;
  border: 2px solid var(--odo-tratar);
  border-radius: 3px;
  vertical-align: -0.125rem;
}

.lt-forma-tratar {
  background: repeating-linear-gradient(45deg, var(--odo-tratar) 0 2px, var(--odo-vacio) 2px 5px);
}

.lt-forma-curso {
  border-style: dashed;
  background: repeating-linear-gradient(45deg, var(--odo-tratar) 0 2px, var(--odo-vacio) 2px 5px);
}

.lt-forma-hecho {
  border-color: var(--odo-hecho);
  background: var(--odo-hecho);
}

/* Los chips de recuento por estado: la forma del estado en el borde (sólido y rayado, de rayas, relleno) y su ícono; el de precios ajustados, con el aviso de la clínica. */
.lt-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.lt-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.75rem;
  border: 2px solid color-mix(in srgb, var(--texto) 42%, var(--papel));
  border-radius: 999px;
  background: var(--papel);
  font-size: var(--t-s);
  font-weight: 600;
}

.lt-chip .icono {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.lt-chip-tratar {
  border-color: var(--odo-tratar);
  background: color-mix(in srgb, var(--odo-tratar) 8%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
}

.lt-chip-curso {
  border-style: dashed;
  border-color: var(--texto);
  background: var(--acento-suave);
}

.lt-chip-hecho {
  border-color: var(--odo-hecho);
  background: color-mix(in srgb, var(--odo-hecho) 9%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-hecho) 90%, #000000);
}

.lt-chip-ajuste {
  border-color: var(--aviso-linea);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

/* Los íconos de estado y de ajuste se leen a 16 px: trazo más grueso y dibujo pleno. Iconos solo lleva geometría; el trazo, el relleno y la raya van aquí, por la clase que pone el llamador. */
.icono-estado-tratar,
.icono-estado-curso,
.icono-estado-hecho,
.icono-ajuste {
  stroke-width: 2.25;
}

.icono-estado-tratar path {
  stroke-width: 1.9;
}

.icono-estado-curso circle {
  stroke-dasharray: 3.9 2.7;
}

.icono-estado-curso path {
  fill: currentColor;
  stroke: none;
}

.icono-estado-hecho circle {
  fill: currentColor;
  stroke: none;
}

/* La palomita del «hecho» se recorta en el color del papel. */
.icono-estado-hecho path {
  stroke: var(--odo-vacio, var(--papel));
  stroke-width: 2.7;
}

/* La tarjeta «Elija una pieza». `container-type` deja decidir por SU ancho (no el de la pantalla) si los dos cuadrantes de un arco van lado a lado. */
.lt-tira {
  container-type: inline-size;
  margin: 0 0 1rem;
  padding: 0.75rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel);
}

.lt-tira-cab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.25rem;
}

.lt-tira h2 {
  flex: 1 1 auto;
  margin: 0;
  font-size: var(--t-l);
}

.lt-ayuda {
  margin: 0 0 0.625rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
}

/* Permanentes (n) / Temporales (n): dos enlaces que se ven como el interruptor del mockup; el de la dentición que se muestra, relleno. */
.lt-den {
  display: inline-flex;
  gap: 0.375rem;
}

.lt-den-op {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  box-sizing: border-box;
  min-height: 2.75rem;
  padding: 0 0.875rem;
  border: 2px solid color-mix(in srgb, var(--texto) 42%, var(--papel));
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-s);
  font-weight: 600;
  text-decoration: none;
}

.lt-den-op[aria-current="true"] {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.lt-den-op:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.lt-den-n {
  display: inline-grid;
  place-items: center;
  min-width: 1.375rem;
  height: 1.375rem;
  padding: 0 0.3125rem;
  border: 1px solid var(--acento-linea);
  border-radius: 0.6875rem;
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-size: 0.75rem;
}

.lt-general,
.lt-cuadrante {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* «Sin pieza»: Generales, Ortopedia y Ortodoncia (P3), en una fila que baja de renglón si no caben. */
.lt-general {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.lt-denticion {
  margin: 0 0 0.75rem;
}

/* Un arco son sus dos cuadrantes: uno sobre otro (cada uno con sus ocho piezas a todo el ancho) y, desde 46rem de tarjeta, lado a lado con la línea media punteada entre ellos. */
.lt-arco {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.375rem 0.875rem;
  margin-bottom: 0.875rem;
}

.lt-cuad-et {
  margin: 0 0 0.25rem;
  color: var(--silenciado);
  font-size: 0.75rem;
  font-weight: 600;
}

.lt-mitad {
  min-width: 0;
}

/* Ocho piezas por fila (cinco en las temporales); si la pantalla es tan angosta que no caben a 40 px, el cuadrante se desplaza de lado: nunca se parte un número. */
.lt-cuadrante {
  display: grid;
  grid-template-columns: repeat(8, minmax(2.5rem, 1fr));
  gap: 0.125rem;
  overflow-x: auto;
  padding: 0.5rem 0.3125rem 0.3125rem;
  margin: -0.5rem -0.3125rem -0.3125rem;
}

.lt-denticion[aria-label="Dentición temporal"] .lt-cuadrante {
  grid-template-columns: repeat(5, minmax(2.5rem, 1fr));
}

.lt-cuadrante li {
  display: flex;
  min-width: 0;
}

/* La pieza («tile»): borde de 2 px que dice el estado por su forma (sólido y rayado: por tratar; de rayas: en tratamiento; azul y liso: hecho), el número, el ícono del estado y «×N» si tiene varias filas. */
.lt-pieza {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.0625rem;
  box-sizing: border-box;
  min-width: 0;
  min-height: 3.5rem;
  padding: 0.25rem 0.0625rem 0.1875rem;
  border: 2px solid var(--linea);
  border-radius: 0.5625rem;
  background: var(--papel);
  color: var(--texto);
  text-align: center;
  text-decoration: none;
}

.lt-pieza-tratar {
  border-color: var(--odo-tratar);
  background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--odo-tratar) 24%, var(--odo-vacio)) 0 2px, var(--odo-vacio) 2px 7px);
}

.lt-pieza-curso {
  border-style: dashed;
  border-color: var(--texto);
  background: var(--acento-suave);
}

.lt-pieza-hecho {
  border-color: var(--odo-hecho);
  background: color-mix(in srgb, var(--odo-hecho) 9%, var(--odo-vacio));
}

/* La pieza elegida: el doble anillo de oro. */
.lt-pieza[aria-current="true"] {
  z-index: 1;
  box-shadow: 0 0 0 2px var(--papel), 0 0 0 5px var(--acento);
}

.lt-pieza:focus-visible {
  outline: 3px solid var(--anillo);
  outline-offset: 2px;
}

.lt-num {
  padding: 0 0.1875rem;
  border-radius: 0.25rem;
  background: var(--papel);
  font-family: var(--letra-titulo);
  font-size: 0.9375rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

/* El ícono del estado y, al lado, «×N» si la pieza tiene varias filas: en la misma línea, dentro de la pieza (el texto no se sale de su caja). */
.lt-est {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
}

.lt-ico {
  display: grid;
  place-items: center;
  height: 1rem;
}

.lt-pieza-tratar .lt-ico {
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
}

.lt-pieza-hecho .lt-ico {
  color: color-mix(in srgb, var(--odo-hecho) 90%, #000000);
}

.lt-ico .icono {
  width: 1rem;
  height: 1rem;
}

.lt-x {
  display: grid;
  place-items: center;
  height: 1rem;
  padding: 0 0.25rem;
  border-radius: 0.5rem;
  background: var(--primario);
  color: var(--sobre-primario);
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
}

/* «Sin pieza: Generales»: la fila de debajo, con el mismo lenguaje del estado. */
.lt-sinpieza {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-top: 0.625rem;
  border-top: 1px solid var(--linea);
}

.lt-sinpieza-et {
  margin-inline-end: 0.25rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 600;
}

.lt-pieza-general {
  flex-direction: row;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0 0.875rem;
  border-radius: 0.625rem;
}

.lt-pieza-general .lt-num {
  background: none;
  font-family: var(--letra);
  font-size: var(--t-s);
  font-weight: 600;
}

/* Lo que se despliega lo dice una flecha: «Cambiar», «Precio», «Retirar» y «Otro tratamiento» no parecían nada pulsable. */
.lt-mas > summary,
.lt-libre > summary {
  justify-content: space-between;
  gap: 0.75rem;
  list-style: none;
}

.lt-mas > summary::-webkit-details-marker,
.lt-libre > summary::-webkit-details-marker {
  display: none;
}

.lt-mas > summary::after,
.lt-libre > summary::after {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transition: transform var(--rapido) var(--salida);
}

.lt-mas > summary::after,
.lt-libre > summary::after {
  transform: rotate(45deg);
}

.lt-mas[open] > summary::after,
.lt-libre[open] > summary::after {
  transform: rotate(-135deg);
}

/* La leyenda «Así se ve cada estado en el 3D del paciente» (R7): tres dientes de ejemplo (los mismos del odontograma, sin enlaces) con su texto, y la nota de lo que se dibuja entero o no se dibuja. */
.odo-glifo {
  display: block;
  flex: none;
  overflow: visible;
}

.odo-glifo .cara polygon {
  cursor: default;
}

.lt-resumen {
  container-type: inline-size;
}

.lt-ley,
.lt-resumen {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: var(--papel);
}

.lt-ley-titulo {
  margin: 0 0 0.5rem;
  font-size: var(--t-s);
  font-weight: 600;
}

.lt-leyenda {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.5rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lt-leyenda li {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--t-s);
}

.lt-leyenda b {
  display: block;
}

.lt-leyenda li > div > span {
  color: var(--silenciado);
}

.lt-ley-nota {
  margin: 0.5rem 0 0;
  color: var(--silenciado);
  font-size: var(--t-xs);
}

/* «Toda la lista»: una fila por tratamiento (la pieza, el tratamiento con sus caras, el estado con su ícono y, con montos, lo que vale); cada fila es un enlace que elige su pieza; el total, al pie. */
.lt-resumen h2 {
  margin: 0 0 0.5rem;
  font-size: var(--t-l);
}

.lt-res {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lt-res li + li {
  border-top: 1px solid var(--linea);
}

.lt-res-f {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto 5.5rem;
  gap: 0.25rem 0.75rem;
  align-items: center;
  box-sizing: border-box;
  min-height: 3rem;
  padding: 0.375rem 0.25rem;
  border-radius: 0.5rem;
  color: var(--texto);
  text-decoration: none;
}

.lt-res-sin-monto .lt-res-f {
  grid-template-columns: 4.5rem minmax(0, 1fr) auto;
}

.lt-res-f:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 1px;
}

.lt-res-p {
  font-family: var(--letra-titulo);
  font-weight: 700;
}

/* «Ortopedia» y «Ortodoncia» (P3) no caben en la columna de la pieza con la letra de un número: más chica y sin salirse. */
.lt-res-p-bloque {
  font-size: 0.6875rem;
  letter-spacing: -0.03em;
}

.lt-res-t {
  min-width: 0;
  overflow-wrap: anywhere;
}

.lt-res-t small {
  margin-left: 0.375rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
}

.lt-res-s {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  justify-self: start;
  padding: 0.125rem 0.625rem;
  border: 2px solid color-mix(in srgb, var(--texto) 42%, var(--papel));
  border-radius: 999px;
  background: var(--papel);
  font-size: var(--t-xs);
  font-weight: 600;
}

.lt-res-s .icono {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.lt-res-s-tratar {
  border-color: var(--odo-tratar);
  background: color-mix(in srgb, var(--odo-tratar) 8%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
}

.lt-res-s-curso {
  border-style: dashed;
  border-color: var(--texto);
  background: var(--acento-suave);
}

.lt-res-s-hecho {
  border-color: var(--odo-hecho);
  background: color-mix(in srgb, var(--odo-hecho) 9%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-hecho) 90%, #000000);
}

.lt-res-v {
  font-weight: 700;
  text-align: right;
}

.lt-res-tot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0.5rem 0 0;
  padding: 0.625rem 0.25rem 0;
  border-top: 2px solid var(--texto);
  font-weight: 600;
}

.lt-res-tot b {
  font-family: var(--letra-titulo);
  font-size: var(--t-xl);
}

@media (hover: hover) and (pointer: fine) {
  .lt-res-f:hover {
    background: var(--acento-suave);
  }
}

/* En el celular: la pieza, el tratamiento y (con montos) lo que vale arriba; el estado debajo, bajo el tratamiento. Si la tarjeta es lo bastante ancha (320 px de contenido), el estado se pasa a la derecha y debajo va lo que vale: dos líneas por fila, no tres. */
@media (max-width: 39.99rem) {
  .lt-res-f,
  .lt-res-sin-monto .lt-res-f {
    grid-template-columns: 3.75rem minmax(0, 1fr) auto;
  }

  .lt-res-v {
    grid-column: 3;
    grid-row: 1;
  }

  .lt-res-s {
    grid-column: 2 / -1;
  }

  @container (min-width: 20rem) {
    .lt-res-p,
    .lt-res-t {
      grid-row: 1 / span 2;
    }

    .lt-res-s {
      grid-column: 3;
      grid-row: 1;
      justify-self: end;
    }

    .lt-res-v {
      grid-column: 3;
      grid-row: 2;
    }
  }
}

/* La rejilla (R4, como el mockup): la tira «Elija una pieza» a la izquierda y el panel de la pieza (22,5 rem) a la derecha, arriba y alineados al borde de arriba; si la rejilla es angosta (el celular, una tableta de pie, la columna de una pantalla
   chica), el panel va debajo de la tira. Decide el ANCHO DE LA REJILLA (consulta de contenedor), no el de la pantalla: la misma lista sirve sola (`/lista`) y dentro de la «Cita del día». */
.lt-rejilla {
  container-type: inline-size;
  margin: 0 0 1rem;
}

.lt-rejilla-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
}

.lt-rejilla-in > .lt-tira,
.lt-rejilla-in > .lt-ley,
.lt-rejilla-in > .lt-resumen {
  margin-bottom: 0;
}

/* Con la rejilla ancha: la tira, la leyenda y «Toda la lista» en la columna de la izquierda, una bajo otra, y el panel ocupa las tres filas de la derecha (la última fila, `1fr`, absorbe lo que le sobre al panel: nada se estira ni queda un hueco bajo la tira). */
@container (min-width: 52rem) {
  .lt-rejilla-in {
    grid-template-columns: minmax(0, 1fr) 22.5rem;
    grid-template-rows: auto auto 1fr;
  }

  .lt-rejilla-in > .lt-tira {
    grid-column: 1;
    grid-row: 1;
  }

  .lt-rejilla-in > .lt-ley {
    grid-column: 1;
    grid-row: 2;
  }

  .lt-rejilla-in > .lt-resumen {
    grid-column: 1;
    grid-row: 3;
  }

  .lt-rejilla-in > .lt-panel {
    grid-column: 2;
    grid-row: 1 / span 3;
  }
}

/* El panel: una tarjeta con tres zonas pegadas, sin relleno propio (cada zona trae el suyo): la cabecera de acento, las filas y el formulario de añadir. */
.lt-panel {
  margin: 0;
  padding: 0;
  overflow: clip;
  scroll-margin-top: 5rem;
}

.lt-pn-vacio {
  padding: 1rem;
}

.lt-pn-vacio h2 {
  margin: 0 0 0.5rem;
  font-size: var(--t-l);
}

.lt-pn-nota,
.lt-pn-sin {
  margin: 0;
  padding: 1rem;
}

.lt-pn-sin {
  border-top: 0;
}

/* La cabecera: el diente de la pieza (68 px, el mismo dibujo del odontograma con lo que proyectan sus filas), «Pieza 36», su nombre y cuántos tratamientos tiene y cuál es el más urgente. */
.lt-pn-cab {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.875rem 1rem;
  border-bottom: 1px solid var(--acento-linea);
  background: var(--acento-suave);
}

.lt-pn-cab .odo-glifo {
  flex: none;
}

.lt-pn-txt {
  min-width: 0;
}

.lt-pn-cab h2 {
  margin: 0;
  font-size: 1.375rem;
  line-height: 1.2;
}

.lt-pn-nom {
  margin: 0.125rem 0 0;
  color: var(--silenciado);
}

.lt-pn-est {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.5rem;
  margin: 0.375rem 0 0;
  font-size: var(--t-s);
}

/* Las filas: una por tratamiento, separadas por un filo. Dentro, cada parte (la cabecera, el estado, el precio, «Cambiar») va una bajo otra; la «×» de retirar es el único elemento que sale del flujo. */
.lt-filas {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lt-fila {
  position: relative;
  padding: 0.875rem 1rem;
  border-top: 1px solid var(--linea);
}

.lt-fila:first-child {
  border-top: 0;
}

.lt-fila > * + * {
  margin-top: 0.625rem;
}

.lt-fila-cab {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  min-width: 0;
}

/* Deja sitio a la «×» de la esquina. */
.lt-fila:has(> .lt-quitar) .lt-fila-cab {
  padding-right: 2.75rem;
}

.lt-fila-glifo {
  flex: none;
}

.lt-fila-texto {
  min-width: 0;
}

.lt-fila-nombre,
.lt-fila-nota,
.lt-fila-meta,
.lt-fila-estado {
  margin: 0;
}

.lt-fila-nombre {
  overflow-wrap: anywhere;
}

.lt-fila-nombre strong {
  font-weight: 600;
}

.lt-caras-f {
  display: inline-flex;
  gap: 0.25rem;
  margin-left: 0.25rem;
  vertical-align: 0.0625rem;
}

.lt-cara-t {
  display: inline-grid;
  place-items: center;
  box-sizing: border-box;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.25rem;
  border: 1px solid var(--borde);
  border-radius: 0.375rem;
  background: var(--papel);
  font-size: 0.75rem;
  font-weight: 700;
}

.lt-fila-nota,
.lt-fila-meta {
  margin-top: 0.125rem;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.lt-fila-meta strong {
  color: var(--texto);
}

.lt-fila-estado {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
}

/* «Precio ajustado», «Sugerido $ 650,00 → editado $ 950,00» y «Volver a $ 650,00»: en una línea que se parte si no cabe. */
.lt-fila-aj {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.125rem 0.5rem;
}

.lt-ajuste .icono {
  width: 0.875rem;
  height: 0.875rem;
}

.lt-sug {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.lt-volver {
  display: contents;
}

/* Los botones de la fila son botones de verdad (un formulario cada uno), pero planos: sin el cristal ni el crecimiento al pasar el puntero del botón de la casa. */
.lt-seg-b,
.lt-enlace {
  contain: none;
  box-shadow: none;
  letter-spacing: 0;
}

.lt-seg-b::before,
.lt-seg-b::after,
.lt-enlace::before,
.lt-enlace::after {
  content: none;
}

@media (hover: hover) and (pointer: fine) {
  .lt-seg-b:hover,
  .lt-enlace:hover {
    box-shadow: none;
    transform: none;
  }

  .lt-seg-b:hover:not([disabled]) {
    background: var(--papel-2);
  }
}

/* El estado: tres botones de la misma medida que el mockup (1 : 1,3 : 0,8), con ícono y texto; el de ahora, pulsado y apagado, con la FORMA de su estado (borde sólido y rayas rojas; borde de rayas; borde azul), no solo el color. */
.lt-estados {
  max-width: none;
  margin-bottom: 0;
}

.lt-estados .campo {
  margin-bottom: 0.625rem;
}

.lt-estados .nota {
  margin: 0.5rem 0 0;
}

.lt-seg-est {
  display: grid;
  grid-template-columns: 1fr 1.3fr 0.8fr;
  gap: 0.375rem;
  max-width: 28rem;
}

.lt-seg-b {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.125rem;
  box-sizing: border-box;
  min-width: 0;
  min-height: 3.25rem;
  margin: 0;
  padding: 0.25rem 0.375rem;
  border: 2px solid color-mix(in srgb, var(--texto) 42%, var(--papel));
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.15;
}

.lt-seg-b .icono {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.lt-seg-b-tratar .icono {
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
}

.lt-seg-b-hecho .icono {
  color: color-mix(in srgb, var(--odo-hecho) 90%, #000000);
}

.lt-seg-b[aria-pressed="true"] {
  opacity: 1;
  cursor: default;
  font-weight: 700;
}

.lt-seg-b-tratar[aria-pressed="true"] {
  border-color: var(--odo-tratar);
  background: color-mix(in srgb, var(--odo-tratar) 8%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
}

.lt-seg-b-curso[aria-pressed="true"] {
  border-style: dashed;
  border-color: var(--texto);
  background: var(--acento-suave);
}

.lt-seg-b-hecho[aria-pressed="true"] {
  border-color: var(--odo-hecho);
  background: color-mix(in srgb, var(--odo-hecho) 9%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-hecho) 90%, #000000);
}

.lt-seg-b:focus-visible {
  outline: 3px solid var(--anillo);
  outline-offset: 2px;
}

/* El precio en línea: «$», el campo, «Guardar» y, debajo, la línea fina de dónde sale el sugerido. */
.lt-pf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.625rem;
  max-width: none;
}

.lt-pf .lt-pre {
  flex: 0 1 8.5rem;
  max-width: 8.5rem;
}

.lt-pf .lt-pre input {
  min-width: 0;
  width: 100%;
}

.lt-guardar {
  flex: none;
  min-height: 2.75rem;
  margin: 0;
  padding: 0.375rem 1rem;
  font-size: var(--t-s);
}

.lt-pf .lt-ayuda-fina {
  flex: 1 1 100%;
  margin: 0;
}

.lt-pf-txt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.125rem 0.5rem;
  margin: 0;
}

.lt-pf-txt strong {
  font-variant-numeric: tabular-nums;
}

.lt-porfijar {
  padding: 0.125rem 0.5rem;
  border: 1px dashed var(--borde);
  border-radius: 0.375rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 700;
}

/* «Volver a $ 650,00»: un enlace de acento (que es un botón de un formulario), de 44 px de alto sin ensanchar la línea. */
.lt-enlace {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  margin: -0.625rem 0;
  padding: 0 0.375rem;
  border: 0;
  background: transparent;
  color: var(--acento-tinta);
  font-size: var(--t-s);
  font-weight: 600;
  text-decoration: underline;
}

.lt-enlace:focus-visible {
  outline: 3px solid var(--anillo);
  outline-offset: 0;
}

/* La «×» de la esquina: el `<summary>` de un `<details>`; al abrirlo, el formulario del motivo sale bajo la cabecera de la fila. */
.lt-quitar > summary {
  position: absolute;
  top: 0.625rem;
  right: 0.75rem;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--linea);
  border-radius: 0.75rem;
  background: var(--papel);
  color: var(--silenciado);
  font-size: 1.375rem;
  line-height: 1;
  list-style: none;
  cursor: pointer;
}

.lt-quitar > summary::-webkit-details-marker {
  display: none;
}

.lt-quitar[open] > summary {
  border-color: var(--texto);
  color: var(--texto);
}

.lt-quitar > summary:focus-visible {
  outline: 3px solid var(--anillo);
  outline-offset: 2px;
}

.lt-fila > .lt-quitar:not([open]) {
  margin-top: 0;
}

@media (hover: hover) and (pointer: fine) {
  .lt-quitar > summary:hover {
    border-color: var(--odo-tratar);
    color: var(--odo-tratar);
  }
}

.lt-mas {
  border-top: 1px solid var(--linea);
}

.lt-mas > summary,
.lt-libre > summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  cursor: pointer;
  font-weight: 600;
}

.lt-mas[open] > summary {
  margin-bottom: 0.5rem;
}

/* «Añadir a la lista» (R5, como el mockup), sobre un fondo de acento suave: «Tratamiento» (la búsqueda y las opciones del catálogo como una lista de combo, con «Otro (texto libre)» al final), las caras en chips, el estado
   segmentado, el valor con su «$», «Más opciones» plegado y el botón. Las casillas y los radios siguen siendo los de siempre (a la vista como chips, botones y filas), así que funciona igual sin JavaScript. */
.lt-agregar {
  margin: 1rem 0 0;
  padding: 1rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-hoja);
  background: var(--acento-suave);
  scroll-margin-top: 5rem;
}

/* Dentro del panel (R4) es su pie: pegado a las filas, a todo el ancho y con solo el filo de arriba; con 22,5 rem de ancho el catálogo enseña cuatro opciones a la vez (las demás, por la lista que se desplaza). */
.lt-panel .lt-agregar {
  margin: 0;
  border-width: 1px 0 0;
  border-radius: 0;
}

.lt-panel .lt-catalogo-lista {
  max-height: min(14rem, 50vh);
}

.lt-agregar h3 {
  margin: 0 0 0.75rem;
  font-size: var(--t-l);
}

.lt-agregar fieldset {
  margin: 0;
  color: var(--texto);
}

.lt-agregar legend,
.lt-agregar .campo > label {
  padding: 0;
  font-size: var(--t-xs);
  font-weight: 600;
}

.lt-agregar legend {
  margin: 0 0 0.375rem;
}

.lt-buscar {
  margin: 0 0 0.75rem;
}

.lt-buscar .campo {
  margin: 0;
}

.lt-buscar-fila {
  display: flex;
  gap: 0.5rem;
}

.lt-buscar-fila input {
  flex: 1 1 auto;
  min-width: 0;
}

.lt-buscar-fila button {
  flex: none;
  min-height: 2.75rem;
}

.lt-buscar-quitar {
  margin: 0.25rem 0 0;
  font-size: var(--t-s);
}

/* Las opciones del catálogo y «Otro»: una sola caja de combo; cada opción, un radio que se ve como una fila (el nombre, lo que dibuja y, a la derecha, el sugerido si se puede ver). */
.lt-combo {
  margin: 0 0 1rem;
  border: 1px solid var(--borde);
  border-radius: 0.625rem;
  background: var(--papel);
}

.lt-catalogo-lista {
  max-height: min(22rem, 60vh);
  padding: 0.25rem;
  overflow: auto;
  /* Si hay más de los que caben, lo dicen las sombras de arriba y de abajo (puro CSS) y cada ítem se detiene al principio de su caja, no a medias. */
  scroll-snap-type: y proximity;
  background:
    linear-gradient(var(--papel) 30%, transparent) top / 100% 1.5rem no-repeat local,
    linear-gradient(transparent, var(--papel) 70%) bottom / 100% 1.5rem no-repeat local,
    linear-gradient(color-mix(in srgb, var(--texto) 16%, transparent), transparent) top / 100% 0.5rem no-repeat scroll,
    linear-gradient(transparent, color-mix(in srgb, var(--texto) 16%, transparent)) bottom / 100% 0.5rem no-repeat scroll;
}

.lt-catalogo-lista ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lt-catalogo-lista li {
  scroll-snap-align: start;
}

.lt-catalogo-lista li[hidden] {
  display: none;
}

.lt-catalogo .lista-vacia {
  margin: 0;
  padding: 0.75rem;
}

.cb-op label {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 2.75rem;
  margin: 0;
  padding: 0.375rem 0.625rem;
  border-radius: 0.5rem;
  cursor: pointer;
  font-size: var(--t-m);
  font-weight: 400;
}

.cb-op input {
  flex: none;
  margin: 0;
}

/* La opción elegida: el fondo de selección y un aro de acento (más el radio marcado), no una raya al costado. */
.cb-op:has(input:checked) label {
  background: var(--seleccion);
  box-shadow: inset 0 0 0 2px var(--acento);
}

.cb-op:has(input:focus-visible) label {
  outline: 3px solid var(--anillo);
  outline-offset: -2px;
}

.cb-t {
  min-width: 0;
  overflow-wrap: anywhere;
}

.cb-t strong {
  display: block;
  font-size: 0.9375rem;
  font-weight: 600;
}

.cb-t small {
  display: block;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 400;
}

.cb-pr {
  flex: none;
  margin-left: auto;
  padding-left: 0.75rem;
  font-size: 0.9375rem;
  font-weight: 700;
  white-space: nowrap;
}

.lt-libre {
  margin: 0;
  border-top: 1px solid var(--linea);
  border-radius: 0 0 0.625rem 0.625rem;
}

.lt-libre > summary {
  padding: 0.375rem 0.875rem 0.375rem 0.875rem;
}

.lt-libre[open] > summary {
  margin-bottom: 0.5rem;
}

.lt-libre > .campo {
  padding: 0 0.875rem;
}

/* Las caras: chips de 44 px (la letra a la vista; el nombre largo, en el aria-label); la elegida, con palomita y relleno. */
.lt-agregar .lt-caras {
  margin: 0 0 1rem;
}

.lt-caras-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.lt-cara {
  position: relative;
}

.lt-cara input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.lt-cara label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  box-sizing: border-box;
  min-width: 2.75rem;
  min-height: 2.75rem;
  margin: 0;
  padding: 0 0.625rem;
  border: 1px solid var(--borde);
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-m);
  font-weight: 700;
  cursor: pointer;
}

.lt-cara input:checked + label {
  border-color: var(--primario);
  background: var(--primario);
  color: var(--sobre-primario);
}

.lt-cara input:checked + label::before {
  content: "✓";
  font-size: 0.75rem;
}

.lt-cara input:focus-visible + label {
  outline: 3px solid var(--anillo);
  outline-offset: 2px;
}

/* El estado inicial: dos botones con ícono y texto (no solo color); el elegido, con la forma de su estado. */
.lt-agregar .lt-seg-campo {
  margin: 0 0 1rem;
}

.lt-seg {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.375rem;
}

.lt-seg-op {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  box-sizing: border-box;
  min-height: 2.75rem;
  margin: 0;
  padding: 0.25rem 0.625rem;
  border: 2px solid color-mix(in srgb, var(--texto) 42%, var(--papel));
  border-radius: 0.625rem;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-s);
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}

.lt-seg-op input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.lt-seg-op .icono {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.lt-seg-tratar:has(input:checked) {
  border-color: var(--odo-tratar);
  background: color-mix(in srgb, var(--odo-tratar) 8%, var(--odo-vacio));
  color: color-mix(in srgb, var(--odo-tratar) 88%, var(--texto));
  font-weight: 700;
}

.lt-seg-curso:has(input:checked) {
  border-style: dashed;
  border-color: var(--texto);
  background: var(--acento-suave);
  font-weight: 700;
}

.lt-seg-op:has(input:focus-visible) {
  outline: 3px solid var(--anillo);
  outline-offset: 2px;
}

.lt-ayuda-fina {
  margin: 0.375rem 0 0;
  font-size: var(--t-xs);
}

/* El valor: «$» y el campo, con «Por fijar» de marca de agua. */
.lt-valor {
  margin: 0 0 1rem;
}

.lt-pre {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  max-width: 10.5rem;
}

.lt-mon {
  color: var(--silenciado);
  font-weight: 600;
}

/* Lo que el mockup no muestra (cantidad y doctor), plegado. */
.lt-mas-opc {
  margin: 0 0 0.75rem;
  border-top: 1px dashed var(--acento-linea);
}

.lt-mas-opc > summary {
  font-size: var(--t-s);
}

.lt-mas-opc .campos-alta {
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.lt-agregar .alta-acciones {
  margin-top: 0;
}

.lt-anadir {
  min-height: 2.75rem;
}

@media (max-width: 39.99rem) {
  .lt-anadir {
    width: 100%;
  }
}

/* R12. El campo «Diagnóstico (K)» del formulario de añadir: un grupo de radios con las mismas opciones del catálogo (el aro de acento, no una raya al costado), la ayuda de cada código solo en el elegido para que la lista no crezca, los demás
   códigos plegados por grupo y, debajo, el resumen de lo que pasará al añadir. Con el campo, el botón y el resumen en la misma tarjeta; todo objetivo de 44 px como mínimo. */
.lt-dx {
  min-width: 0;
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.625rem 0.625rem;
  border: 1.5px solid var(--acento-linea);
  border-radius: 0.625rem;
  background: var(--papel);
}

.lt-dx > legend {
  padding: 0 0.375rem;
  color: var(--acento-tinta);
  font-size: var(--t-s);
  font-weight: 700;
}

.lt-dx-ayuda,
.lt-dx-nota {
  margin: 0 0 0.25rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
}

.lt-dx-nota {
  margin: 0.5rem 0 0;
}

.lt-dx-sub {
  margin: 0.625rem 0 0.125rem;
  color: var(--silenciado);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.lt-dx-aviso {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.625rem;
  border: 1px dashed var(--aviso-linea);
  border-radius: 0.5rem;
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  font-size: var(--t-xs);
}

.lt-dx .cb-op:not(:has(input:checked)) small {
  display: none;
}

.lt-dx .cb-op small {
  margin-top: 0.125rem;
  font-size: var(--t-xs);
}

.lt-dx-lista[hidden],
.lt-dx-grupo[hidden],
.lt-dx-sub[hidden] {
  display: none;
}

.lt-dx-gr {
  margin-top: 0.5rem;
  border-top: 1px solid var(--linea);
}

.lt-dx-gr > summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: var(--t-s);
  font-weight: 600;
  cursor: pointer;
}

.lt-dx-resumen {
  margin: 0 0 0.75rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--acento-linea);
  border-radius: 0.5rem;
  background: var(--acento-suave);
  font-size: var(--t-s);
}

/* La fila ligada a un diagnóstico: una pastilla sobria con el código (en el panel y en «Toda la lista»). */
.lt-dx-liga {
  padding-block: 0.0625rem;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}

.lt-res-t .lt-dx-liga {
  margin-left: 0.375rem;
}

@media (hover: hover) and (pointer: fine) {
  .lt-pieza:hover,
  .lt-den-op:not([aria-current="true"]):hover {
    border-color: var(--texto);
  }
}

/* Con ancho de sobra (la tarjeta, no la pantalla), los dos cuadrantes de un arco van lado a lado, con la línea media punteada entre ellos. */
@container (min-width: 46rem) {
  .lt-arco {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 0.875rem;
  }

  .lt-arco::before {
    content: "";
    position: absolute;
    top: 1.375rem;
    bottom: 0;
    left: 50%;
    border-left: 1px dashed color-mix(in srgb, var(--texto) 42%, var(--papel));
  }

  .lt-cuadrante {
    gap: 0.1875rem;
  }

  /* Con la pieza más angosta (41 px) el ícono y «×N» ya no caben en una línea: uno bajo el otro, y la pieza, algo más alta. */
  .lt-cuadrante .lt-pieza {
    min-height: 4rem;
  }

  .lt-cuadrante .lt-est {
    flex-direction: column;
    gap: 0.0625rem;
  }
}

/* Con puntero fino (ratón), los dos cuadrantes de un arco van lado a lado desde 38 rem de tarjeta (la tira de al lado del panel): la pieza mide 32 px de ancho como mínimo; con el dedo siguen uno sobre otro hasta los 46 rem. */
@media (pointer: fine) {
  @container (min-width: 38rem) {
    .lt-arco {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 0 0.875rem;
    }

    .lt-arco::before {
      content: "";
      position: absolute;
      top: 1.375rem;
      bottom: 0;
      left: 50%;
      border-left: 1px dashed color-mix(in srgb, var(--texto) 42%, var(--papel));
    }

    .lt-cuadrante {
      grid-template-columns: repeat(8, minmax(2rem, 1fr));
      gap: 0.1875rem;
    }

    .lt-cuadrante .lt-pieza {
      min-height: 4rem;
    }

    .lt-cuadrante .lt-est {
      flex-direction: column;
      gap: 0.0625rem;
    }

    .lt-denticion[aria-label="Dentición temporal"] .lt-cuadrante {
      grid-template-columns: repeat(5, minmax(2rem, 1fr));
    }
  }
}

/* En el celular, la tarjeta de la tira sangra hasta el borde de la pantalla (su contenedor le presta `--lt-sangrado`): así caben ocho piezas de 44 px por fila a 390 px. */
@media (max-width: 39.99rem) {
  .lt-tira {
    margin-inline: calc(-1 * var(--lt-sangrado, 0px));
    border-inline-width: 0;
    border-radius: 0;
  }

  .lt-cuadrante {
    gap: 0.125rem;
  }

  .lt-pieza {
    min-height: 3.5rem;
  }
}

@media print {
  .lt-quitar,
  .lt-mas,
  .lt-volver,
  .lt-guardar,
  .lt-agregar,
  .lt-leyenda,
  .lt-ley,
  .lt-den {
    display: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 41. La «Cita del día» del personal (lista de tratamiento C1; spec del 31-oct §4 y §12.6): el perfil del paciente abierto desde la cita, con la
 *     lista al centro. Teléfono primero: una sola columna, la cabecera del paciente pegajosa, los bloques uno tras otro (la lista primero) y una
 *     barra inferior de pestañas, fija, cuyos enlaces son anclas a cada bloque (funciona sin JavaScript); todo objetivo de toque de 44 px como
 *     mínimo. A 1200 px o más, las tres columnas (paciente, lista, publicar) y la barra se va. El estado de una cita se dice con texto (el sello
 *     lo acompaña con color). Nada de esto lleva estilos en línea.
 *     Rediseño según la Variante B del mockup aprobado (R1, marco y orden; R2, cabecera y tarjeta del paciente): a 1200 px o más, DOS columnas (a la izquierda, de 19 rem, el paciente, el diagnóstico, las indicaciones y publicar, apilados; a la derecha una rejilla de dos
 *     columnas: la lista con su leyenda, «Toda la lista», las imágenes y lo hecho hoy, una tarjeta bajo otra, y el panel de la pieza de 22,5 rem a su lado, arriba: R13); en el celular, una sola, en el orden de `CitaDelDia::BLOQUES` (la lista con su panel, la leyenda y «Toda la lista»,
 *     el diagnóstico, las imágenes, lo hecho hoy, las indicaciones, el paciente, publicar).
 * ------------------------------------------------------------------------------------------------------------------ */

/* Una columna flexible y no una rejilla: un hijo `sticky` de una rejilla solo se mueve dentro de su propia fila y nunca se pega. */
.hoy {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

.hoy > * {
  min-width: 0;
  margin: 0;
}

/* La barra fija de abajo no tapa el final de la página. */
body:has(.hoy-pestanas) {
  padding-bottom: calc(3.75rem + env(safe-area-inset-bottom, 0px));
}

/* El título de la página, como el mockup: las migas, «Cita del día» y el día y la hora de la cita (o la nota de que se abrió sin ella). */
.hoy-cabeza {
  padding: 0 0.25rem;
}

.hoy-migas {
  margin: 0;
  color: var(--silenciado);
  font-size: var(--t-xs);
}

.hoy-cabeza h1 {
  margin: 0.125rem 0 0;
  font-size: var(--t-xl);
  line-height: 1.2;
}

.hoy-sub {
  margin: 0.125rem 0 0;
  color: var(--silenciado);
}

/* La barra pegajosa: quién es el paciente (nombre, historia y, con `ver_precios`, el saldo) y, cuando otra persona cambió algo, el aviso. Solo en el celular dice quién es: ahí el bloque del paciente queda abajo; desde 75rem lo dice su tarjeta y la barra
   queda vacía (sin alto) hasta que hay un aviso. */
.hoy-barra {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.hoy-barra .hoy-aviso {
  flex: none;
}

.hoy-quien {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.125rem 0.875rem;
  margin: 0;
  padding: 0.5rem 0.875rem;
  border: 1px solid var(--vidrio-borde);
  border-radius: var(--r-control);
  background: var(--papel);
  font-size: var(--t-s);
}

.hoy-quien strong {
  font-family: var(--letra-titulo);
  font-size: var(--t-m);
  font-weight: 650;
}

.hoy-saldo {
  font-weight: 700;
}

.hoy-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* En el celular las columnas no existen: sus bloques son hijos directos de la columna única (`display: contents`) y cada uno lleva su lugar en el orden del celular (`hoy-orden-<n>`: su posición entre los bloques que salieron, en el orden de `CitaDelDia::BLOQUES`; la tarjeta del paciente, la del primero de los suyos),
   que es también el orden de las pestañas. El marcado va por columnas (el orden de lectura del escritorio); aquí se vuelve al del celular. La clase de la posición `n` vale `4 × n`: entre la lista y el bloque que sigue caben las tres piezas que la lista deja fuera de su tarjeta (R13). */
.hoy-col,
.hoy-izq,
.hoy-der {
  display: contents;
}

@media (max-width: 74.99rem) {
  .hoy-orden-0 { order: 0; }
  .hoy-orden-1 { order: 4; }
  .hoy-orden-2 { order: 8; }
  .hoy-orden-3 { order: 12; }
  .hoy-orden-4 { order: 16; }
  .hoy-orden-5 { order: 20; }
  .hoy-orden-6 { order: 24; }
  .hoy-orden-7 { order: 28; }
  .hoy-orden-8 { order: 32; }
  .hoy-orden-9 { order: 36; }
  .hoy-orden-10 { order: 40; }
  .hoy-orden-11 { order: 44; }
  .hoy-orden-12 { order: 48; }
  .hoy-orden-13 { order: 52; }
  .hoy-orden-14 { order: 56; }
  .hoy-orden-15 { order: 60; }
  .hoy-orden-16 { order: 64; }
  .hoy-orden-17 { order: 68; }
  .hoy-orden-18 { order: 72; }
  .hoy-orden-19 { order: 76; }

  /* Lo que la lista dejó fuera de su tarjeta (R13) va justo tras ella, en el orden de siempre: su panel, la leyenda y «Toda la lista». */
  .hoy-orden-panel { order: 1; }
  .hoy-orden-leyenda { order: 2; }
  .hoy-orden-resumen { order: 3; }
}

.hoy-bloque {
  min-width: 0;
  padding: 1rem;
  scroll-margin-top: 5.5rem;
}

.hoy-bloque h2 {
  margin: 0 0 0.75rem;
  font-size: var(--t-l);
}

.hoy-bloque:focus {
  outline: none;
}

.hoy-bloque:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.hoy-error {
  margin: 0;
  padding: 0.625rem 0.875rem;
  border: 1px dashed var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  font-weight: 600;
}

/* La zona del paciente es UNA tarjeta (la `hoja` del marcado): sus bloques (el paciente, el saldo y las últimas citas) son zonas del mismo papel, separadas por un filo, y sus títulos solo los oye el lector de pantalla
   (el nombre, «Saldo pendiente» y «Últimas 3 citas» ya lo dicen); el de un bloque que falló sí se ve. */
.hoy-col-lado {
  display: block;
  padding: 0;
}

.hoy-col-lado .hoy-bloque {
  padding: 1rem;
}

.hoy-col-lado .hoy-bloque + .hoy-bloque {
  margin-top: 0;
  padding-top: 1rem;
}

.hoy-col-lado .hoy-bloque:not(:has(> .hoy-error)) > h2 {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* En el celular la lista sangra hasta el borde de la pantalla (la tira necesita 366 px para ocho piezas de 44 px) y presta su relleno a la tira (`--lt-sangrado`). */
@media (max-width: 39.99rem) {
  .hoy-bloque-lista {
    --lt-sangrado: 0.75rem;
    margin-inline: -1rem;
    padding-inline: 0.75rem;
    border-inline-width: 0;
    border-radius: 0;
  }
}

/* Lo que la lista deja fuera de su tarjeta (R13): el panel de la pieza, la leyenda y «Toda la lista» son tarjetas aparte, cada una dentro de su envoltorio (que lleva su lugar en el celular); aquí no llevan margen propio. */
.hoy-extra {
  min-width: 0;
}

.hoy-extra > * {
  margin: 0;
}

/* El paciente: el nombre, «41 años · Historia clínica N.º 1» en una línea y, en una caja de acento, la cita de la que se abrió la pantalla. */
.hoy-nombre {
  margin: 0;
  font-family: var(--letra-titulo);
  font-size: var(--t-l);
  font-weight: 650;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.hoy-dato {
  margin: 0.125rem 0 0;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.hoy-cita {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.125rem 0.5rem;
  margin: 0.625rem 0 0;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-control);
  background: var(--acento-suave);
  color: var(--acento-tinta);
  font-size: var(--t-s);
}

/* La hora y el sello de la cita no se parten: si no caben en la línea, pasan enteros a la siguiente. */
.hoy-cita strong,
.hoy-cita .sello {
  white-space: nowrap;
}

.hoy-cita strong {
  font-weight: 650;
}

/* Lo que no se debe olvidar: filas de texto corridas, con su ícono y su «Abrir»; no una tarjeta por alerta. */
.hoy-bloque-paciente .alertas-perfil {
  gap: 0.375rem;
  margin: 0.75rem 0 0;
}

.hoy-bloque-paciente .alerta-perfil {
  align-items: flex-start;
  gap: 0.25rem 0.5rem;
  padding: 0.5rem 0.625rem;
  border-radius: var(--r-control);
  font-size: var(--t-s);
}

.hoy-bloque-paciente .alerta-perfil > span {
  flex: 1 1 8rem;
}

.hoy-bloque-paciente .alerta-perfil svg {
  width: 1rem;
  height: 1rem;
  margin-top: 0.125rem;
}

.hoy-bloque-paciente > .silenciado {
  margin: 0.75rem 0 0;
  font-size: var(--t-s);
}

/* Últimas citas: un `<details>` abierto (se puede plegar) con filas cortas y planas: el día en negrita y debajo la hora, el tipo, el doctor y el estado. */
.hoy-citas-det > summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  margin: -0.5rem 0 0;
  font-family: var(--letra-titulo);
  font-size: var(--t-m);
  font-weight: 650;
  cursor: pointer;
}

.hoy-citas,
.hoy-publicar {
  display: grid;
  gap: 0.625rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hoy-citas {
  gap: 0;
}

.hoy-cita-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.5rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--linea);
  font-size: var(--t-s);
}

/* La cita que se abrió: un fondo tenue (y su pastilla «Esta cita»), no una raya al costado. */
.hoy-cita-actual {
  padding-inline: 0.5rem;
  border-radius: var(--r-control);
  background: var(--acento-suave);
}

.hoy-cita-hora {
  flex: 1 1 100%;
  font-weight: 600;
}

.hoy-cita-det {
  color: var(--silenciado);
}

.hoy-cita-marcas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

/* El saldo: una caja con el monto a la derecha (el practicante, solo la frase); en cero, una línea. */
.hoy-saldo-caja {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

.hoy-saldo-caja strong {
  font-family: var(--letra-titulo);
  font-size: var(--t-xl);
}

.hoy-saldo-texto {
  margin: 0;
  color: var(--silenciado);
}

.hoy-mora {
  margin: 0.625rem 0 0;
  font-size: var(--t-s);
}

.hoy-bloque-saldo p:last-child:not(.hoy-saldo-caja):not(.hoy-saldo-texto) {
  margin-top: 0.625rem;
}

.hoy-publicar li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
}

/* La barra inferior: un enlace por bloque, el de la lista destacado. Si hay más de los que caben, se desliza de lado. */
.hoy-pestanas {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 30;
  padding: 0.375rem 0.5rem calc(0.375rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--vidrio-borde);
  background: var(--papel);
}

.hoy-pestanas ul {
  display: flex;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  list-style: none;
}

.hoy-pestanas li {
  flex: 1 0 auto;
}

.hoy-pestana {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 3.5rem;
  min-height: 2.75rem;
  padding: 0.375rem 0.625rem;
  white-space: nowrap;
  border-radius: var(--r-control);
  color: var(--texto);
  font-size: var(--t-s);
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}

.hoy-pestana-principal {
  background: var(--primario);
  color: var(--sobre-primario);
}

.hoy-pestana:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .hoy-pestana:not(.hoy-pestana-principal):hover {
    background: var(--seleccion);
  }
}

@media (min-width: 75rem) {
  main:has(.hoy),
  .panel:has(> .hoy) {
    max-width: 90rem;
  }

  /* Dos columnas independientes (R13), cada una su propio contenedor (ninguna se estira por la altura de la otra ni deja un hueco entre sus bloques): a la izquierda, de 19 rem, el paciente (`lado`, una sola tarjeta), el diagnóstico, las indicaciones y publicar (`izq`); a la derecha,
     una rejilla de dos columnas: la primera (`hoy-col-centro`) apila la tarjeta de la lista, la leyenda, «Toda la lista», las imágenes de hoy y lo hecho hoy; la segunda, de 22,5 rem, es el panel de la pieza, arriba y a su propio alto (como el mockup: la columna de en medio y el panel quedan parejos). */
  .hoy-cuerpo {
    display: grid;
    grid-template-columns: 19rem minmax(0, 1fr);
    align-items: start;
    gap: 0 1.25rem;
  }

  .hoy-izq,
  .hoy-der {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
  }

  .hoy-der.lt {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22.5rem;
    align-items: start;
    gap: 0 0.75rem;
  }

  .hoy-der.lt > .hoy-col-centro {
    grid-column: 1;
    grid-row: 1;
  }

  .hoy-der.lt > .hoy-extra-panel {
    grid-column: 2;
    grid-row: 1;
  }

  .hoy-col {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
  }

  .hoy-col-lado {
    display: block;
  }

  /* Las tarjetas de una columna van una bajo otra a un solo ritmo, el hueco de la columna: sin el margen de abajo que trae toda tarjeta. */
  .hoy-col > .hoy-bloque {
    margin: 0;
  }

  /* La barra no dice quién es (lo dice la tarjeta del paciente); sin aviso, no ocupa ni el hueco entre bloques. */
  .hoy-quien {
    display: none;
  }

  .hoy-barra:not(:has(.hoy-aviso-enlace:not([hidden]))) {
    margin-bottom: -1rem;
  }

  /* En una columna de lado el nombre y su valor van uno sobre otro (con dos columnas el valor quedaba en 80 px y se partía letra por letra). */
  .hoy-col .datos div {
    grid-template-columns: minmax(0, 1fr);
  }

  .hoy-col .datos dd {
    overflow-wrap: break-word;
  }

  .hoy-pestanas {
    display: none;
  }

  body:has(.hoy-pestanas) {
    padding-bottom: 0;
  }
}

@media print {
  .hoy-pestanas {
    display: none;
  }

  .hoy-barra {
    position: static;
  }
}

/* La barra fija de total (R8; el mockup: «Total», «Total pendiente» y el recuento por estado), pegada abajo y FUERA de toda tarjeta (el `backdrop-filter` de una tarjeta ataría a un hijo fijo): vive en `.hoy` o, en la lista sola, bajo su hoja.
   Fondo macizo con un filete de acento arriba y una sombra suave. En el celular de la «Cita del día» va sobre la barra de pestañas; la página lleva el relleno de las dos para que ningún botón quede oculto al final. Con los montos, el recuento
   (que ya dicen los chips de arriba) queda solo para el lector de pantalla en el celular, así la barra mide una sola fila; sin montos (el practicante) el recuento es lo único que hay y se ve. */
.lt-total {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 28;
  padding: 0.375rem 1rem calc(0.375rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--acento-linea);
  background: var(--papel);
  box-shadow: 0 -10px 30px -22px color-mix(in srgb, var(--c-texto) 50%, transparent);
}

.lt-total-in {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.125rem 1rem;
  max-width: 90rem;
  margin: 0 auto;
}

.lt-total-in > p {
  margin: 0;
}

.lt-total-c {
  display: grid;
  min-width: 0;
}

.lt-total-et {
  color: var(--silenciado);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
}

.lt-total-c strong {
  font-family: var(--letra-titulo);
  font-size: var(--t-l);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.lt-total-corto {
  display: none;
}

.lt-total-cuentas {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.lt-total-presupuesto {
  margin-left: auto;
}

/* Con montos, en el celular, el recuento solo se lee (los chips de arriba ya lo ven): la barra queda en una fila. */
@media (max-width: 74.99rem) {
  .lt-total-monto .lt-total-cuentas {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .lt-total-largo {
    display: none;
  }

  .lt-total-corto {
    display: inline;
  }

  /* Sobre la barra de pestañas de la «Cita del día» (que mide 3,6 rem más lo seguro del equipo). */
  .hoy .lt-total {
    bottom: calc(3.6rem + env(safe-area-inset-bottom, 0px));
    padding-bottom: 0.375rem;
  }
}

@media (min-width: 40rem) {
  .lt-total {
    padding-inline: 2rem;
  }

  .lt-total-in {
    gap: 0.125rem 1.5rem;
  }

  .lt-total-c strong {
    font-size: var(--t-xl);
  }
}

/* La página no deja nada bajo las barras: el relleno de abajo suma la de total (4,5 rem) y, en el celular de la «Cita del día», la de pestañas. */
body:has(.lt-total) {
  padding-bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px));
}

@media (max-width: 74.99rem) {
  body:has(.hoy .lt-total) {
    padding-bottom: calc(8.25rem + env(safe-area-inset-bottom, 0px));
  }
}

@media print {
  .lt-total {
    display: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 42. «Lo hecho hoy» e «Indicaciones» en la «Cita del día» (lista de tratamiento C2; spec del 31-oct §4 y §12.6): listas cortas de lo que ocurrió hoy con el paciente (filas de la lista cuyo estado cambió, atención, documentos,
 *     fotos) y de las indicaciones emitidas. Teléfono primero: una columna; el estado de una fila se dice con forma y texto (la forma es la de la lista), y todo enlace o miniatura que se toca mide 44 px como mínimo.
 *     La rejilla y el pie de las miniaturas son los de las imágenes (sección 36). Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.hoy-lista {
  display: grid;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.hoy-lista li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.hoy-lista a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

.hoy-hecho-sec {
  min-width: 0;
}

.hoy-hecho-sec + .hoy-hecho-sec {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--linea);
}

.hoy-hecho-sec h3 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

.hoy-hecho-sec p {
  margin: 0 0 0.5rem;
}

/* Cada tratamiento, en una línea (el nombre con su pieza, el estado con su ícono y, con montos, lo que vale); si no cabe, pasa a la siguiente, sin tarjetas. */
.hoy-lista:has(.hoy-hecho-fila) {
  container-type: inline-size;
  gap: 0;
}


.hoy-hecho-fila {
  padding: 0.375rem 0;
  border-top: 1px solid var(--linea);
}

.hoy-hecho-fila:first-child {
  border-top: 0;
}

.hoy-hecho-nombre {
  flex: 1 1 8rem;
  min-width: 0;
}
/* Donde no cabe todo en una línea (la columna de 19 rem, un teléfono angosto), el nombre ocupa la suya y debajo van el estado y lo que vale. */
@container (max-width: 20rem) {
  .hoy-hecho-nombre {
    flex-basis: 100%;
  }
}

.hoy-hecho-donde {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.hoy-hecho-estado {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0 0.5rem;
  font-size: 0.75rem;
  white-space: nowrap;
}

.hoy-hecho-estado .icono {
  width: 0.875rem;
  height: 0.875rem;
}

.hoy-hecho-monto {
  margin-left: auto;
  font-size: var(--t-s);
  font-weight: 600;
}

/* «Más de hoy»: la atención, los documentos y las fotos, plegados. */
.hoy-mas-hoy {
  margin-top: 0.5rem;
  border-top: 1px solid var(--linea);
}

.hoy-mas-hoy > summary {
  font-size: var(--t-s);
}

.hoy-mas-hoy .hoy-hecho-sec:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.hoy-hora {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.hoy-hecho-sec .imagenes-rejilla {
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  margin: 0.5rem 0 0.75rem;
}

.hoy-hecho-sec .imagenes-enlace {
  min-height: 2.75rem;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 43. «Imágenes de hoy» en la «Cita del día» (lista de tratamiento C4): las miniaturas de hoy, el segundo paso «Es el paciente correcto» y el formulario
 *     de subida usan lo de las secciones 36 (la rejilla y el pie) y de las horas (los botones de radio de la etiqueta). R11: el bloque va bajo la lista, a todo el ancho de la
 *     columna central, así que las miniaturas son de ~200 px (la imagen de la tarjeta de confirmación también: es la vista previa de lo que se acaba de subir) y la que
 *     esta persona acaba de confirmar lleva «Recién subida». Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

/* Las miniaturas del bloque: dos por fila en el celular y, desde 40 rem, de ~200 px (la rejilla aprovecha el ancho de la columna central). */
.hoy-bloque-imagenes .imagenes-rejilla {
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
}

@media (min-width: 40rem) {
  .hoy-bloque-imagenes .imagenes-rejilla {
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  }
}

/* La que esta persona acaba de confirmar: un aro de acento en la imagen (y «Recién subida» en su pie, que lo dice con texto), no una raya al costado. */
.imagenes-nueva img {
  border-color: var(--acento);
  box-shadow: 0 0 0 2px var(--acento);
}

.imagenes-nueva-et {
  margin-left: 0.25rem;
  vertical-align: 0.0625rem;
}

.imagenes-pieza {
  white-space: nowrap;
}

.hoy-bloque-imagenes .apilada {
  margin: 0 0 1rem;
}

/* «Subir una imagen»: el formulario, plegado hasta que se necesita (o hasta que el servidor lo devuelve con su aviso). */
.hoy-imagenes-mas {
  margin-top: 0.5rem;
  border-top: 1px solid var(--linea);
}

.hoy-imagenes-subir {
  max-width: 40rem;
  margin-top: 0;
}

.hoy-imagenes-subir .horas {
  margin-bottom: 1rem;
}

.hoy-imagenes-subir input[type="file"],
.hoy-imagenes-subir select {
  max-width: 100%;
  min-width: 0;
}

/* Mientras no hay archivo (el campo es obligatorio, así que `:invalid`) no se pinta el «No file chosen» del navegador: el botón (que sigue con su color) y el nombre accesible bastan; con un archivo elegido, el nombre se ve. */
.hoy-imagenes-subir input[type="file"]:invalid {
  color: transparent;
}

/* El botón del selector de archivo, como los botones secundarios (el nativo era gris, de otro sistema). */
.hoy-imagenes-subir input[type="file"]::file-selector-button {
  min-height: 2.75rem;
  margin: 0 0.75rem 0 0;
  padding: 0.5rem 1rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-boton);
  background: var(--papel);
  color: var(--texto);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 44. «Diagnóstico» en la «Cita del día» (lista de tratamiento C5; spec del 31-oct §12.7): los diagnósticos de hoy y de visitas anteriores, el buscador de un solo campo con sus chips, los resultados, el alcance, la vista previa
 *     de lo que el paciente verá y el historial plegable. Teléfono primero: una columna; el estado se dice con texto (el sello solo acompaña) y todo lo que se toca mide 44 px como mínimo. `.dx-publicados` es la lista que
 *     pinta el portal (pestaña «Tratamiento») y la vista previa del personal: el mismo marcado. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.dx {
  display: grid;
  gap: 0.75rem;
  min-width: 0;
}

.dx-sec {
  min-width: 0;
}

.dx-sec h3 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

.dx-sec p {
  margin: 0 0 0.5rem;
}

.dx-lista {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dx-item {
  min-width: 0;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  overflow-wrap: anywhere;
}

.dx-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 0.75rem;
}

.dx-cabeza p {
  margin: 0;
}

.dx-nombre {
  flex: 1 1 12rem;
}

.dx-estado {
  display: inline-flex;
  gap: 0.375rem;
}

/* Dónde, la nota, quién y desde cuándo: una línea corrida. */
.dx-meta {
  margin: 0.25rem 0 0;
  color: var(--silenciado);
  font-size: var(--t-s);
}

.dx-aviso {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

.dx-observacion {
  margin: 0.25rem 0 0;
  font-size: var(--t-s);
}

/* «Lo atienden:» y sus filas, en la misma línea (pasan a la siguiente si no caben). */
.dx-atiende {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.5rem;
  margin-top: 0.25rem;
  font-size: var(--t-s);
}

.dx-atiende p {
  margin: 0;
}

.dx-atiende ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dx-atiende a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

/* Las acciones de un diagnóstico, en una fila: «Se mantiene» y «Resuelto», «Corregir» y «Retirar»; el que se abre ocupa el ancho para su formulario. */
.dx-acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.25rem 0.5rem;
  margin-top: 0.25rem;
}

.dx-mas {
  flex: 0 0 auto;
  border-top: 0;
}

.dx-mas[open] {
  flex: 1 1 100%;
}

.dx-mas > summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.875rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-control);
  background: var(--papel);
  font-size: var(--t-s);
  font-weight: 600;
}

.dx-mas > summary::after {
  display: none;
}

.dx-mas[open] > summary {
  margin-bottom: 0.5rem;
  border-color: var(--texto);
}

.dx-botones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.dx-botones button,
.dx-mas summary {
  min-height: 2.75rem;
}

.dx-estados {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
}

/* Registrar, la vista previa y el historial: cada uno en su `<details class="plegable">`, bajo una línea. */
.dx-plegable {
  min-width: 0;
  border-top: 1px solid var(--linea);
}

/* Los resúmenes de las partes plegables van seguidos, sin hueco de más entre ellos. */
.dx-plegable + .dx-plegable {
  margin-top: -0.75rem;
}

.dx-buscar,
.dx-form {
  min-width: 0;
}

.dx-buscar input[type="search"],
.dx-form input[type="text"],
.dx-form select {
  max-width: 100%;
  min-width: 0;
}

.dx-chips-grupo {
  margin: 0 0 0.75rem;
}

.dx-chips-titulo {
  margin: 0 0 0.25rem;
  font-weight: 650;
}

.dx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dx-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0 0.875rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--papel);
  color: var(--texto);
  font-weight: 600;
  text-decoration: none;
}

.dx-chip-nombre {
  margin-left: 0.25rem;
  font-weight: 400;
  color: var(--silenciado);
}

.dx-resultados,
.dx-alcance {
  margin: 0 0 1rem;
}

.dx-resultados legend,
.dx-alcance legend {
  margin: 0 0 0.5rem;
  padding: 0;
  font-weight: 650;
}

.dx-publicados {
  display: grid;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.dx-publicado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  min-width: 0;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  overflow-wrap: anywhere;
}

.dx-paciente {
  margin: 0 0 0.75rem;
}

.dx-paciente p {
  margin: 0 0 0.5rem;
}

.dx-historial {
  min-width: 0;
}

.dx-historial > summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  cursor: pointer;
  font-weight: 650;
}

.dx-historial h4 {
  margin: 0.75rem 0 0.25rem;
  font-size: var(--t-s);
}

.dx-visita {
  display: grid;
  gap: 0.375rem;
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 45. El carnet con QR y la pantalla de llegada (F1.3, D3, D4 y D6). «Tu carnet» del portal: el QR sobre blanco y la nota de brillo. La tarjeta del
 *     mostrador (`.carnet-tarjeta`): nombre, historia y QR; en papel es lo único que sale (el resto de la página se oculta con las reglas de `.panel` de la
 *     sección 21 y esta tarjeta se vuelve a mostrar), en una sola hoja. La llegada: el campo del código a 16 px como mínimo (el iPad no hace zoom) y la bienvenida con
 *     las iniciales en grande. El SVG del QR sale con atributos y sin estilos: aquí solo se le da el ancho. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.carnet-qr {
  width: min(100%, 20rem);
  margin: 1rem auto;
  padding: 0.5rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-hoja);
  background: #ffffff;
}

.carnet-qr svg {
  display: block;
  width: 100%;
  height: auto;
}

.carnet-qr-datos {
  display: grid;
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.carnet-qr-datos > div {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
}

.carnet-qr-datos dt {
  color: var(--silenciado);
}

.carnet-qr-hoja .enlace-aparte {
  margin: 0 0 1rem;
}

.carnet-qr-hoja .enlace-aparte a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.carnet-qr-datos dd {
  display: block;
  margin: 0;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.carnet-tarjeta {
  display: grid;
  justify-self: center;
  gap: 0.75rem;
  width: 100%;
  max-width: 24rem;
  padding: 1rem 1.25rem 1.25rem;
  border: 1px solid var(--borde);
  border-radius: 14px;
  background: var(--papel);
  text-align: center;
  break-inside: avoid;
}

.carnet-tarjeta > * {
  margin: 0;
}

.carnet-tarjeta-emisor {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: var(--silenciado);
  font-size: var(--t-s);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.carnet-tarjeta-nombre {
  font-size: var(--t-l);
  line-height: 1.2;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.carnet-tarjeta-historia .cifras {
  display: inline;
  margin: 0;
  font-family: var(--letra-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.carnet-tarjeta .carnet-qr {
  width: min(100%, 16rem);
  margin: 0 auto;
}

.carnet-tarjeta-pie {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.carnet-reimprimir {
  max-width: 46rem;
  justify-self: center;
  width: 100%;
}

@media print {
  body:has(.carnet-tarjeta) .cabecera {
    display: none;
  }

  .panel > .carnet-tarjeta {
    display: grid;
    justify-self: start;
    width: 90mm;
    max-width: none;
    padding: 6mm;
    border: 1px solid #000000;
    border-radius: 3mm;
    background: #ffffff;
    color: #000000;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .carnet-tarjeta .carnet-qr {
    width: 52mm;
    padding: 0;
    border: 0;
  }

  .carnet-tarjeta-emisor,
  .carnet-tarjeta-pie {
    color: #000000;
  }
}

.llegada-form .campo input[type="text"] {
  min-height: 3.25rem;
  font-size: 1rem;
}

.llegada-bienvenida {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  text-align: center;
}

.llegada-bienvenida > * {
  margin: 0;
}

.llegada-iniciales {
  display: grid;
  place-items: center;
  width: 7rem;
  height: 7rem;
  border: 2px solid var(--acento);
  border-radius: 50%;
  background: var(--acento-suave);
  font-size: 2.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.llegada-bienvenida h2 {
  font-size: var(--t-xl);
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.llegada-hora {
  color: var(--silenciado);
}

.llegada-bienvenida .acciones {
  justify-content: center;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 46. Los dos sondeos pasivos. «Otra persona cambió…» de la «Cita del día» (lista de tratamiento C7): una línea dentro de la cabecera pegajosa, con la región de estado
 *     (vacía hasta que `hoy.js` escribe) y el enlace «Actualizar», oculto hasta entonces; solo se vuelve una franja cuando el enlace se muestra. La barra de llegadas
 *     (F1.3, D7): arriba en el celular (abajo está la barra de pestañas de la cita) y abajo a la derecha desde 48rem; su región de estado empieza vacía y `llegadas.js`
 *     le añade un aviso por llegada. Sin estilos en línea; el texto lo dice todo (el color solo acompaña).
 * ------------------------------------------------------------------------------------------------------------------ */

.hoy-aviso {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin: 0;
}

.hoy-aviso:has(.hoy-aviso-enlace:not([hidden])) {
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

.hoy-aviso-texto {
  margin: 0;
  font-weight: 600;
}

.hoy-aviso-enlace[hidden] {
  display: none;
}

.barra-llegadas {
  position: fixed;
  z-index: 40;
  bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  right: 0.75rem;
  left: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  max-width: 26rem;
  margin-inline-start: auto;
}

.barra-llegadas-lista {
  display: grid;
  gap: 0.375rem;
}

.barra-llegadas-aviso {
  margin: 0;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--acento-linea);
  border-radius: var(--r-control);
  background: var(--papel);
  box-shadow: var(--sombra);
  color: var(--texto);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.barra-llegadas-cerrar {
  align-self: flex-end;
  min-height: 2.75rem;
}

.barra-llegadas-cerrar[hidden] {
  display: none;
}

/* Abajo (no arriba: tapaba el logo y la navegación) y por encima de lo que ya vive abajo: la barra de pestañas de la Cita del día y el botón «+» del calendario. */
body:has(.hoy-pestanas) .barra-llegadas {
  bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px));
}

body:has(.cal-fab) .barra-llegadas {
  bottom: calc(5.75rem + env(safe-area-inset-bottom, 0px));
}

/* Y sobre la barra fija de total (R8): sola, o con la de pestañas debajo en el celular. */
body:has(.lt-total) .barra-llegadas {
  bottom: calc(5.25rem + env(safe-area-inset-bottom, 0px));
}

@media (max-width: 74.99rem) {
  body:has(.hoy .lt-total) .barra-llegadas {
    bottom: calc(8.75rem + env(safe-area-inset-bottom, 0px));
  }
}

@media (min-width: 48rem) {
  .barra-llegadas {
    left: auto;
    width: 26rem;
  }
}

@media print {
  .barra-llegadas,
  .hoy-aviso {
    display: none;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 47. La cámara de la pantalla de llegada (F1.3, D8c): sobre el campo del código, el botón «Usar la cámara» (y «Detener la cámara» mientras está encendida), el aviso de
 *     estado y la vista del video. Es una mejora de `escaner.js`: en el marcado los botones, el video y el lienzo traen `hidden` (el `[hidden]` de arriba manda) y el
 *     aviso empieza vacío, así que sin JavaScript no ocupan lugar. Los botones son los de siempre (48 px de alto, más de 44 px). El video muestra el cuadro entero que se
 *     lee, sin recortarlo, y no cabe más alto que el 60 % de la pantalla. No hay animación: nada que reducir con prefers-reduced-motion.
 * ------------------------------------------------------------------------------------------------------------------ */

.llegada-camara {
  margin: 0 0 1rem;
}

.llegada-camara .acciones {
  margin: 0;
}

.llegada-camara-estado {
  margin: 0.5rem 0 0;
}

.llegada-camara-estado:empty {
  display: none;
}

.llegada-video {
  display: block;
  width: 100%;
  max-width: 32rem;
  max-height: 60vh;
  margin-top: 0.75rem;
  object-fit: contain;
  border: 2px solid var(--acento);
  border-radius: var(--r-control);
  background: #000000;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 48. La proforma de tratamiento (lista de tratamiento P1 y P2; spec del 31-oct §5): la hoja del papel, A4 y en blanco y negro, con la estructura y las medidas del mockup aprobado, y los botones de la barra de total.
 *     Son DOS hojas (`pf-hoja`) dentro de un `hoja-documento` (solo ese árbol sale en papel; sección 21). En pantalla se ven a su tamaño de papel (210 mm) dentro de un contenedor que se desplaza a lo ancho si la pantalla es más angosta (un teléfono)
 *     y centradas si caben. En papel, la página con nombre `proforma` (A4, con los márgenes del mockup: 11 mm arriba, 14 mm a los lados, 9 mm abajo) da su propio margen y cada hoja ocupa la suya; una pieza con varias líneas va en un `tbody` que no se parte entre páginas.
 *     La página con nombre evita tocar la de los demás documentos (que conservan los márgenes del navegador). La hoja es de papel aunque la pantalla esté en modo oscuro: negro sobre blanco. La marca «Datos de prueba» va DENTRO de la hoja y, al imprimir, la franja
 *     de la página no se imprime con ella. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

@page proforma {
  size: A4;
  margin: 11mm 14mm 9mm;
}

.hoja-proforma {
  min-width: 0;
  max-width: 100%;
  margin: 0 auto 1.5rem;
  padding: 0.75rem;
  overflow-x: auto;
  background: transparent;
  border: 0;
  line-height: 1.25;
}

.pf-hojas {
  display: grid;
  gap: 1rem;
  width: max-content;
  margin: 0 auto;
}

.pf-hoja {
  display: flex;
  flex-direction: column;
  gap: 3.1mm;
  box-sizing: border-box;
  width: 210mm;
  min-height: 297mm;
  padding: 11mm 14mm 9mm;
  background: #ffffff;
  color: #000000;
  font: 9.5pt/1.25 "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  text-align: left;
  box-shadow: 0 10px 34px -14px rgba(0, 0, 0, 0.45);
}

.pf-hoja * {
  box-sizing: border-box;
}

/* Las tablas de la hoja no son las de datos del sistema: sin cabeceras pegajosas, sin fondos ni colores de tema, sin el resalte al pasar el ratón. */
.pf-hoja th,
.pf-hoja td {
  position: static;
  background: transparent;
  color: #000000;
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
  white-space: normal;
}

@media (hover: hover) and (pointer: fine) {
  .pf-hoja tbody tr:hover {
    background: transparent;
  }
}

.pf-cab {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8mm;
}

.pf-izq {
  flex: 1;
  min-width: 0;
}

.pf-clin {
  margin: 0;
  font-size: 12pt;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.pf-titulo {
  margin: 1mm 0 3.2mm;
  font-size: 11pt;
  font-weight: 600;
}

.pf-lin {
  display: flex;
  align-items: baseline;
  gap: 3mm;
  margin: 0 0 1.6mm;
}

.pf-lin span {
  white-space: nowrap;
}

.pf-lin b {
  flex: 1;
  max-width: 105mm;
  padding: 0 1mm;
  border-bottom: 0.6pt solid #000000;
  font-weight: 600;
}

.pf-der {
  flex: none;
  width: 46mm;
  text-align: right;
}

.pf-logo {
  display: block;
  max-width: 46mm;
  height: 12mm;
  margin: 0 0 1.6mm auto;
  object-fit: contain;
  object-position: right center;
}

.pf-doc {
  margin: 0;
  font-size: 8.5pt;
  font-weight: 600;
}

.pf-borrador,
.pf-prueba {
  display: inline-block;
  margin: 1mm 0 0;
  padding: 0.4mm 1.6mm;
  border: 0.8pt solid #000000;
  font-size: 8pt;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.pf-borrador {
  border-style: dashed;
}

.pf-cols {
  display: grid;
  grid-template-columns: 23mm 1fr 26mm;
  padding: 0 1.6mm;
  font-size: 8.5pt;
  font-weight: 600;
}

.pf-cols span:last-child {
  text-align: right;
}

.pf-t {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  break-inside: avoid;
}

.pf-t th,
.pf-t td {
  height: 5.6mm;
  padding: 0 1.6mm;
  border: 0.6pt solid #000000;
  overflow-wrap: anywhere;
  vertical-align: middle;
  line-height: 1.1;
}

.pf-t th[scope="row"] {
  font-weight: 400;
  text-align: left;
}

.pf-t .pf-v {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pf-t tbody,
.pf-t tr {
  break-inside: avoid;
}

.pf-c1 {
  width: 23mm;
}

.pf-c3 {
  width: 26mm;
}

.pf-gen .pf-c1g {
  width: 30mm;
}

.pf-resumen {
  display: flex;
  align-items: baseline;
  align-self: flex-end;
  gap: 5mm;
}

.pf-sub {
  display: flex;
  gap: 4mm;
  margin: 0;
  font-size: 8.5pt;
}

.pf-total {
  display: flex;
  align-items: baseline;
  align-self: flex-end;
  gap: 5mm;
  margin: 0;
  padding: 1mm 3.2mm;
  border: 0.8pt solid #000000;
  font-size: 10.5pt;
}

.pf-total b {
  font-size: 12pt;
  font-variant-numeric: tabular-nums;
}

.pf-ot {
  border: 0.6pt solid #000000;
}

.pf-ot .pf-c1o {
  width: 25mm;
}

.pf-ot th,
.pf-ot td {
  height: 6.2mm;
  border: 0;
}

.pf-ot .pf-ot-n {
  border-right: 0.6pt solid #000000;
  font-weight: 400;
  text-align: left;
  vertical-align: middle;
}

.pf-ot .pf-ot-l {
  padding: 0 1.6mm;
  border-bottom: 0.4pt dotted #000000;
}

.pf-ot .pf-ot-l span {
  margin-right: 2mm;
}

.pf-ot .pf-ot-l b {
  font-weight: 600;
}

.pf-ot .pf-v {
  border-bottom: 0.6pt solid #000000;
  border-left: 0.6pt solid #000000;
}

.pf-ot tr:last-child .pf-v,
.pf-ot tr:last-child .pf-ot-l {
  border-bottom: 0;
}

.pf-nota {
  margin: 0;
  font-size: 8pt;
}

.pf-pie {
  margin-top: auto;
  padding-top: 1.2mm;
  border-top: 0.4pt solid #000000;
  font-size: 7.5pt;
}

.pf-pie p {
  margin: 0;
}

.pf-pie-1 {
  display: flex;
  justify-content: space-between;
  gap: 4mm;
}

.pf-pie-2 {
  margin-top: 0.6mm;
  overflow-wrap: anywhere;
}

@media print {
  /* La hoja es lo único que sale: la franja de la página (los demás documentos conservan la suya) y el borde del contenedor no se imprimen; cada hoja ocupa su página. */
  body:has(.hoja-proforma) .banner-prueba {
    display: none;
  }

  /* El margen de la hoja lo da la página con nombre: lo que envuelve a la hoja no suma el suyo. */
  body:has(.hoja-proforma) {
    display: block;
    min-height: 0;
    padding: 0;
  }

  body:has(.hoja-proforma) main,
  body:has(.hoja-proforma) .panel {
    margin: 0;
    padding: 0;
  }

  .hoja-proforma {
    page: proforma;
    margin: 0;
    padding: 0;
    overflow: visible;
  }

  .pf-hojas {
    display: block;
    width: auto;
    margin: 0;
  }

  .pf-hoja {
    width: auto;
    min-height: 276mm;
    padding: 0;
    box-shadow: none;
    break-after: page;
  }

  .pf-hoja:last-child {
    break-after: auto;
  }

  .pf-logo {
    filter: grayscale(1) contrast(1.15);
  }
}

.lt-proforma {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
}

.lt-proforma-form {
  display: inline-flex;
  margin: 0;
}

.lt-proforma .boton-chico {
  margin: 0;
}

/* En el celular (y en una tableta angosta) los botones bajan a una segunda fila de la barra fija: la página y la barra de llegadas suben lo que ella crece (unos 3 rem). */
@media (max-width: 74.99rem) {
  body:has(.lt-proforma) {
    padding-bottom: calc(7.5rem + env(safe-area-inset-bottom, 0px));
  }

  body:has(.hoy .lt-proforma) {
    padding-bottom: calc(11.25rem + env(safe-area-inset-bottom, 0px));
  }

  body:has(.lt-proforma) .barra-llegadas {
    bottom: calc(8.25rem + env(safe-area-inset-bottom, 0px));
  }

  body:has(.hoy .lt-proforma) .barra-llegadas {
    bottom: calc(11.75rem + env(safe-area-inset-bottom, 0px));
  }
}

/* La entrega de la proforma al portal (P4), solo para el personal y fuera de la hoja: el estado y las fechas de entregada, recibida y leída, y el botón. No sale en papel (el panel solo imprime la hoja). */
.pf-entrega {
  display: grid;
  gap: 0.5rem;
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--linea);
  border-radius: 0.5rem;
  background: var(--papel);
}

.pf-entrega h3 {
  margin: 0;
  font-size: 1rem;
}

.pf-entrega-estados {
  display: grid;
  gap: 0.25rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.pf-entrega-estados span:first-child {
  display: block;
  font-size: 0.8125rem;
  color: var(--silenciado);
}

.pf-entrega .lista-explica {
  margin: 0;
}

.pf-entrega .lt-proforma-form {
  margin: 0;
}

/* 49. La ficha del paciente en el iPad (F1.3, E2): controles grandes para el dedo (la spec pide de 64 a 72 px y letra de 20 a 24 px; aquí, de 56 px y 20 px para arriba) y, al pie, el control del personal: un <details> pequeño y cerrado que el paciente no ve de entrada. */
.ficha-ipad {
  font-size: 1.25rem;
}

.ficha-ipad input:not([type="checkbox"]),
.ficha-ipad select {
  min-height: 3.5rem;
  font-size: 1.25rem;
}

.ficha-ipad .campo label,
.ficha-ipad .opcion label {
  font-size: 1.25rem;
}

.ficha-ipad .ayuda,
.ficha-ipad .error-campo {
  font-size: 1rem;
}

.ficha-ipad .opcion {
  min-height: 3.5rem;
}

.ficha-ipad input[type="checkbox"] {
  width: 1.75rem;
  height: 1.75rem;
}

.ficha-ipad input[type="checkbox"]::before {
  width: 0.9375rem;
  height: 0.5rem;
}

.ficha-ipad button {
  min-height: 3.5rem;
  font-size: 1.25rem;
}

.ficha-ipad .volver-personal {
  margin-top: 2rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--linea);
}

.ficha-ipad .volver-personal summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 0.875rem;
  color: var(--silenciado);
  cursor: pointer;
}

.ficha-ipad .volver-personal .volver-cuerpo {
  padding-top: 0.5rem;
  font-size: 1rem;
}

.ficha-ipad .volver-personal input:not([type="checkbox"]) {
  min-height: 3rem;
  font-size: 1rem;
}

.ficha-ipad .volver-personal button {
  min-height: 3rem;
  font-size: 1rem;
}

/* «Terminar» (E3): grande y a la vista, aparte del envío; y la pantalla neutra «Sesión terminada» que sustituye a todo cuando se limpia la pantalla (el atributo hidden la oculta hasta entonces). */
.ficha-ipad .ficha-terminar {
  margin-top: 1.5rem;
}

.ficha-ipad .terminar {
  min-height: 3.5rem;
  min-width: 12rem;
  font-size: 1.25rem;
}

.ficha-terminada {
  text-align: center;
  padding: 3rem 1.5rem;
}

.ficha-terminada .boton {
  min-height: 3.5rem;
  font-size: 1.25rem;
}

/* 50. Notas internas (F1.2, H4): una sección plegada con la lista de notas del paciente y su formulario, en el bloque de la «Cita del día» y en el perfil. Se apoya en las piezas de «Diagnóstico» (`.dx-lista`, `.dx-item`, `.dx-meta`, `.dx-mas`); aquí solo lo propio: el texto de la nota respeta sus saltos de línea y se parte donde haga falta, y el campo no se sale de la tarjeta. Sin estilos en línea. */
.nota-plegable {
  min-width: 0;
  border-top: 0;
}

.nota-texto {
  margin: 0.25rem 0 0.5rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.nota-form textarea {
  max-width: 100%;
}

.ficha-notas {
  min-width: 0;
}

/* 51. La historia clínica del personal (F1.2, H2): el índice de secciones, cada sección con lo escrito y su formulario, y el historial. Se apoya en las piezas de «Diagnóstico» (`.dx-lista`, `.dx-item`, `.dx-cabeza`, `.dx-meta`), en `.datos` y en `.tabla`; aquí solo lo propio. Sin estilos en línea. */
.hist {
  min-width: 0;
}

/* La marca «borrador pendiente de revisión»: a la vista, con su icono y su texto, mientras la definición no esté aprobada. */
.hist-marca {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0 0 1rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--aviso-linea);
  border-radius: var(--r-control);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
  overflow-wrap: anywhere;
}

.hist-marca svg {
  flex: 0 0 auto;
  width: 1.25rem;
  height: 1.25rem;
}

.hist-seccion a,
.hist-enlace a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

.hist-texto {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.hist-actual,
.hist-formulario {
  min-width: 0;
}

.hist-form textarea,
.hist-form select,
.hist-form input {
  max-width: 100%;
}

.hist-opciones .opcion,
.hist-opciones legend {
  min-width: 0;
}

/* La tabla de un campo: las celdas llevan su control y la tabla se desplaza a lo ancho en lo angosto. */
.hist-tabla th,
.hist-tabla td {
  padding: 0.375rem 0.5rem;
}

.hist-tabla th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 1;
  min-width: 5.5rem;
  background: var(--papel);
  color: var(--texto);
  font-size: var(--t-m);
  white-space: normal;
}

.hist-tabla td input {
  min-width: 7rem;
}

/* Las listas de las celdas llevan el texto entero de su opción («Con patología»): la tabla se desplaza dentro de su caja si no cabe. */
.hist-tabla td select {
  min-width: 9.5rem;
}

.hist-valores .tabla {
  margin: 0;
}

.hoy-enlace {
  margin: 0.25rem 0 0;
}

.hoy-enlace a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 52. La copia impresa de la historia clínica (F1.2, H3): hojas A4 en blanco y negro, con el patrón de la proforma (sección 48): la página con nombre `historia` (margen propio) y una hoja por página con `break-after`. El servidor reparte el contenido y dice «Hoja N de M»
 *     (`PantallasHistoriaHoja`), así que cada `hh-hoja` es una página. En pantalla se ven a su tamaño de papel (210 mm) dentro de un contenedor que se desplaza (un teléfono) o centradas (un monitor). La hoja es de papel aunque la pantalla esté en modo oscuro; el odontograma sale
 *     por la forma (rayado, rayado con borde de rayas, relleno) y no por el color. La franja de «Datos de prueba» de la página no se imprime: la marca va DENTRO de cada hoja. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

@page historia {
  size: A4;
  margin: 11mm 14mm 9mm;
}

.hoja-historia {
  min-width: 0;
  max-width: 100%;
  margin: 0 auto 1.5rem;
  padding: 0.75rem;
  overflow-x: auto;
  background: transparent;
  border: 0;
  line-height: 1.25;
}

.hh-hojas {
  display: grid;
  gap: 1rem;
  width: max-content;
  margin: 0 auto;
}

.hh-hoja {
  --odo-vacio: #ffffff;
  --odo-tratar: #000000;
  --odo-hecho: #000000;
  --odo-trazo: #000000;
  --texto: #000000;
  display: flex;
  flex-direction: column;
  gap: 2.5mm;
  box-sizing: border-box;
  width: 210mm;
  min-height: 297mm;
  padding: 11mm 14mm 9mm;
  background: #ffffff;
  color: #000000;
  font: 9.5pt/1.25 "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  text-align: left;
  box-shadow: 0 10px 34px -14px rgba(0, 0, 0, 0.45);
}

.hh-hoja * {
  box-sizing: border-box;
}

.hh-hoja .membrete {
  margin: 0;
  padding: 0 0 1.5mm;
  border-color: #000000;
}

.hh-hoja .membrete-logo {
  max-height: 12mm;
  filter: grayscale(1) contrast(1.15);
}

.hh-hoja .membrete-nombre {
  font-size: 12pt;
}

.hh-hoja .membrete-descriptor,
.hh-hoja .membrete-datos {
  margin: 0.4mm 0 0;
  color: #000000;
  font-size: 8pt;
}

.hh-titulo-fila,
.hh-cab {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 5mm;
}

.hh-cab {
  padding-bottom: 1.5mm;
  border-bottom: 0.4pt solid #000000;
}

.hh-titulo {
  margin: 0;
  font-size: 14pt;
  font-weight: 700;
}

.hh-corrida {
  margin: 0;
  font-size: 8.5pt;
  overflow-wrap: anywhere;
}

.hh-marcas {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: flex-end;
  gap: 1mm;
}

.hh-borrador,
.hh-prueba {
  margin: 0;
  padding: 0.4mm 1.6mm;
  border: 0.8pt solid #000000;
  font-size: 8pt;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.hh-borrador {
  border-style: dashed;
}

.hh-datos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.8mm 8mm;
  margin: 0;
}

.hh-datos div {
  display: flex;
  align-items: baseline;
  gap: 2mm;
  padding-bottom: 0.4mm;
  border-bottom: 0.4pt solid #000000;
}

.hh-datos dt {
  flex: none;
  font-size: 8pt;
}

.hh-datos dd {
  margin: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.hh-cuerpo {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 1.2mm;
  min-width: 0;
}

.hh-sec {
  margin: 2mm 0 1mm;
  padding-bottom: 0.5mm;
  border-bottom: 0.6pt solid #000000;
  color: #000000;
  font-size: 11pt;
  font-weight: 700;
}

.hh-dato,
.hh-meta,
.hh-menor,
.hh-vacio {
  margin: 0;
}

.hh-meta,
.hh-menor {
  font-size: 8pt;
}

.hh-vacio {
  font-style: italic;
}

.hh-texto {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.hh-lista {
  display: grid;
  gap: 0.6mm;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hh-fila {
  padding-bottom: 0.5mm;
  border-bottom: 0.3pt dotted #000000;
  overflow-wrap: anywhere;
  break-inside: avoid;
}

/* Las tablas de un campo no son las de datos del sistema: líneas finas negras, sin cabeceras pegajosas ni fondos. */
.hh-hoja .tabla {
  overflow: visible;
  margin: 0;
}

.hh-hoja th,
.hh-hoja td {
  position: static;
  padding: 0.3mm 1.6mm;
  border: 0.4pt solid #000000;
  background: transparent;
  color: #000000;
  font-size: 8.5pt;
  letter-spacing: normal;
  text-transform: none;
  white-space: normal;
}

.hh-hoja .hist-tabla {
  width: 100%;
  break-inside: avoid;
}

.hh-hoja .hist-tabla th[scope="row"] {
  min-width: 0;
  font-size: 8.5pt;
  font-weight: 400;
}

.hh-dato-tabla p {
  margin: 0 0 0.6mm;
}

.hh-hoja .hist-valores {
  margin: 0;
}

/* El odontograma: dos filas de dos cuadrantes (la cruz), sin marcos de pantalla; el color no cuenta, la forma sí. */
.hh-odo .odo-cruz {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5mm 5mm;
  margin: 0 0 1.5mm;
}

.hh-odo .odo-cuadrante {
  margin: 0;
  padding: 0.5mm 1mm;
  border: 0.4pt solid #000000;
  border-radius: 0;
  background: none;
}

.hh-odo .odo-cuadrante figcaption {
  margin: 0;
  color: #000000;
  font-size: 7pt;
}

.hh-odo .pieza-numero text {
  fill: #000000;
  font-size: 11px;
}

.hh-odo .cara-restauracion-realizado polygon {
  fill: #6b6b6b;
}

.hh-odo .odo-defs {
  position: absolute;
}

.hh-pie {
  margin-top: auto;
  padding-top: 1.2mm;
  border-top: 0.4pt solid #000000;
  font-size: 7.5pt;
}

.hh-pie p {
  display: flex;
  justify-content: space-between;
  gap: 4mm;
  margin: 0;
}

@media print {
  /* Lo único que sale es la hoja: la franja de la página (los demás documentos conservan la suya) y el borde del contenedor no se imprimen; cada hoja ocupa su página. */
  body:has(.hoja-historia) .banner-prueba {
    display: none;
  }

  /* El margen lo da la página con nombre: lo que envuelve a la hoja no suma el suyo. */
  body:has(.hoja-historia) {
    display: block;
    min-height: 0;
    padding: 0;
  }

  body:has(.hoja-historia) main,
  body:has(.hoja-historia) .panel {
    margin: 0;
    padding: 0;
  }

  .hoja-historia {
    page: historia;
    margin: 0;
    padding: 0;
    overflow: visible;
  }

  .hh-hojas {
    display: block;
    width: auto;
    margin: 0;
  }

  .hh-hoja {
    width: auto;
    min-height: 276mm;
    padding: 0;
    box-shadow: none;
    break-after: page;
  }

  .hh-hoja:last-child {
    break-after: auto;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * 53. «Fotos de hoy» (F1.2, M2): la pantalla de UNA columna del teléfono de la auxiliar. Se apoya en las piezas de siempre (`.hoja`, `.tarjeta`, `.horas` y `.hora` para la etiqueta, `.imagenes-rejilla` y `.imagenes-confirmar` para lo guardado y el segundo paso): aquí solo lo propio. Todo lo que se toca mide
 *     al menos 44 px y nada se desborda a 390 px; sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.fotos-hoy {
  min-width: 0;
  max-width: 32rem;
  margin-inline: auto;
}

.fotos-lista {
  display: grid;
  gap: 0.625rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.foto-cita {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 4.25rem;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--papel);
  color: inherit;
  text-decoration: none;
}

.foto-cita .foto-perfil-mini {
  flex: none;
  margin: 0;
}

.foto-cita .sello {
  flex: none;
}

@media (hover: hover) and (pointer: fine) {
  .foto-cita:hover {
    border-color: var(--borde);
  }
}

.foto-cita:focus-visible {
  outline: 2px solid var(--anillo);
  outline-offset: 2px;
}

.foto-texto {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  overflow-wrap: anywhere;
}

.foto-texto span {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.foto-iniciales {
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--linea);
  border-radius: 50%;
  background: var(--acento-suave);
  font-size: 0.875rem;
  font-weight: 700;
}

.foto-iniciales-grande {
  width: 4.5rem;
  height: 4.5rem;
  font-size: 1.25rem;
}

.foto-paciente {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-width: 0;
  margin: 0 0 1rem;
}

.foto-paciente .perfil-avatar {
  flex: none;
  width: 4.5rem;
  height: 4.5rem;
  margin: 0;
}

.foto-paciente-texto {
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
}

.foto-paciente-texto span {
  color: var(--silenciado);
  font-size: var(--t-s);
}

.foto-subida {
  min-width: 0;
  margin: 0 0 1rem;
}

.foto-subida h2 {
  margin: 0 0 0.5rem;
}

.foto-form .campo input[type="file"] {
  max-width: 100%;
}

/* ------------------------------------------------------------------------------------------------------------------
 * 54. Avisos en el teléfono (N5 de las notificaciones): la segunda sección de «Mis avisos». Se apoya en las piezas de siempre (`.hoja-seccion`, `.texto-legal-bloque`, `.texto-legal`, `.version`,
 *     `.opcion`, `.aviso`, `.sello`, `.acciones`): aquí solo lo propio. La lista de dispositivos (estado dicho con texto y con la forma del sello, no solo con color; el desactivado, con borde
 *     de rayas), los bloques de cada caso del dispositivo (todos ocultos de entrada: push.js deja a la vista el que corresponde), la región donde se dicen los resultados y la marca de
 *     «borrador» del permiso. Los controles de toque miden al menos 44 px (los botones ya miden 48) y nada se desborda a 390 px. Sin estilos en línea.
 * ------------------------------------------------------------------------------------------------------------------ */

.avisos-telefono {
  min-width: 0;
}

.avisos-telefono > h2 {
  margin: 0 0 0.5rem;
}

.avisos-telefono h3,
.avisos-telefono .push-caso > h2 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

.avisos-telefono .dispositivos-titulo {
  margin: 1.25rem 0 0.5rem;
  font-size: var(--t-m);
}

.dispositivos {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.dispositivo {
  display: grid;
  gap: 0.375rem;
  min-width: 0;
  padding: 0.875rem 1rem;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
  background: var(--papel);
}

.dispositivo-baja {
  border-style: dashed;
  border-color: var(--borde);
  background: transparent;
}

.dispositivo-nombre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
}

.dispositivo-este {
  display: inline-block;
  padding: 0 0.5rem;
  border: 1px solid var(--acento-linea);
  border-radius: 999px;
  color: var(--acento-tinta);
  font-size: var(--t-xs);
  font-weight: 700;
  line-height: 1.6;
}

.dispositivo-detalle {
  margin: 0;
  color: var(--silenciado);
  font-size: var(--t-s);
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.dispositivo form {
  margin: 0.25rem 0 0;
}

.push-mensaje {
  margin: 0 0 1rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.push-mensaje:empty {
  display: none;
}

.push-caso {
  margin: 0 0 1.25rem;
  min-width: 0;
}

.push-caso ol {
  display: grid;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
  padding-left: 1.5rem;
}

.push-caso p {
  overflow-wrap: anywhere;
}

.push-activar fieldset {
  margin: 0 0 1rem;
}

.push-activar .silenciado {
  margin: 0 0 0.75rem;
  font-size: var(--t-s);
}

.version-borrador {
  border-style: dashed;
  border-color: var(--aviso-linea);
  background: var(--aviso-fondo);
  color: var(--aviso-texto);
}

[data-push-activar][aria-disabled="true"] {
  opacity: 0.6;
  cursor: progress;
}

/* ------------------------------------------------------------------------------------------------------------------
 * Los avisos de Bodega en la barra (B4; spec del 6-nov-2026, regla 13)
 * ------------------------------------------------------------------------------------------------------------------ */

/*
 * La burbuja con el total de avisos del enlace «Bodega» (stock bajo, por vencer y vencidos). Blanco sobre el rojo de los errores, fijos
 * (no dependen del tema de la clínica): 6,6 a 1 de contraste. El número es decorativo (aria-hidden): quien usa un lector oye «, N avisos»
 * en el texto del enlace. En el teléfono el enlace es una columna con el icono sobre el nombre: la burbuja va sobre su esquina, fuera del
 * flujo, para no sumarle una fila (ni crecer más que los demás enlaces de la barra, que se desplaza a lo ancho si no cabe).
 */
.cabecera nav a .nav-aviso {
  position: absolute;
  top: 0.125rem;
  right: 0.125rem;
  box-sizing: border-box;
  min-width: 1.25rem;
  padding: 0 0.3125rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--c-rojo);
  color: #ffffff;
  font-size: var(--t-xs);
  font-weight: 700;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Desde 48rem el enlace es una fila (icono, nombre): la burbuja entra en ella, después del nombre. */
@media (min-width: 48rem) {
  .cabecera nav a .nav-aviso {
    position: static;
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * Bodega: las existencias y la hoja de un artículo (B5, 6-nov-2026; spec de Bodega, sección 5)
 * ------------------------------------------------------------------------------------------------------------------ */

/* Los dos botones grandes de registrar: uno debajo del otro en el teléfono (el pulgar los alcanza), lado a lado desde 40rem. */
.bodega-acciones {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
  margin: 1.25rem 0 0;
}

.bodega-acciones .boton {
  min-height: 3.5rem;
  font-size: 1.0625rem;
}

/* Los avisos de hoy: tres grupos, cada artículo una fila con su enlace (el objetivo mide 44 px) y su detalle al lado o debajo. */
.bodega-avisos {
  margin-top: 1.5rem;
}

.bodega-grupo {
  margin-top: 1rem;
}

.bodega-grupo h3 {
  margin: 0 0 0.5rem;
  font-size: var(--t-m);
}

.bodega-grupo ul {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--linea);
  border-radius: var(--r-control);
}

.bodega-grupo li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 0.75rem;
  padding: 0 1rem;
  border-bottom: 1px solid var(--linea);
  overflow-wrap: anywhere;
}

.bodega-grupo li:last-child {
  border-bottom: 0;
}

.bodega-grupo li a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 650;
}

.bodega-grupo li .silenciado {
  font-size: var(--t-s);
}

/* El filtro de la lista: separado de la tabla, con sus botones a la altura de un dedo. */
.bodega-filtro {
  margin: 0 0 1.25rem;
}

.bodega-filtro .acciones {
  margin-top: 0.5rem;
}

.apilada .lista-cabeza + .bodega-filtro {
  margin-top: 1rem;
}

/* Desde 40rem, los dos botones de registrar van lado a lado (el filtro ya pone sus campos en dos columnas con `.campos-alta`). */
@media (min-width: 40rem) {
  .bodega-acciones {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------------------------------------------------------------
 * Bodega: los formularios de entrada y de salida (B6, 6-nov-2026)
 * ------------------------------------------------------------------------------------------------------------------ */

/* Cada grupo de campos (fieldset) separado del siguiente; su título es la leyenda. */
.bodega-bloque {
  margin: 0 0 1.5rem;
}

.bodega-bloque > legend {
  margin-bottom: 0.75rem;
  font-size: var(--t-m);
  font-weight: 650;
}

/* El resumen del artículo elegido: lo disponible en grande y lo vencido al lado, sin tocar las tarjetas de los lotes. */
.bodega-resumen {
  margin: 0.75rem 0 1rem;
  overflow-wrap: anywhere;
}

/* «Registrar otra»: un enlace en su propia línea, del alto de un dedo, dentro del aviso de éxito. */
.aviso-ok .bodega-otra {
  display: flex;
  align-items: center;
  width: fit-content;
  min-height: 2.75rem;
  color: inherit;
  font-weight: 700;
  text-decoration-color: currentColor;
}

/* ------------------------------------------------------------------------------------------------------------------
 * Bodega: el informe y su hoja para imprimir (B7, 7-nov-2026)
 * ------------------------------------------------------------------------------------------------------------------ */

/* El enlace al informe, debajo de los botones de registrar (o solo, para quien no registra). */
.bodega-informe {
  margin: 0.75rem 0 0;
}

.bodega-subtitulo {
  margin: 1rem 0 0.25rem;
  font-size: var(--t-m);
}

/* La hoja del informe: A4 en blanco y negro con la página con nombre `bodega` (el patrón de la proforma y la historia). Las tablas no se vuelven tarjetas: en el teléfono la hoja se desplaza a lo ancho dentro de su región.
   La hoja es de papel aunque la pantalla esté en modo oscuro: negro sobre blanco. */
@page bodega {
  size: A4;
  margin: 11mm 14mm 9mm;
}

.hoja-bodega {
  box-sizing: border-box;
  min-width: 0;
  max-width: min(100%, 210mm);
  margin: 0 auto 1.5rem;
  padding: 1rem;
  border-color: #000000;
  background: #ffffff;
  color: #000000;
  font: 9.5pt/1.3 "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  text-align: left;
}

.hoja-bodega .membrete {
  margin: 0 0 2mm;
  padding: 0 0 1.5mm;
  border-color: #000000;
}

.hoja-bodega .membrete-logo {
  max-height: 12mm;
  filter: grayscale(1) contrast(1.15);
}

.hoja-bodega .membrete-nombre {
  font-size: 12pt;
}

.hoja-bodega .membrete-descriptor,
.hoja-bodega .membrete-datos {
  margin: 0.4mm 0 0;
  color: #000000;
  font-size: 0.75rem;
}

.bi-titulo-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1mm 5mm;
}

.bi-titulo {
  margin: 0;
  font-size: 14pt;
  font-weight: 700;
}

/* En blanco y negro: los títulos de la página traen su propio color de tinta. */
.hoja-bodega h1,
.hoja-bodega h2,
.hoja-bodega h3 {
  color: #000000;
}

.bi-prueba {
  margin: 0;
  padding: 0.3mm 2mm;
  border: 0.5pt solid #000000;
  font-size: 0.75rem;
  font-weight: 700;
}

.bi-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1mm 5mm;
  margin: 2mm 0 3mm;
  padding: 0 0 2mm;
  border-bottom: 0.4pt solid #000000;
}

.bi-datos dt {
  font-weight: 700;
}

.bi-datos dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.bi-seccion {
  margin: 4mm 0 0;
}

.bi-seccion h2 {
  margin: 0 0 1.5mm;
  font-size: 11pt;
  break-after: avoid;
}

.bi-seccion .lista-vacia {
  margin: 0;
  color: #000000;
}

.bi-scroll {
  overflow-x: auto;
}

.bi-tabla {
  width: 100%;
  min-width: 44rem;
  border-collapse: collapse;
  font-size: 0.75rem;
}

.bi-tabla th,
.bi-tabla td {
  padding: 0.8mm 1.5mm;
  border: 0.4pt solid #000000;
  text-align: left;
  vertical-align: top;
  overflow-wrap: normal;
}

.bi-tabla thead th {
  border-bottom: 0.9pt solid #000000;
  font-weight: 700;
}

.bi-tabla thead {
  display: table-header-group;
}

.bi-tabla tr {
  break-inside: avoid;
}

.bi-pie {
  margin: 5mm 0 0;
  padding: 1.5mm 0 0;
  border-top: 0.4pt solid #000000;
  font-size: 0.75rem;
}

.bi-pie p {
  margin: 0;
}

@media print {
  /* Lo único que sale es la hoja: la franja de «Datos de prueba» de la página no se imprime (la hoja lleva la suya) y el margen lo da la página con nombre. */
  body:has(.hoja-bodega) .banner-prueba {
    display: none;
  }

  body:has(.hoja-bodega) {
    display: block;
    min-height: 0;
    padding: 0;
  }

  body:has(.hoja-bodega) main,
  body:has(.hoja-bodega) .panel {
    margin: 0;
    padding: 0;
  }

  .hoja-bodega {
    page: bodega;
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
  }

  .bi-scroll {
    overflow: visible;
  }

  .bi-tabla {
    min-width: 0;
  }

  .bi-tabla th,
  .bi-tabla td {
    overflow-wrap: anywhere;
  }

  /* En papel, los tamaños de imprenta (en la pantalla, nunca menos de 12 px). */
  .hoja-bodega .membrete-descriptor,
  .hoja-bodega .membrete-datos,
  .bi-prueba,
  .bi-pie {
    font-size: 8pt;
  }

  .bi-tabla {
    font-size: 8.5pt;
  }
}
