/*
 * Capa base y componentes del sistema visual de EPA 360.
 *
 * NO HAY UN SOLO VALOR LITERAL DE COLOR, TAMAÑO DE LETRA NI RADIO EN ESTE
 * ARCHIVO: todo sale de `tokens.css` con `var(--…)`, y
 * `test/integration/sistema_visual_test.rb` lo verifica. Un color nuevo se
 * agrega en `DESIGN.md`, se espeja en `tokens.css` y recién entonces se usa acá.
 *
 * Propshaft sirve el CSS tal cual: no hay compilador, no hay `@import` (no los
 * reescribe con digest) y no hay framework de terceros. `tokens.css` se enlaza
 * por separado desde el layout, ANTES que esta hoja.
 *
 * Solo están implantadas las piezas que hoy tienen una pantalla detrás:
 * `tarjeta`, `campo`, `campo-error`, `boton-primario`, `boton-fantasma`, `aviso`
 * y `navegacion-operacion`. El resto del catálogo de `DESIGN.md` —`pill-estado`,
 * `tabla`, `hoja-modal`, `stepper`, `tilde`, `casillero-codigo`,
 * `cabecera-modulo`— queda en tokens disponibles y sin clase propia hasta que
 * exista la pantalla que lo use.
 */

/* ==========================================================================
   Tipografía servida desde el propio origen
   ========================================================================== */

/*
 * Quicksand es la familia exclusiva del manual de marca (§1.3), en los dos pesos
 * que la rampa usa. Se sirve desde `app/assets/fonts/` y no desde un tercero:
 * el disco del servidor es descartable y una fuente pedida a otro origen es una
 * dependencia de terceros en tiempo de ejecución, en el camino crítico de cada
 * pantalla. Son los subconjuntos `latin` de la versión SIL OFL, que cubren las
 * acentuadas y los signos de apertura del español.
 *
 * `font-display: swap` porque el texto tiene que ser legible antes de que la
 * fuente llegue: la pila de reserva de `body` es la que se ve mientras tanto.
 */
@font-face {
  font-family: "Quicksand";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/quicksand-500-ae3df5cd.woff2") format("woff2");
}

@font-face {
  font-family: "Quicksand";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/quicksand-700-853cb26c.woff2") format("woff2");
}

/* ==========================================================================
   Capa base
   ========================================================================== */

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

html {
  /* El zoom al 200% es condición de trabajo, no caso de laboratorio: el ajuste
     automático de tamaño de iOS al rotar pelea con eso. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--color-fondo);
  color: var(--color-tinta);
  font-family: var(--tipo-cuerpo-familia), "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

/* La rampa de encabezados es la del nivel semántico, no la del tamaño que
   quede bien: `h1` es el título de la pantalla y hay uno solo. */
h1 {
  margin: 0 0 var(--espacio-4);
  font-size: var(--tipo-titulo-tamano);
  font-weight: var(--tipo-titulo-peso);
  line-height: var(--tipo-titulo-interlinea);
  letter-spacing: var(--tipo-titulo-espaciado);
}

h2 {
  margin: 0 0 var(--espacio-3);
  font-size: var(--tipo-titulo-sm-tamano);
  font-weight: var(--tipo-titulo-sm-peso);
  line-height: var(--tipo-titulo-sm-interlinea);
}

h3 {
  margin: 0 0 var(--espacio-2);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-seccion-interlinea);
}

p {
  margin: 0 0 var(--espacio-3);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--color-naranja-oscuro);
}

/* Los controles no heredan la tipografía del documento por su cuenta. */
input,
button,
select,
textarea {
  font: inherit;
  color: inherit;
}

/* ==========================================================================
   Foco — pieza heredada, nunca suprimida
   ========================================================================== */

/*
 * `foco` no es un atributo de `campo`: TODO elemento interactivo lo hereda, y
 * por eso la regla es universal y no una lista de selectores que alguien tenga
 * que acordarse de ampliar. 2px de trazo en `naranja-oscuro` con 2px de
 * separación, que mide 4.97 / 4.45 / 3.89 sobre las tres superficies del
 * sistema.
 *
 * En esta hoja no hay —ni puede haber— una supresión del anillo: la suite busca
 * `outline` puesto en nada y falla si aparece.
 */
:focus-visible {
  outline: 2px solid var(--color-naranja-oscuro);
  outline-offset: 2px;
}

/*
 * Sobre relleno oscuro el anillo se invierte a blanco: un anillo naranja sobre
 * relleno naranja mediría 1.62:1. La separación se vuelve negativa para que el
 * trazo caiga adentro del relleno, que es la única superficie contra la que el
 * blanco contrasta acá.
 */
.boton-primario:focus-visible {
  outline-color: var(--color-blanco);
  outline-offset: calc(-1 * var(--espacio-0-5));
}

/* ==========================================================================
   Piso táctil
   ========================================================================== */

/*
 * 44px de alto mínimo en todo lo que se toca, sin excepción por rango de botón.
 * Va como regla de la capa base y no componente por componente para que un
 * control nuevo nazca cumpliéndolo.
 */
a[href],
button,
summary,
select,
textarea,
input:not([type="hidden"]) {
  min-height: var(--espacio-toque-minimo);
}

/* ==========================================================================
   Movimiento reducido
   ========================================================================== */

/*
 * La superficie es casi nula —la espina prohíbe parpadeos— pero la regla se
 * declara igual, así que la primera animación que alguien agregue ya nace
 * respetándola. `none` y no una duración diminuta: lo que se pide es que no
 * quede ninguna animación ni transición corriendo, no que corran rápido.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Disposición
   ========================================================================== */

.contenedor {
  width: 100%;
  /* El tope de medida de lectura. No es un token del sistema visual: es una
     decisión de disposición de esta cáscara. */
  max-width: 960px;
  margin-inline: auto;
  padding-inline: var(--espacio-margen-telefono);
}

@media (min-width: 48em) {
  .contenedor {
    padding-inline: var(--espacio-margen-escritorio);
  }
}

/* El salto al contenido es el primer elemento enfocable del documento. Se
   esconde fuera de la pantalla en vez de encogerse a 1px: un control de 1px de
   alto no cumpliría el piso táctil cuando aparece. Un desplazamiento negativo
   no agranda el ancho del documento, así que no rompe el reflow a 320px. */
.salto-al-contenido {
  position: absolute;
  left: -9999px;
  top: var(--espacio-2);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  padding-inline: var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  text-decoration: none;
}

.salto-al-contenido:focus {
  left: var(--espacio-4);
}

/* Texto solo para el lector de pantalla: está en el documento pero no ocupa
   lugar ni se ve. Sirve cuando lo que se ve es un signo que no se lee bien en
   voz alta y la palabra tiene que llegar igual. Recortado a nada y no
   desplazado, así que tampoco puede agrandar el ancho del documento. No es para
   controles enfocables: esos usan el patrón del salto al contenido. */
.texto-para-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- cabecera-cascara ----------------------------------------------------
   LA MISMA CABECERA PARA LAS DOS CÁSCARAS. Se llamaba `cabecera-operacion`
   hasta la Historia 3.3, que le dio puerta al portal: desde entonces lo único
   que cambia entre una y otra es la marca que dice y a dónde apunta su salida,
   las dos decididas por el controlador. Dejarle el nombre viejo la volvería una
   clase que miente, y duplicarla en `cabecera-portal` dejaría dos bloques que se
   desincronizan al primer retoque.

   `navegacion-operacion` y `disposicion-operacion` NO se renombran: esas sí son
   de Operación —el portal tiene la suya desde la Historia 6.1,
   `barra-navegacion-cliente`—. */
.cabecera-cascara {
  background-color: var(--color-superficie);
  border-bottom: 1px solid var(--color-linea);
}

.cabecera-cascara__interior {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--espacio-2);
  padding-block: var(--espacio-2);
}

/* OPERACIÓN SIGUE EN TEXTO Y EL PORTAL YA NO. Hasta el `[2026-09-26]` las dos
   cáscaras se nombraban con letras porque en el repositorio no había un
   vectorial de la marca; desde entonces está `epa-signo.svg`, armado con los
   trazos del isologotipo del manual, y el portal lo usa. Operación conserva su
   frase por decisión del dueño del producto: tiene las dos cáscaras abiertas y
   esa palabra es lo único que le dice en cuál está parado. */
/* EL LOGOTIPO EN LA CABECERA DEL PORTAL `[2026-09-26]`. Alto fijo y ancho
   automático: el signo conserva su proporción, que es lo que el manual pide
   (§1.6, no se alteran proporciones ni espaciado). Se mide en `em` para que
   acompañe al tamaño de la marca en vez de quedar atado a un pixelaje. */
.cabecera-cascara__logotipo {
  display: block;
  width: auto;
  /* Más alto que el logotipo solo: el recuadro del signo incluye el aire que
     compensa el descendente de la «p», así que la tinta ocupa menos de lo que
     mide. */
  height: 2.1em;
}

/* EL SIGNO, CENTRADO EN LA CABECERA `[2026-09-26]`. `position: absolute` con
   los dos bordes en 0 y `margin-inline: auto` lo centra respecto de la
   CABECERA ENTERA y no del espacio que sobra: si se centrara en el sobrante,
   el menú de la izquierda lo correría hacia la derecha, y el signo dejaría de
   estar en el medio de la pantalla.

   `align-self: flex-start` y el `min-height` del disparador lo mantienen
   sobre la misma línea que el ícono cuando el menú se abre y la cabecera
   crece. Y `pointer-events: none` para que, estando por encima, no se coma
   ningún toque destinado al menú. */
.cabecera-cascara__marca {
  position: absolute;
  inset-inline: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  min-height: var(--espacio-toque-fisico);
  margin: 0;
  margin-inline: auto;
  width: fit-content;
  color: var(--color-tinta);
  font-size: var(--tipo-titulo-sm-tamano);
  font-weight: var(--tipo-titulo-sm-peso);
  line-height: var(--tipo-titulo-sm-interlinea);
  pointer-events: none;
}

/* EL SIGNO EN LA PUERTA DEL PORTAL `[2026-09-28]`. La misma imagen que la
   cabecera, en la única pantalla del portal que no tiene cabecera —sin sesión
   no hay cáscara—, así que la clase es propia y no una variante de aquélla: no
   comparten ni el tamaño ni el centrado, y atarlas dejaría dos pantallas que se
   mueven juntas sin motivo.

   Centrado con `margin-inline: auto` y no con `position: absolute` como en la
   cabecera: acá no hay nada al costado que lo corra, así que el sobrante ES el
   centro y no hace falta salirse del flujo.

   Alto fijo y ancho automático, igual que en la cabecera: el signo conserva su
   proporción, que es lo que pide el manual (§1.6). */
.signo-de-ingreso {
  display: block;
  width: auto;
  height: 4rem;
  margin-inline: auto;
  margin-block-end: var(--espacio-6);
}


.disposicion-operacion {
  display: grid;
  gap: var(--espacio-6);
  padding-block: var(--espacio-6);
  align-items: start;
}

/* Lateral en escritorio, apilada en teléfono. */
@media (min-width: 48em) {
  .disposicion-operacion {
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  }
}

.contenido-principal {
  min-width: 0;
}

/* Sin sesión no hay cáscara: la pantalla de ingreso se sirve con el mismo
   contenedor y nada más. */
.contenido-principal:only-child {
  padding-block: var(--espacio-6);
}

/* ==========================================================================
   Componentes
   ========================================================================== */

/* --- aviso ---------------------------------------------------------------
   El único mensaje no bloqueante del sistema. No se apila: el segundo
   reemplaza al primero, y por eso la región es una sola y vive en el layout. */
.aviso {
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-tinta);
  color: var(--color-blanco);
  border-radius: var(--radio-md);
  box-shadow: var(--sombra-flotante);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- tarjeta -------------------------------------------------------------
   Blanco sobre el fondo, borde de línea, sin sombra. */
.tarjeta {
  padding: var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-lg);
}

/* --- campo ---------------------------------------------------------------
   Etiqueta visible siempre; el placeholder no es etiqueta. El error aparece
   junto al campo, nunca como resumen al principio de la pantalla. */
.campo {
  display: block;
  margin-bottom: var(--espacio-4);
}

/* En el rol `cuerpo` y no en `etiqueta`: §Typography asigna la etiqueta de campo
   a `cuerpo`, y 12px queda acotado a `banda-temporal` y a la cabecera de
   `tabla`. La lista de prohibiciones veta tipografía bajo 13px fuera de
   `pill-estado`, y una etiqueta de campo se lee tanto como el valor que rotula. */
.campo__etiqueta {
  display: block;
  margin-bottom: var(--espacio-1);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

.campo__control {
  display: block;
  width: 100%;
  padding: var(--espacio-3);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

.campo__control[aria-invalid="true"] {
  border-color: var(--color-vencido);
}

/* --- campo-error ---------------------------------------------------------
   El mensaje debajo de los campos que lo causaron, con su palabra y no solo
   con el borde rojo: el color acompaña, nunca informa solo. 8px de aire arriba,
   como `campo__consejo`: pegado al control, el anillo de foco le rayaba la
   primera línea. */
.campo-error {
  margin: var(--espacio-2) 0 var(--espacio-4);
  color: var(--color-vencido);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- boton-primario ------------------------------------------------------
   Uno solo por pantalla: la acción que la pantalla existe para hacer. Relleno
   `naranja-oscuro` —no el institucional— porque es el que llega a 4.5:1 con
   texto blanco. */
.boton-primario {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: var(--espacio-5);
  background-color: var(--color-naranja-oscuro);
  border: 1px solid var(--color-naranja-oscuro);
  border-radius: var(--radio-md);
  color: var(--color-blanco);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  line-height: var(--tipo-boton-interlinea);
  cursor: pointer;
}

/* --- boton-fantasma ------------------------------------------------------
   Salidas y descartes. Nunca naranja: irse no es la acción que EPA promueve. */
.boton-fantasma {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: var(--espacio-3);
  background-color: transparent;
  border: none;
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  line-height: var(--tipo-boton-interlinea);
  cursor: pointer;
  transition: background-color 120ms ease-in-out;
}

/* Un realce, no una afordancia: el control ya se ve y se lee sin pasar el
   puntero por encima. Con `prefers-reduced-motion` el cambio sigue estando y lo
   único que desaparece es el tiempo que tarda. */
.boton-fantasma:hover {
  background-color: var(--color-superficie-crema);
}

.boton-fantasma__forma {
  display: inline;
  margin: 0;
}

/* --- boton-secundario ----------------------------------------------------
   EL SEGUNDO RANGO QUE NO ES UNA SALIDA. Hasta la Historia 3.3 el sistema tenía
   el primario —la acción que la pantalla existe para hacer— y el fantasma, que
   es para irse o descartar. «No me acuerdo la contraseña» no es ninguna de las
   dos: es un camino principal de verdad —con cuatro visitas al año es
   probablemente la vía de ingreso más usada— que no puede competir con Ingresar
   en la misma tarjeta.

   Contorno y no relleno, y NUNCA naranja: el naranja es del primario, y dos
   rellenos naranjas en la misma pantalla es no tener jerarquía. Ancho completo y
   debajo del primario, que es lo que lo hace un botón y no letra chica al pie
   (UX-DR, FR-009).

   Se usa sobre un `a`, así que se declaran también las propiedades que un enlace
   trae de fábrica y un `button` no: el subrayado y el color heredado. */
.boton-secundario {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding-inline: var(--espacio-5);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  line-height: var(--tipo-boton-interlinea);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease-in-out;
}

/* Un realce, no una afordancia: el contorno ya dice que es un control. Con
   `prefers-reduced-motion` el cambio sigue estando y lo único que desaparece es
   el tiempo que tarda. */
.boton-secundario:hover {
  background-color: var(--color-superficie-crema);
}

/* --- acciones-apiladas ---------------------------------------------------
   Los dos controles del ingreso del portal, uno debajo del otro y del mismo
   ancho: es lo que hace que «No me acuerdo la contraseña» se lea como un camino
   y no como una nota al pie. `grid` y no `flex` porque el estiramiento al ancho
   de la columna es el de fábrica, así que el primario no necesita una variante
   propia para acompañar al secundario. */
.acciones-apiladas {
  display: grid;
  gap: var(--espacio-3);
}

/* `[2026-11-04]` Después de la salida escrita o de la fila de un documento, los
   botones quedaban pegados: ninguno de los dos bloques deja margen abajo. Se
   mide en capturas de Mi perfil y Mis documentos. */
.portal-salida + .acciones-apiladas,
.documento + .acciones-apiladas,
.perfil-bloque + .acciones-apiladas {
  margin-top: var(--espacio-5);
}

/* --- navegacion-operacion ------------------------------------------------
   Solo se muestra una sección cuando tiene contenido detrás: hoy es únicamente
   Inicio. La lista vive en `app/views/layouts/_navegacion.html.erb`. */
.navegacion-operacion {
  min-width: 0;
}

.navegacion-operacion__hoja {
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
}

/* `list-item` y no `flex`: en `flex` el navegador se queda sin el triangulito
   de apertura, y la hoja pasaría a leerse como un rótulo en vez de como algo
   que se abre. La afordancia no puede depender de pasar el puntero. */
.navegacion-operacion__disparador {
  display: list-item;
  list-style-position: inside;
  padding-block: var(--espacio-3);
  padding-inline: var(--espacio-3);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  cursor: pointer;
}

.navegacion-operacion__lista {
  margin: 0;
  padding: var(--espacio-2);
  list-style: none;
}

.navegacion-operacion__enlace {
  display: flex;
  align-items: center;
  padding-inline: var(--espacio-3);
  border-radius: var(--radio-sm);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  text-decoration: none;
  transition: background-color 120ms ease-in-out;
}

.navegacion-operacion__enlace:hover {
  background-color: var(--color-superficie-crema);
}

/* La sección activa se marca con fondo Y texto, no solo con color: el color
   acompaña y nunca identifica solo (NFR-16). */
.navegacion-operacion__enlace[aria-current="page"] {
  background-color: var(--color-naranja-tenue);
  color: var(--color-naranja-activo);
  font-weight: var(--tipo-seccion-peso);
}

/*
 * En escritorio la hoja queda abierta y su disparador desaparece: la navegación
 * es lateral y permanente. `::details-content` es lo que permite abrirla desde
 * CSS; donde el navegador todavía no lo entiende, la regla del disparador no se
 * aplica —está encerrada en el `@supports`— y la navegación sigue funcionando
 * como hoja desplegable, que es degradación y no rotura.
 */
@media (min-width: 48em) {
  .navegacion-operacion__hoja::details-content {
    content-visibility: visible;
    block-size: auto;
  }

  @supports selector(::details-content) {
    .navegacion-operacion__disparador {
      display: none;
    }
  }
}

/* --- fila-lista ----------------------------------------------------------
   La fila de una lista de datos, del catálogo de `DESIGN.md`
   (`components.fila-lista`). Se implanta recién ahora porque recién ahora hay
   una pantalla detrás: la lista de trabajos programados de Inicio.

   `min-height` en el piso táctil y no en un valor de lectura: la fila es la
   unidad que se toca en teléfono.

   Rejilla y no `flex` con `space-between`: en `flex` cada celda mide lo que mide
   su contenido, así que los rótulos del encabezado no caen sobre las celdas de
   abajo —y la desviación es peor justo cuando una fila dice "Nunca" en vez de una
   fecha—. Con tres pistas proporcionales, todas las filas usan la misma
   definición y las columnas quedan alineadas.

   Las pistas son `minmax(0, …fr)` y no anchos fijos: a 320px se encogen y el
   texto envuelve, sin desbordar a lo ancho. */
.fila-lista {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  /* Las celdas se encogen a su contenido dentro de su pista; sin esto el pill
     —que como ítem de rejilla se estira— pintaría su fondo de columna a
     columna. Las pistas no se mueven, así que las columnas siguen alineadas. */
  justify-items: start;
  gap: var(--espacio-3);
  min-height: var(--espacio-toque-minimo);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border-bottom: 1px solid var(--color-linea);
}

/* Los rótulos de columna. Es la banda de encabezado de `components.lista-accion`
   —`{typography.etiqueta}`—, aplicada como modificador de la fila y no como un
   componente nuevo: son las mismas tres columnas y la misma caja. */
.fila-lista--encabezado {
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* --- pill-estado ---------------------------------------------------------
   La píldora de estado, del catálogo de `DESIGN.md` (`components.pill-estado`).
   El único lugar del sistema donde la tipografía baja de 12px: 11px es su rol
   `pill` y de nadie más. Los 12px de `etiqueta` sí se usan en otro lado —la banda
   de rótulos de `fila-lista`, acá arriba—, que es para lo que existe ese rol.

   Se implantan las dos variantes que hoy tienen caso —`ok` y `atencion`—; las
   otras cuatro de la paleta entran cuando exista la pantalla que las use, no
   antes.

   La píldora NUNCA va sola: adentro va la palabra del estado. El color
   acompaña y nunca identifica solo (NFR-16). */
.pill-estado {
  display: inline-block;
  padding: var(--espacio-0-5) var(--espacio-2);
  border-radius: var(--radio-sm);
  font-family: var(--tipo-pill-familia);
  font-size: var(--tipo-pill-tamano);
  font-weight: var(--tipo-pill-peso);
  line-height: var(--tipo-pill-interlinea);
}

.pill-estado--ok {
  background-color: var(--color-ok-fondo);
  color: var(--color-ok);
}

.pill-estado--atencion {
  background-color: var(--color-atencion-fondo);
  color: var(--color-atencion);
}

/* --- la lista de trabajos de Inicio --------------------------------------
   Disposición y nada más: ni un color, ni un tamaño, ni un radio. Es el
   contenedor que agrupa las `fila-lista` y despoja la lista de sus viñetas y su
   sangría de fábrica. */
.seccion-trabajos {
  margin-top: var(--espacio-6);
}

.lista-trabajos {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --- lista-accion y banda-temporal (Historia 11.4) ------------------------
   La home del Admin, del catálogo de `DESIGN.md` (`components.lista-accion`,
   `components.banda-temporal`): cuatro bandas separadas por `{spacing.6}`, sin
   fondo propio. El rótulo de cada banda es un `h2` real —los puntos de salto
   de la pantalla— dibujado en el rol `etiqueta` y en `tinta-suave`, que es lo
   que la espina le asigna. */
.lista-accion {
  display: grid;
  gap: var(--espacio-6);
  margin-top: var(--espacio-6);
}

.banda-temporal__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* «nada por ahora»: una banda vacía es información, no un error. Se lee a
   13px, el piso de lectura, y no en el rol de la etiqueta. */
.banda-temporal__vacia {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.banda-temporal__filas,
.fila-lista__apiladas {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --- fila-lista--accion ---------------------------------------------------
   UN MODIFICADOR y no un cambio de `.fila-lista`: la base está cableada a las
   tres pistas de la lista de trabajos. La fila de acción es de UNA pista, con
   el texto y, a su lado, la palabra de la acción.

   FILA SIMPLE: la fila ES el `<a>` —tocar cualquier punto abre la validación—,
   así que hereda el piso táctil de `a[href]` y el anillo de `:focus-visible`
   sin declarar nada. Se le quita el subrayado y el color de enlace: lo que
   dice que es una acción es la palabra en naranja oscuro, no el texto entero
   subrayado.

   A 320px un nombre de sede o una ubicación larga se parten: nunca piden
   scroll horizontal. */
.fila-lista--accion {
  grid-template-columns: minmax(0, 1fr);
  color: var(--color-tinta);
  text-decoration: none;
  overflow-wrap: anywhere;
}

a.fila-lista--accion:hover,
.fila-lista__entrada:hover {
  background-color: var(--color-superficie-crema);
}

/* FILA COLAPSADA: la sede con la cantidad arriba —`titulo-sm`, el rol que la
   espina le da al nombre de cliente en fila colapsada— y cada entrada apilada
   debajo, cada una su propio enlace de ancho completo. */
.fila-lista--colapsada {
  justify-items: stretch;
  gap: var(--espacio-2);
}

.fila-lista__sede {
  margin: 0;
  font-size: var(--tipo-titulo-sm-tamano);
  font-weight: var(--tipo-titulo-sm-peso);
  line-height: var(--tipo-titulo-sm-interlinea);
}

.fila-lista__apiladas {
  display: grid;
  gap: var(--espacio-1);
}

.fila-lista__entrada {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: var(--espacio-1);
  padding: var(--espacio-2) 0;
  color: var(--color-tinta);
  text-decoration: none;
  border-top: 1px solid var(--color-linea);
}

/* La palabra de la acción, en `naranja-oscuro`: el naranja significa acción y
   nada más. Debajo del texto en teléfono; a su lado en escritorio. */
.fila-lista__accion {
  color: var(--color-naranja-oscuro);
  font-weight: var(--tipo-boton-peso);
}

@media (min-width: 48em) {
  .fila-lista--accion,
  .fila-lista__entrada {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .fila-lista--colapsada {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- estado general (Historia 11.4) ---------------------------------------
   EL MISMO BLOQUE EN DOS TAMAÑOS. Compacto debajo de la lista cuando hay algo
   pendiente; grande, arriba de las bandas, cuando no hay nada: el día sin
   nada es el día normal, y el bloque crece para ocupar el lugar de la lista.

   Cada cifra lleva su palabra al lado. En teléfono, una cifra por renglón; con
   lugar, dos columnas. Las pistas son `minmax(0, 1fr)`: a 320px nada pide
   scroll horizontal. */
.estado-general {
  margin-top: var(--espacio-6);
  overflow-wrap: anywhere;
}

.estado-general__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

.estado-general__cifras {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 30em) {
  .estado-general__cifras {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.estado-general__cifra {
  min-width: 0;
  padding: var(--espacio-3);
  background-color: var(--color-superficie-alta);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-sm);
}

.estado-general__numero {
  display: block;
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

.estado-general__rotulo {
  display: block;
}

.estado-general__detalle {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Grande: el bloque ocupa el lugar de la lista. La cifra sube al rol
   `titulo` y cada una gana aire. */
.estado-general--grande .estado-general__cifra {
  padding: var(--espacio-5);
}

.estado-general--grande .estado-general__numero {
  font-size: var(--tipo-titulo-tamano);
  font-weight: var(--tipo-titulo-peso);
  line-height: var(--tipo-titulo-interlinea);
  letter-spacing: var(--tipo-titulo-espaciado);
}

/* --- pill-estado, dos variantes más ---------------------------------------
   Entran ahora porque ahora tienen pantalla detrás: `neutro` para el insumo
   dado de baja —la baja es lógica, así que la fila sigue estando y su estado
   no es una alarma— y `porvencer` para el umbral desactualizado, que es una
   decisión pendiente y no un error.

   Igual que las otras dos: la píldora NUNCA va sola, adentro va la palabra del
   estado. El color acompaña y nunca identifica solo (NFR-16). */
.pill-estado--neutro {
  background-color: var(--color-neutro-fondo);
  color: var(--color-neutro);
}

.pill-estado--porvencer {
  background-color: var(--color-porvencer-fondo);
  color: var(--color-porvencer);
}

/* --- cabecera-modulo -----------------------------------------------------
   La cabecera de un módulo de intervención, del catálogo de `DESIGN.md`
   (`components.cabecera-modulo`). Se implanta recién ahora porque recién ahora
   hay una pantalla que agrupe por módulo.

   EL COLOR VIVE SOLO EN LA BARRA IZQUIERDA. El texto va en `tinta` sobre
   `superficie-crema` (13.6:1) y nunca encima del color: dos de los cinco
   módulos son indistinguibles en luminancia y para daltonismo, así que el
   número y el nombre son el mecanismo real de discriminación (UX-DR6, NFR-16).

   3px no es un token: es una medida de disposición, del mismo orden que el
   trazo de 1px de los bordes y los 2px del anillo de foco, y vive en la hoja
   que la usa.

   Tipografía `cuerpo-sm` y no la de `h2`: la mitigación de NFR-16 solo mitiga
   si se lee, y `DESIGN.md` la fija en el piso de lectura y no más abajo. */
.cabecera-modulo {
  margin: var(--espacio-5) 0 var(--espacio-2);
  padding: var(--espacio-2) var(--espacio-3);
  background-color: var(--color-superficie-crema);
  border-left: 3px solid var(--color-tinta);
  border-radius: var(--radio-sm);
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La primera cabecera no se despega de la banda de rótulos: el margen de arriba
   separa un módulo del anterior, y arriba del primero no hay ninguno. */
.lista-catalogo > li:nth-child(2) .cabecera-modulo {
  margin-top: 0;
}

.cabecera-modulo--0 { border-left-color: var(--color-modulo-0); }
.cabecera-modulo--1 { border-left-color: var(--color-modulo-1); }
.cabecera-modulo--2 { border-left-color: var(--color-modulo-2); }
.cabecera-modulo--3 { border-left-color: var(--color-modulo-3); }

/* El módulo 4 en pantalla usa su variante oscurecida: el institucional no llega
   al contraste contra crema. El impreso sigue siendo `--color-modulo-4`. */
.cabecera-modulo--4 { border-left-color: var(--color-modulo-4-pantalla); }

/* --- el catálogo ---------------------------------------------------------
   Disposición y nada más: ni un color, ni un tamaño, ni un radio. */
.lista-catalogo {
  margin: 0;
  padding: 0;
  list-style: none;
}

.catalogo-acciones {
  margin-top: var(--espacio-4);
}

.catalogo-vacio > :last-child {
  margin-top: var(--espacio-4);
}

/* Cinco pistas y no las tres de la base: la fila del catálogo lleva nombre,
   cantidad, umbral, vencimiento y estado. Es un MODIFICADOR y no un cambio de
   `.fila-lista`, que sigue cableada a las tres pistas de la lista de trabajos
   de Inicio: ampliarla sin modificador desalinearía esa pantalla. */
.fila-lista--catalogo {
  grid-template-columns:
    minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.5fr);
}

/* A 320px las pistas se encogen por debajo del ancho de una palabra larga.
   Sin esto, "Vencimiento" desbordaría su pista y la pantalla pediría scroll
   horizontal, que es lo único que el reflow no perdona. */
.fila-lista--catalogo > * {
  overflow-wrap: anywhere;
}

/* La celda del nombre lleva el ícono del insumo Y su nombre. El ícono no es una
   pista de la rejilla: es la identidad del insumo, al lado de su nombre.
   `min-width: 0` para que la celda pueda encogerse por debajo del ancho del
   nombre —sin eso, a 320px la pista se niega a achicarse y la pantalla pide
   scroll horizontal, que es lo único que el reflow no perdona—. */
.celda-insumo {
  display: flex;
  align-items: center;
  gap: var(--espacio-2);
  min-width: 0;
}

/* Caja fija con `object-fit: contain`: los SVG del manual van de 26x54 a
   cuadrados, y sin caja la fila mediría distinto en cada renglón.

   Se sirven como archivo con `image_tag` y NUNCA incrustados en la vista:
   llevan el naranja institucional y medidas en px adentro, y una vista no puede
   declarar ni una cosa ni la otra. Como `<img>` no se repinta por CSS, y está
   bien: ese naranja es el color del ícono en el manual. */
.insumo-icono {
  flex: none;
  width: var(--espacio-6);
  height: var(--espacio-6);
  object-fit: contain;
}

/* La marca genérica del módulo, para el insumo sin ícono propio. No dibuja
   geometría nueva —el manual lo prohíbe (UX-DR7, NFR-29)—: usa el mismo
   lenguaje que `cabecera-modulo`, que es como el sistema ya nombra un módulo
   sin dibujo. EL COLOR VIVE SOLO EN LA BARRA IZQUIERDA y el número va en tinta
   sobre crema, así que se lee igual en daltonismo (UX-DR6, NFR-16). */
.insumo-icono--generico {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-superficie-crema);
  border-left: 3px solid var(--color-tinta);
  border-radius: var(--radio-sm);
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.insumo-icono--generico-0 { border-left-color: var(--color-modulo-0); }
.insumo-icono--generico-1 { border-left-color: var(--color-modulo-1); }
.insumo-icono--generico-2 { border-left-color: var(--color-modulo-2); }
.insumo-icono--generico-3 { border-left-color: var(--color-modulo-3); }

/* Igual que la cabecera: el módulo 4 en pantalla usa su variante oscurecida. */
.insumo-icono--generico-4 { border-left-color: var(--color-modulo-4-pantalla); }

/* Un insumo puede llevar TRES palabras de estado a la vez —dado de baja, con el
   umbral desactualizado Y sin ícono propio—, así que la celda envuelve en lugar
   de estirar. */
.celda-estados {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-1);
}

/* --- el formulario del insumo --------------------------------------------
   La casilla es la única forma de campo donde la etiqueta va al lado y no
   arriba: el control es cuadrado y chico, y una etiqueta arriba lo dejaría
   flotando. */
.campo--casilla {
  display: flex;
  align-items: center;
  gap: var(--espacio-2);
  min-height: var(--espacio-toque-minimo);
}

.campo--casilla .campo__etiqueta {
  margin-bottom: 0;
}

/* El tilde mide 24px y su ÁREA TÁCTIL son los 44px del contenedor de arriba,
   que es lo que `components.tilde` prescribe. Por eso acá se baja el
   `min-height` que la capa base le pone a todo `input`: estirar la casilla a
   44px de alto la deformaría, y el piso táctil ya lo cumple la fila entera,
   que es lo que se toca —la etiqueta también alterna el tilde—. */
.campo__tilde {
  flex: none;
  width: var(--espacio-6);
  height: var(--espacio-6);
  min-height: var(--espacio-6);
  accent-color: var(--color-naranja-oscuro);
}

/* El consejo que acompaña a un campo: de dónde sale el número propuesto, qué
   pasa si el insumo no vence, qué pasa si se lo da de baja. Es texto de apoyo y
   se lee como tal; el campo lo declara con `aria-describedby`.

   8px DE AIRE ARRIBA, porque casi siempre va pegado al control: el anillo de
   foco ocupa 4px por fuera de la caja (2px de trazo y 2px de separación), así
   que con menos el anillo raya la primera línea. Antes el margen era -8px y la
   caja del control tapaba 7px de la primera línea en trece campos. */
.campo__consejo {
  margin: var(--espacio-2) 0 var(--espacio-4);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* El -8px solo vale después de un `.campo` entero (una casilla, el campo de un
   formulario), cuyos 16px de margen inferior lo absorben: el consejo queda a
   8px de su campo y no a 16px, para que se lea como suyo y no como del
   siguiente. Pegado a un control no hay margen que lo absorba. */
.campo + .campo__consejo {
  margin-top: calc(-1 * var(--espacio-2));
}

/* --- campo-aviso ---------------------------------------------------------
   Una decisión pendiente junto al campo que la pide —el umbral desactualizado—.
   No es un error: nada está mal, falta que alguien decida. Por eso usa la
   paleta `porvencer` y no la de `vencido`, que es la de `campo-error`. */
.campo-aviso {
  margin: var(--espacio-2) 0;
  padding: var(--espacio-3);
  background-color: var(--color-porvencer-fondo);
  border-radius: var(--radio-md);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- requisitos-faltantes ------------------------------------------------
   Qué falta completar, junto al botón que lo describe (UX-DR22). Nace vacío y
   lo escribe `requisitos_controller.js`; sin JavaScript se queda vacío y no
   ocupa lugar. */
.requisitos-faltantes {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.requisitos-faltantes:empty {
  margin: 0;
}

/* El botón apagado deja de ofrecerse como acción, y se nota sin depender del
   color: el cursor cambia y el relleno pierde el naranja. Lo que dice POR QUÉ
   está apagado es el mensaje de arriba, no este estilo. */
.boton-primario:disabled {
  background-color: var(--color-neutro-fondo);
  border-color: var(--color-linea-fuerte);
  color: var(--color-neutro);
  cursor: not-allowed;
}

/* --- las listas administrables -------------------------------------------
   Los barrios y las categorías de cliente (Historia 1.3). Disposición y nada
   más: ni un color, ni un tamaño, ni un radio.

   Clases con nombre propio y no las del catálogo: `.lista-catalogo`,
   `.catalogo-acciones` y `.catalogo-vacio` son disposición pura y servirían tal
   cual, pero su nombre dice "catálogo" y estas pantallas no lo son. Unificar las
   dos familias en un nombre neutro es un renombre que toca las vistas de la
   Historia 1.1 y pertenece a quien agregue la tercera lista del sistema. */
.lista-valores {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lista-acciones {
  margin-top: var(--espacio-4);
}

.lista-vacia > :last-child {
  margin-top: var(--espacio-4);
}

/* DOS pistas, no las tres de la base ni las cinco del catálogo: la fila de una
   lista administrable lleva nombre y estado. Es un MODIFICADOR y no un cambio de
   `.fila-lista`, que sigue cableada a las tres pistas de la lista de trabajos de
   Inicio: ampliarla sin modificador desalinearía esa pantalla.

   Con dos pistas el reflow a 320px no tiene por dónde romperse —el nombre tiene
   el 75% del ancho y el estado es una palabra—, así que no hace falta una prueba
   de navegador nueva. */
.fila-lista--valores {
  grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
}

/* A 320px un nombre de barrio largo y sin espacios desbordaría su pista y la
   pantalla pediría scroll horizontal, que es lo único que el reflow no perdona. */
.fila-lista--valores > * {
  overflow-wrap: anywhere;
}

/* --- la lista de clientes (Historia 6.5) ----------------------------------
   Nombre, estado y última entrada. Un MODIFICADOR propio y no un cambio de
   `--valores`, que siguen usando las listas de barrios y categorías con sus dos
   pistas. Sigue el patrón de apilado de `.fila-lista--stock`.

   TELÉFONO PRIMERO: cada renglón es una TARJETA de una columna. La banda de
   rótulos no dice nada cuando los datos no están en columnas, así que se oculta,
   y cada dato lleva su propio rótulo visible. */
.fila-lista--clientes {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--clientes.fila-lista--encabezado {
  display: none;
}

/* A 320px un nombre largo y sin espacios desbordaría la tarjeta y la pantalla
   pediría scroll horizontal, que es lo único que el reflow no perdona. */
.fila-lista--clientes > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

.cliente-celda__rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* «Nunca» y, debajo, la bienvenida con su píldora; si no entra, la píldora
   baja. */
.cliente-celda__dato {
  display: block;
}

.cliente-celda__bienvenida {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-1) var(--espacio-2);
  margin-top: var(--espacio-1);
}

/* En escritorio, tres pistas con banda de rótulos: los rótulos por celda
   sobran. */
@media (min-width: 48em) {
  .fila-lista--clientes {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1.5fr);
  }

  .fila-lista--clientes.fila-lista--encabezado {
    display: grid;
  }

  .cliente-celda__rotulo {
    display: none;
  }
}

/* --- Repartidores (Historia 12.8) ------------------------------------------
   El molde de la lista de clientes: en el teléfono cada fila es una tarjeta de
   una columna con el rótulo visible en cada dato; en escritorio, tres pistas
   con banda de rótulos. Todo por token. */
.fila-lista--repartidores {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--repartidores.fila-lista--encabezado {
  display: none;
}

/* Un email largo y sin espacios desbordaría la tarjeta a 320px. */
.fila-lista--repartidores > * {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.repartidor-celda__nombre,
.repartidor-celda__email {
  display: block;
}

.repartidor-celda__nombre {
  font-weight: var(--tipo-etiqueta-peso);
}

.repartidor-celda__email,
.repartidor-celda__nota {
  color: var(--color-tinta-media);
}

.repartidor-celda--acciones {
  display: flex;
  flex-direction: column;
  gap: var(--espacio-2);
  width: 100%;
}

.repartidor-celda__forma {
  margin: 0;
}

@media (min-width: 48em) {
  .fila-lista--repartidores {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1.5fr);
  }

  .fila-lista--repartidores.fila-lista--encabezado {
    display: grid;
  }
}

/* --- Organizaciones (Historia 16.1) ----------------------------------------
   El molde de Repartidores: en el teléfono cada fila es una tarjeta de una
   columna, y solo la celda de cuántas sedes agrupa lleva su rótulo visible
   (el nombre y el botón no lo necesitan); en escritorio, tres pistas —
   nombre, cuántas sedes agrupa y «Borrar»— con banda de rótulos. */
.fila-lista--organizaciones {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--organizaciones.fila-lista--encabezado {
  display: none;
}

/* Un nombre largo y sin espacios desbordaría la tarjeta a 320px. */
.fila-lista--organizaciones > * {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.organizacion-celda__nombre {
  font-weight: var(--tipo-etiqueta-peso);
}

.organizacion-celda__forma {
  margin: 0;
}

@media (min-width: 48em) {
  .fila-lista--organizaciones {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
  }

  .fila-lista--organizaciones.fila-lista--encabezado {
    display: grid;
  }
}

/* --- el índice de Configuración ------------------------------------------
   Una sección con contenido detrás (UX-DR11): las tres pantallas que existen,
   cada una con su nombre enlazado y la línea que dice para qué es. Disposición y
   tipografía de apoyo; el color del enlace lo pone la capa base. */
.indice-configuracion {
  margin: var(--espacio-6) 0 0;
  padding: 0;
  list-style: none;
}

.indice-configuracion > li + li {
  margin-top: var(--espacio-5);
}

/* Solo el margen: la tipografía del `h2` ya la pone la capa base, y volver a
   declararla acá sería una segunda fuente de la que desincronizarse. */
.indice-configuracion__nombre {
  margin: 0 0 var(--espacio-1);
}

/* La línea que dice para qué es la pantalla: texto de apoyo y se lee como tal,
   igual que `campo__consejo` junto a un campo. */
.indice-configuracion__para-que {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- el registro de correos ----------------------------------------------
   La lista de notificaciones (Historia 2.1). Disposición y nada más: ni un
   color, ni un tamaño, ni un radio.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: los seis estados entran en las
   cuatro que ya existen —`ok` para entregada, `porvencer` para enviada (el
   proveedor la aceptó y todavía no se sabe si llegó), `atencion` para las tres
   que no llegaron y `neutro` para la pendiente—. El mapa lo declara
   `Notificacion::TONOS`, que es donde se decide, y acá no hace falta nada. */
.lista-notificaciones {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* CINCO pistas, no las tres de la base: destinatario, asunto, fecha, plantilla y
   estado. Es un MODIFICADOR y no un cambio de `.fila-lista`, que sigue cableada
   a las tres pistas de la lista de trabajos de Inicio.

   El asunto se lleva la pista más ancha porque es lo que se lee para reconocer
   un envío; la última carga además el botón de reenvío y el motivo del rebote,
   así que tampoco es la más angosta. */
.fila-lista--notificaciones {
  grid-template-columns:
    minmax(0, 2fr) minmax(0, 3fr) minmax(0, 2fr) minmax(0, 2fr) minmax(0, 2fr);
  align-items: start;
}

/* A 320px un destinatario largo sin espacios —una casilla con un dominio de
   veinte letras— desbordaría su pista y la pantalla pediría scroll horizontal,
   que es lo único que el reflow no perdona. */
.fila-lista--notificaciones > * {
  overflow-wrap: anywhere;
}

/* La celda de estado apila tres cosas —la píldora, el botón y el motivo— y las
   apila SIEMPRE, también en escritorio: en una fila quedarían pegadas y el botón
   perdería su piso táctil contra el borde de la píldora. */
.fila-lista--notificaciones > :last-child {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--espacio-2);
}

/* El motivo del rebote: texto de apoyo y se lee como tal, igual que la línea de
   para-qué del índice de Configuración. */
.notificaciones__motivo {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- el historial de stock -----------------------------------------------
   Los movimientos de un insumo (Historia 4.1). Disposición y nada más: ni un
   color, ni un tamaño, ni un radio. */
.lista-movimientos {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* CINCO pistas: fecha, lote, cantidad, motivo y quién. Es un MODIFICADOR y no un
   cambio de `.fila-lista`, que sigue cableada a las tres pistas de Inicio. La
   cantidad es un número corto y se lleva la pista más angosta; el email es lo
   más largo. */
.fila-lista--movimientos {
  grid-template-columns:
    minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr) minmax(0, 2fr) minmax(0, 3fr);
  align-items: start;
}

/* A 320px un email largo sin espacios desbordaría su pista y la pantalla pediría
   scroll horizontal, que es lo único que el reflow no perdona. */
.fila-lista--movimientos > * {
  overflow-wrap: anywhere;
}

/* Lo que un ajuste suma a la celda del motivo (Historia 4.5): qué se creía,
   qué había y la nota, cada cosa en su renglón y leída como apoyo. */
.movimiento-ajuste {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- el stock del depósito -----------------------------------------------
   Un renglón por insumo con sus lotes debajo (Historia 4.3). Ni un color, ni un
   tamaño de letra, ni un radio que no salga del espejo.

   `vencido` entra ahora porque ahora tiene pantalla detrás: el lote vencido.
   Igual que las demás variantes, la píldora NUNCA va sola: adentro va la
   palabra. El color acompaña y nunca identifica solo (NFR-16). */
.pill-estado--vencido {
  background-color: var(--color-vencido-fondo);
  color: var(--color-vencido);
}

/* TELÉFONO PRIMERO: cada renglón es una TARJETA de una columna. La banda de
   rótulos no dice nada cuando los datos no están en columnas, así que se oculta,
   y cada dato lleva su propio rótulo visible. */
.fila-lista--stock {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--stock.fila-lista--encabezado {
  display: none;
}

/* A 320px un nombre o una fecha larga desbordarían la tarjeta y la pantalla
   pediría scroll horizontal, que es lo único que el reflow no perdona. */
.fila-lista--stock > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

.stock-celda__rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* Los lotes van APILADOS dentro de su celda, uno por renglón, con su píldora al
   lado; si no entra, la píldora baja. */
.lotes-en-deposito {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lote-en-deposito {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-1) var(--espacio-2);
}

/* En escritorio, una rejilla de cuatro pistas con banda de rótulos: los rótulos
   por celda sobran. Los lotes se llevan la pista más ancha; el total es un
   número corto. */
@media (min-width: 48em) {
  .fila-lista--stock {
    grid-template-columns:
      minmax(0, 2fr) minmax(0, 2.5fr) minmax(0, 1fr) minmax(0, 1.5fr);
  }

  .fila-lista--stock.fila-lista--encabezado {
    display: grid;
  }

  .stock-celda__rotulo {
    display: none;
  }
}

/* --- qué conviene comprar -------------------------------------------------
   Un renglón por insumo activo con su consumo, su stock sin vencer, su
   cobertura y cuánto comprar (Historia 14.8). La misma forma que el stock:
   disposición y nada más, ni un color, ni un tamaño, ni un radio nuevos.

   TELÉFONO PRIMERO: cada renglón es una TARJETA de una columna, la banda de
   rótulos se oculta y cada dato lleva su rótulo visible (`.stock-celda__rotulo`,
   que en escritorio ya se oculta arriba). */
.sugerencia-de-compra__bajada {
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta-suave);
}

.lista-sugerencia-de-compra {
  margin-top: var(--espacio-4);
}

.fila-lista--compra {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--compra.fila-lista--encabezado {
  display: none;
}

/* A 320px un nombre largo no puede pedir scroll horizontal. */
.fila-lista--compra > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* En escritorio, cinco pistas con banda de rótulos. */
@media (min-width: 48em) {
  .fila-lista--compra {
    grid-template-columns:
      minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1fr);
  }

  .fila-lista--compra.fila-lista--encabezado {
    display: grid;
  }
}

/* --- el panel de métricas -------------------------------------------------
   Los siete indicadores del negocio como TARJETAS con su nombre y código, su
   número y su lectura en palabras (Historia 15.1). Ningún gráfico: el número es
   el dato. Referencia visual: el mockup de métricas (`.mgrid`, `.mcard`).

   TELÉFONO PRIMERO: una columna, sin scroll horizontal; en escritorio, tres. */
.metricas__periodo {
  margin: var(--espacio-1) 0 var(--espacio-4);
  color: var(--color-tinta-suave);
}

/* El corte elegido, bajo el período (Historia 15.6): la misma voz, pegado a
   él. */
.metricas__periodo:has(+ .metricas__corte) {
  margin-bottom: var(--espacio-1);
}

.metricas__corte {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-suave);
}

.metricas__subtitulo {
  margin: var(--espacio-6) 0 var(--espacio-3);
}

.metricas__atajos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: 0 0 var(--espacio-4);
  padding: 0;
  list-style: none;
}

.metricas__atajo {
  display: inline-flex;
  align-items: center;
  min-height: var(--espacio-toque-minimo);
  padding-inline: var(--espacio-3);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  text-decoration: none;
}

/* El atajo elegido con fondo Y borde, más `aria-current`: el color acompaña,
   nunca identifica solo. */
.metricas__atajo[aria-current="true"] {
  background-color: var(--color-naranja-tenue);
  border-color: var(--color-naranja-borde);
  color: var(--color-naranja-activo);
}

.metricas__rango-campos {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0 var(--espacio-4);
  margin: 0;
  padding: 0;
  border: none;
}

.metricas__rango-campos > legend {
  padding: 0;
}

.metricas__grilla {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.metrica {
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-lg);
  overflow-wrap: anywhere;
}

.metrica > p {
  margin: 0;
}

.metrica__nombre {
  color: var(--color-tierra);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
  text-transform: uppercase;
}

.metrica__valor {
  margin-top: var(--espacio-1);
  font-size: var(--tipo-titulo-tamano);
  font-weight: var(--tipo-titulo-peso);
  line-height: var(--tipo-titulo-interlinea);
  font-variant-numeric: tabular-nums;
}

.metrica__valor--sin-datos {
  font-size: var(--tipo-titulo-sm-tamano);
  line-height: var(--tipo-titulo-sm-interlinea);
  color: var(--color-tinta-media);
}

.metrica__lectura {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.metrica__nota {
  margin-top: var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-style: italic;
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.metricas__incidentes {
  margin: 0;
}

.metricas__distribuciones {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-4);
}

.metricas__distribucion-titulo {
  margin: 0 0 var(--espacio-2);
}

.metricas__lista {
  margin: 0;
}

.metricas__renglon {
  display: flex;
  justify-content: space-between;
  gap: var(--espacio-3);
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
}

.metricas__renglon > dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* --- el ranking de insumos más consumidos (Historia 15.4) -------------------
   Una lista ordenada con BARRAS DE CSS, sin gráficos. El dato es el texto
   (nombre y cantidad); la barra es decoración y va oculta al lector.

   EL LARGO DE LA BARRA SALE DE UNA CLASE POR ESCALÓN, de 5 en 5: la vista no
   puede llevar `style=`, y un `var()` a una propiedad propia no pasa el guarda
   de tokens (todo `var()` de las hojas apunta a tokens.css). Cada escalón fija
   `flex-basis`, que es el largo sobre el eje principal de la PISTA: en el
   teléfono la pista es un renglón y la barra crece a lo ancho; en escritorio es
   una columna y crece a lo alto, apoyada abajo (`justify-content: flex-end`,
   como el `.bars` del mockup). Una sola clase sirve para los dos formatos, y
   los dos se imprimen.

   TELÉFONO PRIMERO: un renglón por insumo, sin scroll horizontal; desde 48em,
   columnas. */
.ranking {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ranking__insumo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--espacio-1) var(--espacio-3);
  min-width: 0;
}

.ranking__nombre {
  min-width: 0;
  overflow-wrap: anywhere;
}

.ranking__cantidad {
  color: var(--color-tinta-media);
  font-variant-numeric: tabular-nums;
}

.ranking__pista {
  grid-column: 1 / -1;
  display: flex;
  height: var(--espacio-2);
}

.ranking__barra {
  flex-grow: 0;
  flex-shrink: 0;
  background-color: var(--color-tierra);
  border-radius: var(--radio-sm);
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.ranking__barra--5 { flex-basis: 5%; }
.ranking__barra--10 { flex-basis: 10%; }
.ranking__barra--15 { flex-basis: 15%; }
.ranking__barra--20 { flex-basis: 20%; }
.ranking__barra--25 { flex-basis: 25%; }
.ranking__barra--30 { flex-basis: 30%; }
.ranking__barra--35 { flex-basis: 35%; }
.ranking__barra--40 { flex-basis: 40%; }
.ranking__barra--45 { flex-basis: 45%; }
.ranking__barra--50 { flex-basis: 50%; }
.ranking__barra--55 { flex-basis: 55%; }
.ranking__barra--60 { flex-basis: 60%; }
.ranking__barra--65 { flex-basis: 65%; }
.ranking__barra--70 { flex-basis: 70%; }
.ranking__barra--75 { flex-basis: 75%; }
.ranking__barra--80 { flex-basis: 80%; }
.ranking__barra--85 { flex-basis: 85%; }
.ranking__barra--90 { flex-basis: 90%; }
.ranking__barra--95 { flex-basis: 95%; }
.ranking__barra--100 { flex-basis: 100%; }

@media (min-width: 48em) {
  /* Columnas de igual ancho, con un mínimo que deja entrar «unidades» y un
     nombre corto: con muchos insumos pasan a otra línea en vez de angostarse.
     Las pistas miden lo mismo y van arriba de los rótulos, así que en cada
     línea las barras quedan apoyadas sobre la misma base aunque un nombre ocupe
     dos renglones. */
  .ranking {
    grid-template-columns: repeat(auto-fill, minmax(calc(var(--espacio-6) * 4), 1fr));
    row-gap: var(--espacio-6);
  }

  .ranking__insumo {
    display: flex;
    flex-direction: column;
    gap: var(--espacio-1);
    font-size: var(--tipo-cuerpo-sm-tamano);
    line-height: var(--tipo-cuerpo-sm-interlinea);
    text-align: center;
  }

  .ranking__pista {
    order: -1;
    flex-direction: column;
    justify-content: flex-end;
    height: calc(var(--espacio-6) * 6);
    margin-bottom: var(--espacio-1);
  }

  .metricas__rango-campos {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  .metricas__rango-campos > legend {
    grid-column: 1 / -1;
  }

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

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

/* --- llevarse las métricas (Historia 15.7) -----------------------------------
   Los dos botones bajo el período y el corte: el CSV es un enlace y el PDF abre
   el diálogo de imprimir. `.metricas__solo-papel` es lo que la pantalla no
   muestra y el papel sí: la línea del corte global. */
.metricas__exportar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
  margin-bottom: var(--espacio-4);
}

.metricas__solo-papel {
  display: none;
}

/* La misma voz que `.metricas__corte`, bajo el período: el corte global y el
   día en que se generó, que solo se ven en el papel. */
.metricas__corte-global,
.metricas__generado {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-suave);
}

/* LA HOJA DE IMPRESIÓN: el PDF de la reunión de cierre. Saca la cáscara (el
   salto, la cabecera y la navegación) y los controles del panel (período,
   corte y exportar), lleva la disposición a una sola columna y muestra la
   línea del corte global. El período y el corte quedan en el papel. Las barras
   del ranking NO se tocan: ya llevan `print-color-adjust: exact` y se imprimen
   con su largo. */
@media print {
  .salto-al-contenido,
  .cabecera-cascara,
  .navegacion-operacion,
  .metricas__periodos,
  .metricas__cortes,
  .metricas__exportar {
    display: none;
  }

  .metricas__solo-papel {
    display: block;
  }

  .metricas__periodo:has(+ .metricas__corte-global) {
    margin-bottom: var(--espacio-1);
  }

  .disposicion-operacion {
    display: block;
  }
}

/* --- los kits en depósito -------------------------------------------------
   Un kit por fila, del más viejo al más nuevo (Historia 5.2). La misma forma que
   el stock: disposición y nada más, ni un color, ni un tamaño, ni un radio.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: la salud usa `vencido` y `ok`, y el
   logístico `neutro`. La variante `info` de «en tránsito» entra con la historia
   que escriba esa transición.

   TELÉFONO PRIMERO: cada fila es una TARJETA de una columna, la banda de rótulos
   se oculta y cada dato lleva su rótulo visible (`.stock-celda__rotulo`, que en
   escritorio ya se oculta arriba). */
.fila-lista--kits {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--kits.fila-lista--encabezado {
  display: none;
}

/* A 320px un serial o una fecha larga no pueden pedir scroll horizontal. */
.fila-lista--kits > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* La fecha de armado va DEBAJO del serial, no a su lado. */
.kits-armado-el {
  display: block;
}

/* En escritorio, una rejilla de cinco pistas con banda de rótulos: la quinta es
   el enlace «Asignar» (Historia 5.3), cuyo rótulo solo lo oye el lector. */
@media (min-width: 48em) {
  .fila-lista--kits {
    grid-template-columns:
      minmax(0, 2fr) minmax(0, 1.5fr) minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr);
  }

  .fila-lista--kits.fila-lista--encabezado {
    display: grid;
  }
}

/* --- los incidentes declarados --------------------------------------------
   Un incidente por fila, los abiertos primero (Historia 10.2). La misma forma
   que los kits y el stock: disposición y nada más, ni un color, ni un tamaño,
   ni un radio.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: el estado del incidente usa
   `atencion` —espera una decisión— y `neutro` para el cerrado, que sigue
   estando y no es una alarma.

   TELÉFONO PRIMERO: cada fila es una TARJETA de una columna, la banda de
   rótulos se oculta y cada dato lleva su rótulo visible
   (`.stock-celda__rotulo`, que en escritorio ya se oculta arriba). */
.fila-lista--incidentes {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-lista--incidentes.fila-lista--encabezado {
  display: none;
}

/* A 320px un nombre de cliente o una ubicación larga no pueden pedir scroll
   horizontal, que es lo único que el reflow no perdona. */
.fila-lista--incidentes > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Los dos datos de apoyo de la fila, en su propio renglón y leídos como apoyo:
   la nota de la foto DEBAJO del identificador, y el serial debajo de la
   ubicación —que acompaña, nunca la reemplaza—.

   `nota-de-foto` y no `sin-foto`: desde la Historia 10.3 el mismo renglón dice
   también que la foto llegó por encima del objetivo de peso, así que ya no
   habla solo de ausencias.

   La NOTA DEL ORIGEN (Historia 10.5) entra en el mismo grupo: es otro dato de
   apoyo del identificador —que lo cargó EPA— y se lee igual en la fila y en el
   detalle. El formulario nuevo no necesita ningún componente propio. */
.incidentes-nota-de-origen,
.incidentes-nota-de-foto,
.incidentes-serial {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* En escritorio, una rejilla de seis pistas con banda de rótulos. */
@media (min-width: 48em) {
  .fila-lista--incidentes {
    grid-template-columns:
      minmax(0, 1.2fr) minmax(0, 1.5fr) minmax(0, 1.5fr) minmax(0, 1.2fr) minmax(0, 1.2fr) minmax(0, 1fr);
  }

  .fila-lista--incidentes.fila-lista--encabezado {
    display: grid;
  }
}

/* Las acciones de la lista (Historia 11.6): registrar, en primario, y al lado
   las reposiciones en curso en rango secundario. Se apilan cuando no entran; el
   secundario deja de ocupar el ancho entero que tiene en el portal. */
.incidentes-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
}

.incidentes-acciones .boton-secundario {
  width: auto;
}

/* --- las reposiciones en curso (Historia 11.6) ----------------------------
   Tres grupos por paso, uno debajo del otro y sin pestañas, separados como las
   bandas de Inicio. El rótulo de cada grupo es un `h2` real dibujado en el rol
   `etiqueta` y en `tinta-suave`, y un grupo vacío dice su frase a 13px: es
   información, no un error. Disposición y nada más: ni un color de estado, ni
   una variante nueva de `.pill-estado` —el paso va con su palabra—.

   TELÉFONO PRIMERO: cada fila y cada grupo de sede y kit es una TARJETA de una
   columna, con el rótulo de cada dato visible. A 320px un nombre de cliente,
   una ubicación o un insumo largos se parten: nunca piden scroll horizontal. */
.reposiciones {
  overflow-wrap: anywhere;
}

.reposiciones-grupos {
  display: grid;
  gap: var(--espacio-6);
  margin-top: var(--espacio-6);
}

.reposiciones-grupo {
  min-width: 0;
}

.reposiciones-grupo__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

.reposiciones-grupo__vacio {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.reposiciones-filas,
.reposiciones-listas,
.reposicion-fila__faltantes {
  margin: 0;
  padding: 0;
  list-style: none;
}

.reposiciones-filas,
.reposiciones-listas {
  display: grid;
  gap: var(--espacio-3);
}

/* Una tarjeta por reposición, de una columna en el teléfono. */
.reposicion-fila,
.reposiciones-sede,
.reposiciones-kit,
.reposicion-lista {
  min-width: 0;
  overflow-wrap: anywhere;
}

.reposicion-fila,
.reposiciones-kit {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-3);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
}

.reposicion-fila > * {
  min-width: 0;
}

.reposiciones-rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* Las listas para salir: la sede es un grupo con su nombre de título y sus
   kits apilados; cada kit es la tarjeta, con sus reposiciones adentro. */
.reposiciones-sede {
  display: grid;
  gap: var(--espacio-3);
}

.reposiciones-sede + .reposiciones-sede {
  margin-top: var(--espacio-4);
}

.reposiciones-sede__titulo,
.reposiciones-kit__titulo {
  margin: 0;
}

.reposicion-lista + .reposicion-lista {
  padding-top: var(--espacio-3);
  border-top: 1px solid var(--color-linea);
}

.reposicion-lista__encabezado {
  margin: 0;
}

.reposicion-lista__desde {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.reposiciones-volver {
  margin-top: var(--espacio-6);
}

/* En escritorio la fila reparte sus datos en pistas; los rótulos siguen
   visibles porque no hay banda de encabezado. Lo que falta y la acción ocupan
   el ancho entero, debajo. */
@media (min-width: 48em) {
  .reposicion-fila {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1.5fr) minmax(0, 1.2fr);
  }

  .reposicion-fila > :nth-child(n + 5) {
    grid-column: 1 / -1;
  }
}

/* --- las entregas (Historia 12.1) -----------------------------------------
   Dos pantallas: la lista de entregas planificadas y planificar una por
   destino. ESCRITORIO PRIMERO: cada entrega y cada destino es una tarjeta que
   reparte sus datos en pistas y se apila en el teléfono, con el rótulo de cada
   dato visible. Disposición y nada más: ni un color de estado nuevo, ni una
   variante de `.pill-estado`.

   A 320px un nombre de sede, una dirección o un insumo largos se parten: nunca
   piden scroll horizontal. */
.entregas {
  overflow-wrap: anywhere;
}

.entregas-acciones {
  margin: 0 0 var(--espacio-4);
}

.entregas-lista,
.entrega-fila__carga,
.entrega-items {
  margin: 0;
  padding: 0;
  list-style: none;
}

.entregas-lista,
.entregas-destinos {
  display: grid;
  gap: var(--espacio-4);
  margin-top: var(--espacio-4);
}

.entrega-fila,
.entrega-destino {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-3);
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.entrega-fila > *,
.entrega-destino > * {
  min-width: 0;
}

.entregas-rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* Lo que acompaña a un dato: la dirección debajo del destino, el vencimiento
   del código y el detalle de un ítem. */
.entregas-apoyo,
.entrega-destino__direccion,
.entrega-item__detalle {
  display: block;
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.entrega-fila__forma {
  margin: var(--espacio-2) 0 0;
}

.entrega-destino__nombre,
.entrega-destino__grupo {
  margin: 0;
}

.entrega-destino__grupo {
  margin-top: var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

.entrega-destino__carga {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: none;
}

.entrega-destino__carga > legend {
  padding: 0;
}

.entrega-item {
  min-width: 0;
}

.entrega-item .campo--casilla {
  margin-bottom: 0;
}

/* El detalle del ítem, alineado con el texto de su etiqueta y no con el
   tilde. */
.entrega-item__detalle {
  padding-left: calc(var(--espacio-6) + var(--espacio-2));
}

.entrega-destino__boton {
  width: 100%;
  min-height: var(--espacio-toque-minimo);
}

.entregas-volver {
  margin-top: var(--espacio-6);
}

/* En escritorio la entrega reparte sus datos en cuatro pistas, y el destino
   pone la carga a la izquierda y la fecha con el botón a la derecha. */
@media (min-width: 48em) {
  .entrega-fila {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 2fr) minmax(0, 1.2fr);
  }

  .entrega-destino__boton {
    width: auto;
  }
}

/* La marca «En reparto» de una fila de la lista (Historia 12.2), debajo de la
   fecha. También «Pendiente» (Historia 12.5). */
.entrega-fila__estado {
  margin-top: var(--espacio-1);
}

/* Historia 12.5 — «No hubo nadie el …», una línea por visita fallida, debajo
   de la fecha. Historia 12.6 — arriba, la historia: las fechas planificadas y
   los intentos fallidos con el código, con el mismo tono. */
.entrega-fila__visitas,
.entrega-fila__historia {
  margin: var(--espacio-2) 0 0;
  padding: 0;
  list-style: none;
}

/* --- entregas en curso e historial (Historia 12.6) -------------------------
   Dos secciones, cada una con su título y su lista de tarjetas. La columna
   «Confirmó» de una entregada ocupa la pista del código: la palabra «código»
   o «excepción» se lee en el mismo lugar. Disposición y nada más. */
.entregas-seccion + .entregas-seccion {
  margin-top: var(--espacio-6);
}

.entregas-seccion__titulo {
  margin: 0 0 var(--espacio-2);
}

.entregas-seccion__resumen {
  margin: 0;
  font-weight: var(--tipo-etiqueta-peso);
}

/* --- confirmar sin código (Historia 12.6) ---------------------------------
   TELÉFONO PRIMERO, una columna: el resumen con las pistas de la fila de la
   lista, los seis motivos —cada fila de 44px (`.campo--casilla`)— y el botón
   primario de 56px con el ancho entero. A 320px nada pide scroll horizontal. */
.confirmacion-sin-codigo__resumen {
  margin: var(--espacio-4) 0;
}

.confirmacion-sin-codigo__motivos {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.confirmacion-sin-codigo__leyenda {
  margin-bottom: var(--espacio-2);
  padding: 0;
  font-weight: var(--tipo-etiqueta-peso);
}

.confirmacion-sin-codigo__motivo {
  margin: 0;
}

.confirmacion-sin-codigo__marca {
  margin: var(--espacio-4) 0;
  color: var(--color-tinta-media);
}

/* El botón es un `input`: la regla base de 44px (`input:not([type="hidden"])`)
   pesa más que una sola clase, así que el de 56px se ancla al formulario. */
.confirmacion-sin-codigo__forma .confirmacion-sin-codigo__boton {
  width: 100%;
  min-height: var(--espacio-toque-fisico);
}

/* La pantalla de reprogramar: el resumen de la entrega con las pistas de la
   fila de la lista, y el botón con el ancho entero en el teléfono y su ancho
   en escritorio. */
.reprogramacion-de-entrega__resumen {
  margin: var(--espacio-4) 0;
}

.reprogramacion-de-entrega__boton {
  width: 100%;
  min-height: var(--espacio-toque-minimo);
}

@media (min-width: 48em) {
  .reprogramacion-de-entrega__boton {
    width: auto;
  }
}

/* --- el reparto (Historia 12.2) --------------------------------------------
   La ruta de hoy, en la vereda y con una mano. TELÉFONO PRIMERO SIN
   EXCEPCIÓN: una sola columna en todos los anchos, y todo lo que se toca mide
   56px (`--espacio-toque-fisico`), también el enlace secundario del día vacío.
   Disposición y nada más: el estado usa `.pill-estado--neutro` con su palabra,
   sin variante nueva.

   A 320px un nombre de sede, una dirección o un insumo largos se parten: nunca
   piden scroll horizontal. */
.reparto {
  overflow-wrap: anywhere;
}

.reparto__fecha {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

.reparto__salida {
  margin: var(--espacio-4) 0;
}

/* El botón ocupa el ancho entero en TODOS los anchos: la pantalla es de
   teléfono. */
.reparto .boton-primario.boton-primario--fisico,
.reparto__accion {
  width: 100%;
  min-height: var(--espacio-toque-fisico);
}

.reparto__salio {
  margin: var(--espacio-4) 0;
  font-weight: var(--tipo-etiqueta-peso);
}

.reparto-destinos,
.reparto-cosas {
  margin: 0;
  padding: 0;
  list-style: none;
}

.reparto-destinos {
  display: grid;
  gap: var(--espacio-4);
  margin-top: var(--espacio-4);
}

.reparto-destino {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-2);
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

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

.reparto-destino__direccion,
.reparto-cosa__insumos {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.reparto-cosas {
  display: grid;
  gap: var(--espacio-3);
}

.reparto-cosa {
  min-width: 0;
  padding-top: var(--espacio-2);
  border-top: 1px solid var(--color-linea);
}

.reparto-cosa > p {
  margin: 0;
}

.reparto-cosa__nombre {
  font-weight: var(--tipo-etiqueta-peso);
}

.reparto-cosa__donde {
  margin-top: var(--espacio-1);
}

/* Historia 12.3 — «Confirmar con código», un enlace de 56px por entrega del
   destino (`.reparto__accion`), uno debajo del otro. Historia 12.5 — debajo
   de cada uno, «No hay nadie», el botón secundario de 56px de la misma
   entrega. */
.reparto-destino__confirmaciones {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.reparto-destino__entrega {
  display: grid;
  gap: var(--espacio-2);
  min-width: 0;
}

.reparto__no-hay-nadie {
  margin: 0;
}

/* --- confirmar con código (Historia 12.3) ---------------------------------
   En la vereda y con una mano. TELÉFONO PRIMERO, una sola columna, y todo lo
   que se toca mide 56px (`--espacio-toque-fisico`).

   `casillero-codigo` (DESIGN.md): seis casilleros de 60px de alto —el toque
   físico más una unidad— y ancho fluido con 44px de mínimo, en DOS GRUPOS DE
   TRES QUE QUEDAN JUNTOS. A lo ancho, los dos grupos en una fila; cuando no
   entran, un grupo debajo del otro, que además ayuda al dictado («K7M» y
   después «R4T»). A 320px nada pide scroll horizontal. */
.confirmacion-de-entrega {
  overflow-wrap: anywhere;
}

.confirmacion-de-entrega__sede {
  margin: var(--espacio-2) 0 0;
}

.confirmacion-de-entrega__direccion,
.confirmacion-de-entrega__cuando {
  margin: var(--espacio-1) 0 var(--espacio-3);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.confirmacion-de-entrega__carga {
  margin: var(--espacio-1) 0 var(--espacio-4);
  padding-left: var(--espacio-5);
}

/* LA REGIÓN DE ANUNCIO. Vacía no ocupa lugar, pero sigue en el documento: una
   región que aparece recién con el texto no se anuncia en todos los lectores. */
.confirmacion-de-entrega__anuncio {
  margin: var(--espacio-4) 0;
  font-weight: var(--tipo-etiqueta-peso);
}

.confirmacion-de-entrega__anuncio:empty {
  margin: 0;
}

.confirmacion-de-entrega .boton-primario.boton-primario--fisico,
.confirmacion-de-entrega__accion {
  width: 100%;
  min-height: var(--espacio-toque-fisico);
}

/* Historia 12.5 — «No hay nadie», VISIBLE SIN SCROLL EN TODO MOMENTO: va
   después de los casilleros y se pega al borde de abajo de la ventana
   (`sticky`), también con el teclado abierto, que achica la ventana. El fondo
   es el de la tarjeta, así lo que pasa por debajo no se lee a través. Con el
   código vencido o bloqueado, arriba del botón va la frase que lo dice. */
.confirmacion-de-entrega__pendiente {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin: var(--espacio-4) 0;
  padding: var(--espacio-2) 0;
  background-color: var(--color-superficie);
}

.confirmacion-de-entrega__no-sirve {
  margin: 0 0 var(--espacio-2);
  font-weight: var(--tipo-etiqueta-peso);
}

.confirmacion-de-entrega__no-hay-nadie {
  margin: 0;
}

/* Historia 12.6 — con el código vencido o bloqueado, «Confirmar sin código»
   —el secundario de 56px— o, para otra cuenta, a quién pedírselo. Va ANTES de
   «No hay nadie», que sigue pegado abajo. */
.confirmacion-de-entrega__excepcion {
  margin: var(--espacio-4) 0 0;
}

.confirmacion-de-entrega__excepcion > p {
  margin: 0;
}

/* El enlace es un `a[href]`: el piso de 44px de la capa base pesa más que una
   sola clase, así que el de 56px se ancla al bloque. */
.confirmacion-de-entrega__excepcion .confirmacion-de-entrega__accion {
  min-height: var(--espacio-toque-fisico);
}

.confirmacion-de-entrega__lleva {
  margin-top: var(--espacio-4);
}

/* Historia 12.4 — «¿Dónde quedó el kit nuevo?», debajo de lo que se entregó:
   la frase de que no es obligatorio con el tono de los datos secundarios, y un
   formulario por kit, separados entre sí. El botón «Guardar ubicación» es el
   secundario de 56px (`.confirmacion-de-entrega__accion`). */
.confirmacion-de-entrega__ubicaciones {
  margin: 0 0 var(--espacio-4);
}

.confirmacion-de-entrega__opcional {
  margin: var(--espacio-1) 0 var(--espacio-3);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.confirmacion-de-entrega__ubicacion + .confirmacion-de-entrega__ubicacion {
  margin-top: var(--espacio-5);
}

/* El botón es un `input`: la regla base de 44px (`input:not([type="hidden"])`)
   pesa más que una sola clase, así que el de 56px se ancla al formulario. */
.confirmacion-de-entrega__ubicacion .confirmacion-de-entrega__accion {
  min-height: var(--espacio-toque-fisico);
}

.casilleros {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.casilleros__leyenda {
  margin-bottom: var(--espacio-2);
  padding: 0;
  font-weight: var(--tipo-etiqueta-peso);
}

.casilleros__grupos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3) var(--espacio-4);
}

/* Cada grupo pide lo que miden sus tres casilleros al mínimo y crece con lo
   que sobre: si los dos no entran en la fila, el segundo baja entero. */
.casilleros__grupo {
  display: grid;
  flex: 1 1 calc(3 * var(--espacio-toque-minimo) + 2 * var(--espacio-2));
  grid-template-columns: repeat(3, minmax(var(--espacio-toque-minimo), 1fr));
  gap: var(--espacio-2);
  min-width: 0;
}

.casillero-codigo {
  width: 100%;
  min-width: var(--espacio-toque-minimo);
  height: calc(var(--espacio-toque-fisico) + var(--espacio-1));
  padding: 0;
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-family: var(--tipo-codigo-familia), "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: var(--tipo-codigo-tamano);
  font-weight: var(--tipo-codigo-peso);
  line-height: var(--tipo-codigo-interlinea);
  letter-spacing: var(--tipo-codigo-espaciado);
  text-align: center;
  text-transform: uppercase;
}

/* --- el detalle de un incidente -------------------------------------------
   Solo lectura y sin ninguna acción (Historia 10.2). Disposición y nada más. */
.detalle-incidente {
  overflow-wrap: anywhere;
}

.detalle-incidente__titulo {
  margin-top: var(--espacio-6);
}

.detalle-incidente__carga {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La foto entra en el ancho de la tarjeta; a 320px no puede pedir scroll. */
.detalle-incidente__foto {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--radio-sm);
}

/* --- validar un incidente -------------------------------------------------
   La foto al lado de lo declarado (Historia 11.1). ESCRITORIO PRIMERO: dos
   columnas que se apilan solas cuando no entran —teléfono o página ampliada—,
   sin media query. `min(100%, 26rem)` es lo que evita el scroll horizontal a
   400px: una columna nunca pide más que el ancho que tiene.

   LA PANTALLA ES MÁS ANCHA QUE EL TOPE DE LECTURA: con la navegación lateral,
   los 960px de `.contenedor` no alcanzan para dos columnas de 26rem, y el
   lado a lado es el pedido de la historia. Se amplía SOLO donde está esta
   pantalla. */
.contenedor:has(.validacion-incidente) {
  max-width: 80rem;
}

.validacion-incidente {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: var(--espacio-6);
  align-items: start;
}

/* Una celda de rejilla no puede pedir más que su pista. */
.validacion-incidente > * {
  min-width: 0;
}

.validacion-incidente__controles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
  margin-bottom: var(--espacio-2);
}

.validacion-incidente__controles[hidden] {
  display: none;
}

/* Los tres controles en una fila y no apilados a lo ancho: apilados empujan la
   foto debajo del borde de la pantalla. */
.validacion-incidente__controles .boton-secundario {
  width: auto;
}

/* EL MARCO TIENE SCROLL PROPIO y un alto acotado al viewport: ampliar la foto
   la recorre adentro del marco y no agranda la página. El alto está elegido
   para que a 1280×800 la foto ajustada termine dentro de la pantalla.

   EN EL NIVEL 1 LA FOTO ENTRA ENTERA (contener): nunca más ancha que el marco
   ni más alta que su tope, así una foto vertical de teléfono se ve completa
   sin scroll. Es lo que se ve sin JavaScript; con JavaScript,
   `zoom_de_foto_controller.js` lee este mismo tope del marco, ajusta la foto
   a él y escala los niveles mayores desde ese tamaño. */
.validacion-incidente__marco {
  max-height: 55vh;
  overflow: auto;
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-sm);
}

.validacion-incidente__imagen {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 55vh;
  margin-inline: auto;
}

.validacion-incidente__nota,
.validacion-incidente__nivel {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* El motivo de la falla, en su propio renglón debajo del insumo. */
.validacion-incidente__motivo {
  display: block;
  flex-basis: 100%;
  margin: 0;
}

/* Las menciones se leen con su palabra; el borde acompaña. */
.validacion-incidente__menciones {
  margin-block: var(--espacio-4);
  padding: var(--espacio-3);
  border-inline-start: 3px solid var(--color-naranja-oscuro);
}

.validacion-incidente__menciones p,
.validacion-incidente__menciones ul {
  margin: 0;
}

.validacion-incidente__accion {
  margin-top: var(--espacio-6);
}

/* Ajustar, debajo de Validar: la frase y el enlace, que se parten antes de
   pedir scroll. */
.validacion-incidente__alternativa {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2) var(--espacio-3);
  margin-top: var(--espacio-4);
}

.validacion-incidente__alternativa .boton-secundario {
  width: auto;
}

/* --- ajustar lo que se va a reponer (Historia 11.2) ------------------------
   Un renglón por insumo: el nombre y lo declarado a un lado, la cantidad al
   otro. La cantidad es angosta —es un número de pocas cifras— y la columna del
   nombre nunca pide más que lo que queda: a 400px el renglón se acomoda sin
   scroll horizontal. El motivo de la falla ocupa el renglón entero. */
.ajuste-incidente__renglon {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 6rem);
  gap: var(--espacio-1) var(--espacio-3);
  align-items: center;
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.ajuste-incidente__insumo .campo__etiqueta,
.ajuste-incidente__insumo .campo__consejo {
  margin: 0;
}

.ajuste-incidente__motivo {
  grid-column: 1 / -1;
  margin: 0;
}

.ajuste-incidente__por-que {
  margin-top: var(--espacio-6);
}

/* El bloque del ajuste en el detalle del incidente, debajo de lo que se va a
   reponer. */
.ajuste-de-reposicion {
  margin-top: var(--espacio-4);
  overflow-wrap: anywhere;
}

/* --- hoja-modal (Historia 11.3) -------------------------------------------
   La pieza del catálogo de `DESIGN.md` (`components.hoja-modal`), implantada
   con la primera pantalla que la usa: la confirmación del rechazo. Superficie
   blanca, radio `xl`, `espacio-5` adentro y la sombra de lo que flota.

   EL VELO ES LA TINTA AL 32 %, que es lo que `components.hoja-modal.velo`
   declara (`rgba(42,37,33,0.32)`): se lo arma desde el token con `color-mix`
   para que ningún color literal viva fuera de `tokens.css`.

   Nunca más ancha que la pantalla menos sus márgenes: a 400px entra sin scroll
   horizontal. Dibujada abierta por el servidor —sin JavaScript no es modal—
   se lee en el flujo de la página, debajo del botón que la pidió, y no flota
   sobre el contenido. */
.hoja-modal {
  width: 100%;
  max-width: min(32rem, calc(100% - 2 * var(--espacio-margen-telefono)));
  padding: var(--espacio-5);
  background-color: var(--color-superficie);
  color: var(--color-tinta);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-xl);
  box-shadow: var(--sombra-flotante);
  overflow-wrap: anywhere;
}

.hoja-modal::backdrop {
  background: color-mix(in srgb, var(--color-tinta) 32%, transparent);
}

.hoja-modal:not(:modal) {
  position: static;
  max-width: none;
  margin: var(--espacio-4) 0 0;
}

/* --- rechazar un incidente (Historia 11.3) ---------------------------------
   El formulario va debajo de Ajustar, en la columna de lo declarado. «Rechazar…»
   es secundario —Validar sigue siendo la acción primaria de la pantalla— y
   apagado se nota sin depender del color, igual que el primario. */
.rechazo-incidente {
  margin-top: var(--espacio-6);
  padding-top: var(--espacio-4);
  border-top: 1px solid var(--color-linea);
}

.rechazo-incidente .campo {
  margin-top: var(--espacio-3);
}

.rechazo-incidente__abrir:disabled {
  background-color: var(--color-neutro-fondo);
  border-color: var(--color-linea-fuerte);
  color: var(--color-neutro);
  cursor: not-allowed;
}

.rechazo-incidente__titulo {
  margin: 0 0 var(--espacio-3);
}

/* El motivo copiado en la hoja, con su palabra adelante. */
.rechazo-incidente__motivo {
  padding: var(--espacio-3);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

/* Los dos botones de la hoja, uno debajo del otro y del mismo ancho: en
   teléfono no se parten a medias. */
.rechazo-incidente__acciones {
  display: grid;
  gap: var(--espacio-3);
  margin-top: var(--espacio-4);
}

/* El bloque del rechazo en el detalle del incidente, debajo de lo que se iba a
   reponer. */
.rechazo-incidente__detalle {
  margin-top: var(--espacio-4);
  overflow-wrap: anywhere;
}

/* El motivo del rechazo al lado del «Cerrado · rechazado» de la lista y de la
   tarjeta del portal: un renglón de apoyo, NUNCA un pill ni un color propio. */
.rechazo-incidente__nota {
  display: block;
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  overflow-wrap: anywhere;
}

/* --- las plantillas de correo ---------------------------------------------
   La lista de plantillas agrupada por sistema (Historia 2.2). Disposición y
   nada más: ni un color, ni un tamaño, ni un radio que no salga del espejo.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: la clasificación de consolidación
   entra en las que ya existen —`atencion` para la que el cliente espera, que es
   la que no se puede demorar ni juntar con nada, y `neutro` para la que se puede
   juntar—. */
.grupo-de-plantillas {
  margin-top: var(--espacio-6);
}

/* Qué es ese sistema: texto de apoyo y se lee como tal, igual que la línea de
   para-qué del índice de Configuración. Sin esto, «Resumen diario del Admin» no
   explica por qué siete de las filas no tienen asunto. */
.grupo-de-plantillas__explicacion {
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.lista-plantillas {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Las tres pistas de la base sirven —nombre, clave y consolidación— y lo único
   que cambia es el reparto: la clave es larga y con guiones bajos, así que pide
   tanto espacio como el nombre. */
.fila-lista--plantillas {
  grid-template-columns: minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr);
  align-items: start;
}

/* A 320px una clave como `bloque_recertificaciones_sin_respuesta` no tiene
   dónde envolver y desbordaría su pista, que es lo único que el reflow no
   perdona. */
.fila-lista--plantillas > * {
  overflow-wrap: anywhere;
}

.plantillas__clave {
  color: var(--color-tinta-suave);
  font-family: var(--tipo-codigo-familia);
  font-size: var(--tipo-cuerpo-sm-tamano);
  letter-spacing: var(--tipo-codigo-espaciado);
}

/* --- el editor de plantillas ----------------------------------------------
   El control real —`input` o `textarea`— se esconde y al lado se monta el
   cuadro `contenteditable` que dibuja las fichas. `hidden` por sí solo no
   alcanza: `.campo__control` declara `display: block` y gana por especificidad,
   así que el control escondido seguiría ocupando su lugar. */
.campo__control[hidden] {
  display: none;
}

/* Hereda la caja de `.campo__control` —la vista le pone las dos clases— y
   agrega lo único propio de un cuadro que edita texto con saltos: que los
   respete, y que una línea larga sin espacios no lo desborde. */
.editor-de-plantilla {
  min-height: var(--espacio-toque-minimo);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* LA FICHA. `--radio-full` es la única forma pastilla del sistema que
   corresponde acá: no es un control de la pantalla sino una marca dentro del
   texto, que es justamente lo que la excepción del token contempla.

   Del rol `codigo` toma la familia y el espaciado —que es lo que hace que se lea
   como un dato del sistema y no como una palabra del texto— pero NO el tamaño:
   28px es el del código de entrega en su pantalla, y adentro de un renglón de
   cuerpo partiría la interlínea. El tamaño es el del texto que la rodea. */
.ficha-variable {
  display: inline-block;
  padding: var(--espacio-0-5) var(--espacio-2);
  background-color: var(--color-naranja-tenue);
  border: 1px solid var(--color-naranja-borde);
  border-radius: var(--radio-full);
  color: var(--color-atencion);
  font-family: var(--tipo-codigo-familia);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  letter-spacing: var(--tipo-codigo-espaciado);
  white-space: nowrap;
}

/* --- el repertorio de variables -------------------------------------------
   Las variables que esta plantilla puede usar, junto al control que las recibe.
   Los botones nacen apagados —sin JavaScript no hay dónde insertar una ficha— y
   los enciende `plantilla_controller.js`. */
.repertorio-de-variables {
  margin: var(--espacio-2) 0 var(--espacio-3);
}

.repertorio-de-variables__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

.repertorio-de-variables__lista {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: 0 0 var(--espacio-2);
  padding: 0;
  list-style: none;
}

/* EL PISO TÁCTIL DE 44px vale también acá: son botones de dedo, y una ficha mide
   lo que mide su texto. La altura la pone el botón y no la ficha, para que la
   marca de adentro siga midiendo lo mismo que cuando vive en el texto. */
.repertorio-de-variables__lista .boton-fantasma {
  min-height: var(--espacio-toque-minimo);
  padding-inline: var(--espacio-2);
}

/* Apagado dice lo que es: sin JavaScript el botón no inserta nada, y la lista se
   lee como lo que queda siendo —las variables disponibles para escribirlas a
   mano—. Se atenúa y deja de ofrecer el cursor de mano. */
.repertorio-de-variables__lista .boton-fantasma:disabled {
  color: var(--color-tinta-suave);
  cursor: default;
}

.repertorio-de-variables__lista .boton-fantasma:disabled:hover {
  background-color: transparent;
}

/* --- la clasificación, en solo lectura ------------------------------------
   Lo que la plantilla declara de sí misma (AD-12). Se muestra y no se edita: la
   maquinaria que la consume es de una fase posterior, y una palanca que hoy no
   mueve nada sería un control que miente. */
.clasificacion-de-plantilla {
  margin-top: var(--espacio-6);
  padding-top: var(--espacio-4);
  border-top: 1px solid var(--color-linea);
}

.clasificacion-de-plantilla__lista {
  margin: 0 0 var(--espacio-2);
  padding: 0;
  list-style: none;
}

.clasificacion-de-plantilla__lista > li + li {
  margin-top: var(--espacio-1);
}

/* --- el bloque del alta de un cliente -------------------------------------
   Los cuatro bloques del alta de una sede (Historia 3.1): identificación, dónde
   queda, contacto y facturación. Disposición y nada más: ni un color, ni un
   tamaño, ni un radio que no salga del espejo.

   El sistema no tenía idioma de AGRUPACIÓN DE CAMPOS —el catálogo y las listas
   tienen siete campos y dos, que entran en una columna corrida— y los quince del
   alta lo necesitan: sin bloques son quince decisiones sin ningún orden que
   ayude a tomarlas.

   `section` con `header` y no `fieldset` con `legend`: la explicación de cada
   bloque es un párrafo debajo del título y `legend` no admite estructura sin
   pelearse con su caja en todos los navegadores. La agrupación semántica la da
   el encabezado real —`h2` bajo el `h1` de la pantalla—, que es la jerarquía que
   el piso de accesibilidad pide. */
.bloque-de-alta {
  margin-bottom: var(--espacio-8);
}

/* `[2026-11-06]` La baja del cliente va después del formulario: separada de
   «Volver a los clientes» igual que un bloque del siguiente. */
.bloque-de-estado-del-cliente {
  margin-top: var(--espacio-8);
  margin-bottom: 0;
}

.bloque-de-alta__cabecera {
  margin-bottom: var(--espacio-4);
  padding-bottom: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
}

/* Solo el margen: la tipografía del `h2` ya la pone la capa base, igual que en
   el índice de Configuración, y volver a declararla acá sería una segunda fuente
   de la que desincronizarse. */
.bloque-de-alta__titulo {
  margin: 0 0 var(--espacio-1);
}

/* De dónde sale lo que va en el bloque: texto de apoyo y se lee como tal, igual
   que la línea de para-qué del índice de Configuración. */
.bloque-de-alta__explicacion {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* UNA COLUMNA de arranque y no dos que se achican: a 320px dos campos por
   renglón dejan cada control en la mitad de un teléfono, y un campo de dirección
   no se llena en 140px. La segunda pista entra en el mismo corte que usa el
   resto de la cáscara. */
.bloque-de-alta__campos {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--espacio-4);
}

@media (min-width: 48em) {
  .bloque-de-alta__campos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --- bloque-de-acceso ----------------------------------------------------
   El bloque «Acceso» de la ficha del cliente (Historia 3.2). Reusa entera la
   familia `bloque-de-alta` —la caja, la cabecera, el título y la explicación son
   los mismos— y agrega solo lo que ese idioma no tenía: una fila con el estado
   del último envío y su fecha, el motivo del rebote debajo, y la separación del
   único botón.

   Ni un color, ni un tamaño, ni un radio que no salga del espejo. */
.bloque-de-acceso__envio {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
  margin: 0 0 var(--espacio-2);
}

/* Cuándo salió. Texto de apoyo y se lee como tal: el dato que manda es el estado
   de al lado, que va adentro de la píldora con su palabra. */
.bloque-de-acceso__fecha {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* El motivo del rebote es LO ACCIONABLE —dice si la casilla no existe o si el
   envío ni salió— así que no se pinta de apoyo: se lee al mismo tamaño que el
   cuerpo, en la paleta de atención. */
.bloque-de-acceso__motivo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-atencion);
}

/* Qué significa todo esto, en una oración. */
.bloque-de-acceso__situacion {
  margin: 0 0 var(--espacio-4);
}

/* `button_to` envuelve el botón en un `<form>` que por omisión es de bloque; sin
   esto el formulario agrega su propio margen debajo del bloque. */
.bloque-de-acceso__forma {
  display: inline;
  margin: 0;
}

/* --- bloque-del-informe --------------------------------------------------
   El bloque «Informe de auditoría» de la ficha del cliente (Historia 3.6).
   Reusa entera la familia `bloque-de-alta` —la caja, la cabecera, el título y la
   explicación son los mismos— y agrega solo lo que ese idioma no tenía: la línea
   de estado del adjunto y el formulario de un solo campo que va debajo.

   Ni un color, ni un tamaño, ni un radio que no salga del espejo. */
.bloque-del-informe__estado {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--espacio-2);
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-media);
}

/* CÓMO SE LLAMA EL ARCHIVO. Es el dato que manda de la línea, así que se lee
   como dato y no como texto de apoyo. `overflow-wrap` porque un nombre largo
   —los relevamientos llegan con fecha y sede adentro del nombre— tiene que
   partirse y leerse entero, no salirse de la tarjeta. */
.bloque-del-informe__archivo {
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-family: var(--tipo-dato-familia);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

/* Cuánto pesa y de cuándo es: contexto del dato de al lado y se lee como tal. */
.bloque-del-informe__detalle {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Dónde lo ve el cliente, en una oración. */
.bloque-del-informe__donde {
  margin: 0 0 var(--espacio-4);
}

/* El formulario de la subida no necesita caja propia: el bloque ya es la caja.
   Lo único que declara es que su campo no arrastre el margen del último
   elemento del bloque. */
.bloque-del-informe__forma {
  margin: 0;
}

/* --- bloque-de-personal --------------------------------------------------
   El bloque «Personal de esta sede» de la ficha del cliente (Historia 7.4), en
   solo lectura. Reusa entera la familia `bloque-de-alta` y las filas de
   `lista-valores > fila-lista`, como «Kits de esta sede», y agrega solo lo que
   ese idioma no tenía: la separación entre grupos, el margen del `h3` de cada
   grupo y la celda del certificado apilada, con la marca «por vencer» debajo de
   la línea.

   Ni un color, ni un tamaño, ni un radio que no salga del espejo. */
.bloque-de-personal__grupo + .bloque-de-personal__grupo {
  margin-top: var(--espacio-6);
}

.bloque-de-personal__titulo {
  margin: 0 0 var(--espacio-2);
}

/* La pista más ancha es la del certificado: es el texto más largo de la fila. */
.bloque-de-personal__fila,
.bloque-de-personal__encabezado {
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 2fr);
}

/* APILADA y no en línea: a 320px la línea del certificado ya envuelve, y la
   marca al lado quedaría partida entre renglones. */
.bloque-de-personal__certificado {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--espacio-1);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --- reglas-de-contrasena ------------------------------------------------
   Las dos reglas de la pantalla de definir contraseña, que se muestran
   CUMPLIÉNDOSE (Historia 3.2). El sistema no tenía idioma de «regla que se
   cumple»: `campo__consejo` es texto de apoyo sin estado y `pill-estado` es una
   etiqueta de una palabra, y acá hacen falta las dos cosas a la vez —la regla,
   su marca y su palabra— repetidas en una lista.

   NFR-16: la marca y el color acompañan, y la PALABRA es la que identifica. Por
   eso el estado cumplido cambia el color Y la palabra, nunca solo el color. */
.reglas-de-contrasena {
  margin: var(--espacio-2) 0 var(--espacio-4);
  padding: 0;
  list-style: none;
}

.regla {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--espacio-2);
  margin-bottom: var(--espacio-1);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La marca ocupa el mismo ancho cumplida que sin cumplir: sin esto, el texto de
   las dos reglas se corre de lugar a cada tecla y la lista tiembla mientras
   alguien escribe. */
.regla__marca {
  display: inline-block;
  min-width: var(--espacio-4);
  font-family: var(--tipo-dato-familia);
  text-align: center;
}

/* La palabra de estado: «Falta» o «Listo». Es lo que hace que la regla se pueda
   leer sin ver el color ni la marca. */
.regla__estado {
  margin-left: auto;
  font-family: var(--tipo-etiqueta-familia);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  letter-spacing: var(--tipo-etiqueta-espaciado);
  line-height: var(--tipo-etiqueta-interlinea);
}

/* Sin `text-transform`: la palabra se lee como está escrita en `es.yml` y no como
   una versión que la hoja inventó —es la misma disciplina que `pill-estado`, que
   tampoco transforma la palabra del estado—.

   Cumplida. El mismo verde que el resto del sistema usa para «esto está bien»,
   y nunca como única señal: la palabra cambia junto con el color. */
.regla--cumplida {
  color: var(--color-ok);
}

/* --- las pantallas públicas del portal -----------------------------------
   Las dos líneas de texto de las tres pantallas del portal (Historia 3.2): la
   que baja la ansiedad arriba —«olvidarse es normal»— y la que dice qué hacer
   después, abajo.

   Solo disposición y jerarquía de lectura: son párrafos de `main.tarjeta`, que
   ya trae la caja. */
.portal-intro {
  margin: 0 0 var(--espacio-5);
  color: var(--color-tinta-media);
}

.portal-salida {
  margin: var(--espacio-5) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- franja-de-alcance -----------------------------------------------------
   La sede que el gerente de Organización está mirando y en qué modo (Historia
   17.2, DESIGN.md `franja-de-alcance`). Fija arriba, 100% de ancho, superficie
   crema —no blanca, para leerse como capa de contexto y no como contenido— con
   borde inferior fuerte. Dos renglones: la sede en peso fuerte y el modo chico
   en tinta media. Se despliega sin JavaScript (`<details>`); cada fila mide un
   toque mínimo y la mirada lleva un tilde, no solo un fondo. */
.franja-de-alcance {
  position: sticky;
  top: 0;
  z-index: 1;
  width: 100%;
  background-color: var(--color-superficie-crema);
  border-bottom: 1px solid var(--color-linea-fuerte);
}

.franja-de-alcance__resumen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--espacio-2);
  min-height: var(--espacio-toque-minimo);
  padding-block: var(--espacio-1);
  cursor: pointer;
}

/* Con una sola sede en el alcance (Historia 17.4) no hay despliegue: los mismos
   dos renglones, sin flecha y sin nada que tocar. */
.franja-de-alcance__resumen--fija {
  cursor: default;
}

.franja-de-alcance__textos {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* La marca de despliegue que `display: flex` le saca al `summary`: sin ella
   nada dice que la franja se abre para cambiar de sede. Gira al abrirse. */
.franja-de-alcance__flecha {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-tamano);
  line-height: var(--tipo-cuerpo-interlinea);
  transition: transform 0.15s ease;
}

.franja-de-alcance__despliegue[open] .franja-de-alcance__flecha {
  transform: rotate(180deg);
}

.franja-de-alcance__sede {
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

.franja-de-alcance__modo {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.franja-de-alcance__lista {
  margin: 0;
  padding: 0 0 var(--espacio-2);
  list-style: none;
}

.franja-de-alcance__item + .franja-de-alcance__item {
  border-top: 1px solid var(--color-linea);
}

.franja-de-alcance__forma {
  margin: 0;
}

/* La fila, sea el botón que elige otra sede o el párrafo de la mirada: nombre
   y modo en la misma línea, con el lugar del tilde reservado a la izquierda
   para que los nombres queden alineados. */
.franja-de-alcance__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--espacio-2);
  width: 100%;
  min-height: var(--espacio-toque-minimo);
  margin: 0;
  padding: 0;
  background-color: transparent;
  border: none;
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
  text-align: start;
}

button.franja-de-alcance__fila {
  cursor: pointer;
}

button.franja-de-alcance__fila:hover {
  background-color: var(--color-superficie-alta);
}

.franja-de-alcance__tilde {
  display: inline-block;
  width: var(--espacio-4);
  color: var(--color-naranja-activo);
  font-weight: var(--tipo-seccion-peso);
}

.franja-de-alcance__fila--mirada .franja-de-alcance__nombre {
  font-weight: var(--tipo-seccion-peso);
}

/* --- menu-cliente ---------------------------------------------------------
   EL MENÚ DEL PORTAL. `[Reescrito 2026-09-25]` Hasta esta fecha acá vivía
   `barra-navegacion-cliente`: fija abajo, cuatro destinos con palabras
   (UX-DR12). Pasa a ser un menú desplegable por decisión del dueño del
   producto.

   `[2026-11-04]` SALE DE LA IZQUIERDA Y TAPA PARTE DEL FONDO, por pedido del
   dueño del producto. Invierte la regla de septiembre («empuja, no tapa»):
   abierto, la lista es un panel fijo contra el borde izquierdo, con sombra, y
   el resto de la pantalla queda detrás de un velo. Tocar el velo lo cierra
   (`navegacion_controller`), igual que `Esc` y que el ícono, que queda visible
   encima del panel en el mismo lugar. Las tres capas se ordenan con `z-index`
   dentro de este bloque: velo, panel, ícono.

   El contenedor del portal sigue sin reservar alto abajo: no hay barra fija
   que tape el final de la pantalla. */
/* `[2026-09-26]` EL MENU VIVE DENTRO DE LA CABECERA, sobre el margen derecho
   y en el mismo renglón que el logotipo: antes era una franja propia debajo y
   eran dos niveles. Sin fondo ni borde propios, porque ya está sobre los de
   la cabecera.

   `margin-inline-start: auto` lo empuja a la derecha del interior, que es
   flex. Y `flex-basis: 100%` en la lista hace que, al abrirse, caiga al
   renglón de abajo ocupando todo el ancho en vez de colgar angosta bajo el
   ícono: la cabecera crece y EMPUJA lo que sigue, que es la regla que este
   menú no puede romper. */
.menu-cliente {
  /* `[2026-09-26]` A LA IZQUIERDA y sin el `margin-inline-start: auto` que lo
     mandaba a la derecha: el lugar del medio es del signo. */
  flex: 0 0 auto;
  /* Conserva el alto del ícono cuando este pasa a ser fijo al abrir el panel:
     sin esto la cabecera se achica y la pantalla de atrás salta. */
  min-height: var(--espacio-toque-fisico);
}


/* NADA DE `display: contents` ACA: en un `<details>` saca al elemento de la
   caja y hay navegadores que dejan de ocultarle el contenido cuando está
   cerrado, o sea que el menú aparecería abierto siempre. El elemento se deja
   como viene. */
.menu-cliente__hoja {
  position: relative;
}

/* EL VELO. Un elemento de verdad dentro del `<details>` y no un `::before`:
   Safari trata al `<details>` de forma propia y no está garantizado que le
   dibuje un pseudoelemento. Como es contenido del `<details>`, solo existe con
   el menú abierto. Tocarlo cierra (`navegacion_controller`); sin JavaScript
   igual frena el toque —nada de atrás se activa por accidente— y el menú se
   cierra con el ícono. */
.menu-cliente__velo {
  position: fixed;
  inset: 0;
  z-index: 10;
  background-color: var(--velo-de-hoja);
}

/* EL PANEL. Contra el borde izquierdo y de arriba abajo; angosto en escritorio
   y casi todo el ancho en un teléfono, pero nunca todo: el velo que se ve al
   costado es lo que dice que atrás sigue la pantalla. Arriba deja libre el
   alto de la cabecera, que es donde queda el ícono para cerrarlo. */
.menu-cliente__hoja[open] .menu-cliente__lista {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  z-index: 11;
  width: min(20rem, 85vw);
  padding-block-start: calc(var(--espacio-toque-fisico) + 2 * var(--espacio-2));
  padding-inline: var(--espacio-4);
  overflow-y: auto;
  align-content: start;
  background-color: var(--color-superficie);
  box-shadow: var(--sombra-flotante);
  animation: menu-cliente-entra 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* `[2026-11-04]` ENTRA Y SALE DESLIZÁNDOSE, y el velo aparece y se va con él.
   Arranca rápido y frena al final, que es lo que se lee como un movimiento y no
   como un salto. Para salir, `navegacion_controller` pone `--cerrando`, espera
   que terminen las dos animaciones y recién ahí cierra el `<details>`. Con
   movimiento reducido la regla global les saca la animación y el controlador
   cierra en el acto: no hay nada que esperar. */
.menu-cliente__hoja[open] .menu-cliente__velo {
  animation: menu-cliente-velo-entra 280ms ease-out;
}

/* CON `[open]` EN EL SELECTOR, para que pese más que la regla de entrada: sin
   eso la animación de entrada le ganaba y el panel se cerraba de golpe (medido
   en captura el 2026-11-04). */
.menu-cliente__hoja[open].menu-cliente__hoja--cerrando .menu-cliente__lista {
  animation: menu-cliente-sale 240ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

.menu-cliente__hoja[open].menu-cliente__hoja--cerrando .menu-cliente__velo {
  animation: menu-cliente-velo-sale 240ms ease-in forwards;
}

/* Encima del panel, en su esquina de arriba a la izquierda: el gesto que lo
   abrió es el que lo cierra. Fijo y no en su lugar de la cabecera porque en
   escritorio la cabecera está centrada y el ícono quedaba flotando a mitad del
   panel, desalineado de las opciones (medido en captura el 2026-11-04). En el
   teléfono cae en el mismo lugar que cerrado. */
.menu-cliente__hoja[open] > .menu-cliente__disparador {
  position: fixed;
  top: var(--espacio-2);
  inset-inline-start: var(--espacio-4);
  z-index: 12;
}

/* Entra deslizándose desde el borde. Con movimiento reducido la regla global
   le saca la animación y aparece directamente. */
@keyframes menu-cliente-entra {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(0);
  }
}

@keyframes menu-cliente-sale {
  from {
    transform: translateX(0);
  }

  to {
    transform: translateX(-100%);
  }
}

@keyframes menu-cliente-velo-entra {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes menu-cliente-velo-sale {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
  }
}

/* --- menu-lateral-cliente --------------------------------------------------
   `[2026-11-04]` EL MENÚ DEL PORTAL EN ESCRITORIO: una columna fija y siempre
   visible a la izquierda del contenido, como la navegación de Operación, y con
   el mismo corte (48em). En el teléfono no se dibuja: ahí el menú es el panel
   de la cabecera (`menu-cliente`), que a su vez desaparece en escritorio. Las
   dos variantes salen del mismo parcial y con los mismos destinos. */
.disposicion-portal {
  padding-block: var(--espacio-6);
}

.menu-lateral-cliente {
  display: none;
}

@media (min-width: 48em) {
  .disposicion-portal {
    display: grid;
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    gap: var(--espacio-6);
    align-items: start;
  }

  .menu-lateral-cliente {
    display: block;
    min-width: 0;
  }

  .menu-cliente {
    display: none;
  }

  /* Sin el ícono, la cabecera del portal se quedaba sin nada en el flujo —el
     signo va centrado con `position: absolute`— y se achicaba a una tira, con
     el signo encima del contenido (medido en captura el 2026-11-04). Conserva
     el mismo alto que en el teléfono: el ícono más el aire de arriba y abajo. */
  .cabecera-cascara__interior:has(.menu-cliente) {
    min-height: calc(var(--espacio-toque-fisico) + 2 * var(--espacio-2));
  }
}

.menu-lateral-cliente__lista {
  display: grid;
  gap: var(--espacio-1);
  margin: 0;
  padding: var(--espacio-2);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  list-style: none;
}

/* «Cerrar sesión» separada de los destinos: no es un lugar a donde ir. */
.menu-lateral-cliente__item--salida {
  margin-top: var(--espacio-1);
  padding-top: var(--espacio-1);
  border-top: 1px solid var(--color-linea);
}

/* DOS CLASES, por la misma razón que en `menu-cliente`: el piso táctil global
   de `a[href]` pesa más que una clase sola. */
.menu-lateral-cliente .menu-lateral-cliente__enlace {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--espacio-toque-minimo);
  padding-inline: var(--espacio-3);
  border-radius: var(--radio-sm);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  text-align: start;
  text-decoration: none;
  transition: background-color 120ms ease-in-out;
}

.menu-lateral-cliente .menu-lateral-cliente__enlace:hover {
  background-color: var(--color-superficie-crema);
}

/* El activo, con fondo Y texto Y peso, como en Operación: el color acompaña y
   nunca identifica solo (NFR-16). */
.menu-lateral-cliente__enlace[aria-current="page"] {
  background-color: var(--color-naranja-tenue);
  color: var(--color-naranja-activo);
  font-weight: var(--tipo-seccion-peso);
}

.menu-lateral-cliente__forma {
  display: contents;
}

.menu-lateral-cliente .menu-lateral-cliente__enlace--salida {
  border: none;
  background: none;
  cursor: pointer;
}


/* El triángulo de fábrica se retira y en su lugar van las tres rayas: el
   `list-style: none` solo no alcanza en WebKit, que lo dibuja igual. */
.menu-cliente__disparador {
  display: flex;
  gap: var(--espacio-2);
  align-items: center;
  min-height: var(--espacio-toque-fisico);
  color: var(--color-tinta);
  /* El ícono se mide en `em`, así que el tamaño de letra del disparador es lo
     que fija su porte aunque la palabra ya no se vea. */
  font-size: var(--tipo-titulo-sm-tamano);
  font-weight: var(--tipo-seccion-peso);
  list-style: none;
  cursor: pointer;
}

.menu-cliente__disparador::-webkit-details-marker {
  display: none;
}

/* LAS TRES RAYAS, equidistantes POR CONSTRUCCIÓN y no por tres números que
   haya que mantener a mano. El elemento es un cuadrado con borde arriba y
   abajo, y la del medio se centra sola en el espacio que queda: mover el
   tamaño no desacomoda nada.

   `[2026-09-26]` Antes eran tres rayas absolutas con `top` calculado a mano, y
   estaban desparejas —2px de hueco arriba contra 4 abajo—. La causa: una caja
   absoluta se posiciona desde el PADDING BOX, que empieza DESPUÉS del borde,
   así que `top: 0` no es el tope de la raya del medio sino su base. El primer
   intento de arreglo movió la de abajo tomando el tope como referencia y la
   dejó peor (2 y 6). Con el centrado automático el error no se puede repetir.

   `currentColor` para que hereden el color del rótulo sin declarar ninguno. */
/* EN `em` Y NO EN PIXELES `[2026-09-26]`: el ícono se mide contra la palabra
   que tiene al lado. `0.72em` es aproximadamente la altura de una mayúscula,
   así que las tres rayas ocupan lo mismo que la M de «Menú» en vez de
   sobresalir y hacerla parecer chica. El ancho guarda la proporción. */
.menu-cliente__icono {
  position: relative;
  display: block;
  width: 1.05em;
  height: 0.72em;
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
}

.menu-cliente__icono::before {
  position: absolute;
  inset-inline: 0;
  top: 50%;
  border-top: 2px solid currentColor;
  content: "";
  transform: translateY(-50%);
}

.menu-cliente__lista {
  display: grid;
  margin: 0;
  padding: 0;
  padding-block-end: var(--espacio-2);
  list-style: none;
}

.menu-cliente__item {
  border-top: 1px solid var(--color-linea);
}

/* `[2026-09-25]` LAS SEIS OPCIONES SON IGUALES, sin aire extra antes de la
   salida. Acá vivía un `margin-block-start` en `--salida` que buscaba separar
   «Cerrar sesión» del grupo, pero un margen superior cae ANTES del borde, así
   que esos 12px aparecían entre «Mis documentos» y la línea siguiente: todas
   las opciones tenían su línea a la misma distancia del texto menos una. Lo
   notó el dueño del producto mirando la pantalla. La clase se conserva por si
   la salida vuelve a necesitar algo propio. */

/* DOS CLASES Y NO UNA, igual que la barra que reemplaza: el piso táctil
   global lo declara `a[href]`, que con su atributo pesa más (0-1-1) que una
   clase sola (0-1-0) y le ganaba a este `min-height`, dejando las opciones en
   los 44px del piso general en vez de los 56 de un destino de navegación. */
.menu-cliente .menu-cliente__enlace {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--espacio-toque-fisico);
  padding-inline: var(--espacio-2);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  text-align: start;
  text-decoration: none;
}

/* El destino activo se marca con color, PESO Y SUBRAYADO: el peso y el
   subrayado son las señales que no dependen de ver el color (NFR-16), y
   `aria-current` es la mitad que no depende de ver. */
.menu-cliente__enlace[aria-current="page"] {
  color: var(--color-naranja-activo);
  font-weight: var(--tipo-seccion-peso);
  text-decoration: underline;
  text-underline-offset: var(--espacio-1);
}

/* El `button_to` de salir envuelve su botón en un formulario, que sin esto
   mete un bloque entre el `li` y el control y le rompe la altura. */
.menu-cliente__forma {
  display: contents;
}

.menu-cliente__enlace--salida {
  border: none;
  background: none;
  cursor: pointer;
}

/* --- los kits del portal ---------------------------------------------------
   La raíz del portal (Historia 6.1, UX-DR27): una tarjeta por kit, encabezada
   por su ubicación, con el serial y la fecha de asociación abajo y los pills al
   pie. Disposición y jerarquía de lectura; cada color, tamaño y radio sale del
   espejo.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: la salud usa las de
   `SaludDeKit::VARIANTES` y el logístico `neutro`, igual que Operación. */
/* EL TÍTULO DE LA LISTA DE KITS `[2026-09-29]`. Pasó de ser el `h1` de la
   pantalla a encabezar solo su lista, debajo del número de emergencia y de los
   avisos. El mismo margen que `mas-kits-portal__titulo`, que es el encabezado
   hermano de esa pantalla, y aire arriba para que se lea como el comienzo de
   una sección y no como el pie del bloque anterior. */
.kits-portal__titulo {
  margin: var(--espacio-5) 0 var(--espacio-3);
}

.lista-kits-portal {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A 320px una ubicación o un serial largos se parten y se leen enteros: no
   piden scroll horizontal ni quedan cortados. */
.kit-portal {
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.kit-portal__ubicacion {
  margin: 0 0 var(--espacio-1);
}

/* El serial, secundario y chico: a 13px, que es el piso de lectura. */
.kit-portal__serial {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.kit-portal__asociado {
  margin: 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.kit-portal__estados {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: var(--espacio-3) 0 0;
}

/* --- el número de emergencia del portal (Historia 6.4, FR-042) ------------
   Arriba de la lista, un único enlace `tel:` que ocupa el bloque entero. El
   borde izquierdo es el naranja INSTITUCIONAL: nunca un color de módulo, que
   solo señala su módulo, ni un color de estado, porque la emergencia no es un
   estado ni una alarma.

   Anidada bajo `.tarjeta` y no una clase suelta: el piso táctil de la capa
   base, `a[href]`, pesa más que una clase sola. `min-width: 0` y
   `overflow-wrap: anywhere` para que un número largo se parta a 320px en vez de
   pedir scroll horizontal. */
.tarjeta .emergencia-portal {
  display: flex;
  align-items: center;
  gap: var(--espacio-3);
  min-width: 0;
  min-height: var(--espacio-toque-minimo);
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-left: 3px solid var(--color-naranja);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  overflow-wrap: anywhere;
  text-decoration: none;
}

/* Caja fija con `object-fit: contain`, como `.insumo-icono`: el SVG del manual
   es alto y angosto, y no se recolorea ni se redimensiona. */
.emergencia-portal__icono {
  flex: none;
  width: var(--espacio-8);
  height: var(--espacio-8);
  object-fit: contain;
}

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

.emergencia-portal__numero {
  color: var(--color-tinta);
  font-family: var(--tipo-titulo-sm-familia), "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: var(--tipo-titulo-sm-tamano);
  font-weight: var(--tipo-titulo-sm-peso);
  line-height: var(--tipo-titulo-sm-interlinea);
}

/* El rótulo y la indicación a 13px, que es el piso de lectura. */
.emergencia-portal__titulo,
.emergencia-portal__llamar {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- el detalle de un kit del portal (Historia 6.2) ----------------------
   Encabezado, condiciones y el contenido por módulo. Reusa `.kit-portal__serial`,
   `.kit-portal__asociado`, `.kit-portal__estados`, `.cabecera-modulo` e
   `.insumo-icono*`; acá va solo la disposición, con tokens.

   A 320px una ubicación, un serial o un nombre de insumo largos se parten y se
   leen enteros: no piden scroll horizontal. */
.detalle-kit-portal {
  min-width: 0;
  overflow-wrap: anywhere;
}

.detalle-kit-portal__volver {
  margin: 0 0 var(--espacio-3);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.detalle-kit-portal__ubicacion {
  margin: 0 0 var(--espacio-1);
}

.detalle-kit-portal__estado {
  margin-top: var(--espacio-5);
}

.detalle-kit-portal__titulo {
  margin: 0;
}

.detalle-kit-portal__vacio {
  margin-top: var(--espacio-5);
}

.detalle-kit-portal__renglones {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* El ícono al lado y los textos apilados: el ícono no se achica y la columna de
   textos puede encogerse por debajo del ancho de un nombre largo. */
.detalle-kit-portal__renglon {
  display: flex;
  align-items: flex-start;
  gap: var(--espacio-3);
  min-width: 0;
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
}

.detalle-kit-portal__textos {
  display: flex;
  flex-direction: column;
  gap: var(--espacio-1);
  min-width: 0;
}

.detalle-kit-portal__nombre {
  font-weight: var(--tipo-titulo-sm-peso);
}

.detalle-kit-portal__dato {
  color: var(--color-tinta-suave);
}

.detalle-kit-portal__vencido,
.detalle-kit-portal__marca {
  display: flex;
  flex-wrap: wrap;
}

/* El renglón por vencer (Historia 6.3): el borde izquierdo en `porvencer` y
   NUNCA en el color de un módulo, que en este producto no señala estados. El
   borde acompaña a la fecha en negrita, a los días que faltan y al pill con su
   palabra: el color no va solo (NFR-16). 3px es la misma medida de disposición
   que la barra de `cabecera-modulo`. */
.detalle-kit-portal__renglon--porvencer {
  padding-left: var(--espacio-2);
  border-left: 3px solid var(--color-porvencer);
}

.detalle-kit-portal__fecha-por-vencer {
  color: var(--color-tinta);
  font-weight: var(--tipo-titulo-sm-peso);
}

.detalle-kit-portal__dias-restantes {
  color: var(--color-porvencer);
}

/* --- el historial de incidentes del portal (Historia 10.6, FR-040) --------
   Una tarjeta por incidente, encabezada por su identificador —el mismo que
   viajó en el asunto del acuse—, con la fecha y el kit abajo y el pill del
   estado al pie. Misma forma que `.kit-portal`, que es la tarjeta que el
   cliente ya sabe leer; se declara aparte porque las partes son otras y
   compartir las clases ataría dos pantallas que van a divergir (la Épica 11 le
   suma el motivo del rechazo a esta fila y no a la del kit).

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: el estado usa las de
   `PalabrasDelIncidente::VARIANTES`, las mismas que Operación, y adentro del
   pill va siempre la palabra (NFR-16).

   A 320px un identificador o una ubicación largos se parten y se leen enteros:
   no piden scroll horizontal. */
.lista-incidentes-portal {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.incidente-portal {
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.incidente-portal__identificador {
  margin: 0 0 var(--espacio-1);
}

/* La fecha y el kit, secundarios y chicos: a 13px, que es el piso de lectura. */
.incidente-portal__fecha {
  margin: 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.incidente-portal__kit {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La aclaración de que lo cargó EPA: un renglón más de la tarjeta y NUNCA un
   pill —no es un estado— ni un color propio, que la leería como una alarma. */
.incidente-portal__nota {
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.incidente-portal__estados {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: var(--espacio-3) 0 0;
}

/* --- las secciones del historial y las reposiciones recibidas (Historia 12.7,
   FR-041) -------------------------------------------------------------------
   Con dos secciones, cada una la encabeza su `h2` y las tarjetas pasan a `h3`.
   La tarjeta de una recibida tiene la forma de la del incidente —la que el
   cliente ya sabe leer—: la fecha arriba, que es el enlace a su detalle, y el
   kit, lo que llegó y el incidente que cerró abajo, chicos. Sin pill: una
   recibida no tiene estado que decir. NINGUNA VARIANTE NUEVA DE `.pill-estado`.

   A 320px una ubicación o una lista de insumos largas se parten y se leen
   enteras: no piden scroll horizontal. */
.historial-portal__seccion {
  min-width: 0;
  margin-top: var(--espacio-5);
}

.historial-portal__titulo {
  margin: 0 0 var(--espacio-3);
}

.lista-reposiciones-portal {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.reposicion-portal {
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.reposicion-portal__fecha {
  margin: 0 0 var(--espacio-1);
}

/* El enlace es un `a[href]` en línea: en bloque en línea, el piso táctil de la
   capa base se cumple de verdad. */
.reposicion-portal__fecha a {
  display: inline-flex;
  align-items: center;
}

/* El kit, lo que llegó y el incidente, secundarios: a 13px, que es el piso de
   lectura. */
.reposicion-portal__fecha-detalle,
.reposicion-portal__kit,
.reposicion-portal__insumos,
.reposicion-portal__incidente {
  margin: 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.reposicion-portal__insumos {
  color: var(--color-tinta);
}

/* El detalle: los mismos datos, con los insumos uno por renglón. */
.detalle-reposicion-portal {
  min-width: 0;
  overflow-wrap: anywhere;
}

.detalle-reposicion-portal__volver {
  margin: 0 0 var(--espacio-3);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.detalle-reposicion-portal__insumos {
  margin-top: var(--espacio-5);
}

.detalle-reposicion-portal__renglones {
  margin: 0;
  padding: 0;
  list-style: none;
}

.detalle-reposicion-portal__renglon {
  min-width: 0;
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
}

/* --- el perfil del cliente -----------------------------------------------
   Las clases de «Mi perfil» y de sus dos recorridos de edición (Historia 3.5,
   FR-012, FR-111): los dos bloques, las filas de dato con etiqueta y valor, la
   marca de candado y la nota de lo que va a pasar.

   Solo disposición y jerarquía de lectura: cada color, cada tamaño y cada radio
   salen del espejo con `var(--…)`. */
.perfil-bloque {
  margin-top: var(--espacio-6);
}

/* El rótulo de cada bloque. Es un `h2` de verdad —la jerarquía de encabezados es
   real y no una decoración— y se lee como rótulo de sección. */
.perfil-bloque__titulo {
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta-media);
  font-family: var(--tipo-etiqueta-familia);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  letter-spacing: var(--tipo-etiqueta-espaciado);
  line-height: var(--tipo-etiqueta-interlinea);
}

/* Una fila de la ficha: el dato a la izquierda y, a la derecha, su acción o su
   candado. `wrap` para que en un teléfono angosto la acción baje en vez de
   apretar el valor hasta partirlo. */
.perfil-fila {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
  align-items: baseline;
  justify-content: space-between;
  padding: var(--espacio-3) 0;
  border-bottom: 1px solid var(--color-linea);
}

.perfil-fila__dato {
  min-width: 0;
}

.perfil-fila__etiqueta {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* `overflow-wrap` y no `nowrap`: un email largo tiene que partirse y leerse
   entero, no salirse de la tarjeta ni quedar cortado con puntos suspensivos —es
   justamente el dato que el cliente viene a verificar—. */
.perfil-fila__valor {
  display: block;
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

/* «Cambiar». Piso táctil de 44px heredado del token físico: es un destino que se
   toca con el pulgar en un teléfono. */
.perfil-fila__accion {
  display: inline-flex;
  align-items: center;
  min-height: var(--espacio-toque-fisico);
  color: var(--color-naranja-oscuro);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-cuerpo-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

/* LO QUE GESTIONA EPA, EN UNA LISTA COMPACTA `[2026-11-04]`. Se sigue
   mostrando —lo bloqueado no se esconde (FR-012)—, pero junto y en letra de
   ayuda, en un recuadro crema que lo separa de lo editable. Etiqueta y valor
   en la misma línea; en un teléfono angosto el valor baja solo (`wrap`) en vez
   de apretarse. */
.perfil-resumen {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.perfil-resumen__fila {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--espacio-3);
}

.perfil-resumen__etiqueta {
  flex: 0 0 9rem;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.perfil-resumen__valor {
  flex: 1 1 12rem;
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* El cambio de email que está esperando confirmación. No es un error —nada está
   mal— y por eso usa la paleta `info` y no la de `vencido`: lo que dice es qué
   está pasando y con qué dirección se sigue entrando mientras tanto. */
.perfil-pendiente {
  margin: var(--espacio-3) 0 0;
  padding: var(--espacio-3);
  background-color: var(--color-info-fondo);
  border-radius: var(--radio-md);
  color: var(--color-info);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Lo que va a pasar al mandar el formulario, junto al botón que lo manda: que
   hasta confirmar se sigue entrando con la dirección anterior. Es la frase que
   convierte el paso extra en algo que cuida y no en burocracia. */
.perfil-nota {
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-3);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- los documentos del cliente ------------------------------------------
   «Mis documentos» del Portal Cliente (Historia 3.6, FR-011): la fila del
   informe de auditoría con su botón de descarga, y el estado vacío que la
   mayoría de los clientes ve primero.

   Solo disposición y jerarquía de lectura: cada color, cada tamaño y cada radio
   salen del espejo con `var(--…)`. */
.documento {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-4);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

/* La columna de texto se achica antes que el botón: en un teléfono angosto el
   botón baja entero en vez de quedar partido en dos renglones. */
.documento__dato {
  flex: 1 1 auto;
  min-width: 0;
}

/* QUÉ ES, antes de cómo se llama: el nombre del archivo lo eligió quien lo
   subió y puede no decirle nada al cliente. */
.documento__tipo {
  display: block;
  color: var(--color-tinta-suave);
  font-family: var(--tipo-etiqueta-familia);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  letter-spacing: var(--tipo-etiqueta-espaciado);
  line-height: var(--tipo-etiqueta-interlinea);
}

/* `overflow-wrap` y no `nowrap`: un nombre largo se parte y se lee entero, no
   se sale de la tarjeta ni queda cortado con puntos suspensivos. */
.documento__archivo {
  display: block;
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-family: var(--tipo-dato-familia);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

/* Cuánto pesa y de cuándo es. El peso no es adorno: avisa antes de tocar el
   botón con datos móviles. */
.documento__detalle {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* EL ESTADO VACÍO NO SE PINTA COMO UN ERROR (NFR-16): nada está mal, todavía no
   hay informe en Mis documentos, todavía no hay kits asignados en la raíz del
   portal (Historia 6.1, UX-DR17) o la sede todavía no declaró ningún incidente
   en Historial (Historia 10.6), o todavía no recibió ninguna reposición
   (Historia 12.7), o todavía no cargó a nadie en su padrón (Historia 7.1), o
   todavía no hay certificados vigentes de su gente (Historia 9.5). Usa
   la caja neutra de la crema y el tono de cuerpo, no la paleta
   de atención ni la de vencido, y lo que comunica es el texto y nunca el
   color. */
.documento-vacio,
.kits-portal-vacio,
.historial-portal-vacio,
.padron-portal-vacio,
.certificados-portal-vacio,
.historial-portal__sin-recibidas {
  margin-top: var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
}

/* Adentro de una sección del historial (Historia 12.7) el vacío va pegado a su
   `h2`, que ya lo separa de lo de arriba. */
.historial-portal__seccion .historial-portal-vacio,
.historial-portal__seccion .historial-portal__sin-recibidas {
  margin-top: 0;
}

/* --- alta de compra ------------------------------------------------------
   Las dos pantallas del alta de compra (Historia 4.2). Se usan de pie en el
   depósito, con la caja recién abierta: todo lo que se toca sube del piso de
   44px al de 56px (`--espacio-toque-fisico`), y en el teléfono el botón y las
   opciones ocupan el ancho entero. Ni un color, ni un tamaño de letra, ni un
   radio que no salga del espejo. */
.boton-primario.boton-primario--fisico {
  width: 100%;
  min-height: var(--espacio-toque-fisico);
}

.alta-compra .campo__control {
  min-height: var(--espacio-toque-fisico);
}

.opciones-insumo {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* La opción ES un enlace a la pantalla siguiente, dibujado como renglón
   tocable. `overflow-wrap` para que un nombre largo se parta y no empuje el
   documento a 320px. */
.opciones-insumo .opcion-insumo {
  display: flex;
  align-items: center;
  min-height: var(--espacio-toque-fisico);
  padding-inline: var(--espacio-3);
  border-bottom: 1px solid var(--color-linea);
  color: var(--color-tinta);
  overflow-wrap: anywhere;
}

/* El lote de la baja por vencimiento (Historia 4.4): el mismo renglón tocable,
   en dos líneas —el insumo arriba, cuándo venció y cuánto hay debajo—. */
.opciones-insumo .opcion-lote {
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding-block: var(--espacio-2);
}

.opcion-lote__detalle {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Las acciones de `/stock`: el primario y, al lado, la baja en rango
   secundario. Se apilan cuando no entran; el secundario deja de ocupar el
   ancho entero que tiene en el portal. */
.stock-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
}

.stock-acciones .boton-secundario {
  width: auto;
}

/* Los lotes en cero de la elección del ajuste (Historia 4.5): un `<details>`
   cerrado, cuyo rótulo es tan tocable como un lote. `list-item` y no `flex`:
   así el rótulo conserva el triángulo que dice que se abre. */
.lotes-en-cero {
  margin-top: var(--espacio-4);
}

.lotes-en-cero > summary {
  display: list-item;
  box-sizing: border-box;
  min-height: var(--espacio-toque-fisico);
  padding: var(--espacio-3);
  cursor: pointer;
  overflow-wrap: anywhere;
}

/* La falla del alta: dice que NO SE REGISTRÓ, con su palabra. El color de
   vencido acompaña; el texto es el que informa. */
.aviso-de-falla {
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-vencido-fondo);
  border-radius: var(--radio-md);
  color: var(--color-vencido);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.aviso-de-falla > p,
.aviso-de-falla > ul {
  margin: 0;
}

.aviso-de-falla > ul {
  padding-left: var(--espacio-5);
}

/* El aviso de envío sin respuesta. Nace vacío y lo escribe
   `envio_controller.js`; vacío no ocupa lugar. */
.aviso-de-envio {
  margin: 0 0 var(--espacio-3);
  padding: var(--espacio-3);
  background-color: var(--color-porvencer-fondo);
  border-radius: var(--radio-md);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.aviso-de-envio:empty {
  margin: 0;
  padding: 0;
}

/* --- armado de kit -------------------------------------------------------
   La pantalla del armado (Historia 5.1). Se usa de pie, con una mano: UNA
   COLUMNA a todo ancho, un control por renglón y todo lo que se escribe o se
   elige sube al piso de 56px. El tilde sigue siendo el de 24px con su área
   táctil de 44px (`.campo--casilla`). */
.armado .campo__control {
  min-height: var(--espacio-toque-fisico);
}

/* El checklist es un `fieldset` por semántica —agrupa los seis componentes—, no
   por dibujo: sin el borde ni la sangría de fábrica. */
.checklist-armado {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.checklist-armado__titulo,
.insumos-armado__titulo {
  margin: var(--espacio-4) 0 var(--espacio-2);
  padding: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-seccion-interlinea);
}

.insumos-armado {
  margin-block: var(--espacio-2) var(--espacio-4);
}

.renglones-armado {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Un renglón por insumo: tilde con el nombre, cantidad, lote y aviso, apilados.
   `overflow-wrap` para que un nombre largo se parta y no empuje el documento a
   320px. */
.renglon-armado {
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.renglon-armado .campo {
  margin-bottom: var(--espacio-2);
}

.renglon-armado__nombre {
  color: var(--color-tinta);
}

.renglon-armado__consejo {
  margin: var(--espacio-1) 0 0;
}

/* «Este lote tiene N» y «No hay stock sin vencer»: una decisión pendiente, no un
   error. Por eso la paleta `porvencer`, con su palabra. Vacío no ocupa lugar. */
.renglon-armado__aviso {
  margin: 0 0 var(--espacio-2);
  padding: var(--espacio-3);
  background-color: var(--color-porvencer-fondo);
  border-radius: var(--radio-md);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.renglon-armado__aviso:empty {
  margin: 0;
  padding: 0;
}

.renglon-armado__errores {
  padding-left: var(--espacio-5);
}

/* --- retiro de una reposición --------------------------------------------
   Confirmar el retiro (Historia 11.5), de pie frente al estante: el mismo
   dibujo que el armado. UNA COLUMNA a todo ancho, el lote al piso de 56px y el
   tilde de 24px con su área táctil de 44px (`.campo--casilla`). Los textos
   largos se parten antes de pedir scroll horizontal a 320px. Ni un color, ni
   un tamaño de letra, ni un radio que no salga del espejo. */
.retiro .campo__control {
  min-height: var(--espacio-toque-fisico);
}

.retiro__titulo {
  margin: var(--espacio-4) 0 var(--espacio-2);
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-seccion-interlinea);
}

/* La reposición espera stock ENTERA: una decisión pendiente, no un error. La
   paleta `porvencer`, con su palabra. */
.retiro__espera,
.renglon-retiro__faltante {
  margin: 0 0 var(--espacio-2);
  padding: var(--espacio-3);
  background-color: var(--color-porvencer-fondo);
  border-radius: var(--radio-md);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  overflow-wrap: anywhere;
}

.renglones-retiro {
  margin: 0 0 var(--espacio-4);
  padding: 0;
  list-style: none;
}

/* Un renglón por insumo: tilde con el nombre, cantidad y lote, apilados. */
.renglon-retiro {
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.renglon-retiro .campo {
  margin-bottom: var(--espacio-2);
}

.renglon-retiro__nombre {
  color: var(--color-tinta);
}

.renglon-retiro__cantidad {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
}

.renglon-retiro__errores {
  padding-left: var(--espacio-5);
}

/* Los insumos por vencer del mismo kit (Historia 14.6), arriba del formulario
   y separados de él por la línea de siempre. «Sumar al envío» es secundario:
   la acción primaria de la pantalla sigue siendo confirmar el retiro. */
.retiro__por-vencer {
  margin-bottom: var(--espacio-4);
  padding-bottom: var(--espacio-4);
  border-bottom: 1px solid var(--color-linea);
}

.retiro__sumar {
  margin: 0;
}

.renglon-retiro__sumado {
  margin: 0 0 var(--espacio-2);
}

/* --- ficha del kit -------------------------------------------------------
   El serial GRANDE, en el rol `codigo`, para copiarlo a la etiqueta de la caja
   sin confundir un número. */
.ficha-kit__serial {
  margin: var(--espacio-2) 0;
  color: var(--color-tinta);
  font-family: var(--tipo-codigo-familia), "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: var(--tipo-codigo-tamano);
  font-weight: var(--tipo-codigo-peso);
  line-height: var(--tipo-codigo-interlinea);
  letter-spacing: var(--tipo-codigo-espaciado);
  overflow-wrap: anywhere;
}

.ficha-kit__etiqueta {
  margin-top: 0;
}

.ficha-kit__contenido {
  margin-top: var(--espacio-5);
}

.contenido-kit {
  margin: 0;
  padding: 0;
  list-style: none;
}

.contenido-kit__renglon {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--espacio-1) var(--espacio-3);
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.contenido-kit__detalle {
  color: var(--color-tinta-suave);
}

/* --- historial del kit (Historia 5.4) -------------------------------------
   Una columna, lo último arriba. Solo tokens: el título en el peso de
   `titulo-sm`, cuándo y quién en tinta suave, y los textos largos (un email,
   una ubicación) se parten antes de pedir scroll horizontal a 320px. */
.historial-kit {
  margin: 0;
  padding: 0;
  list-style: none;
}

.historial-kit__entrada {
  padding-block: var(--espacio-3);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.historial-kit__entrada p {
  margin: 0;
}

.historial-kit__cuando,
.historial-kit__quien {
  color: var(--color-tinta-suave);
}

.historial-kit__titulo {
  color: var(--color-tinta);
  font-weight: var(--tipo-titulo-sm-peso);
}

.historial-kit__detalle {
  margin: var(--espacio-1) 0 0;
  padding-left: var(--espacio-5);
}

.historial-kit__cierre {
  margin-top: var(--espacio-3);
  overflow-wrap: anywhere;
}

.historial-kit__cierre--saltos {
  color: var(--color-vencido);
}

/* La desasociación (Historia 5.5), entre el título y la lista: separada de las
   entradas por la misma línea, y el nombre de una sede larga se parte. */
.historial-kit__desasociar {
  padding-block: var(--espacio-3);
  border-bottom: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

/* Por qué se desasocia (Historia 13.6): dos radios, cada fila de 44px
   (`.campo--casilla`), con el molde de confirmar sin código. */
.historial-kit__motivos {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.historial-kit__leyenda {
  margin-bottom: var(--espacio-2);
  padding: 0;
  font-weight: var(--tipo-etiqueta-peso);
}

.historial-kit__motivo {
  margin: 0;
}

/* Lo que el kit tiene abierto (Historia 13.6): avisa y no bloquea. El color de
   por vencer acompaña; el texto es el que informa. */
.historial-kit__pendientes {
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-porvencer-fondo);
  border-radius: var(--radio-md);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.historial-kit__pendientes > p,
.historial-kit__pendientes > ul {
  margin: 0;
}

.historial-kit__pendientes > ul {
  padding-left: var(--espacio-5);
}

@media (min-width: 48em) {
  .boton-primario.boton-primario--fisico {
    width: auto;
  }
}

/* --- declaración de incidente (Historia 10.1) -----------------------------
   El botón de la raíz del portal, el formulario de tres o cuatro pasos y el
   recibido. Teléfono primero, en una columna, operable a 320px y con zoom al
   200%: todo texto largo se parte en vez de pedir scroll horizontal. Ni un
   color, ni un tamaño de letra, ni un radio que no salga del espejo. */

/* La raíz: debajo de los kits, el botón y, debajo, el aviso de la foto ANTES de empezar. Anidado
   bajo `.declarar-portal` porque el piso táctil de la capa base, `a[href]`,
   pesa más que una clase sola. */
.declarar-portal {
  margin: var(--espacio-4) 0 0;
}

.declarar-portal .boton-primario {
  text-decoration: none;
}

.declarar-portal__aviso,
.declarar-portal__sin-kits {
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.declaracion {
  overflow-wrap: anywhere;
}

/* Un paso es un `fieldset` por semántica, no por dibujo. SIN `display`: el
   controlador lo oculta con el atributo `hidden`, y un `display` acá le ganaría. */
.paso-declaracion {
  min-width: 0;
  margin: 0 0 var(--espacio-6);
  padding: 0;
  border: 0;
}

.paso-declaracion__cabecera {
  margin: 0 0 var(--espacio-3);
  padding: 0;
}

/* --- indicador-paso ------------------------------------------------------
   «Paso N de M»: cuántos pasos hay y en cuál se está, con palabras y no con
   puntos que haya que contar. */
.indicador-paso {
  display: block;
  margin: 0 0 var(--espacio-1);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.paso-declaracion__titulo {
  margin: 0;
}

.paso-declaracion__errores {
  padding-left: var(--espacio-5);
}

.paso-declaracion__consejo {
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta-media);
}

.declaracion .campo__control {
  min-height: var(--espacio-toque-fisico);
}

/* Los dos trabajos del campo y la advertencia, apilados debajo de él y antes
   del contador. */
.descripcion-declaracion__consejo,
.descripcion-declaracion__advertencia {
  margin: var(--espacio-2) 0 var(--espacio-1);
}

.descripcion-declaracion__contador {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Seguir y Volver. Volver queda debajo, en su rango de salida. */
.paso-declaracion__acciones {
  display: grid;
  gap: var(--espacio-2);
  margin-top: var(--espacio-4);
}

.paso-declaracion__acciones[hidden] {
  display: none;
}

.paso-declaracion__volver {
  justify-self: start;
}

/* Los kits, por ubicación y con el serial chico: cada opción es un renglón
   tocable de 56px, y la etiqueta entera elige. */
.opciones-kit {
  margin: 0;
  padding: 0;
  list-style: none;
}

.opcion-kit {
  display: flex;
  align-items: center;
  gap: var(--espacio-3);
  min-height: var(--espacio-toque-fisico);
  padding-inline: var(--espacio-3);
  border-bottom: 1px solid var(--color-linea);
}

.opcion-kit__control {
  flex: none;
  width: var(--espacio-6);
  height: var(--espacio-6);
  min-height: var(--espacio-6);
  accent-color: var(--color-naranja-oscuro);
}

.opcion-kit__etiqueta {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  min-height: var(--espacio-toque-fisico);
  cursor: pointer;
}

.opcion-kit__ubicacion {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.opcion-kit__serial {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Los insumos del kit, por módulo. */
.insumos-declarables[hidden] {
  display: none;
}

.insumos-declarables__kit {
  margin: var(--espacio-4) 0 var(--espacio-2);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-seccion-interlinea);
}

.renglones-declaracion {
  margin: 0;
  padding: 0;
  list-style: none;
}

.renglon-declaracion {
  padding-block: var(--espacio-2);
  border-bottom: 1px solid var(--color-linea);
}

/* El `tilde` de 24px con su área táctil de 44px: la fila entera, que es lo que
   se toca. */
.renglon-declaracion__nombre {
  display: flex;
  align-items: center;
  gap: var(--espacio-2);
  min-width: 0;
  color: var(--color-tinta);
  cursor: pointer;
}

.renglon-declaracion__unica {
  margin: 0 0 0 var(--espacio-8);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- stepper -------------------------------------------------------------
   La cantidad de un insumo: − y + de 44px a los lados del número, entre 1 y lo
   que hay en el kit. Sin JavaScript los botones no existen y el número se
   escribe. */
.stepper {
  margin: var(--espacio-1) 0 0 var(--espacio-8);
}

.stepper__etiqueta {
  display: block;
  margin-bottom: var(--espacio-1);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.stepper__controles {
  display: flex;
  align-items: stretch;
  gap: var(--espacio-2);
}

.declaracion .stepper__valor {
  width: calc(var(--espacio-10) * 2);
  min-height: var(--espacio-toque-minimo);
  text-align: center;
}

.stepper__boton {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--espacio-toque-minimo);
  min-height: var(--espacio-toque-minimo);
  padding: 0;
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
  cursor: pointer;
}

.stepper__boton[hidden] {
  display: none;
}

.stepper__boton:disabled {
  background-color: var(--color-neutro-fondo);
  color: var(--color-neutro);
  cursor: not-allowed;
}

.stepper__hay {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- subida-archivo y la opción sin foto ----------------------------------
   Dos caminos con EL MISMO PESO VISUAL: la misma caja, el mismo borde, el mismo
   alto. Ninguno es el primario de la pantalla: eso es el envío. */
.opciones-foto {
  display: grid;
  gap: var(--espacio-3);
  margin: 0 0 var(--espacio-4);
}

.subida-archivo,
.opcion-sin-foto {
  position: relative;
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
}

.subida-archivo__boton,
.opcion-sin-foto__etiqueta {
  display: flex;
  align-items: center;
  min-height: var(--espacio-toque-minimo);
  margin: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-boton-fisico-tamano);
  font-weight: var(--tipo-boton-fisico-peso);
  line-height: var(--tipo-boton-fisico-interlinea);
  cursor: pointer;
}

.subida-archivo__reglas,
.opcion-sin-foto__consejo {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Sin JavaScript el selector de archivo se ve tal cual, debajo de su etiqueta. */
.subida-archivo__control {
  display: block;
  max-width: 100%;
  margin-top: var(--espacio-2);
}

/* Con JavaScript, la etiqueta es el botón y el selector queda recortado a nada
   pero ENFOCABLE: el anillo de foco lo dibuja la caja entera. */
.subida-archivo--mejorada .subida-archivo__control {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
  opacity: 0;
}

.subida-archivo--mejorada:focus-within {
  outline: 2px solid var(--color-naranja-oscuro);
  outline-offset: 2px;
}

.subida-archivo__elegida {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.subida-archivo__elegida:empty {
  margin: 0;
}

/* --- la miniatura de la foto mientras se comprime -------------------------
   Historia 10.3. La foto elegida se ve enseguida y, encima, un indicador
   OPACO que dice que se está preparando —opaco porque va sobre una fotografía
   cualquiera y el contraste no se puede dejar al azar—.

   El indicador solo existe con la clase `--preparando`, que pone y saca
   `compresion_controller.js`: al terminar queda la miniatura sola. Sin
   JavaScript la `figure` nace `hidden` y nada de esto se dibuja.

   NO PIDE SCROLL A 320px: la imagen nunca pasa del ancho de su caja. */
.miniatura-de-foto {
  position: relative;
  max-width: calc(var(--espacio-10) * 5);
  margin: var(--espacio-2) 0 0;
}

.miniatura-de-foto__imagen {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radio-sm);
}

/* NO SE DIBUJA HASTA QUE HAY ALGO QUE PREPARAR: `display: none` lo saca del
   árbol, no lo esconde fuera de la pantalla —que es lo que haría un recorte
   posicionado y lo dejaría en el árbol de accesibilidad—. Solo el estado
   `--preparando` lo trae. */
.miniatura-de-foto__indicador {
  display: none;
}

.miniatura-de-foto--preparando .miniatura-de-foto__indicador {
  display: block;
  position: absolute;
  bottom: var(--espacio-2);
  left: var(--espacio-2);
  max-width: calc(100% - var(--espacio-4));
  margin: 0;
  padding: var(--espacio-1) var(--espacio-2);
  background-color: var(--color-tinta);
  color: var(--color-blanco);
  border-radius: var(--radio-sm);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* --- el recibido ----------------------------------------------------------- */
.recibido-incidente {
  overflow-wrap: anywhere;
}

.recibido-incidente__identificador {
  margin: var(--espacio-3) 0;
  color: var(--color-tinta);
  font-family: var(--tipo-dato-familia), "Trebuchet MS", "Segoe UI", system-ui, sans-serif;
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

.recibido-incidente__kit {
  color: var(--color-tinta-media);
}

.recibido-incidente__nada-mas {
  font-weight: var(--tipo-seccion-peso);
}

/* --- pedir más kits (Historia 13.1) ---------------------------------------
   La sección «Más kits» de la raíz del portal, el formulario de un solo campo
   y el recibido. Teléfono primero, en una columna, operable a 320px: todo
   texto largo se parte en vez de pedir scroll horizontal. Ni un color, ni un
   tamaño de letra, ni un radio que no salga del espejo. */

/* La sección va debajo de los kits y de la declaración, separada por una
   línea: es otro tema. */
.mas-kits-portal {
  margin: var(--espacio-6) 0 0;
  padding-top: var(--espacio-5);
  border-top: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.mas-kits-portal__titulo {
  margin: 0 0 var(--espacio-3);
}

.mas-kits-portal__intro {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

/* Una tarjeta por pedido en curso, con la misma caja que la de un kit. */
.lista-pedidos-de-kits {
  display: grid;
  gap: var(--espacio-3);
  margin: 0 0 var(--espacio-4);
  padding: 0;
  list-style: none;
}

.pedido-de-kits {
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.pedido-de-kits__cantidad {
  margin: 0 0 var(--espacio-1);
  font-weight: var(--tipo-seccion-peso);
}

.pedido-de-kits__fecha {
  margin: 0;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* EL ESTADO SE DICE CON PALABRAS: no hay color que lo reemplace. */
.pedido-de-kits__estado {
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta);
}

.pedir-kits,
.recibido-pedido-de-kits {
  overflow-wrap: anywhere;
}

.pedir-kits .campo__control {
  min-height: var(--espacio-toque-minimo);
}

/* EL AVISO DE QUE CAMBIA LO QUE SE PAGA, antes del botón y en su propia caja:
   es lo que la sede tiene que leer antes de pedir. */
.pedir-kits__aviso {
  margin: 0 0 var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.pedir-kits__aviso p {
  margin: 0;
}

.pedir-kits__aviso .pedir-kits__aviso-titulo {
  margin-bottom: var(--espacio-2);
  font-weight: var(--tipo-seccion-peso);
}

.recibido-pedido-de-kits__cantidad {
  margin: var(--espacio-3) 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.recibido-pedido-de-kits__nada-mas {
  font-weight: var(--tipo-seccion-peso);
}

/* --- pedir la baja de un kit (Historia 13.2) -------------------------------
   El aviso de la baja en la tarjeta de su kit, la sección «Dar de baja un kit»
   de la raíz, el formulario y el recibido. Mismo molde que pedir más kits:
   teléfono primero, una columna, operable a 320px, y todo texto largo se parte
   en vez de pedir scroll horizontal. Los radios reusan `.opciones-kit` de la
   declaración. Ni un color, ni un tamaño de letra, ni un radio que no salga del
   espejo. */

/* LA BAJA EN CURSO DENTRO DE LA TARJETA DEL KIT, separada por una línea: el
   estado se dice con palabras y no hay color que lo reemplace. */
.kit-portal__baja {
  margin: var(--espacio-3) 0 0;
  padding-top: var(--espacio-3);
  border-top: 1px solid var(--color-linea);
}

.kit-portal__baja p {
  margin: 0;
}

.kit-portal__baja .kit-portal__baja-pedida {
  font-weight: var(--tipo-seccion-peso);
}

.kit-portal__baja .kit-portal__baja-disponible {
  margin-top: var(--espacio-1);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La sección va debajo de «Más kits», con la misma separación. */
.dar-de-baja-portal {
  margin: var(--espacio-6) 0 0;
  padding-top: var(--espacio-5);
  border-top: 1px solid var(--color-linea);
  overflow-wrap: anywhere;
}

.dar-de-baja-portal__titulo {
  margin: 0 0 var(--espacio-3);
}

.dar-de-baja-portal__intro {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

.pedir-baja,
.recibido-pedido-de-baja {
  overflow-wrap: anywhere;
}

/* Los kits son un `fieldset` por semántica, no por dibujo. */
.pedir-baja__kits {
  min-width: 0;
  padding: 0;
  border: 0;
}

.pedir-baja__pregunta {
  padding: 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.pedir-baja__kits .campo__consejo {
  margin: 0 0 var(--espacio-3);
}

.pedir-baja__motivo {
  min-height: var(--espacio-toque-fisico);
  resize: vertical;
}

/* EL AVISO DE LA CONFIRMACIÓN (Historia 18.4): que lo retira EPA y la repregunta
   de si deja ese lugar sin kit, antes del motivo y en su propia caja. */
.pedir-baja__aviso {
  margin: 0 0 var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.pedir-baja__aviso p {
  margin: 0;
}

.pedir-baja__aviso .pedir-baja__aviso-titulo {
  margin-bottom: var(--espacio-2);
  font-weight: var(--tipo-seccion-peso);
}

/* EL KIT QUE SE CONFIRMA (Historia 18.4): la ubicación grande y el serial
   abajo, con las piezas de `.opcion-kit`. */
.pedir-baja__kit {
  display: flex;
  flex-direction: column;
  margin: var(--espacio-3) 0 var(--espacio-4);
}

.pedir-baja__aviso p + p {
  margin-top: var(--espacio-2);
}

.recibido-pedido-de-baja__kit {
  margin: var(--espacio-3) 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

/* --- las solicitudes de kit (Historia 13.3) --------------------------------
   Clientes → Solicitudes de kit: grupos por acción pendiente, uno debajo del
   otro y sin pestañas, separados como las reposiciones. El rótulo de cada
   grupo es un `h2` real en el rol `etiqueta` y en `tinta-suave`. Disposición y
   nada más: el tipo va en `pill-estado--neutro` y la cotización sin respuesta
   en `pill-estado--atencion`, las dos con su palabra.

   TELÉFONO PRIMERO: cada pedido es una TARJETA de una columna, con el rótulo
   de cada dato visible. A 320px un nombre de sede, una ubicación o un motivo
   largos se parten: nunca piden scroll horizontal. */
.solicitudes-kit {
  overflow-wrap: anywhere;
}

.solicitudes-kit-grupos {
  display: grid;
  gap: var(--espacio-6);
  margin-top: var(--espacio-6);
}

.solicitudes-kit-grupo {
  min-width: 0;
}

.solicitudes-kit-grupo__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

.solicitudes-kit-filas {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.solicitud-kit-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-3);
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.solicitud-kit-fila > * {
  min-width: 0;
}

/* La fila a la que se llegó desde Inicio (`#solicitud_kit_{id}`): se marca con
   el fondo crema y el borde naranja, para que el ojo la encuentre. */
.solicitud-kit-fila:target {
  background-color: var(--color-superficie-crema);
  border-color: var(--color-naranja-oscuro);
}

.solicitudes-kit-rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

/* El tipo y lo pedido, en una línea que se parte si no entra. */
.solicitud-kit-fila__pedido {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
}

/* Lo que acompaña a un dato: el motivo de una baja. */
.solicitudes-kit-apoyo {
  display: block;
  margin-top: var(--espacio-1);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.solicitud-kit-fila__espera,
.solicitud-kit-fila__estado {
  display: block;
}

.solicitud-kit-fila__sin-respuesta {
  margin-top: var(--espacio-1);
}

/* `button_to` envuelve el botón en un `<form>` de bloque: sin margen propio. */
.solicitud-kit-fila__forma {
  margin: 0;
}

/* La respuesta del cliente a una propuesta enviada (Historia 13.4): «El cliente
   aceptó» arriba y, debajo, el `<details>` de «El cliente no aceptó…». Se
   apilan en una columna; nada pide scroll horizontal. */
.solicitud-kit-fila__respuesta {
  display: grid;
  gap: var(--espacio-3);
  min-width: 0;
}

/* El rótulo que se abre: tan tocable como un botón (el piso de 44px lo pone
   la capa base) y con el triángulo que dice que se abre —`list-item` y no
   `flex`, como los lotes en cero—. */
.solicitud-kit-fila__rechazo > summary,
.solicitud-kit-fila__escribir-propuesta > summary {
  display: list-item;
  box-sizing: border-box;
  padding: var(--espacio-3) 0;
  color: var(--color-tinta);
  font-size: var(--tipo-boton-tamano);
  font-weight: var(--tipo-boton-peso);
  line-height: var(--tipo-boton-interlinea);
  cursor: pointer;
  overflow-wrap: anywhere;
}

.solicitud-kit-fila__forma-rechazo,
.solicitud-kit-fila__forma-propuesta {
  min-width: 0;
  margin: var(--espacio-2) 0 0;
}

/* El consejo va debajo del campo, sin montarse sobre su borde: el campo de
   esta forma no deja margen propio que el consejo pueda recuperar. */
.solicitud-kit-fila__forma-rechazo .campo__consejo,
.solicitud-kit-fila__forma-propuesta .campo__consejo {
  margin: var(--espacio-2) 0 0;
}

/* El motivo de una rechazada terminada, debajo de su estado, y el texto de
   una propuesta enviada (Historia 18.2): una palabra larga no desborda. */
.solicitud-kit-fila__motivo-de-rechazo,
.solicitud-kit-fila__propuesta-texto {
  overflow-wrap: anywhere;
}

.solicitudes-kit-volver {
  margin-top: var(--espacio-6);
}

/* En escritorio la fila reparte sus datos en tres pistas; la acción ocupa el
   ancho entero debajo y el botón deja de ocupar todo el ancho. */
@media (min-width: 48em) {
  .solicitud-kit-fila {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 2fr) minmax(0, 1.5fr);
  }

  .solicitud-kit-fila > :nth-child(n + 4) {
    grid-column: 1 / -1;
  }

  .solicitud-kit-fila__aceptar,
  .solicitud-kit-fila__rechazar,
  .solicitud-kit-fila__mandar-propuesta {
    width: auto;
  }

  /* El aceptar deja de ocupar el ancho entero: su `form` se ajusta a él. */
  .solicitud-kit-fila__respuesta {
    justify-items: start;
  }

  .solicitud-kit-fila__rechazo {
    justify-self: stretch;
  }
}

/* Las acciones de la lista de clientes (Historia 13.3): el alta, en primario,
   y al lado las solicitudes de kit en rango secundario. Se apilan cuando no
   entran; el secundario deja de ocupar el ancho entero. */
.lista-acciones--clientes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
}

.lista-acciones--clientes .boton-secundario {
  width: auto;
}

/* --- los parámetros del negocio (Historia 13.3) ----------------------------
   Un `fieldset` por grupo, con su `legend` como título, y un campo corto por
   parámetro con su unidad al lado. Disposición y nada más. */
.parametros-de-negocio {
  overflow-wrap: anywhere;
}

.parametros-de-negocio__grupo {
  min-width: 0;
  margin: var(--espacio-6) 0;
  padding: 0;
  border: 0;
}

.parametros-de-negocio__titulo {
  margin-bottom: var(--espacio-3);
  padding: 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.parametros-de-negocio__control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
}

/* Un número de hasta tres cifras: el control no ocupa el ancho entero. */
.parametros-de-negocio__valor {
  width: calc(3 * var(--espacio-toque-minimo));
  max-width: 100%;
}

.parametros-de-negocio__ayuda {
  margin-top: var(--espacio-2);
}

/* --- el padrón del portal (Historia 7.1, FR-085) --------------------------
   «Estado de mi gente»: hasta tres grupos —Sin capacitar, Vigente, Vencido
   (Historia 7.2)— con una tarjeta apilada por persona, con la misma forma que
   las del historial y las de los kits. «Por vencer» es una marca dentro de la
   tarjeta y reusa `.pill-estado--porvencer`, sin variante nueva.

   Teléfono primero: a 320px un nombre o un sector largos se parten y se leen
   enteros, sin scroll horizontal. Cada color, tamaño y radio sale del espejo. */
.padron-portal__grupo {
  min-width: 0;
  margin-top: var(--espacio-5);
}

.padron-portal__titulo {
  margin: 0 0 var(--espacio-3);
}

.lista-personas-portal {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.persona-portal {
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.persona-portal__nombre {
  margin: 0;
}

/* El sector, secundario y chico: a 13px, que es el piso de lectura. UNA FILA
   SIN SECTOR NO ESCRIBE NADA —el guion de celda vacía es del patrón `tabla`—
   así que este renglón sencillamente no se dibuja. */
.persona-portal__sector {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* En qué, desde cuándo y hasta cuándo (Historia 7.2): con la misma forma
   secundaria y chica que el sector. */
.persona-portal__certificado {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* `[2026-11-05]` La capacitación que espera la persona: cuándo y dónde, o que
   espera fecha. Es lo que el cliente viene a mirar, así que va en tinta plena y
   no en la suave del certificado. */
.persona-portal__espera {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* La marca «por vencer», debajo del certificado y dentro de la misma tarjeta. */
.persona-portal__marca {
  margin: var(--espacio-2) 0 0;
}

/* La línea que dice que el aviso llega por correo: información, no alarma. */
.padron-portal__consulta {
  margin: var(--espacio-3) 0 0;
}

/* La única acción primaria de la pantalla, separada de lo que la precede —el
   vacío o la lista del último grupo—. */
.padron-portal__acciones {
  margin-top: var(--espacio-5);
}

/* El aviso de nombre repetido (Historia 7.1) reusa `.campo-aviso`, que es la
   caja de una decisión pendiente y NO la del error. Lo único que agrega es la
   lista de homónimas adentro: el aviso las nombra con su sector, que es lo que
   deja decidir si es otra persona. */
.campo-aviso__titulo {
  margin: 0 0 var(--espacio-2);
  font-weight: var(--tipo-seccion-peso);
}

/* A 320px un nombre largo se parte y se lee entero: no pide scroll
   horizontal. */
.campo-aviso__lista {
  margin: 0 0 var(--espacio-2);
  padding-left: var(--espacio-4);
  overflow-wrap: anywhere;
}

.campo-aviso p:last-child {
  margin-bottom: 0;
}

/* --- la baja del padrón (Historia 7.3, FR-125) ----------------------------
   «Dar de baja» en cada tarjeta es un enlace a la confirmación, no un botón
   que escribe: `inline-flex` para que el piso táctil de la capa base valga
   sobre un `a` en línea. */
.persona-portal__accion {
  margin: var(--espacio-2) 0 0;
}

.persona-portal__baja {
  display: inline-flex;
  align-items: center;
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* `[2026-09-28]` ACÁ VIVÍAN LOS ESTILOS DE LAS DADAS DE BAJA:
   `padron-portal__bajas` y sus dos hijos —el `<details>` plegado del pie de «Mi
   gente»—, `persona-portal--baja`, `persona-portal__forma` —la caja del botón
   «Reactivar»—, y `campo-aviso__marca` y `campo-aviso__reactivar`, de la
   homónima dada de baja en el aviso del alta.

   Se fueron todos con la decisión del dueño del producto de no mostrar en
   ninguna pantalla a una persona dada de baja: ningún marcado los nombra ya. */

/* La confirmación de la baja: las tres consecuencias en su propia caja, antes
   del botón, igual que el aviso de pedir la baja de un kit. A 320px un nombre
   largo en el título se parte y se lee entero. */
.baja-de-persona__titulo {
  overflow-wrap: anywhere;
}

.baja-de-persona__sector {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  overflow-wrap: anywhere;
}

.baja-de-persona__consecuencias {
  margin: 0 0 var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.baja-de-persona__intro {
  margin: 0 0 var(--espacio-2);
  font-weight: var(--tipo-seccion-peso);
}

.baja-de-persona__lista {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding-left: var(--espacio-5);
}

/* `[2026-11-06]` La confirmación de la baja de un cliente, en Operación: el
   mismo molde que la de una persona del padrón —las consecuencias en una caja
   crema, antes del botón—. */
.baja-de-sede h1 {
  overflow-wrap: anywhere;
}

.baja-de-sede__consecuencias {
  margin: 0 0 var(--espacio-5);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

.baja-de-sede__consecuencias > p {
  margin: 0 0 var(--espacio-2);
  font-weight: var(--tipo-seccion-peso);
}

.baja-de-sede__lista {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding-left: var(--espacio-5);
}

/* --- pedir capacitación (Historia 8.1, AD-8) -------------------------------
   Elegir a quién, no cuándo: una lista de tarjetas apiladas con la misma forma
   que las del padrón, con casilla solo en las anotables; quien ya espera o
   está vigente dice por qué con su palabra y no lleva casilla. El alta va
   debajo, en su propio `fieldset`, dentro del mismo formulario.

   Teléfono primero: una columna, operable a 320px, y todo texto largo se parte
   en vez de pedir scroll horizontal. Cada color, tamaño y radio sale del
   espejo. */
.pedir-capacitacion,
.recibido-pedido-de-capacitacion {
  overflow-wrap: anywhere;
}

.pedir-capacitacion .campo__control {
  min-height: var(--espacio-toque-minimo);
}

.pedir-capacitacion__sin-fecha {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

/* Los dos `fieldset` son agrupación semántica, no dibujo: sin el borde ni la
   sangría de fábrica. */
.pedir-capacitacion__gente,
.pedir-capacitacion__alta {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.pedir-capacitacion__alta {
  margin-top: var(--espacio-5);
  padding-top: var(--espacio-4);
  border-top: 1px solid var(--color-linea);
}

.pedir-capacitacion__leyenda {
  margin: 0 0 var(--espacio-3);
  padding: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
}

.pedir-capacitacion__alta-intro {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.pedir-capacitacion .campo-error p {
  margin: 0 0 var(--espacio-1);
}

.lista-para-anotar {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.para-anotar {
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
}

/* Sin casilla —espera o está vigente—: la misma forma sin la crema, para que
   no se lea como elegible. La razón la dice su renglón de situación. */
.para-anotar--sin-casilla {
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
}

.para-anotar__nombre {
  margin: 0;
  font-weight: var(--tipo-seccion-peso);
}

.para-anotar__sector,
.para-anotar__situacion {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Nadie a quien anotar: la caja neutra del vacío, no la del error. */
.pedir-capacitacion__vacio {
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
}

.pedir-capacitacion__vacio p {
  margin: 0;
}

.pedir-capacitacion__vacio .pedir-capacitacion__cubierta {
  margin-top: var(--espacio-2);
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.pedir-capacitacion__acciones {
  margin-top: var(--espacio-4);
}

.pedir-capacitacion__volver {
  margin: var(--espacio-4) 0 0;
}

.recibido-pedido-de-capacitacion__cantidad {
  margin: var(--espacio-3) 0;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.recibido-pedido-de-capacitacion__lista {
  margin: 0 0 var(--espacio-4);
  padding-left: var(--espacio-5);
}

.recibido-pedido-de-capacitacion__nada-mas {
  font-weight: var(--tipo-seccion-peso);
}

/* --- tarjeta-destacada: la propuesta de recertificación (Historia 9.2) -----
   UNA POR PANTALLA COMO MÁXIMO, y es la única pieza naranja que no es un
   control (DESIGN.md): fondo `naranja-tenue` y borde `naranja-borde`. Va en el
   inicio del portal, debajo del número de emergencia.

   Adentro, la misma forma que «Pedir capacitación»: renglones apilados con su
   casilla, sobre la superficie blanca para que se despeguen del naranja. Lo
   contestado lleva la misma forma sin casilla, con su palabra.

   Teléfono primero: una columna, operable a 320px, y todo texto largo se parte
   en vez de pedir scroll horizontal. Cada color, tamaño y radio sale del
   espejo. */
.tarjeta-destacada {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: var(--espacio-4);
  background-color: var(--color-naranja-tenue);
  border: 1px solid var(--color-naranja-borde);
  border-radius: var(--radio-lg);
  color: var(--color-tinta);
  overflow-wrap: anywhere;
}

.propuesta-recertificacion__titulo {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
}

.propuesta-recertificacion__intro {
  margin: 0 0 var(--espacio-2);
}

.propuesta-recertificacion__sin-fecha {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

/* El `fieldset` es agrupación semántica, no dibujo. */
.propuesta-recertificacion__gente {
  min-width: 0;
  margin: 0 0 var(--espacio-4);
  padding: 0;
  border: 0;
}

.propuesta-recertificacion__leyenda,
.propuesta-recertificacion__subtitulo {
  margin: 0 0 var(--espacio-3);
  padding: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-seccion-peso);
}

.propuesta-recertificacion .campo-error p {
  margin: 0 0 var(--espacio-1);
}

/* El envío por omisión (la tecla Enter sobre una casilla) no se ve ni se
   toca; y «Marcar todas» nace oculto hasta que lo muestra su controlador. Los
   dos llevan una clase de botón que declara `display`, que le ganaría al
   `hidden` de fábrica. */
.propuesta-recertificacion__por-omision[hidden],
.propuesta-recertificacion__marcar-todas[hidden] {
  display: none;
}

.propuesta-recertificacion__marcar-todas {
  min-height: var(--espacio-toque-minimo);
  margin: 0 0 var(--espacio-3);
}

.propuesta-recertificacion__lista {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.propuesta-recertificacion__renglon {
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border-radius: var(--radio-md);
}

.propuesta-recertificacion__renglon--contestado {
  border: 1px solid var(--color-linea);
}

.propuesta-recertificacion__nombre {
  margin: 0;
  font-weight: var(--tipo-seccion-peso);
}

.propuesta-recertificacion__sector,
.propuesta-recertificacion__vence,
.propuesta-recertificacion__respuesta {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.propuesta-recertificacion__ya-no-trabaja {
  min-height: var(--espacio-toque-minimo);
  margin: var(--espacio-2) 0 0 calc(-1 * var(--espacio-3));
}

.propuesta-recertificacion__acciones {
  margin-top: var(--espacio-4);
}

.propuesta-recertificacion__contestados {
  margin-top: var(--espacio-4);
}

.propuesta-recertificacion__mis-fechas {
  margin: var(--espacio-3) 0 0;
}

/* --- los certificados del personal (Historia 9.5) -------------------------
   Capacitación → «Certificados»: una tarjeta por persona con su certificado
   vigente y, si EPA ya subió el archivo, su nombre, su peso y «Descargar».
   El vacío usa la caja neutra compartida de los estados vacíos del portal.

   La falta del archivo NO ES UNA ALARMA: tinta suave, sin banda ni color de
   error. Teléfono primero: una columna, y el nombre del archivo se parte en vez
   de pedir scroll horizontal. Cada color, tamaño y radio sale del espejo. */
.certificados-portal {
  overflow-wrap: anywhere;
}

.lista-certificados {
  display: grid;
  gap: var(--espacio-3);
  margin: var(--espacio-5) 0 0;
  padding: 0;
  list-style: none;
}

.certificado-portal {
  min-width: 0;
  padding: var(--espacio-3) var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
}

.certificado-portal__nombre {
  margin: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
}

.certificado-portal__sector,
.certificado-portal__vigencia,
.certificado-portal__sin-archivo {
  margin: var(--espacio-1) 0 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.certificado-portal__vigencia {
  color: var(--color-tinta-media);
}

/* El botón baja entero antes que partirse: la columna de texto se achica. */
.certificado-portal__archivo {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-3);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--espacio-3);
}

.certificado-portal__dato {
  flex: 1 1 auto;
  min-width: 0;
}

.certificado-portal__nombre-archivo {
  display: block;
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-family: var(--tipo-dato-familia);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

.certificado-portal__peso {
  display: block;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.certificados-portal__volver {
  margin: var(--espacio-4) 0 0;
}

/* `[2026-11-05]` El cliente sube el certificado: las reglas una vez arriba de
   la lista y un formulario por persona, debajo de su archivo o de la falta. */
.certificados-portal__reglas {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.certificado-portal__forma {
  display: grid;
  gap: var(--espacio-3);
  margin: var(--espacio-3) 0 0;
}

/* --- la cola de capacitación (Historia 8.3) -------------------------------
   Capacitaciones → «Cola de capacitación». Disposición y tokens: ni un color,
   ni un tamaño, ni un radio literales.

   EL RESUMEN ES UN ESTADO NORMAL, NO UNA ALERTA: la caja neutra de crema, la
   misma del vacío, nunca los colores de atención o de error.

   NINGUNA VARIANTE NUEVA DE `.pill-estado`: la situación usa `neutro` (nunca
   capacitada), `porvencer` (vigente, con cuánto le queda) y `vencido`.

   TELÉFONO PRIMERO: cada `fila-cola` es una TARJETA de una columna, la banda de
   rótulos se oculta y cada dato lleva su rótulo visible (`.stock-celda__rotulo`,
   que en escritorio se oculta). */
.cola-resumen,
.cola-vacia {
  margin: var(--espacio-4) 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
}

.cola-resumen p,
.cola-vacia p {
  margin: 0;
}

.cola-resumen p + p,
.cola-vacia p + p {
  margin-top: var(--espacio-2);
}

.cola-resumen__total,
.cola-vacia__titulo {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

/* Los controles de orden: enlaces GET. El activo se marca con fondo Y texto
   más `aria-current`, como la sección activa de la navegación. */
.cola-orden {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
  margin: 0 0 var(--espacio-4);
}

.cola-orden__rotulo {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.cola-orden__lista {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.cola-orden__enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--espacio-toque-minimo);
  padding-inline: var(--espacio-3);
  border-radius: var(--radio-sm);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
  text-decoration: none;
}

.cola-orden__enlace:hover {
  background-color: var(--color-superficie-crema);
}

.cola-orden__enlace[aria-current="true"] {
  background-color: var(--color-naranja-tenue);
  color: var(--color-naranja-activo);
  font-weight: var(--tipo-seccion-peso);
}

.fila-cola {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.fila-cola--encabezado {
  display: none;
}

/* A 320px un nombre o una sede largos no pueden pedir scroll horizontal. */
.fila-cola > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

.fila-cola__nombre {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

/* Cuánto le queda va DEBAJO de la píldora, como texto. */
.fila-cola__quedan {
  display: block;
  margin-top: var(--espacio-1);
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* En escritorio, cinco pistas con banda de rótulos. */
@media (min-width: 48em) {
  .fila-cola {
    grid-template-columns:
      minmax(0, 2fr) minmax(0, 1.5fr) minmax(0, 2fr) minmax(0, 1.5fr) minmax(0, 1.5fr);
  }

  .fila-cola--encabezado {
    display: grid;
  }
}

/* --- armar una fecha de capacitación (Historia 8.4) -----------------------
   «Armar la fecha», su formulario y las fechas en armado de la cola. Solo
   tokens: ni un color, ni un tamaño, ni un radio literales.

   La acción «Armar una fecha» de la cola es primaria con gente y secundaria
   con la cola vacía, que sigue sin acción primaria. */
.cola-acciones {
  margin: var(--espacio-4) 0;
}

.fechas-en-armado {
  margin: var(--espacio-6) 0;
}

.fechas-en-armado__lista {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Una fila por tentativa, entera tocable. En el teléfono los datos se apilan;
   en escritorio van en una línea. */
.fechas-en-armado__enlace {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-1) var(--espacio-3);
  min-height: var(--espacio-toque-minimo);
  padding: var(--espacio-3) var(--espacio-4);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  color: var(--color-tinta);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.fechas-en-armado__enlace:hover {
  background-color: var(--color-superficie-crema);
}

.fechas-en-armado__dia {
  font-weight: var(--tipo-seccion-peso);
}

.fechas-en-armado__cantidad {
  color: var(--color-tinta-media);
}

/* Los datos de la fecha, arriba de «Armar la fecha». */
.fecha-datos {
  margin: 0 0 var(--espacio-4);
}

.fecha-datos p {
  margin: 0 0 var(--espacio-2);
}

.fecha-datos__dia {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.fecha-datos__aviso {
  color: var(--color-tinta-media);
}

/* --- medidor-de-cupo (DESIGN · medidor-de-cupo) ---------------------------
   La cifra en `typography.dato` sobre `superficie-alta`. La barra es un
   `span` por lugar que `flex: 1` reparte: el que falta hasta el mínimo en
   `linea-fuerte`, el logrado en `ok`, el que excede el máximo en `porvencer`.
   Nunca rojo: una fecha a medio llenar no es un error. */
.medidor-de-cupo {
  margin: 0 0 var(--espacio-6);
  padding: var(--espacio-3);
  background-color: var(--color-superficie-alta);
  border-radius: var(--radio-sm);
  color: var(--color-tinta);
}

.medidor-de-cupo p {
  margin: 0 0 var(--espacio-2);
}

.medidor-de-cupo__rotulo {
  color: var(--color-tinta-media);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.medidor-de-cupo__cifra,
.medidor-de-cupo__excedente {
  font-family: var(--tipo-dato-familia);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

.medidor-de-cupo__barra {
  display: flex;
  gap: var(--espacio-0-5);
  min-height: var(--espacio-2);
}

.medidor-de-cupo__tramo {
  flex: 1;
  min-width: 0;
  border-radius: var(--radio-sm);
}

.medidor-de-cupo__tramo--logrado {
  background-color: var(--color-ok);
}

.medidor-de-cupo__tramo--faltante {
  background-color: var(--color-linea-fuerte);
}

.medidor-de-cupo__tramo--excedente {
  background-color: var(--color-porvencer);
}

.medidor-de-cupo__tramo--libre {
  background-color: var(--color-superficie);
}

/* El grupo y la cola libre de «Armar la fecha» reusan `fila-cola`; se suma la
   pista del botón. «vence N días antes» va debajo de la situación, como texto. */
.fecha-grupo,
.fecha-cola {
  margin: var(--espacio-6) 0 0;
}

.fila-grupo__vence-antes {
  display: block;
  margin-top: var(--espacio-1);
  color: var(--color-porvencer);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.fila-cola__forma {
  margin: 0;
}

.fila-cola__accion {
  min-height: var(--espacio-toque-minimo);
}

.fecha-cola .fila-cola__origen {
  display: block;
  color: var(--color-tinta-media);
}

/* --- fechas armadas y confirmar (Historia 8.5) ----------------------------
   «Fechas armadas», el bloque de confirmar de la pantalla de la fecha y el
   aviso de una confirmada bajo su mínimo. Solo tokens: ni un color, ni un
   tamaño, ni un radio literales.

   Las acciones de la cola —«Armar una fecha» y «Fechas armadas»— van juntas y
   se apilan en el teléfono. */
.cola-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2) var(--espacio-3);
}

.fechas-armadas__lista {
  display: grid;
  gap: var(--espacio-4);
  margin: var(--espacio-4) 0 0;
  padding: 0;
  list-style: none;
}

/* Una fila por fecha: el enlace con los datos arriba, el medidor debajo. */
.fechas-armadas__fila {
  padding: var(--espacio-3) var(--espacio-4);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.fechas-armadas__enlace {
  display: grid;
  gap: var(--espacio-1);
  min-height: var(--espacio-toque-minimo);
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta);
  text-decoration: none;
}

.fechas-armadas__enlace:hover .fechas-armadas__dia {
  text-decoration: underline;
}

.fechas-armadas__cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-1) var(--espacio-3);
}

.fechas-armadas__dia {
  font-weight: var(--tipo-seccion-peso);
}

.fechas-armadas__sedes {
  color: var(--color-tinta-media);
}

.fechas-armadas__fila .medidor-de-cupo {
  margin: 0;
}

/* Confirmar: la línea que dice qué pasa y la primaria. */
.fecha-confirmar {
  margin: 0 0 var(--espacio-6);
}

.fecha-confirmar p {
  margin: 0 0 var(--espacio-2);
}

.fecha-confirmar__bajo-el-minimo,
.fecha-cola__aviso {
  color: var(--color-tinta-media);
}

.fecha-confirmar__forma {
  margin: var(--espacio-3) 0 0;
}

/* Una confirmada bajo su mínimo: TEXTO sobre la fecha, no una alerta. Se
   marca con `atencion`, nunca rojo, y la palabra dice qué pasa. */
.fecha-bajo-el-minimo {
  margin: var(--espacio-3) 0 var(--espacio-6);
  padding: var(--espacio-3);
  background-color: var(--color-atencion-fondo);
  border-radius: var(--radio-sm);
  color: var(--color-tinta);
}

.fecha-bajo-el-minimo p {
  margin: 0 0 var(--espacio-2);
}

.fecha-bajo-el-minimo p:last-child {
  margin: 0;
}

/* --- reprogramar o cancelar (Historia 8.6) --------------------------------
   El bloque de una confirmada con sus dos salidas secundarias, que se apilan
   en el teléfono; la línea de una dictada o cancelada; y el «qué pasa» de los
   dos formularios. Solo tokens. */
.fecha-cambios {
  margin: 0 0 var(--espacio-6);
}

.fecha-cambios__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2) var(--espacio-3);
  margin: var(--espacio-3) 0 0;
}

.fecha-cambios__que-pasa {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

.fecha-cambios__que-pasa p {
  margin: 0;
}

.fecha-datos__registro {
  color: var(--color-tinta-media);
}

/* --- registrar la capacitación dictada (Historia 9.3) ---------------------
   La entrada en la pantalla de la fecha, el formulario con una tabla por sede
   y lo registrado de una dictada. Teléfono primero: la tabla se apila por
   fila en pantallas angostas y se abre en columnas desde 48em, sin scroll
   horizontal. Solo tokens: ni un color, ni un tamaño, ni un radio literales. */
.fecha-registrar {
  margin: 0 0 var(--espacio-6);
}

.fecha-registrar p {
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta-media);
}

.registro-de-capacitacion {
  overflow-wrap: anywhere;
}

.registro-de-capacitacion .campo__control {
  min-height: var(--espacio-toque-minimo);
}

.registro-de-capacitacion__intro {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-media);
}

.registro-sede {
  margin: var(--espacio-6) 0 0;
}

.registro-sede__titulo {
  margin: 0 0 var(--espacio-3);
}

.registro-sede__vacia {
  margin: 0;
  color: var(--color-tinta-media);
}

.tabla-registro {
  width: 100%;
  border-collapse: collapse;
}

.tabla-registro thead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.tabla-registro,
.tabla-registro tbody,
.tabla-registro tr,
.tabla-registro td {
  display: block;
}

.tabla-registro__fila {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--espacio-1) var(--espacio-3);
  padding: var(--espacio-3) 0;
  border-bottom: 1px solid var(--color-linea);
}

.tabla-registro__casilla {
  grid-row: span 3;
  padding-top: var(--espacio-1);
}

.tabla-registro__nombre {
  display: block;
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.tabla-registro__sector,
.tabla-registro__situacion {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.tabla-registro__sector {
  display: block;
}

/* Marcar a una vigente le cambia la certificación: se dice con palabra, en la
   paleta `atencion`, nunca solo con color. */
.tabla-registro__advertencia {
  display: block;
  margin-top: var(--espacio-1);
  color: var(--color-atencion);
  font-weight: var(--tipo-seccion-peso);
}

.tabla-registro__vence .campo__control {
  width: 100%;
}

@media (min-width: 48em) {
  .tabla-registro {
    display: table;
  }

  .tabla-registro thead {
    position: static;
    display: table-header-group;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
  }

  .tabla-registro tbody {
    display: table-row-group;
  }

  .tabla-registro tr,
  .tabla-registro__fila {
    display: table-row;
  }

  .tabla-registro th,
  .tabla-registro td {
    display: table-cell;
    padding: var(--espacio-3) var(--espacio-2);
    border-bottom: 1px solid var(--color-linea);
    text-align: left;
    vertical-align: top;
  }

  .tabla-registro th {
    color: var(--color-tinta-media);
    font-size: var(--tipo-cuerpo-sm-tamano);
    font-weight: var(--tipo-seccion-peso);
  }
}

.registro-de-capacitacion__acciones {
  margin-top: var(--espacio-5);
}

/* Los dos `fieldset` de abajo son agrupación semántica, no dibujo. */
.registro-de-capacitacion__extra {
  min-width: 0;
  margin: var(--espacio-5) 0 0;
  padding: var(--espacio-4) 0 0;
  border: 0;
  border-top: 1px solid var(--color-linea);
}

.registro-de-capacitacion__leyenda {
  margin: 0 0 var(--espacio-3);
  padding: 0;
  color: var(--color-tinta);
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
}

.registro-de-capacitacion__ayuda {
  margin: 0 0 var(--espacio-4);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Lo registrado de una dictada: por sede, el tipo y el día, y cada
   participante con su vencimiento. Sin botones. */
.fecha-dictada {
  margin: 0 0 var(--espacio-6);
}

.fecha-dictada__sede {
  margin: var(--espacio-4) 0 0;
  padding: var(--espacio-3) var(--espacio-4);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.fecha-dictada__nombre {
  margin: 0 0 var(--espacio-1);
}

.fecha-dictada__tipo {
  margin: 0 0 var(--espacio-3);
  color: var(--color-tinta-media);
}

.fecha-dictada__participantes {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.fecha-dictada__participante {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-1) var(--espacio-3);
}

.fecha-dictada__persona {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.fecha-dictada__vence {
  color: var(--color-tinta-media);
}

/* Historia 9.4 — el certificado de cada participante. Las reglas van al inicio
   de la sección, antes de cualquier campo de archivo; debajo de cada persona, el
   archivo que tiene (o que le falta) y su formulario propio, cada uno en su
   propia línea del renglón. Ni un color, ni un tamaño que no salga del espejo. */
.fecha-dictada__reglas {
  margin: 0 0 var(--espacio-1);
  color: var(--color-tinta-media);
}

.fecha-dictada__donde {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.fecha-dictada__participante + .fecha-dictada__participante {
  padding-top: var(--espacio-2);
  border-top: 1px solid var(--color-linea);
}

.fecha-dictada__certificado {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--espacio-1) var(--espacio-2);
  margin: 0;
  color: var(--color-tinta-media);
}

.fecha-dictada__certificado--falta {
  color: var(--color-tinta-suave);
}

.fecha-dictada__archivo {
  overflow-wrap: anywhere;
  color: var(--color-tinta);
  font-family: var(--tipo-dato-familia);
  font-size: var(--tipo-dato-tamano);
  font-weight: var(--tipo-dato-peso);
  line-height: var(--tipo-dato-interlinea);
}

.fecha-dictada__entrega {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

.fecha-dictada__forma {
  flex-basis: 100%;
  margin: 0;
}

.fechas-dictadas {
  margin: var(--espacio-6) 0 0;
}

/* Historia 9.6 — «Recertificaciones sin respuesta». Un RESUMEN NORMAL, no una
   alerta: sin colores de alarma. Una tarjeta por sede, de una columna en el
   teléfono; la vacía es la buena noticia de la cola (`.cola-vacia`). */
.sin-respuesta-vacia {
  margin: var(--espacio-4) 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-md);
  color: var(--color-tinta-media);
}

.sin-respuesta-vacia p {
  margin: 0;
}

.sin-respuesta-vacia p + p {
  margin-top: var(--espacio-2);
}

.sin-respuesta-vacia__titulo {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.sin-respuesta__lista {
  display: grid;
  gap: var(--espacio-4);
  margin: var(--espacio-4) 0 0;
  padding: 0;
  list-style: none;
}

.sin-respuesta__sede {
  padding: var(--espacio-4);
  border: 1px solid var(--color-linea-fuerte);
  border-radius: var(--radio-md);
  overflow-wrap: anywhere;
}

.sin-respuesta__sede p {
  margin: 0 0 var(--espacio-2);
  color: var(--color-tinta-media);
}

.sin-respuesta__nombre {
  margin: 0 0 var(--espacio-2);
}

.sin-respuesta__rotulo {
  color: var(--color-tinta-suave);
}

.sin-respuesta__telefono a {
  display: inline-flex;
  align-items: center;
  min-height: var(--espacio-toque-minimo);
}

.sin-respuesta__cobertura,
.sin-respuesta__cantidad {
  color: var(--color-tinta);
  font-weight: var(--tipo-seccion-peso);
}

.sin-respuesta__personas {
  display: grid;
  gap: var(--espacio-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sin-respuesta__persona {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-1) var(--espacio-3);
}

.sin-respuesta__persona-nombre {
  color: var(--color-tinta);
}

.sin-respuesta__vence {
  color: var(--color-tinta-media);
}

/* Operación → «Prevención» (Historia 14.2): las propuestas de reposición por
   vencimiento, un bloque por cliente con sus kits adentro y, en cada kit, sus
   propuestas. Disposición y nada más: la urgencia va en las píldoras que ya
   existen —`--vencido`, `--atencion`, `--porvencer`, `--neutro`—, siempre con
   su palabra.

   TELÉFONO PRIMERO: cada cliente es una TARJETA de una columna y cada insumo
   lleva el rótulo de cada dato visible. A 320px un nombre de sede, una
   dirección o una ubicación largos se parten: nunca piden scroll horizontal. */
.propuestas-preventivas {
  overflow-wrap: anywhere;
}

.propuestas-preventivas__bajada {
  margin: var(--espacio-2) 0 0;
  color: var(--color-tinta-suave);
}

.propuestas-preventivas__grupos {
  display: grid;
  gap: var(--espacio-6);
  margin-top: var(--espacio-6);
}

.propuestas-preventivas__grupo {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-4);
  min-width: 0;
  padding: var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-linea);
  border-radius: var(--radio-md);
}

.propuestas-preventivas__grupo > * {
  min-width: 0;
}

/* Historia 14.7 — la sección de arriba: lo vencido en un kit que ninguna
   propuesta activa incluye. Una tarjeta como la de un cliente, con el borde
   del estado vencido; cada renglón es su píldora, su frase y el enlace al kit,
   que se parten a 320px. */
.propuestas-preventivas__vencidos {
  display: grid;
  gap: var(--espacio-2);
  min-width: 0;
  margin-top: var(--espacio-6);
  padding: var(--espacio-4);
  background-color: var(--color-superficie);
  border: 1px solid var(--color-vencido);
  border-radius: var(--radio-md);
}

.propuestas-preventivas__vencidos-lista {
  display: grid;
  gap: var(--espacio-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.propuestas-preventivas__vencido {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--espacio-2);
  min-width: 0;
}

.propuestas-preventivas__cabecera {
  display: grid;
  gap: var(--espacio-2);
}

.propuestas-preventivas__cliente {
  margin: 0;
  font-size: var(--tipo-seccion-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-seccion-interlinea);
}

.propuestas-preventivas__direccion,
.propuestas-preventivas__generada {
  margin: 0;
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Las píldoras del grupo, en una línea que se parte si no entra. */
.propuestas-preventivas__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  margin: 0;
}

/* La oferta de consolidar: palabras, no botón (el botón es de la 14.3). */
.propuestas-preventivas__consolidar {
  margin: 0;
  padding: var(--espacio-2) var(--espacio-3);
  background-color: var(--color-atencion-fondo);
  border-radius: var(--radio-sm);
}

.propuestas-preventivas__kit {
  display: grid;
  gap: var(--espacio-3);
  padding-top: var(--espacio-3);
  border-top: 1px solid var(--color-linea);
}

.propuestas-preventivas__kit-nombre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--espacio-2);
  margin: 0;
  font-size: var(--tipo-cuerpo-tamano);
  font-weight: var(--tipo-seccion-peso);
  line-height: var(--tipo-cuerpo-interlinea);
}

.propuestas-preventivas__propuesta {
  display: grid;
  gap: var(--espacio-2);
}

.propuestas-preventivas__insumos {
  display: grid;
  gap: var(--espacio-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Un insumo: una columna en teléfono, tres desde que entran. */
.propuestas-preventivas__insumo {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--espacio-2);
  padding: var(--espacio-2) var(--espacio-3);
  background-color: var(--color-superficie-crema);
  border-radius: var(--radio-sm);
}

.propuestas-preventivas__dato {
  min-width: 0;
}

.propuestas-preventivas__rotulo {
  display: block;
  color: var(--color-tinta-media);
  font-size: var(--tipo-etiqueta-tamano);
  font-weight: var(--tipo-etiqueta-peso);
  line-height: var(--tipo-etiqueta-interlinea);
  letter-spacing: var(--tipo-etiqueta-espaciado);
}

@media (min-width: 48em) {
  .propuestas-preventivas__insumo {
    grid-template-columns: minmax(0, 2fr) minmax(0, 2fr) minmax(0, 1fr);
  }
}

/* Las acciones de una propuesta (Historia 14.3): Editar, Juntar y Cancelar…,
   en una fila que se parte en teléfono. Nada pide scroll horizontal. */
.propuestas-preventivas__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--espacio-2);
  align-items: center;
}

/* `button_to` envuelve el botón en un `<form>` de bloque: sin margen propio.
   «Sacar de espera» (Historia 14.4) también. */
.propuestas-preventivas__juntar,
.propuestas-preventivas__sacar {
  margin: 0;
}

/* Una propuesta pospuesta (Historia 14.4): la píldora «Esperando compañía»
   —la `--neutro` que ya existe, con su palabra—, el motivo y cuándo vuelve
   sola. Disposición y tokens, nada más. */
.propuestas-preventivas__espera {
  display: grid;
  gap: var(--espacio-2);
}

.propuestas-preventivas__motivo,
.propuestas-preventivas__vuelve {
  margin: 0;
}

.propuestas-preventivas__vuelve {
  color: var(--color-tinta-suave);
  font-size: var(--tipo-cuerpo-sm-tamano);
  font-weight: var(--tipo-cuerpo-sm-peso);
  line-height: var(--tipo-cuerpo-sm-interlinea);
}

/* Lo que propone la propuesta que se cancela (Historia 14.3). */
.cancelacion-propuesta__insumos {
  margin: 0 0 var(--espacio-3);
}
