/* Sistema de layout — ver docs/superpowers/diseno-layout.md.
   Este archivo lo toca un solo agente (§0 "Reparto de trabajo"). Las cinco
   pestañas consumen estas clases; nadie escribe CSS dentro de su pestaña. */

:root {
  /* --- paleta existente, sin cambios: verificada en contraste, §7.1 --- */
  --tinta: #17202a;
  --tenue: #6b7684;
  --linea: #dfe4ea;
  --fondo: #f6f7f9;
  --panel: #ffffff;
  --acento: #1c6ea4;
  --ok: #1e7a4d;
  --aviso: #8a6100;
  --aviso-fondo: #fdf3d7;
  --alarma: #a02020;
  --alarma-fondo: #fbe4e4;

  /* --- nuevos: superficie y realce --- */
  --realce: #eef4f9;        /* fila actual, chips de parámetro, fondo del badge */
  --linea-fuerte: #b9c2cc;  /* borde superior de las filas hito de una cascada */
  --tenue-fuerte: #55606e;  /* texto secundario cuando va sobre --realce */

  /* --- nuevos: métrica del layout --- */
  --ancho-app: 2100px;      /* tope del lienzo entero */
  --medida: 68ch;           /* prosa legible: ~545 px a 15 px */
  --medida-corta: 44ch;     /* línea de origen dentro de un .dato */
  --hueco: 1.25rem;         /* separación entre tarjetas */
  --hueco-corto: .75rem;    /* separación dentro de una tarjeta */
  --margen: clamp(1rem, 2.2vw, 2.5rem);   /* aire lateral del lienzo */
  --radio: 8px;
  --radio-corto: 5px;
  --alto-superior: 112px;   /* la sobreescribe la media query de abajo */
}

@media (min-width: 901px) {
  :root { --alto-superior: 92px; }
}

/* ============================== 1. La rejilla ============================= */

/* --- 1.2 Contenedor --- */

* { box-sizing: border-box; }

html { scroll-padding-top: calc(var(--alto-superior) + 1rem); }

body {
  margin: 0;
  font: 15px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--tinta);
  background: var(--fondo);
}

/* main deja de ser rejilla: es solo el contenedor con tope y centrado. La
   rejilla la pone cada pestaña con `.lienzo` (§1.3). Nunca overflow-x:
   hidden aquí — enmascararía un desbordamiento en vez de arreglarlo. */
main {
  max-width: var(--ancho-app);
  margin-inline: auto;
  padding: var(--margen);
}

/* Compatibilidad temporal: hasta que cada pestaña devuelva su propio
   `.lienzo` (§1.3), sus tarjetas son hijas directas de <main> sin rejilla
   que las separe. Este margen es lo único que evita que se toquen borde con
   borde; se retira en cuanto la pestaña migre a `.lienzo` (el gap pasa a
   ponerlo la rejilla, no <main>). */
main > .tarjeta,
main > section {
  margin-bottom: var(--hueco);
}
main > .tarjeta:last-child,
main > section:last-child {
  margin-bottom: 0;
}

/* --- 1.3 El lienzo de 12 columnas --- */

.lienzo {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--hueco);
  align-items: start;
}

.col-3  { grid-column: span 3; }
.col-4  { grid-column: span 4; }
.col-5  { grid-column: span 5; }
.col-6  { grid-column: span 6; }
.col-7  { grid-column: span 7; }
.col-8  { grid-column: span 8; }
.col-9  { grid-column: span 9; }
.col-12 { grid-column: 1 / -1; }

/* Título que nombra una banda de tarjetas. Siempre a todo el ancho. */
.banda-titulo {
  grid-column: 1 / -1;
  margin: .6rem 0 -.35rem;
  font-size: .95rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tenue-fuerte);
  display: flex;
  align-items: baseline;
  gap: .5rem;
}
.banda-titulo:first-child { margin-top: 0; }

/* --- 1.4 Los tres tramos y dónde colapsan --- */

/* ≤1180 px — seis columnas. El par 5+7 se apila; los tercios pasan a mitades. */
@media (max-width: 1180px) {
  .lienzo { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .col-3, .col-4, .col-6 { grid-column: span 3; }
  .col-5, .col-7, .col-8, .col-9 { grid-column: span 6; }
}

/* ≤820 px — una columna. */
@media (max-width: 820px) {
  .lienzo { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-12 { grid-column: 1 / -1; }
}

/* --- 1.5 Cabecera fija y banda de alarma --- */

.superior {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--panel);
  border-bottom: 1px solid var(--linea);
}

header { padding: .85rem var(--margen) 0; }
header h1 { margin: 0 0 .6rem; font-size: 1.05rem; }

.barra-cabecera {
  max-width: var(--ancho-app);
  margin-inline: auto;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: end;
  column-gap: 1.5rem;
}

.barra-cabecera h1 { margin: 0 0 .6rem; font-size: 1.05rem; }

nav { display: flex; gap: .25rem; flex-wrap: nowrap; overflow-x: auto; }
nav button {
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  padding: .5rem .9rem;
  font: inherit;
  color: var(--tenue);
  cursor: pointer;
  white-space: nowrap;
}
nav button.activa { color: var(--acento); border-bottom-color: var(--acento); }

#banda:empty { display: none; }
.banda { padding: .6rem var(--margen); font-size: .87rem; }
.banda + .banda { border-top: 1px solid var(--panel); }
.banda.aviso { background: var(--aviso-fondo); color: var(--aviso); }
.banda.alarma, .banda.error { background: var(--alarma-fondo); color: var(--alarma); font-weight: 600; }

@media (max-width: 900px) {
  .barra-cabecera { grid-template-columns: 1fr; row-gap: .35rem; align-items: stretch; }
  .barra-cabecera h1 { margin-bottom: 0; }
  .quien { order: 2; }
  .leyenda { order: 3; }
}

/* --- 1.6 Cero scroll horizontal de página --- */
/* 1) toda pista de rejilla es minmax(0, 1fr) — ya aplicado arriba y en las
      rejillas anidadas (.datos, .rejilla) más abajo.
   2) todo hijo de rejilla/flex que contenga una tabla lleva min-width: 0.
   3) lo que no cabe, hace scroll dentro de su propio contenedor. */
.tarjeta { min-width: 0; }
/* `contain: paint` además del overflow. Sin él, una tabla ancha dentro de
   .tabla-scroll sigue contando para el scrollWidth del documento y la página
   entera se desplaza en horizontal (reproducido en Líderes a 375 px: 150 px
   de desbordamiento con la tabla ya recortada visualmente). No es la columna
   pegajosa ni el eje Y —se descartaron los dos—: es que el overflow recorta
   la pintura pero no retira la caja del cálculo de scroll del documento.
   `contain: paint` sí, y es exactamente lo que un contenedor con scroll
   quiere decir. */
.tabla-scroll { overflow-x: auto; contain: paint; }
.grafico { overflow-x: auto; contain: paint; }

/* .tarjeta es display:grid (§1.8): sus hijos directos son ítems de esa
   rejilla de una sola columna implícita, y un ítem de rejilla tiene
   min-width: auto por defecto — el tamaño de su contenido, sin encoger.
   Sin esto, una tabla ancha que no cabe (tablaItems, tablaBonos…) infla la
   columna implícita más allá del ancho disponible y el desbordamiento se
   escapa de la tarjeta hacia la página: el mismo "grid blowout" que la
   regla 2 de §1.6 ya cubre para .tarjeta dentro de .lienzo, aplicado aquí
   al nivel de rejilla interior que es cada tarjeta. */
.tarjeta > * { min-width: 0; }

/* --- 1.7 Anchos de prosa contra anchos de dato --- */

.nota, .tarjeta__pregunta, .origen { max-width: var(--medida); }
.dato__origen { max-width: var(--medida-corta); }
.cascada__origen { max-width: var(--medida); }

/* --- 1.8 Tarjeta --- */

.tarjeta {
  background: var(--panel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 1.1rem 1.25rem;
  display: grid;
  gap: var(--hueco-corto);
  align-content: start;
}

.tarjeta__cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* El título de tarjeta es <h3>: la banda temática que agrupa las tarjetas
   es su <h2>, de modo que el esquema del documento refleja la agrupación
   que se ve (§7). El tamaño no cambia — la jerarquía es semántica. */
.tarjeta h3 { margin: 0; font-size: .95rem; letter-spacing: .02em; }

/* La pregunta que contesta la tarjeta. Una sola línea, siempre en forma de
   pregunta: es la promesa pedagógica de la tarjeta. */
.tarjeta__pregunta { margin: 0; font-size: .85rem; color: var(--tenue-fuerte); }

/* Apila varios bloques dentro de una misma tarjeta manteniendo el hueco. */
.pila { display: grid; gap: var(--hueco-corto); }

/* --- 1.9 Tablas (base) --- */

table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
th, td { padding: .42rem .55rem; border-bottom: 1px solid var(--linea); text-align: right; }
th:first-child, td:first-child { text-align: left; }
th { font-size: .8125rem; color: var(--tenue); font-weight: 600; }
tfoot td { font-weight: 600; border-bottom: 0; }

/* Primera columna fija al hacer scroll horizontal. Obligatoria en toda tabla
   de más de 5 columnas: sin ella, al desplazarse se pierde de vista qué fila
   se está leyendo. */
.col-fija th:first-child,
.col-fija td:first-child {
  position: sticky;
  left: 0;
  background: var(--panel);
  z-index: 1;
}

/* Tabla larga: alto acotado + cabecera pegajosa DENTRO del contenedor. Solo
   funciona con overflow: auto (no con overflow-x: auto de .tabla-scroll a
   secas: sin acotar el alto, el eje Y computa a `auto` y la cabecera nunca
   se pega). La primera columna fija, en cambio, funciona en ambas. */
.tabla-scroll--alta { max-height: 60vh; overflow: auto; }
.tabla-scroll--alta thead th {
  position: sticky;
  top: 0;
  background: var(--panel);
  z-index: 2;
  box-shadow: inset 0 -1px 0 var(--linea);
}

.fila-actual { background: var(--realce); }
.fila-actual td { font-weight: 600; }

/* La celda fija de una fila resaltada lleva su propio fondo opaco (lo
   necesita para tapar lo que pasa por debajo al desplazarse), y ese fondo
   ganaba al del <tr>: la fila actual salía resaltada a partir de la segunda
   columna, con el primer hueco en blanco. */
.col-fija .fila-actual th:first-child,
.col-fija .fila-actual td:first-child {
  background: var(--realce);
}

/* --- 1.10 Tablas que son formulario --- */

.tabla-form td { padding: .3rem .35rem; }
.tabla-form input, .tabla-form select { padding: .35rem .45rem; }

@media (max-width: 700px) {
  .tabla-form, .tabla-form tbody, .tabla-form tr, .tabla-form td { display: block; width: 100%; }
  .tabla-form thead { display: none; }
  .tabla-form tr {
    border: 1px solid var(--linea);
    border-radius: var(--radio-corto);
    padding: .6rem .7rem;
    margin-bottom: .6rem;
  }
  .tabla-form td {
    display: grid;
    grid-template-columns: 9rem minmax(0, 1fr);
    align-items: center;
    gap: .5rem;
    border: 0;
    padding: .22rem 0;
    text-align: left;
  }
  .tabla-form td::before {
    content: attr(data-etiqueta);
    font-size: .8125rem;
    color: var(--tenue);
  }
  .tabla-form .fila-borrar { justify-items: end; grid-template-columns: 1fr; }
  .tabla-form .fila-borrar::before { content: none; }
}

/* --- 1.11 Formularios --- */

.rejilla { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .8rem; }

.campo { display: grid; gap: .2rem; align-content: start; }
label { display: block; font-size: .8125rem; color: var(--tenue); }

/* Pista in situ: el spec §11.3 exige explicar completitud vs actividad al
   lado del control, no en un párrafo al final. */
.campo__pista { font-size: .78rem; color: var(--tenue); line-height: 1.35; }

input, select {
  width: 100%;
  padding: .45rem .55rem;
  border: 1px solid var(--linea);
  border-radius: var(--radio-corto);
  font: inherit;
  font-variant-numeric: tabular-nums;
  background: #fff;
  color: var(--tinta);
}

.casilla-linea { display: flex; gap: .5rem; align-items: center; margin: 0; }
.casilla-linea input { width: auto; }

/* --- 1.12 Gráficos --- */
/* web/js/chart.js no se toca en esta reestructuración: emite SVG con
   width/height intrínsecos y viewBox. El envoltorio los adapta sin que el
   texto del SVG baje nunca de su tamaño nominal. Una tarjeta que contiene un
   gráfico nunca se coloca en menos de col-4. */
.grafico svg {
  display: block;
  width: 100%;
  height: auto;
  min-width: 36rem;   /* 576 px: nunca por debajo del tamaño intrínseco */
  max-width: 46rem;   /* 736 px: escala máxima 1,29×, texto ≤ 15,5 px */
}

/* ======================= 2. El patrón pedagógico ========================= */

/* --- 2.1 .dato — una cifra y de dónde salió --- */

.datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 22rem));
  gap: var(--hueco-corto);
  justify-content: start;
}

.dato {
  border: 1px solid var(--linea);
  border-left: 3px solid var(--linea-fuerte);
  border-radius: var(--radio-corto);
  padding: .65rem .8rem .7rem;
  display: grid;
  gap: .15rem;
  align-content: start;
}

.dato__etiqueta {
  font-size: .8125rem;
  color: var(--tenue);
  display: flex;
  align-items: baseline;
  gap: .35rem;
  flex-wrap: wrap;
}

.dato__valor {
  font-size: 1.35rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.dato__origen {
  margin: .15rem 0 0;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--tenue-fuerte);
}

.dato--principal .dato__valor { font-size: 1.8rem; }
.dato--positivo { border-left-color: var(--ok); }
.dato--positivo .dato__valor { color: var(--ok); }
.dato--negativo { border-left-color: var(--alarma); }
.dato--negativo .dato__valor { color: var(--alarma); }
.dato--aviso { border-left-color: var(--aviso); }

/* --- 2.2 .cascada — la resta corrida --- */

.cascada { font-variant-numeric: tabular-nums; }

.cascada__c-concepto { width: 22rem; }
.cascada__c-origen   { width: auto; }
.cascada__c-peso     { width: 7rem; }
.cascada__c-importe  { width: 10rem; }

.cascada th[scope="row"] {
  text-align: left;
  font-weight: 400;
  color: var(--tinta);
  font-size: 1rem;
}

.cascada__origen {
  text-align: left;
  font-size: .82rem;
  line-height: 1.4;
  color: var(--tenue-fuerte);
}

.cascada__importe { white-space: nowrap; }
.cascada__importe--resta { color: var(--tenue-fuerte); }
.cascada__importe--negativo { color: var(--alarma); font-weight: 600; }

/* Hito = un escalón numerado de la cascada. Se separa de la resta anterior. */
/* Fila de aviso dentro de una cascada («Todavía no hay bonos mensuales»):
   una sola celda con colspan, que debe leerse como prosa y no como un
   concepto de la columna izquierda. */
.cascada__nota-fila {
  color: var(--tenue-fuerte);
  font-size: .85rem;
  font-style: italic;
  max-width: var(--medida);
}

.cascada__hito > * { border-top: 2px solid var(--linea-fuerte); font-weight: 600; }
.cascada__hito .cascada__origen { font-weight: 400; }

/* Barra de proporción: SOLO presentación. Nunca lleva un número dentro. */
.cascada__peso { padding-block: .55rem; }
.cascada__barra {
  display: block;
  height: 8px;
  width: var(--peso, 0%);
  min-width: 2px;
  border-radius: 2px;
  background: var(--acento);
}
.cascada__barra--resta { background: var(--tenue); }
.cascada__barra--negativo { background: var(--alarma); }

/* Variante sin columna de origen ni barra: para tarjetas laterales estrechas. */
.cascada--compacta .cascada__c-origen,
.cascada--compacta .cascada__origen,
.cascada--compacta .cascada__c-peso,
.cascada--compacta .cascada__peso { display: none; }

@media (max-width: 820px) {
  .cascada__c-peso, .cascada__peso { display: none; }
  .cascada__c-concepto { width: 40%; }
}

/* --- 2.3 .desglose — el reparto por nivel --- */

.desglose__nivel { font-weight: 600; white-space: nowrap; }
.desglose__factor { color: var(--tenue-fuerte); }
.desglose__como {
  text-align: left;
  font-size: .82rem;
  line-height: 1.4;
  color: var(--tenue-fuerte);
  max-width: var(--medida);
}
.desglose__resultado { font-weight: 600; }
.desglose__total > * { border-top: 2px solid var(--linea-fuerte); }

@media (max-width: 1180px) { .desglose__como { display: none; } }

/* Fila separadora que nombra un grupo de métricas (§4.5, Comparador). Listada
   en el inventario de clases (§6): la regla vive aquí aunque el ejemplo del
   documento esté en la sección del Comparador, porque §6 es alcance de esta
   base compartida. */
.desglose__grupo th {
  text-align: left;
  background: var(--realce);
  color: var(--tenue-fuerte);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .75rem;
  position: sticky;
  left: 0;
}

/* --- 2.4 .veredicto — la conclusión en palabras --- */

.veredicto {
  border-radius: var(--radio-corto);
  border-left: 4px solid var(--linea-fuerte);
  padding: .7rem .9rem;
  display: grid;
  gap: .25rem;
  background: var(--fondo);
}
.veredicto__titulo { font-size: .95rem; }
.veredicto__cuerpo { margin: 0; font-size: .85rem; max-width: var(--medida); }
.veredicto--ok     { border-left-color: var(--ok);     color: var(--ok); }
.veredicto--aviso  { border-left-color: var(--aviso);  background: var(--aviso-fondo); color: var(--aviso); }
.veredicto--alarma { border-left-color: var(--alarma); background: var(--alarma-fondo); color: var(--alarma); }
.veredicto--ok .veredicto__cuerpo,
.veredicto--aviso .veredicto__cuerpo,
.veredicto--alarma .veredicto__cuerpo { color: inherit; }

/* --- 2.5 Notas --- */

.nota { font-size: .82rem; color: var(--tenue-fuerte); margin: 0; line-height: 1.5; }
.nota--aviso  { color: var(--aviso); }
.nota--alarma { color: var(--alarma); }

/* =================== 3. La convención de interconexión ==================== */

/* --- 3.1 Los numerales ①–⑧ --- */

.etapa {
  display: inline-block;
  min-width: 1.35em;
  text-align: center;
  background: var(--realce);
  color: var(--acento);
  border-radius: 4px;
  padding: 0 .1em;
  font-size: .95em;
  line-height: 1.4;
}
.visualmente-oculta {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

/* --- 3.2 La leyenda permanente --- */

.leyenda { font-size: .82rem; padding-bottom: .6rem; }
.leyenda summary { cursor: pointer; color: var(--acento); }
.leyenda__lista {
  list-style: none;
  margin: .5rem 0 0;
  padding: 0;
  display: grid;
  gap: .3rem;
  max-width: var(--medida);
}
@media (min-width: 901px) {
  .leyenda[open] .leyenda__lista {
    position: absolute;
    right: var(--margen);
    z-index: 30;
    background: var(--panel);
    border: 1px solid var(--linea);
    border-radius: var(--radio);
    padding: .9rem 1.1rem;
    box-shadow: 0 8px 24px rgb(23 32 42 / .12);
  }
}

/* --- 3.4 Escala explícita --- */

.escala {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--tenue);
  border: 1px solid var(--linea);
  border-radius: 999px;
  padding: 0 .45em;
  white-space: nowrap;
}

/* --- 3.5 .param — "esto lo configuraste tú" --- */

.param {
  background: var(--realce);
  color: var(--acento);
  border-radius: 3px;
  padding: 0 .3em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.enlace-config { font-size: .8rem; color: var(--acento); text-decoration: none; white-space: nowrap; }
.enlace-config:hover, .enlace-config:focus-visible { text-decoration: underline; }

/* ============================ 7. Accesibilidad ============================ */

/* --- 7.2 Foco --- */

:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
  border-radius: 3px;
}
input:focus-visible, select:focus-visible { outline-offset: 0; }

/* --- 7.4 Movimiento --- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ======================= Restos del formulario ============================
   Lo que quedó de la base anterior y las cinco pestañas siguen emitiendo:
   son los controles del formulario de Config, no cifras. Las clases de
   presentación de dinero que vivían aquí (.cifra*, .cascada tr.total,
   .cascada td.negativo, .tarjeta h2.subtitulo) las retiró §5.3: ninguna
   pestaña las emite ya, y conservarlas invitaba a volver a usarlas. */

svg { display: block; max-width: 100%; }

.fila-borrar { width: 2.4rem; }
.fila-borrar button { border: 0; background: none; cursor: pointer; color: var(--tenue); font-size: 1rem; }
.fila-borrar button:hover { color: var(--alarma); }

td.base { color: var(--tenue); font-size: .8rem; }
td.sangrada { padding-left: 1.4rem; color: var(--tenue); }

.acciones { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .9rem; }

button.pulsable, .acciones button {
  border: 1px solid var(--linea);
  background: var(--panel);
  border-radius: var(--radio-corto);
  padding: .4rem .8rem;
  font: inherit;
  cursor: pointer;
}

.acciones button:hover { border-color: var(--acento); color: var(--acento); }
.acciones button:disabled { opacity: .5; cursor: not-allowed; }
.acciones button:disabled:hover { border-color: var(--linea); color: inherit; }

/* ============================ La página de login ==========================
   web/login.html + web/js/login.js: sus cuatro vistas (entrar, registro,
   cambiar-pin, token). Sin variables ni colores nuevos — .acceso solo centra
   el lienzo y reutiliza .tarjeta para la tarjeta misma (§1.8). */

.acceso {
  min-height: calc(100vh - 2 * var(--margen));
  padding: var(--margen);
  display: grid;
  place-items: center;
}

.acceso__tarjeta {
  width: 100%;
  max-width: 26rem;
  gap: .9rem;
}
.acceso__tarjeta h1 { margin: 0; font-size: 1.15rem; }

/* Compartida con .admin-pin (panel del superadministrador, más abajo): el
   mismo campo "de solo lectura, para copiar" aparece en la entrega del
   token (aquí) y en la del PIN. Un solo par de declaraciones para las dos. */
.acceso__tarjeta input[readonly],
.admin-pin input[readonly] { background: var(--realce); color: var(--tinta); }

/* ============================ El panel del superadministrador =============
   web/admin.html + web/js/admin.js: sin calculadora por ninguna parte, y con
   pestañas desde el primer día (§9 del spec) aunque hoy solo haya "Usuarios".
   Reutiliza .tarjeta, .tabla-form, .nota, .acciones, .campo — sin variables
   ni colores nuevos. */

.admin-cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1rem var(--margen) 0;
  max-width: var(--ancho-app);
  margin-inline: auto;
}
.admin-cabecera h1 { margin: 0 0 .6rem; font-size: 1.05rem; }

/* Compartida con .quien (web/index.html, la tira de la propia calculadora,
   §9 del spec): mismo "quién eres + botón de salir", en dos páginas
   distintas. .quien añade flex-wrap porque, a diferencia de admin-quien
   (solo email + botón), lleva además el vencimiento del token — sin ajuste
   se saldría de la cabecera en móvil (§1.6, cero scroll horizontal). */
.admin-quien, .quien { display: flex; align-items: center; gap: .7rem; font-size: .85rem; color: var(--tenue); }

.quien { flex-wrap: wrap; }

/* C1 de la ronda 1 de review de la tarea 11: .quien vive en una columna
   "auto" de la rejilla de .barra-cabecera (§1.5, ancho ≥901px — a
   ≤900px .barra-cabecera colapsa a una sola columna y .quien tiene su
   propia fila entera, sin nadie con quien competir por ancho), y una
   columna "auto" se dimensiona al max-content de su contenido SIN límite
   — un email real más "Vence: <ISO>" pueden pedir 400+ px, y como <nav>
   es la ÚNICA columna flexible (1fr) y su mínimo automático es 0 (tiene
   overflow-x:auto, así que su "automatic minimum size" colapsa a 0 en vez
   de a su min-content), es <nav> quien se come el hueco entero antes de
   que .quien ceda un solo píxel — medido en Chrome real: a 1024-1150px,
   <nav> caía a 204-325px, y con un email más largo llegaba a 0px del
   todo (cero pestañas visibles). min-width:0 no basta por sí solo (una
   columna "auto" no se comprime durante el reparto de espacio negativo,
   solo lo hacen las columnas "fr"): hace falta un tope explícito en la
   propia contribución de .quien al max-content de su columna. 14rem es
   ese tope — nunca reclama más, sea cual sea la longitud real del email
   — y flex-wrap (arriba) reparte email/vencimiento/botón en más de una
   línea cuando no caben en 14rem, en vez de desbordar.

   Va en su propia media query (no como regla incondicional) A PROPÓSITO:
   una regla `.quien { max-width: 14rem }` suelta aquí, sin condición,
   GANABA a la de la media query de ≤900px que le habría quitado el tope
   (misma especificidad — una sola clase cada una —, y en el CSS el
   orden de aparición en el archivo desempata; esta regla vive DESPUÉS de
   la de ≤900px, así que ganaba ella pese a que la condición de la media
   query fuera cierta). Confirmado en Chrome real: con la regla suelta,
   .quien seguía atascada en 224px incluso a 900px de viewport, donde
   antes ocupaba toda la fila (845px) sin que hiciera ninguna falta
   recortarla — <nav> no compite por nada ahí. Ponerla en su propia media
   query evita la carrera de raíz, en vez de intentar ganarla con un
   `max-width: none` en la regla de ≤900px (que habría dependido, de
   nuevo, de qué regla se declara más tarde en el archivo). */
@media (min-width: 901px) {
  .quien { min-width: 0; max-width: 14rem; }
}

/* El email es el único campo de longitud arbitraria de la tira (el
   vencimiento es un ISO-8601 de longitud fija): sin esto, un email largo
   de verdad se saldría de los 14rem de .quien empujando el vencimiento y
   el botón "Salir" fuera de la caja en vez de, simplemente, truncarse. */
#quien-email {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-acciones { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.admin-dias { width: 6rem; }

/* Alta directa. En una línea mientras quepa, y apilada cuando no: el email
   necesita sitio de sobra y el resto no, así que el flex-grow va solo en él.
   align-items: flex-end alinea el botón con la BASE de los campos, no con su
   etiqueta — sin eso queda flotando a media altura. */
.admin-alta { display: flex; align-items: flex-end; gap: .8rem; flex-wrap: wrap; }
.admin-alta .campo { margin: 0; }
.admin-alta .campo:first-child { flex: 1 1 18rem; }
.admin-alta .campo:nth-child(2) { flex: 0 0 13rem; }
.admin-alta .campo:nth-child(3) { flex: 0 0 10rem; }
.admin-alta select { width: 100%; }
.admin-alta .acciones { margin: 0; }

/* Bloqueada / Token vencido (§9: "de un vistazo"), junto al dato al que
   corresponden — nunca su propia columna. */
.insignia {
  display: inline-block;
  font-size: .72rem;
  font-weight: 600;
  border-radius: 999px;
  padding: .05em .6em;
  margin-left: .35em;
  white-space: nowrap;
}
.insignia--alarma { background: var(--alarma-fondo); color: var(--alarma); }
.insignia--aviso  { background: var(--aviso-fondo);  color: var(--aviso); }
