/* ============================================================
   Penwork — componentes del sistema de diseño

   Piezas reutilizables: botón, caja, ficha, tabla, badges,
   formularios, mensajes, toast, modal, pestañas y matriz.

   Ni un literal de color: todo sale de `tokens.css`. Ni un
   `style=` en el marcado que las use: la CSP del producto declara
   `style-src 'self'` sin `unsafe-inline`, así que la geometría se
   coloca con clases y, cuando de verdad es dinámica, desde el
   CSSOM en JavaScript (`elemento.style.width`), que la CSP no
   bloquea. El `macros/ui.j2` del sistema de 4d3 coloca geometría
   con `style=`: ese patrón NO se copia aquí.
   ============================================================ */

/* ============================================================
   Contratos de superficie
   ============================================================
   Un componente no hereda el color del sitio donde cae: lo
   declara. Cada superficie redefine los tokens SEMÁNTICOS de su
   subárbol —texto, texto secundario y anillo de foco— y con eso
   `.tenue`, las cabeceras de tabla, las etiquetas de ficha y el
   foco se resuelven solos, sin una regla por combinación.

   El fallo que esto evita, y que ocurrió en el primer render de la
   landing: la matriz del cuadro vive dentro de una sección negra,
   heredó el texto blanco y los nombres de las personas quedaron
   blancos sobre blanco. Invisibles, sin un error en consola y sin
   que ningún linter lo notara.
   ============================================================ */

/* Superficie clara: restablece el texto oscuro aunque el contenedor sea negro. */
.tarjeta,
.ficha,
.tabla,
.matriz,
.matriz-env,
.caja-codigo,
.vacio,
.conversacion,
.soltar,
.pestanas,
.insignia,
.toast.ok,
.toast.peligro {
  --txt:   var(--negro);
  --txt-2: var(--tinta-2);
  --txt-3: var(--tinta-3);
  --foco:  var(--azul);
  color: var(--txt);
}

/* Superficie oscura: texto blanco, secundario plata y foco mantequilla — el
   azul sobre negro se queda en 2,45:1 y no vale como anillo. El fondo lo pone
   cada componente; esto es solo el contrato de color. */
.oscuro,
.lateral,
.asistente > .rail,
.cierre,
.tarjeta.azul,
.aviso-caja.accion,
.ficha > .cab,
.caja-codigo > .cab,
.toast {
  --txt:   var(--blanco);
  --txt-2: var(--plata);
  --txt-3: var(--plata);
  --foco:  var(--foco-oscuro);
  color: var(--txt);
}

/* --- Botón --------------------------------------------------------------- */
/* La acción primaria de la identidad: relleno azul, borde negro de 2px y
   sombra dura desplazada que crece al pasar por encima. El movimiento se anula
   entero bajo `prefers-reduced-motion` (regla en `base.css`). */

.boton {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-cuerpo);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  padding: var(--esp-2) var(--esp-4);
  border: var(--borde-ancho) solid var(--borde);
  background: var(--azul);
  color: var(--blanco);
  cursor: pointer;
  box-shadow: var(--sombra);
  transition: transform var(--micro), box-shadow var(--micro), background var(--micro);
}
.boton:hover {
  background: var(--azul-osc);
  color: var(--blanco);
  transform: var(--alza);
  box-shadow: var(--sombra-alta);
}
.boton:active { transform: var(--hunde); box-shadow: var(--sombra-hundida); }
.boton:disabled,
.boton[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* Secundario: sin relleno. El borde negro de 2px es lo que lo identifica, así
   que cumple 1.4.11 de sobra (18,58:1) sin depender del color. */
.boton.secundario {
  background: var(--papel);
  color: var(--negro);
}
.boton.secundario:hover { background: var(--gris); color: var(--negro); }

/* Mantequilla: la llamada de la landing y las confirmaciones amables. */
.boton.mantequilla {
  background: var(--mantequilla);
  color: var(--negro);
}
.boton.mantequilla:hover { background: var(--mantequilla); color: var(--negro); }

/* Peligro: destruye algo. Rojo sobre blanco da 6,22, y el borde sigue negro
   para que no sea el color lo único que lo distingue. */
.boton.peligro {
  background: var(--papel);
  color: var(--rojo);
}
.boton.peligro:hover { background: var(--tinte-rojo); color: var(--rojo); }

.boton.grande { font-size: var(--texto-guia); padding: var(--esp-3) var(--esp-5); }
.boton.pequeno {
  font-size: var(--texto-menudo);
  padding: var(--esp-1) var(--esp-2);
  border-width: var(--borde-ancho-fino);
  box-shadow: var(--sombra-baja);
}
.boton.secundario.pequeno, .boton.peligro.pequeno { box-shadow: none; }
.boton.pequeno:hover { transform: var(--alza-corta); box-shadow: var(--sombra-hundida); }

/* Sobre superficie oscura el botón se vuelve contorno blanco. */
.oscuro .boton.secundario {
  background: transparent;
  color: var(--blanco);
  border-color: var(--blanco);
}
.oscuro .boton.secundario:hover { background: var(--negro-2); color: var(--blanco); }

/* Botón que parece un enlace: acciones terciarias dentro de tablas y fichas.
   Subrayado siempre, para no depender del color. */
button.enlace,
.enlace {
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  color: var(--azul);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
button.enlace:hover, .enlace:hover { color: var(--azul-osc); }
button.enlace:disabled { opacity: 0.45; cursor: not-allowed; }

.acciones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  align-items: center;
}

/* --- Caja con sombra dura ------------------------------------------------ */
/* `.tarjeta` es la caja de la identidad. La sombra es opcional: dentro de una
   rejilla densa (el panel de la aplicación) resta más que aporta, y por eso la
   variante `.plana` existe. */

/* Cada componente que pinta su propia superficie clara declara TAMBIÉN su
   color de texto. Sin eso, una tarjeta dentro de una `.seccion.oscuro` hereda
   el blanco del contenedor y queda blanco sobre blanco: invisible, sin un solo
   error y sin que ningún linter lo note. Le pasó a la matriz del cuadro en el
   primer render de la landing — los nombres de las personas desaparecieron. */
.tarjeta {
  background: var(--papel);
  color: var(--txt);
  border: var(--borde-ancho) solid var(--borde);
  padding: var(--esp-4);
  box-shadow: var(--sombra-alta);
}
.tarjeta.plana { box-shadow: none; border-width: var(--borde-ancho-fino); padding: 0; }
.tarjeta.estrecha { max-width: 34rem; margin-inline: auto; }
.tarjeta.texto { box-shadow: none; }
.tarjeta.destacada { background: var(--mantequilla); }
.tarjeta.seria { background: var(--tinte-rojo); border-color: var(--rojo); }
.tarjeta.azul { background: var(--azul); color: var(--blanco); }
.tarjeta.gris { background: var(--gris); }

.tarjeta > h1, .tarjeta > h2, .tarjeta > h3 { margin-bottom: var(--esp-2); }
.tarjeta > p + p,
.tarjeta > p + ul,
.tarjeta > * + .acciones { margin-top: var(--esp-3); }

/* Cabecera de tarjeta: título, cuenta y acciones a la derecha. */
.tarjeta > header {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  padding: var(--esp-2) var(--esp-4);
  border-bottom: 1px solid var(--borde-fino);
  margin: calc(-1 * var(--esp-4)) calc(-1 * var(--esp-4)) var(--esp-3);
}
.tarjeta.plana > header { margin: 0; }
.tarjeta > header > .der { margin-left: auto; display: flex; gap: var(--esp-1); }

/* Cifra de cabecera: «6 en la bóveda», «3 cesiones activas». */
.cuenta {
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-micro);
  background: var(--gris);
  color: var(--negro);
  padding: var(--esp-0) var(--esp-1);
  white-space: nowrap;
}
.contador {
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-menudo);
  background: var(--mantequilla);
  color: var(--negro);
  padding: var(--esp-1) var(--esp-2);
  white-space: nowrap;
}

/* --- Sección oscura ----------------------------------------------------- */
/* Bloque a sangre en negro. Marca a sus hijos con `.oscuro` para que el foco
   pase a mantequilla y los botones cambien de variante. */

/* `.oscuro` es un CONTRATO, no solo un fondo: marca «esta superficie es
   oscura» para que el anillo de foco pase a mantequilla, el botón secundario
   se vuelva contorno blanco y los rótulos cambien de color. El fondo negro es
   su valor por defecto, y cualquier regla más específica lo sustituye — así
   `.aviso-caja.accion.oscuro` y `.cierre.oscuro` son azules y siguen teniendo
   el contrato. */
.oscuro {
  background: var(--negro);
}
.oscuro .rotulo { color: var(--mantequilla); }
.oscuro a:hover { color: var(--mantequilla); }

/* --- Rejilla ------------------------------------------------------------ */

.rejilla { display: grid; gap: var(--esp-4); }
.rejilla.dos { grid-template-columns: repeat(2, 1fr); }
.rejilla.tres { grid-template-columns: repeat(3, 1fr); }
/* Tabla más ficha lateral: el patrón de las pantallas de trabajo. */
.rejilla.con-ficha { grid-template-columns: 1fr var(--ficha); align-items: start; }

@media (max-width: 1100px) {
  .rejilla.con-ficha { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
  .rejilla.dos, .rejilla.tres { grid-template-columns: 1fr; }
}

/* --- Tabla -------------------------------------------------------------- */

.tabla-env { overflow-x: auto; }

.tabla {
  border-collapse: collapse;
  width: 100%;
  color: var(--txt);
}
.tabla thead th {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-micro);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--txt-2);
  text-align: left;
  padding: var(--esp-1) var(--esp-3);
  background: var(--gris-3);
  border-bottom: 1px solid var(--borde-fino);
  white-space: nowrap;
}
.tabla tbody tr { border-bottom: 1px solid var(--borde-fino); }
.tabla tbody tr:last-child { border-bottom: 0; }
.tabla tbody tr:hover { background: var(--tinte-azul); }
.tabla tbody tr.sel {
  background: var(--tinte-azul-2);
  box-shadow: inset 3px 0 0 var(--azul);
}
.tabla th[scope="row"] {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-cuerpo);
  text-align: left;
}
.tabla td, .tabla th[scope="row"] {
  padding: var(--esp-2) var(--esp-3);
  vertical-align: middle;
}
.tabla .secundario-linea {
  display: block;
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: var(--texto-menudo);
  color: var(--txt-2);
}

/* --- Badges de estado --------------------------------------------------- */
/* Los tonos NO pueden llamarse `error`, `exito`, `aviso` ni `cargando`: esos
   cuatro son nombres de componente (los mensajes, más abajo) y la cascada los
   suma. Un `.insignia.error` heredaba el `display: block`, el relleno, el borde
   izquierdo y el `✖` del `::before` del mensaje, y el badge salía con dos
   símbolos y del ancho de la celda. De ahí `peligro`. */
/* Ningún estado se distingue solo por color: cada uno lleva su símbolo en el
   marcado (`● ○ ✖ ✔ ▲`), que además sobrevive a una impresión en blanco y
   negro. Los símbolos no están en el subconjunto latino de las fuentes y caen
   al del sistema, igual que en el sistema anterior. */

.insignia {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-0);
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-micro);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 2px var(--esp-1);
  white-space: nowrap;
  background: var(--gris);
  color: var(--txt-2);
}
.insignia.ok      { background: var(--mantequilla); color: var(--negro); }
.insignia.activa  { background: var(--azul); color: var(--blanco); }
.insignia.neutra  { background: var(--gris); color: var(--txt-2); }
.insignia.peligro { background: var(--tinte-rojo); color: var(--rojo); box-shadow: inset 0 0 0 1.5px var(--rojo); }
.insignia.fuerte  { background: var(--negro); color: var(--blanco); }

/* Estados en celda de tabla, sin caja. */
.estado-ok    { color: var(--negro); }
.estado-aviso { color: var(--txt-2); }
.estado-error { color: var(--rojo); }

/* --- Ficha lateral ------------------------------------------------------ */

.ficha {
  background: var(--papel);
  color: var(--txt);
  border: var(--borde-ancho-fino) solid var(--borde);
}
.ficha > .cab {
  background: var(--negro);
  color: var(--sobre-negro);
  padding: var(--esp-3);
}
.ficha > .cab .a {
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-h2);
}
.ficha > .cab .b {
  font-size: var(--texto-menudo);
  color: var(--sobre-negro-2);
  margin-top: 3px;
}
.ficha .acc { padding: var(--esp-3); display: flex; flex-wrap: wrap; gap: var(--esp-1); }

/* --- Listas de definición: los datos de una ficha ---------------------- */

.datos, .ejes { margin: 0; }
.datos > div, .ejes > div {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: var(--esp-2);
  padding: var(--esp-2) var(--esp-3);
  border-bottom: 1px solid var(--borde-fino);
}
.datos > div:last-child, .ejes > div:last-child { border-bottom: 0; }
.datos dt, .ejes dt {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--txt-2);
  padding-top: 2px;
}
.datos dd, .ejes dd {
  margin: 0;
  font-size: var(--texto-cuerpo);
  /* Una ficha recibe identificadores que no tienen dónde partirse: un número de
     serie de 40 hexadecimales es una sola «palabra» y se salía de la caja. Con
     `anywhere` el navegador parte donde haga falta, y solo cuando hace falta
     —a diferencia de `break-all`, que partiría también las palabras normales—. */
  overflow-wrap: anywhere;
}
.datos dd code, .ejes dd code { overflow-wrap: anywhere; }

@media (max-width: 560px) {
  .datos > div, .ejes > div { grid-template-columns: 1fr; gap: 3px; }
}

/* Barra de progreso fina (vigencia, fuerza, avance). El ancho lo escribe el
   JavaScript desde el CSSOM, nunca un `style=` en la plantilla. */
.barrita { display: block; height: 7px; background: var(--gris); margin-top: 7px; }
.barrita i { display: block; height: 100%; background: var(--azul); }
.barrita i.pronto { background: var(--rojo); }
/* Deciles para marcado estático. El JavaScript prefiere escribir el ancho por
   el CSSOM (`elemento.style.width`), que es exacto y la CSP no bloquea; estas
   clases existen para las plantillas y los ejemplos, donde no hay JS que lo
   calcule. */
.barrita i.d1 { width: 10%; } .barrita i.d2 { width: 20%; }
.barrita i.d3 { width: 30%; } .barrita i.d4 { width: 40%; }
.barrita i.d5 { width: 50%; } .barrita i.d6 { width: 60%; }
.barrita i.d7 { width: 70%; } .barrita i.d8 { width: 80%; }
.barrita i.d9 { width: 90%; } .barrita i.d10 { width: 100%; }

/* --- Lista con viñeta -------------------------------------------------- */

.lista { list-style: none; margin: 0; padding: 0; }
.lista li {
  position: relative;
  padding: var(--esp-2) 0 var(--esp-2) var(--esp-4);
  border-bottom: 1px solid var(--borde-fino);
}
.lista li:last-child { border-bottom: 0; }
.lista li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--esp-2) + 0.55em);
  width: 10px;
  height: 10px;
  background: var(--mantequilla);
  box-shadow: inset 0 0 0 1.5px var(--negro);
}

/* Comparativa a dos columnas: «como se hace hoy» / «con Penwork». */
.comparativa {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: var(--borde-ancho) solid var(--borde);
}
.comparativa > .col { padding: var(--esp-5); }
.comparativa > .col:first-child {
  border-right: var(--borde-ancho) solid var(--borde);
  background: var(--gris);
}
.comparativa ul { list-style: none; margin: 0; padding: 0; }
.comparativa li {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: var(--esp-2);
  padding: var(--esp-2) 0;
  border-bottom: 1px solid var(--borde-fino);
}
.comparativa li:last-child { border-bottom: 0; }
.comparativa .m { font-family: var(--tipo-titulo); font-weight: 900; }
.comparativa > .col:first-child .m { color: var(--rojo); }
.comparativa > .col:last-child .m { color: var(--azul); }

@media (max-width: 800px) {
  .comparativa { grid-template-columns: 1fr; }
  .comparativa > .col:first-child {
    border-right: 0;
    border-bottom: var(--borde-ancho) solid var(--borde);
  }
}

/* --- Estado vacío ----------------------------------------------------- */

.vacio {
  border: var(--borde-ancho) dashed var(--borde-fino);
  background: var(--papel);
  color: var(--txt);
  padding: var(--esp-6) var(--esp-4);
  text-align: center;
}
.vacio p { max-width: 46ch; margin-inline: auto; }
.vacio p + p { margin-top: var(--esp-3); }

/* --- Formularios ------------------------------------------------------ */

.campo { margin-top: var(--esp-4); }

label {
  display: block;
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  margin-bottom: var(--esp-1);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="date"],
input[type="number"],
select,
textarea {
  width: 100%;
  padding: var(--esp-2) var(--esp-2);
  border: var(--borde-ancho-fino) solid var(--borde);
  border-radius: 0;
  background: var(--papel);
  color: var(--txt);
  font-family: var(--tipo-texto);
  font-size: var(--texto-cuerpo);
}
input::placeholder, textarea::placeholder { color: var(--txt-3); opacity: 1; }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: var(--rojo); border-width: var(--borde-ancho); }
input:disabled, select:disabled, textarea:disabled { background: var(--gris-3); color: var(--txt-2); }

/* La ayuda de un campo. Nunca es el único sitio donde vive una restricción
   importante: eso va en el propio mensaje de error. */
.ayuda {
  font-size: var(--texto-menudo);
  color: var(--txt-2);
  margin-top: var(--esp-1);
}

/* Casilla con etiqueta larga al lado: el patrón de las confirmaciones. */
.casilla {
  display: flex;
  gap: var(--esp-2);
  align-items: flex-start;
  margin-top: var(--esp-4);
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: var(--texto-cuerpo);
  cursor: pointer;
}
/* 24px, no 22: cuando la casilla va sola en una celda de tabla —sin etiqueta
   visible que ensanche el blanco de pulsación— los 22px incumplían el criterio
   2.5.8 de WCAG 2.2 (objetivo mínimo de 24×24 CSS), que es nivel AA. */
.casilla input {
  width: 24px;
  height: 24px;
  accent-color: var(--azul);
  margin: 1px 0 0;
  flex: 0 0 auto;
}

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  align-items: flex-end;
  margin-bottom: var(--esp-4);
}
.filtros input, .filtros select { width: auto; min-width: 12rem; }
.filtros label { margin-bottom: 0; }

/* Medidor de fuerza: cuatro tramos. El texto que lo acompaña dice lo mismo,
   así que quien no distinga el color no se queda sin la información. */
.medidor { display: flex; gap: 5px; margin-top: var(--esp-1); }
.medidor span { height: 6px; flex: 1; background: var(--gris-2); }
.medidor span.on { background: var(--azul); }
.medidor span.on.alto { background: var(--negro); }
.medidor-txt {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  margin-top: var(--esp-1);
}

/* Zona de arrastre. El borde va en `--txt-3` (5,45:1) y no en `--borde-fino`
   (1,47:1) porque esto **es un control**: recibe el fichero, tiene su botón y su
   `cursor: pointer`, y su único límite visual es esa línea. La justificación de
   `--borde-fino` —«separador decorativo que no identifica ningún control»— vale
   para `.vacio`, que solo informa, pero no aquí. Lo destapó la auditoría de la
   Fase 2a-ter, donde la zona de arrastre está en primer plano. */
.soltar {
  margin-top: var(--esp-4);
  border: var(--borde-ancho) dashed var(--txt-3);
  background: var(--papel);
  color: var(--txt);
  padding: var(--esp-6) var(--esp-4);
  text-align: center;
  cursor: pointer;
}
.soltar:hover { border-color: var(--azul); }
/* Dos estados distintos: `.encima` es «hay algo arrastrándose sobre la zona» y
   `.lleno` es «ya hay un documento elegido». */
.soltar.encima { border-color: var(--azul); background: var(--tinte-azul); }
.soltar.lleno { border-style: solid; border-color: var(--azul); background: var(--tinte-azul); }
.soltar .tit { font-family: var(--tipo-titulo); font-weight: 700; font-size: var(--texto-h2); }
.soltar .sub { font-size: var(--texto-menudo); color: var(--txt-2); margin-top: var(--esp-0); }

/* Separador «o» entre dos vías de entrada. La regla se dibuja con dos
   pseudo-elementos para que la palabra quede centrada sin marcado extra. */
.separador-o {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  margin: var(--esp-3) 0;
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  color: var(--txt-2);
}
.separador-o::before, .separador-o::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--borde-fino);
}

/* --- Mensajes -------------------------------------------------------- */
/* Cada uno lleva su símbolo en `::before`: el color no es lo único que
   distingue un error de un acierto. */

.error, .exito, .aviso, .cargando {
  display: block;
  font-size: var(--texto-cuerpo);
  padding: var(--esp-2) var(--esp-3);
  margin-top: var(--esp-3);
  border-left: 4px solid var(--borde-fino);
  background: var(--gris-3);
}
.error::before, .exito::before, .aviso::before, .cargando::before {
  font-family: var(--tipo-titulo);
  font-weight: 900;
  margin-right: var(--esp-1);
}
.error   { background: var(--tinte-rojo); border-left-color: var(--rojo); color: var(--rojo); }
.error::before   { content: "\2716"; }        /* ✖ */
.exito   { background: var(--tinte-mantequilla); border-left-color: var(--mantequilla); color: var(--negro); }
.exito::before   { content: "\2714"; }        /* ✔ */
.aviso   { background: var(--gris); border-left-color: var(--negro); color: var(--negro); }
.aviso::before   { content: "\25B2"; }        /* ▲ */
.cargando { background: var(--tinte-azul); border-left-color: var(--azul); color: var(--negro); }
.cargando::before { content: "\25CF"; }       /* ● */

/* Nota al margen: informa sin ser un estado. */
.nota {
  margin-top: var(--esp-4);
  border-left: 4px solid var(--mantequilla);
  background: var(--tinte-mantequilla);
  padding: var(--esp-3);
  font-size: var(--texto-cuerpo);
}
.nota b { font-family: var(--tipo-titulo); font-weight: 900; }
.nota.seria { border-left-color: var(--rojo); background: var(--tinte-rojo); }

/* --- Toast ----------------------------------------------------------- */
/* Confirmación efímera de una acción. Vive fuera de cualquier contenedor que
   htmx sustituya, es `role="status"` y no roba el foco: quien esté navegando
   con teclado no pierde el sitio. */

.toasts {
  position: fixed;
  right: var(--esp-3);
  bottom: var(--esp-3);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
  max-width: min(26rem, calc(100vw - 2 * var(--esp-3)));
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--esp-2);
  background: var(--negro);
  color: var(--sobre-negro);
  border: var(--borde-ancho) solid var(--negro);
  box-shadow: var(--sombra);
  padding: var(--esp-2) var(--esp-3);
  font-size: var(--texto-cuerpo);
}
.toast.ok    { background: var(--mantequilla); color: var(--negro); border-color: var(--negro); }
.toast.peligro { background: var(--tinte-rojo); color: var(--rojo); border-color: var(--rojo); }
.toast .cerrar {
  margin-left: auto;
  background: none;
  border: 0;
  color: inherit;
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-h2);
  line-height: 1;
  cursor: pointer;
}

/* --- Modal ----------------------------------------------------------- */

dialog {
  border: var(--borde-ancho) solid var(--borde);
  border-radius: 0;
  padding: 0;
  background: var(--papel);
  color: var(--txt);
  box-shadow: var(--sombra-elevada);
  max-width: min(34rem, calc(100vw - 2 * var(--esp-4)));
  width: 100%;
}
dialog::backdrop { background: var(--negro); opacity: 0.55; }
dialog > form, dialog > .cuerpo { padding: var(--esp-4); }
dialog h2 { margin-bottom: var(--esp-2); }
dialog .acciones { margin-top: var(--esp-4); justify-content: flex-end; }

/* --- Pestañas -------------------------------------------------------- */
/* La activa se distingue por relleno negro Y por atributo, no solo por color.
   Se admiten las dos semánticas a propósito: `aria-selected` para un widget de
   pestañas gobernado por JavaScript, y `aria-current="page"` cuando las
   pestañas son en realidad **enlaces a dos URL distintas**, que es el caso de
   Compartidos. Fingir un `role="tab"` sobre un enlace que navega es peor para
   un lector de pantalla que decir la verdad: son navegación. */

.pestanas {
  display: flex;
  gap: var(--esp-0);
  border-bottom: var(--borde-ancho) solid var(--borde);
  margin-bottom: var(--esp-4);
}
.pestanas a, .pestanas button {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-cuerpo);
  padding: var(--esp-2) var(--esp-3);
  border: var(--borde-ancho) solid var(--borde);
  border-bottom: 0;
  background: var(--gris-3);
  color: var(--txt-2);
  text-decoration: none;
  cursor: pointer;
  margin-bottom: calc(-1 * var(--borde-ancho));
}
.pestanas a:hover, .pestanas button:hover { background: var(--gris); color: var(--negro); }
.pestanas [aria-selected="true"],
.pestanas [aria-current="page"] {
  background: var(--negro);
  color: var(--blanco);
  border-color: var(--negro);
}
.pestanas [aria-selected="true"]:hover,
.pestanas [aria-current="page"]:hover { background: var(--negro); color: var(--blanco); }

/* --- Matriz ---------------------------------------------------------- */
/* El cuadro de permisos: filas de personas, columnas de certificados, celdas
   con `aria-pressed`. La matriz SOLO LEE (ADR-1c.5): pulsar una celda abre su
   ficha o entra en el flujo de compartir, nunca crea ni destruye una cesión
   por sí misma. */

.matriz-env {
  overflow-x: auto;
  border: var(--borde-ancho) solid var(--borde);
  background: var(--papel);
}
/* Sobre superficie oscura el borde de la matriz es blanco: el negro sobre negro
   no se ve, y la tabla necesita un límite. */
.oscuro .matriz-env { border-color: var(--blanco); }

.matriz {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  background: var(--papel);
  color: var(--txt);
}
.matriz thead th {
  background: var(--gris);
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  text-align: left;
  padding: var(--esp-2);
  vertical-align: bottom;
  line-height: 1.25;
  border: 1px solid var(--borde-fino);
}
.matriz thead th small {
  display: block;
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: var(--texto-micro);
  color: var(--txt-2);
}
.matriz tbody th {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-cuerpo);
  text-align: left;
  padding: var(--esp-2);
  background: var(--papel);
  border: 1px solid var(--borde-fino);
  white-space: nowrap;
}
.matriz tbody th small {
  display: block;
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: var(--texto-menudo);
  color: var(--txt-2);
}
.matriz td { border: 1px solid var(--borde-fino); padding: 0; }

/* La celda es un botón que ocupa su hueco entero. El texto de la celda vacía
   («—») es información, no decoración: va en --txt-3, que pasa AA (5,45),
   y no en el gris del mockup, que se quedaba en 1,66. */
.matriz td button {
  display: block;
  width: 100%;
  min-height: 3.25rem;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-menudo);
  color: var(--txt-3);
  transition: background var(--micro);
}
.matriz td button:hover { background: var(--tinte-azul); }
.matriz td button[aria-pressed="true"] { background: var(--azul); color: var(--blanco); }
.matriz td button[aria-pressed="true"]:hover { background: var(--azul-osc); }
/* Ni activa ni vacía. Dos estados intermedios que el color solo no distingue,
   así que cada uno lleva su propio texto en la celda: «Caducada» y «Por
   activar». Pintar una cesión pendiente como una casilla vacía diría que no hay
   nada entre esas dos personas, y sí lo hay. */
.matriz td button.caducada { background: var(--gris); color: var(--txt-2); }
.matriz td button.pendiente {
  background: var(--mantequilla);
  color: var(--negro);
  box-shadow: inset 0 0 0 2px var(--negro);
}

/* El foco de la matriz es mantequilla, como pide la fase, con un anillo negro
   por fuera. La mantequilla sola es invisible sobre una celda blanca (1,47):
   el anillo negro es lo que hace que se vea en una celda vacía, y la
   mantequilla lo que lo hace visible sobre el azul de una celda activa. */
.matriz td button:focus-visible {
  outline: none;
  box-shadow:
    inset 0 0 0 var(--foco-ancho) var(--foco-oscuro),
    inset 0 0 0 calc(var(--foco-ancho) + 2px) var(--negro);
}
.matriz td button.foco {
  box-shadow: inset 0 0 0 var(--foco-ancho) var(--foco-oscuro),
              inset 0 0 0 calc(var(--foco-ancho) + 2px) var(--negro);
}

/* Las acciones de la ficha dependen del estado de la celda seleccionada, y lo
   resuelve la cascada: `cuadro.js` escribe `data-activa` en la ficha y el CSS
   enseña el botón que toca. Hacerlo con `hidden` desde JavaScript funcionaría
   igual, pero esto no puede desincronizarse. */
[data-cuadro-ficha][data-viva="1"] [data-solo-vacia] { display: none; }
[data-cuadro-ficha][data-viva="0"] [data-solo-viva] { display: none; }
/* Sin celda elegida todavía no se ofrece ninguna acción. */
[data-cuadro-ficha]:not([data-viva]) .acc { display: none; }

/* --- Raíl de progreso ----------------------------------------------- */
/* La escalera de pasos de un asistente. En vertical sobre fondo negro en
   escritorio; en móvil se convierte en una tira de barras. */

.escalera { list-style: none; margin: 0; padding: 0; }
.escalera li {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: var(--esp-2);
  padding: var(--esp-2) 0;
  align-items: start;
  color: var(--sobre-negro-2);
}
.escalera .num {
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-menudo);
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: var(--borde-ancho-fino) solid var(--sobre-negro-2);
  border-radius: 50%;
}
.escalera .et { font-family: var(--tipo-titulo); font-weight: 700; font-size: var(--texto-cuerpo); }
.escalera .de { display: none; font-size: var(--texto-menudo); margin-top: 2px; }
.escalera li.activo { color: var(--sobre-negro); }
.escalera li.activo .num { background: var(--mantequilla); color: var(--negro); border-color: var(--mantequilla); }
.escalera li.activo .de { display: block; color: var(--sobre-negro-2); }
.escalera li.hecho .num { background: var(--azul); border-color: var(--azul); color: var(--blanco); }

/* Secuencia de pasos numerados en el cuerpo de una pantalla. */
.pasos { list-style: none; margin: var(--esp-3) 0 0; padding: 0; counter-reset: paso; }
.pasos > li {
  counter-increment: paso;
  position: relative;
  padding: var(--esp-2) 0 var(--esp-2) var(--esp-6);
  border-bottom: 1px solid var(--borde-fino);
}
.pasos > li:last-child { border-bottom: 0; }
.pasos > li::before {
  content: counter(paso);
  position: absolute;
  left: 0;
  top: var(--esp-2);
  width: 1.75rem;
  height: 1.75rem;
  display: grid;
  place-items: center;
  background: var(--negro);
  color: var(--blanco);
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-menudo);
}

/* --- Paginación ----------------------------------------------------- */

.paginacion {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  margin-top: var(--esp-4);
}
.paginacion .posicion {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  color: var(--txt-2);
}

/* --- Bloque de código / clave ---------------------------------------- */

.caja-codigo {
  border: var(--borde-ancho-fino) solid var(--borde);
  background: var(--papel);
  color: var(--txt);
}
.caja-codigo > .cab {
  background: var(--negro);
  color: var(--sobre-negro);
  padding: var(--esp-1) var(--esp-3);
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
}
.caja-codigo .codigo {
  padding: var(--esp-3);
  font-family: var(--tipo-mono);
  font-size: var(--texto-cuerpo);
  line-height: 2;
  letter-spacing: 0.06em;
  word-break: break-all;
}
.caja-codigo .acc { padding: 0 var(--esp-3) var(--esp-3); }

/* ============================================================
   Esqueletos de página
   ============================================================
   Los componentes de arriba montan una pantalla; estos montan un
   documento. Están aquí, y no en la hoja del proyecto, porque son
   justo lo que necesita cualquier superficie que consuma el
   paquete: el agente de escritorio y las preferencias de Windows
   quieren el mismo lateral oscuro y la misma cabecera pública que
   la web, y sin ellos «consumible tal cual» sería mentira.
   ============================================================ */

/* --- Cabecera y pie públicos -------------------------------------------- */

.cabecera {
  border-bottom: var(--borde-ancho) solid var(--borde);
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--papel);
}
.cabecera > .envoltura {
  display: flex;
  align-items: center;
  gap: var(--esp-5);
  min-height: 70px;
}
.cabecera .marca { font-size: var(--texto-h3); }
.cabecera nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-4);
  align-items: center;
}
.cabecera nav a {
  font-family: var(--tipo-titulo);
  font-weight: 500;
  font-size: var(--texto-cuerpo);
  text-decoration: none;
}
.cabecera .boton { padding: var(--esp-1) var(--esp-3); box-shadow: var(--sombra-baja); }

.pie {
  padding: var(--esp-5) 0;
  font-size: var(--texto-menudo);
  border-top: var(--borde-ancho) solid var(--borde);
}
.pie > .envoltura {
  display: flex;
  justify-content: space-between;
  gap: var(--esp-3);
  flex-wrap: wrap;
  align-items: center;
  font-family: var(--tipo-titulo);
  font-weight: 500;
}
.pie nav { display: flex; gap: var(--esp-3); flex-wrap: wrap; }
.pie .legal { font-family: var(--tipo-texto); font-weight: 400; color: var(--txt-2); }
.pie .idiomas { display: flex; gap: var(--esp-0); }
.pie .idioma {
  background: none;
  border: var(--borde-ancho-fino) solid transparent;
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  padding: 2px var(--esp-1);
  cursor: pointer;
  color: inherit;
}
.pie .idioma:hover { border-color: var(--borde); }
.pie .idioma.activo { background: var(--mantequilla); border-color: var(--borde); }

/* --- Sección de página pública ----------------------------------------- */

.seccion {
  padding: var(--esp-8) 0;
  border-bottom: var(--borde-ancho) solid var(--borde);
}
.seccion.oscuro { border-bottom-color: var(--negro); }
.seccion h2 { font-size: var(--texto-titular); max-width: 19ch; }
.seccion .sub { margin-top: var(--esp-3); max-width: 56ch; font-size: var(--texto-guia); }
.seccion .rejilla { margin-top: var(--esp-6); }
.seccion .comparativa { margin-top: var(--esp-6); }

/* Cabecera de sección con una cifra a la derecha. */
.seccion-cab {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--esp-4);
  flex-wrap: wrap;
  margin-bottom: var(--esp-6);
}

/* --- Hero -------------------------------------------------------------- */

.hero {
  padding: var(--esp-7) 0 var(--esp-6);
  border-bottom: var(--borde-ancho) solid var(--borde);
}
.hero > .envoltura {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: var(--esp-7);
  align-items: center;
}
.hero h1 { font-size: var(--texto-hero); letter-spacing: -0.03em; line-height: 1; }
.hero h1 b { color: var(--azul); font-weight: 900; }
.hero .lede { margin-top: var(--esp-4); }
.hero .acciones { margin-top: var(--esp-5); }
.hero .nota-pie { margin-top: var(--esp-4); font-size: var(--texto-menudo); color: var(--txt-2); }

@media (max-width: 940px) {
  .hero > .envoltura { grid-template-columns: 1fr; gap: var(--esp-6); }
}

/* Cierre a sangre: el último bloque de una página pública. */
.cierre { padding: var(--esp-8) 0; text-align: center; background: var(--azul); color: var(--blanco); }
.cierre h2 { color: var(--blanco); margin: 0 auto; max-width: 16ch; font-size: var(--texto-titular); }
.cierre p { margin: var(--esp-4) auto 0; max-width: 48ch; font-size: var(--texto-guia); }
.cierre .acciones { justify-content: center; margin-top: var(--esp-5); }

/* --- Conversación (transcripción de mensajes) ------------------------- */

.conversacion {
  background: var(--gris);
  color: var(--txt);
  border: var(--borde-ancho) solid var(--borde);
  padding: var(--esp-4);
  box-shadow: var(--sombra-elevada);
}
.conversacion > .cab {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: var(--esp-3);
}
.burbuja {
  background: var(--papel);
  border: var(--borde-ancho) solid var(--borde);
  padding: var(--esp-2);
  font-size: var(--texto-cuerpo);
  margin-bottom: var(--esp-1);
  max-width: 88%;
}
.burbuja.mia { background: var(--mantequilla); margin-left: auto; }
.burbuja .adjunto {
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
}
.burbuja .adjunto span {
  background: var(--negro);
  color: var(--blanco);
  padding: 3px var(--esp-0);
  font-size: var(--texto-micro);
}
.conversacion > .remate {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  margin-top: var(--esp-3);
}

/* --- Marco de aplicación: lateral oscuro + contenido ------------------ */

.app {
  display: grid;
  grid-template-columns: var(--lateral) 1fr;
  min-height: 100vh;
  /* El fondo de la columna del lateral lo pinta la rejilla, no el lateral.
     `.lateral` es `position: sticky` con `height: 100vh` —tiene que serlo para
     que el menú acompañe al scroll—, y eso le impide estirarse hasta el final de
     una pantalla larga: el negro se cortaba a media página y debajo quedaba
     blanco. Con el degradado, la columna se ve entera aunque el elemento no la
     ocupe. Se apaga bajo el corte, donde el lateral pasa a ser una barra. */
  background: linear-gradient(
    to right,
    var(--negro) 0 var(--lateral),
    transparent var(--lateral)
  );
}
/* `min-width: 0` en los hijos de cada contenedor que reparte espacio, y no es un
   apaño: el valor inicial de `min-width` para un elemento de rejilla o de flex es
   `auto`, que significa «no bajes de tu contenido». Con eso, un `overflow-x:
   auto` interior NO constriñe nada y el contenido más ancho empuja el documento
   entero a lo ancho. Se detectó midiendo el zoom al 200 %: bajo el corte de
   940px el menú del lateral pasa a una tira horizontal de siete elementos, y sus
   715px de contenido hacían que la página desbordara 107px. Afecta igual a las
   tablas anchas dentro de `.contenido` y a las rejillas de la ficha lateral. */
.app > *,
.contenido > *,
.rejilla > *,
.lateral > * { min-width: 0; }

.lateral {
  background: var(--negro);
  color: var(--sobre-negro);
  padding: var(--esp-4) var(--esp-3);
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
}
.lateral .marca { color: var(--sobre-negro); font-size: var(--texto-h3); padding: 0 var(--esp-1); }

/* Selector de organización: inicial y nombre. */
.org {
  margin: var(--esp-4) 0 var(--esp-1);
  padding: var(--esp-2);
  background: var(--negro-2);
  display: flex;
  align-items: center;
  gap: var(--esp-1);
}
.org .ini {
  width: 26px;
  height: 26px;
  background: var(--mantequilla);
  color: var(--negro);
  display: grid;
  place-items: center;
  font-family: var(--tipo-titulo);
  font-weight: 900;
  font-size: var(--texto-micro);
  flex: 0 0 auto;
}
.org .nom {
  display: block;
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  line-height: 1.2;
}
.org .sub { display: block; font-size: var(--texto-micro); color: var(--sobre-negro-2); }

.menu { list-style: none; margin: var(--esp-3) 0 0; padding: 0; }
.menu a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-1);
  padding: var(--esp-1) var(--esp-2);
  text-decoration: none;
  color: var(--sobre-negro-2);
  font-family: var(--tipo-titulo);
  font-weight: 500;
  font-size: var(--texto-cuerpo);
}
.menu a:hover { background: var(--negro-2); color: var(--sobre-negro); }
/* La página actual: relleno azul Y `aria-current`, nunca solo el color. */
.menu a[aria-current="page"] { background: var(--azul); color: var(--blanco); font-weight: 700; }
.menu .pin {
  background: var(--mantequilla);
  color: var(--negro);
  font-family: var(--tipo-titulo);
  font-size: var(--texto-micro);
  font-weight: 900;
  padding: 1px var(--esp-0);
}

.lateral-pie {
  margin-top: auto;
  padding: var(--esp-2) var(--esp-2) 0;
  border-top: 1px solid var(--negro-2);
  font-size: var(--texto-menudo);
  color: var(--sobre-negro-2);
}
.lateral-pie b {
  display: block;
  color: var(--sobre-negro);
  font-family: var(--tipo-titulo);
  font-size: var(--texto-cuerpo);
}

/* Cabecera de la zona de trabajo. */
.topbar {
  background: var(--papel);
  border-bottom: var(--borde-ancho-fino) solid var(--borde);
  padding: 0 var(--esp-4);
  min-height: 68px;
  display: flex;
  align-items: center;
  gap: var(--esp-3);
  position: sticky;
  top: 0;
  z-index: 20;
}
.topbar h1 { font-size: var(--texto-h1-app); }
.topbar .der { margin-left: auto; display: flex; gap: var(--esp-1); align-items: center; flex-wrap: wrap; }

.contenido { padding: var(--esp-4) var(--esp-4) var(--esp-7); display: grid; gap: var(--esp-4); }

/* Bajo el corte, el lateral se convierte en una barra con el menú en una tira
   desplazable en horizontal. La organización y el pie se retiran: en 360px de
   ancho, el nombre del usuario no compite con la navegación. */
@media (max-width: 940px) {
  .app { grid-template-columns: 1fr; background: none; }
  .lateral { position: static; height: auto; padding: var(--esp-3); }
  .menu { display: flex; overflow-x: auto; gap: var(--esp-0); margin-top: var(--esp-3); }
  .menu li { flex: 0 0 auto; }
  .org, .lateral-pie { display: none; }
}
@media (max-width: 640px) {
  .contenido, .topbar { padding-left: var(--esp-3); padding-right: var(--esp-3); }
}

/* --- Marco de asistente: raíl de pasos + panel ----------------------- */

.asistente { display: grid; grid-template-columns: 330px 1fr; min-height: 100vh; }
.asistente > .rail {
  background: var(--negro);
  color: var(--sobre-negro);
  padding: var(--esp-6) var(--esp-5);
  display: flex;
  flex-direction: column;
}
.asistente > .rail .marca { color: var(--sobre-negro); font-size: var(--texto-h3); }
.rail-tit {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sobre-negro-2);
  margin: var(--esp-7) 0 var(--esp-4);
}
.rail-pie { margin-top: auto; font-size: var(--texto-menudo); color: var(--sobre-negro-2); padding-top: var(--esp-5); }
.asistente > .panel { padding: var(--esp-7) var(--esp-6) var(--esp-6); display: flex; flex-direction: column; }
.asistente > .panel > .cuerpo { max-width: 600px; flex: 1; }
.asistente h1 { font-size: var(--texto-h1); }
.paso-n {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-menudo);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--azul);
  margin-bottom: var(--esp-2);
}
/* Barra de navegación del asistente, pegada al cuerpo. */
.barra-pasos {
  margin-top: var(--esp-6);
  padding-top: var(--esp-4);
  border-top: var(--borde-ancho-fino) solid var(--borde);
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  max-width: 600px;
}
.barra-pasos .der { margin-left: auto; display: flex; gap: var(--esp-2); }

@media (max-width: 900px) {
  .asistente { grid-template-columns: 1fr; }
  .asistente > .rail { padding: var(--esp-3) var(--esp-4); }
  .rail-tit, .rail-pie { display: none; }
  /* La escalera pasa a una tira de barras: el número deja de leerse y lo que
     informa es el color del tramo, con el paso escrito en `.paso-n`. */
  .escalera { display: flex; gap: var(--esp-1); margin-top: var(--esp-3); }
  .escalera li { grid-template-columns: 1fr; padding: 0; flex: 1; gap: var(--esp-0); }
  .escalera .et, .escalera .de, .escalera li.activo .de { display: none; }
  .escalera .num {
    width: 100%;
    height: 6px;
    border-radius: 0;
    border: 0;
    background: var(--negro-2);
    font-size: 0;
  }
  .escalera li.activo .num { background: var(--mantequilla); }
  .escalera li.hecho .num { background: var(--azul); }
  .asistente > .panel { padding: var(--esp-5) var(--esp-4); }
}

/* --- Rejilla de avisos de cabecera ---------------------------------- */

.avisos { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--esp-3); }
.aviso-caja {
  border: var(--borde-ancho-fino) solid var(--borde);
  padding: var(--esp-3);
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
  background: var(--papel);
}
.aviso-caja.urgente { background: var(--mantequilla); }
.aviso-caja.accion { background: var(--azul); color: var(--blanco); }
.aviso-caja .et {
  font-family: var(--tipo-titulo);
  font-weight: 700;
  font-size: var(--texto-micro);
  letter-spacing: var(--separa-etiqueta);
  text-transform: uppercase;
}
.aviso-caja .fr { font-family: var(--tipo-titulo); font-weight: 900; font-size: var(--texto-h3); line-height: 1.15; }
.aviso-caja .boton { margin-top: auto; align-self: flex-start; }

@media (max-width: 900px) {
  .avisos { grid-template-columns: 1fr; }
}

/* --- Fila «próximamente» ------------------------------------------------ */
/* Una capacidad que todavía no existe, dentro de una ficha que sí. El fondo
   apagado la separa del resto, pero lo que la hace inconfundible es la
   insignia con su texto: quien no distinga el gris sigue leyendo «Fase 3 ·
   próximamente» (ADR-1c.4). Nunca lleva un valor de ejemplo. */
.datos > .proximamente, .ejes > .proximamente { background: var(--gris-3); }
.datos > .proximamente dt, .ejes > .proximamente dt { color: var(--txt-3); }
.datos > .proximamente dd, .ejes > .proximamente dd { display: grid; gap: var(--esp-0); }

/* === Visor de documentos y colocación de la estampa (F5) ==================
 *
 * Vive en el paquete y no en la hoja de la aplicación porque lo usan **dos**
 * superficies: la pantalla de firmar de la web y la de la webview del agente.
 * Es la regla del propio sistema: lo que le sirve a más de un consumidor sube
 * aquí, y baja a `estilos.css` lo que solo es de una pantalla.
 * ========================================================================= */

/* El visor solo aparece en la vista de firmar. Su altura es el ancla de la
   pantalla: sin ella, cada documento cambiaría el alto de la página y colocar
   la estampa sería perseguir un objetivo en movimiento. */
.visor {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(14rem, 20rem);
  gap: var(--esp-3);
  margin-top: var(--esp-2);
}
@media (max-width: 60rem) {
  .visor { grid-template-columns: minmax(0, 1fr); }
}

.visor-marco {
  border: var(--borde-ancho) solid var(--borde);
  background: var(--gris-3);
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.visor-barra {
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  flex-wrap: wrap;
  padding: var(--esp-1);
  border-bottom: var(--borde-ancho-fino) solid var(--borde);
  background: var(--papel);
}
.visor-barra .separador { flex: 1 1 auto; }
.visor-barra input[type="number"] { width: 4.5rem; }

/* El desplazamiento vive aquí y no en la página: el visor se mueve, la pantalla
   de firmar no. */
.visor-lienzo,
.visor-hueco {
  overflow: auto;
  height: min(70vh, 46rem);
  padding: var(--esp-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--esp-2);
}
/* El estado vacío («abriendo el documento…») va centrado; el documento, NO.
   Centrar contenido de un flex más alto que su caja empuja la parte de arriba
   fuera del área desplazable: con el zoom alto no había forma de llegar al
   principio de la primera hoja, y el visor abría en la junta entre dos. */
.visor-hueco {
  justify-content: center;
  color: var(--txt-2);
  text-align: center;
}
.visor-lienzo {
  justify-content: flex-start;
}

.visor-pagina {
  position: relative;
  flex: 0 0 auto;
  background: var(--papel);
  box-shadow: var(--sombra-baja);
}
.visor-canvas { display: block; }

/* Un `fieldset` agrupa las casillas de la estampa porque son un grupo de
   verdad y su `legend` es lo que oye un lector de pantalla al entrar. El marco
   del navegador sobra: el grupo ya se distingue por el título y el aire. */
.sin-marco {
  border: 0;
  padding: 0;
  margin: var(--esp-2) 0 0;
}
.sin-marco > legend {
  padding: 0;
  margin-bottom: var(--esp-1);
}

/* --- La capa de colocación --------------------------------------------- */
/* `colocacion.js` le escribe left/bottom/width/height en porcentaje desde el
   CSSOM —lo único que la CSP estricta permite para geometría dinámica—, así que
   la caja tiene que seguir siendo absoluta dentro de un contenedor posicionado. */
.colocacion {
  position: absolute;
  inset: 0;
  cursor: crosshair;
  touch-action: none;
}
.colocacion-caja {
  position: absolute;
  border: var(--borde-ancho-fino) solid var(--azul);
  background: var(--tinte-azul);
  overflow: hidden;
  display: flex;
}
.colocacion-previa {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 2px 4px;
  font-family: var(--tipo-titulo);
  font-size: 0.62rem;
  line-height: 1.15;
  color: var(--txt);
  overflow: hidden;
}
.colocacion-rubrica {
  height: 100%;
  max-width: 34%;
  object-fit: contain;
  flex: 0 0 auto;
}
.colocacion-texto {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.colocacion-texto > * {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.colocacion-rotulo,
.colocacion-menor { color: var(--txt-2); font-size: 0.92em; }

/* Hueco de la rúbrica cuando se pidió pero todavía no se puede descifrar. */
.colocacion-hueco {
  flex: 0 0 auto;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30%;
  border: var(--borde-ancho-fino) dashed var(--txt-3);
  color: var(--txt-2);
  font-size: 0.85em;
}

/* El foco del sistema, tal cual: la capa es operable con teclado y tiene que
   verse dónde está sin depender del color. */
.colocacion:focus-visible {
  outline: var(--foco-ancho) solid var(--foco);
  outline-offset: calc(var(--foco-margen) * -1);
}

/* Ayuda de teclado: siempre presente en el marcado, no solo al enfocar. */
.colocacion-ayuda {
  margin-top: var(--esp-1);
  color: var(--txt-2);
  font-size: var(--texto-menudo);
}
.colocacion-ayuda kbd {
  font-family: var(--tipo-mono);
  border: var(--borde-ancho-fino) solid var(--borde);
  border-radius: 2px;
  padding: 0 3px;
}

/* Quien pide menos movimiento no quiere que la página se deslice sola al
   cambiar de hoja; `visor.js` también lo consulta antes de hacer scroll. */
@media (prefers-reduced-motion: reduce) {
  .visor-lienzo { scroll-behavior: auto; }
}

