/* ============================================================
   PRAEVIS — Control operacional
   Grafito + amarillo de seguridad · mobile-first

   La paleta es la misma que la del módulo de reportes: son dos partes del
   mismo producto y el día que convivan no pueden parecer dos aplicaciones.
   Lo que cambia acá es el uso, no los colores.

   Mobile-first de verdad: el control se hace parado frente a un extintor,
   con el celular en una mano y a veces con guantes. De ahí salen tres
   reglas que atraviesan todo:
     · nada tocable mide menos de 44 px de alto
     · el texto no baja de 16 px (menos que eso, iOS hace zoom al enfocar)
     · las decisiones frecuentes son botones grandes, no listas desplegables
   ============================================================ */

@font-face {
  font-family: Archivo;
  src: url('/fuentes/Archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --cement:    #ECEAE3;
  --graphite:  #1A1C20;
  --yellow:    #F4B400;
  --yellow-dk: #d89e00;
  --surface:   #FFFFFF;
  --muted:     #6b7078;
  --muted-2:   #4b5058;
  --line-soft: #c9c6bd;

  /* Los tres estados de una respuesta. Son los mismos verde/rojo del otro
     módulo: quien usa los dos no tiene que reaprender qué significa cada uno. */
  --cumple:    #0E7A5F;
  --no-cumple: #D0392B;
  --na:        #6b7078;
  --warn:      #E08600;

  --radius:    4px;
  --radius-sm: 3px;
  /* Alto de la barra. Es una variable porque los títulos de sección se pegan
     justo debajo: si se escriben los dos a mano, un día quedan pisados. */
  --barra-alto: 58px;
  --font: Archivo, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', 'Cascadia Mono', Consolas, 'Liberation Mono', monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--graphite);
  background: var(--cement);
  -webkit-text-size-adjust: 100%;
}

/* ── Barra superior ─────────────────────────────────────────── */

.barra {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: .5rem;
  min-height: var(--barra-alto);
  padding: 0 .75rem;
  background: var(--graphite);
  color: #fff;
  border-bottom: 3px solid var(--yellow);
}
.barra img { height: 22px; display: block; }
/* El título cede antes que el nombre del cliente: con «Marco normativo» y una
   empresa de nombre largo, en 390 px no entran los dos y lo que no puede
   perderse es de qué cliente se está hablando. */
.barra .titulo {
  font-weight: 600; font-size: 1rem;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.barra .espacio { flex: 1 1 0; min-width: 0; }
/* 44 px de alto también acá: la flecha de volver y el nombre del cliente se
   tocan con guantes igual que todo lo demás. */
.barra a, .barra button {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px;
  color: #fff; background: none; border: 0; font: inherit;
  text-decoration: none; padding: 0 .5rem; cursor: pointer; border-radius: var(--radius-sm);
}
.barra a:hover, .barra button:hover { background: rgba(255,255,255,.12); }
.barra .cliente {
  flex: none;
  font-size: .85rem; color: #cfd2d6; border: 1px solid #3a3e45;
  padding: 0 .75rem; border-radius: 999px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 45vw;
}

/* Salir, en la barra de arriba. **Existe además del de la lateral** porque los
   tres roles que salen a campo ven la barra en el celular y la lateral sólo en
   el escritorio: se dibujan los dos y el CSS muestra el que entra, igual que
   las tablas y sus tarjetas. Dos caminos a lo mismo no molestan; lo que molesta
   es buscarlo donde tiene que estar y no encontrarlo. */
.barra .salir-barra {
  flex: none; font-size: .85rem; color: #cfd2d6;
  border: 1px solid #3a3e45; border-radius: 999px; padding: 0 .9rem;
}

/* ── Estructura ─────────────────────────────────────────────── */

main { max-width: 60rem; margin: 0 auto; padding: 1rem; }
main.angosto { max-width: 34rem; }

h1 { font-size: 1.35rem; margin: .25rem 0 .2rem; }
h2 { font-size: 1.05rem; margin: 1.5rem 0 .6rem; }
.sub { color: var(--muted); margin: 0 0 1.2rem; }

.tarjeta {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
}

/* ── Formularios ────────────────────────────────────────────── */

label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: .3rem; }
.campo { margin-bottom: 1rem; }
.campo .ayuda { font-weight: 400; color: var(--muted); font-size: .85rem; }

/* `password` se sumó el 05/09/2026, con el login: sin él los campos de clave
   quedaban de 21 px y con la letra chica, que es justo lo que esta regla
   existe para evitar — con menos de 16 px iOS hace zoom al enfocar y la
   pantalla salta, y 21 px de alto no se acierta con guantes. Lo encontró la
   prueba que mide lo dibujado, no mirar la pantalla. */
input[type=text], input[type=search], input[type=email], input[type=tel],
input[type=date], input[type=number], input[type=password], select, textarea {
  width: 100%;
  /* 16px o más: con menos, iOS hace zoom al enfocar y la pantalla salta. */
  font: inherit; font-size: 16px;
  padding: .65rem .7rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--graphite);
  min-height: 44px;
}
textarea { min-height: 5rem; resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--yellow); outline-offset: -1px; border-color: var(--yellow-dk);
}

/* El buscador de código. Grande a propósito: es lo primero que toca el
   inspector y lo hace con guantes. */
.buscador input {
  font-size: 1.35rem; font-family: var(--mono); letter-spacing: .06em;
  text-align: center; padding: .9rem; min-height: 56px;
}

.boton {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  font: inherit; font-weight: 600;
  min-height: 44px; padding: .65rem 1.1rem;
  border: 1px solid var(--graphite);
  border-radius: var(--radius);
  background: var(--graphite); color: #fff;
  cursor: pointer; text-decoration: none;
}
.boton:hover { background: #2b2f36; }
.boton.principal { background: var(--yellow); border-color: var(--yellow-dk); color: var(--graphite); }
.boton.principal:hover { background: var(--yellow-dk); }
.boton.suave { background: var(--surface); color: var(--graphite); border-color: var(--line-soft); }
.boton.suave:hover { background: #f3f1ec; }
.boton[disabled] { opacity: .5; cursor: not-allowed; }
.boton.ancho { width: 100%; }

.acciones { display: flex; gap: .6rem; flex-wrap: wrap; }

/* ── Listas ─────────────────────────────────────────────────── */

.lista { list-style: none; margin: 0; padding: 0; }
.lista > li { border-bottom: 1px solid var(--line-soft); }
.lista > li:last-child { border-bottom: 0; }

.item {
  display: flex; align-items: center; gap: .8rem;
  padding: .75rem .25rem; min-height: 44px;
  color: inherit; text-decoration: none;
}
.item:hover { background: #f6f4ef; }
.item .codigo {
  font-family: var(--mono); font-weight: 600; font-size: .95rem;
  background: var(--cement); border: 1px solid var(--line-soft);
  padding: .2rem .45rem; border-radius: var(--radius-sm); white-space: nowrap;
}
.item .cuerpo { flex: 1; min-width: 0; }
.item .cuerpo .principal { font-weight: 600; }
/* `display: block` no es decorativo: `overflow` y `text-overflow` **no aplican
   a un elemento en línea**, así que sin esto el recorte con puntos suspensivos
   no ocurría y el texto largo se desbordaba de su caja, metiéndose debajo de la
   etiqueta de estado que tiene al lado. Estaba así desde siempre y no se veía
   porque los textos entraban justos. */
.item .cuerpo .secundario {
  display: block;
  color: var(--muted); font-size: .88rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.item .flecha { color: var(--muted); }
/* La etiqueta de estado en su propio renglón, debajo del nombre. Al lado del
   nombre competía por el ancho: en 390 px una empresa de nombre largo obliga a
   elegir entre partir el nombre o partir la etiqueta, y ninguna de las dos se
   lee bien. Abajo entra entera y sigue siendo lo primero que se ve. */
.item .cuerpo .estado-fila { display: block; margin: .2rem 0 .15rem; }

/* Los botones de una persona, en Equipo. **Van siempre en su propio renglón**,
   debajo del nombre. Son hasta cuatro —Empresas, Reiniciar clave, Mirar como,
   Dar de baja— y al lado del nombre no entran: con `flex: none` no se partían,
   se salían de la tarjeta, que es lo peor de los dos mundos —el botón no está,
   y encima no se ve que falta—.
   **En todos los anchos y no sólo en el celular**: arriba de 68rem Equipo se
   parte en dos columnas de unos 440 px, así que la pantalla ancha es tan
   estrecha como el teléfono y un punto de corte por viewport se equivocaba
   justo ahí. Es el criterio de `.estado-fila`: lo que no entra al lado, va
   abajo entero.
   El `wrap` va en una clase y no en `.item` a secas: `.item` lo usan todas las
   listas de la plataforma, y ninguna otra necesita que sus partes se
   reacomoden. */
.item.con-acciones { flex-wrap: wrap; }
.item .acciones-fila { flex-basis: 100%; margin: .5rem 0 0; }

/* El botón de acciones de una fila: **una sola cosa tocable y no cuatro**.
   Cuadrado de 44 px, porque no tiene texto que lo ensanche y un rectángulo
   angosto con tres puntos adentro se erra con guantes. */
.boton.mas {
  flex: none; align-self: center;
  width: 44px; min-width: 44px; padding: 0;
  font-size: 1.35rem; line-height: 1; letter-spacing: .05em;
}

/* ── Etiquetas de estado ────────────────────────────────────── */

.etiqueta {
  display: inline-block; font-size: .78rem; font-weight: 600;
  padding: .15rem .5rem; border-radius: 999px;
  border: 1px solid currentColor; white-space: nowrap;
}
.etiqueta.ok   { color: var(--cumple); }
.etiqueta.mal  { color: var(--no-cumple); }
.etiqueta.gris { color: var(--muted); }
/* Se llamaba `.etiqueta.aviso` y colisionaba con `.aviso`, la caja de mensaje:
   un elemento con las dos clases tomaba de `.aviso` el fondo, el borde
   izquierdo y el padding grande —gana por ir después en el archivo— y la
   pastilla salía del tamaño de un botón. Se renombró el modificador, que es el
   que tenía el nombre peor puesto: esto no avisa nada, marca que algo pide
   atención. */
.etiqueta.atencion { color: var(--warn); }
/* `.etiqueta.marca` se quitó el 01/09/2026 junto con lo único que la usaba: el
   resumen «9 · EXTINTOR» de arriba del inventario. Decía el número pero no
   llevaba a él, repetía el filtro cuando ya estaba puesto, y en el celular se
   comía tres renglones. La cuenta se mudó adentro del filtro de tipo, que es
   donde se usa. */

/* ── Datos en dos columnas ──────────────────────────────────── */

.datos { display: grid; grid-template-columns: auto 1fr; gap: .4rem 1rem; margin: 0; }
.datos dt { color: var(--muted); font-size: .9rem; }
.datos dd { margin: 0; font-weight: 600; }

/* ── Checklist ──────────────────────────────────────────────── */

/* **Pegajoso sólo donde se ganó el lugar** (06/09/2026). Nací —y vivía— en
   `.seccion-titulo` a secas, así que se pegaba en las siete pantallas que lo
   usan. En el checklist sirve: las secciones son largas y saber en cuál estás
   mientras respondés es parte de responder. En las otras seis son encabezados
   de bloques cortos, y lo único que hacía era arrastrar una franja gris por la
   pantalla al desplazar —además, con `.dos-columnas` se pegan dos a la vez a
   distinta altura—. Ahora se pide con `.pegajoso`, y lo pide el checklist. */
.seccion-titulo {
  background: var(--cement);
  font-size: .8rem; font-weight: 700; letter-spacing: .06em;
  color: var(--muted-2);
  padding: .7rem .25rem .35rem;
  border-bottom: 1px solid var(--line-soft);
}
.seccion-titulo.pegajoso { position: sticky; top: var(--barra-alto); z-index: 10; }

/* El nombre de la empresa arriba de su gente, adentro de una tarjeta. No es
   `.seccion-titulo`: aquél se pega arriba al desplazar, y varios pegados a la
   vez adentro de la misma tarjeta se superponen. */
.grupo-titulo {
  font-family: var(--mono, inherit);
  font-size: .78rem; font-weight: 700; letter-spacing: .08em;
  color: var(--muted-2); text-transform: uppercase;
  padding: .8rem .25rem .4rem;
  border-bottom: 1px solid var(--line-soft);
}
.grupo-titulo:first-child { padding-top: .2rem; }

.pregunta { padding: .9rem .25rem; border-bottom: 1px solid var(--line-soft); }
/* `align-items: flex-start` no es cosmético: sin él, un hijo de flex se estira
   a lo alto de toda la fila. La marca de resultado, con su radio grande, dejaba
   de ser una pastilla y se volvía un óvalo tan alto como el enunciado — cuatro
   renglones en el celular. */
.pregunta .enunciado { display: flex; align-items: flex-start; gap: .6rem; margin-bottom: .6rem; }
.pregunta .n {
  font-family: var(--mono); color: var(--muted); font-size: .85rem;
  min-width: 1.6rem; padding-top: .15rem;
}
.pregunta .texto { flex: 1; }
/* La referencia normativa es un botón, no un adorno: se toca y dice qué es esa
   norma. Se dibuja discreta —debajo del enunciado y en gris— porque el
   inspector está mirando el extintor, no el decreto; pero está ahí cuando
   alguien pregunta en qué se basa el ítem. */
.norma {
  display: flex; align-items: center; width: 100%; text-align: left;
  font: inherit; font-size: .78rem; color: var(--muted);
  background: none; border: 0;
  cursor: pointer; text-decoration: underline dotted;
  text-underline-offset: 2px;

  /* El área de toque llega a 44 px, pero el relleno se compensa con margen
     negativo para que el diseño no se mueva. Sin esto había dos malas salidas:
     dejarla en 23 px —imposible de acertar con guantes— o darle 44 px de alto
     real, que en un checklist de catorce ítems empuja el trabajo 300 px hacia
     abajo. Se toca cómodo y ocupa casi lo mismo. */
  min-height: 44px;
  padding: .6rem 0;
  margin: -.35rem 0 -.4rem;
}
.norma:hover { color: var(--graphite); }
.norma:focus-visible { outline: 2px solid var(--yellow); outline-offset: 1px; }

/* Tres botones grandes, no un desplegable: con guantes, un toque y listo. */
.opciones { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.opciones button {
  font: inherit; font-weight: 600; font-size: .95rem;
  min-height: 48px; padding: .5rem;
  border: 1.5px solid var(--line-soft); border-radius: var(--radius);
  background: var(--surface); color: var(--muted-2); cursor: pointer;
}
.opciones button[aria-pressed=true] { color: #fff; }
.opciones button.v[aria-pressed=true] { background: var(--cumple);    border-color: var(--cumple); }
.opciones button.x[aria-pressed=true] { background: var(--no-cumple); border-color: var(--no-cumple); }
.opciones button.n[aria-pressed=true] { background: var(--na);        border-color: var(--na); }
.opciones button[disabled] { opacity: .35; cursor: not-allowed; }

.extra { margin-top: .7rem; padding-left: 2.2rem; }
.extra.oculto { display: none; }

.miniaturas { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .5rem; }
.miniaturas img {
  width: 72px; height: 72px; object-fit: cover;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}

/* Barra de avance, fija abajo mientras se carga el checklist. */
.avance {
  position: sticky; bottom: 0; z-index: 15;
  background: var(--surface); border-top: 1px solid var(--line-soft);
  padding: .7rem 1rem; margin: 0 -1rem;
  display: flex; align-items: center; gap: .8rem;
}
.avance .texto { flex: 1; font-size: .9rem; color: var(--muted-2); }
.avance .barra-avance { height: 4px; background: var(--cement); border-radius: 999px; overflow: hidden; }
.avance .barra-avance > span { display: block; height: 100%; background: var(--yellow); transition: width .2s; }

/* ── Avisos ─────────────────────────────────────────────────── */

.aviso {
  padding: .75rem .9rem; border-radius: var(--radius);
  border-left: 4px solid var(--warn); background: #fff8ec;
  font-size: .92rem; margin-bottom: 1rem;
}
.aviso.error { border-left-color: var(--no-cumple); background: #fdefee; }
.aviso.ok    { border-left-color: var(--cumple);    background: #eef7f4; }

.vacio { text-align: center; color: var(--muted); padding: 2.5rem 1rem; }

/* El cartel que confirma que algo se guardó. Va abajo, sobre la navegación:
   en el celular la mirada y el pulgar están abajo, y arriba lo taparía la
   franja de modo prueba. Se va solo — no es algo que haya que cerrar. */
.flotante {
  position: fixed; z-index: 60;
  left: 50%; bottom: calc(56px + env(safe-area-inset-bottom, 0px) + .8rem);
  transform: translate(-50%, .5rem);
  max-width: min(22rem, calc(100vw - 2rem));
  padding: .7rem 1.1rem; border-radius: 999px;
  background: var(--graphite); color: #fff;
  font-size: .95rem; font-weight: 600; text-align: center;
  box-shadow: 0 6px 20px rgba(0,0,0,.28);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.flotante.visible { opacity: 1; transform: translate(-50%, 0); }
.flotante.ok::before { content: '✓ '; color: var(--cumple); }
.flotante.error { background: var(--no-cumple); }
/* Sin navegación abajo —el checklist— el cartel baja a ras del borde. */
body:not(.con-nav) .flotante { bottom: calc(env(safe-area-inset-bottom, 0px) + 5.5rem); }
@media (prefers-reduced-motion: reduce) {
  .flotante { transition: opacity .18s ease; transform: translate(-50%, 0); }
}

/* ── Qué le falta a la empresa ──────────────────────────────── */
/* Va adentro de la tarjeta, así que no usa `.seccion-titulo`: ese es de fondo
   cemento, y adentro de una tarjeta blanca queda como una banda gris. */
.titulo-pasos { margin: 0 0 .5rem; font-size: 1.05rem; }

/* El renglón de cuentas: «2 sitios · 23 controles · 40 elementos».
   Reemplazó a una lista de pasos con tildes verdes, que mentía: un sitio no es
   un paso que se cierra, es una lista que se sigue tocando. Un número no
   promete que algo terminó. */
.resumen-alta {
  margin: .9rem 0 0; font-size: .92rem; color: var(--muted);
}
.acciones + .resumen-alta, .boton + .resumen-alta { margin-top: 1rem; }
.resumen-alta .cuenta { font-weight: 700; color: var(--graphite); }

/* Cuánto hay de cada cosa, al lado del título de su sección. */
.seccion-titulo .cuantos {
  float: right; font-weight: 700; color: var(--graphite);
  letter-spacing: 0; text-transform: none;
}

/* La cuenta que acaba de cambiar parpadea, arriba y en su sección a la vez.
   Es lo que muestra que el resumen y la sección son la misma cosa: sin esto
   el número se movía solo y había que deducir por qué. */
@keyframes recien-cambio {
  from { background: var(--yellow); box-shadow: 0 0 0 4px var(--yellow); }
  to   { background: transparent;   box-shadow: 0 0 0 4px transparent; }
}
.cuenta.recien, .cuantos.recien {
  border-radius: 2px;
  animation: recien-cambio 1.1s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .cuenta.recien, .cuantos.recien { animation: none; }
}

/* Una casilla cuyo blanco es la fila entera. Un cuadradito de 22 px no se
   acierta con guantes; el nombre del control mide 300 px y sí. La etiqueta
   envuelve la casilla y el texto, nunca el desplegable de al lado: adentro,
   elegir la frecuencia desmarcaría lo que se acaba de activar. */
.casilla {
  display: flex; align-items: center; gap: .8rem;
  flex: 1; min-width: 0; min-height: 44px;
  margin: 0; font-weight: inherit; font-size: inherit; cursor: pointer;
}
.casilla input[type=checkbox] {
  flex: none; width: 24px; height: 24px; margin: 0;
  accent-color: var(--cumple);
}
.casilla:hover { background: #f6f4ef; }
.casilla input[disabled] { cursor: not-allowed; }

/* ── Utilidades ─────────────────────────────────────────────── */

.mono { font-family: var(--mono); }
.chico { font-size: .88rem; }
.apagado { color: var(--muted); }
.centrado { text-align: center; }
.oculto { display: none !important; }
.pila > * + * { margin-top: .6rem; }

/* `align-items: end` y no el `stretch` por omisión: con un campo con rótulo al
   lado de uno sin rótulo, el estirado le da a los desplegables el alto del más
   alto y quedan tres veces más grandes de lo que deberían. */
.filtros { display: flex; gap: .5rem; flex-wrap: wrap; align-items: end; margin-bottom: 1rem; }
.filtros select, .filtros input { width: auto; flex: 1 1 8rem; }
/* Las fechas llevan rótulo: dos campos de fecha uno al lado del otro, sin decir
   cuál es cuál, se llenan al revés la mitad de las veces. */
.filtros .campo-fecha {
  flex: 1 1 9rem; display: flex; flex-direction: column; gap: .15rem;
  font-size: .78rem; font-weight: 600; color: var(--muted); margin: 0;
}
/* `flex: none` adentro del rótulo: el `flex: 1 1 8rem` de arriba también lo
   agarra, y en una columna eso es crecer **a lo alto** hasta llenarla. */
.filtros .campo-fecha input { width: 100%; flex: none; }

/* ── Una empresa es un lugar ────────────────────────────────── */
/* La miga de pan y las solapas. Las dibuja `UI.empresa()` en ui.js, igual para
   todas las solapas: es lo que hace que cambiar de solapa no se sienta como
   cambiar de página. Antes el menú marcaba una sección y el título decía otra
   cosa; acá el nombre de la empresa es el título, y se ve de dónde colgás. */
.empresa-tapa { margin-bottom: 1.25rem; }

.miga {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin: 0 0 .7rem; font-size: 1.15rem;
}
.miga a {
  color: var(--muted); text-decoration: none; font-size: .95rem;
  /* 44 px también acá: es la salida de la empresa y se toca con guantes. */
  display: inline-flex; align-items: center; min-height: 44px;
}
.miga a:hover { color: var(--graphite); }
.miga .sep { color: var(--line-soft); }
.miga strong { font-weight: 800; letter-spacing: -.01em; }

/* Las solapas se corren a lo ancho en el celular en vez de apilarse: cinco
   apiladas empujarían el contenido abajo del pliegue en cada pantalla. */
.solapas {
  display: flex; gap: .15rem;
  overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--line-soft);
}
.solapas::-webkit-scrollbar { display: none; }
/* Un degradado en el borde derecho avisa que hay más solapas. Sin esto, en
   390 px la quinta queda cortada y parece que la fila termina ahí. */
.empresa-tapa { position: relative; }
.empresa-tapa::after {
  content: ''; position: absolute; right: 0; bottom: 1px; width: 2.2rem; height: 44px;
  background: linear-gradient(to right, rgba(236,234,227,0), var(--cement) 75%);
  pointer-events: none;
}
@media (min-width: 44rem) { .empresa-tapa::after { display: none; } }
.solapas a {
  flex: none; position: relative;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 .9rem; white-space: nowrap;
  font-size: .95rem; font-weight: 600; color: var(--muted);
  text-decoration: none;
}
.solapas a:hover { color: var(--graphite); background: #f3f1ec; }
.solapas a[aria-current=page] { color: var(--graphite); }
/* La marca de «estás acá» es una barra del amarillo de seguridad, igual que en
   la navegación de abajo: quien no distingue bien los grises igual la ve. */
.solapas a[aria-current=page]::after {
  content: ''; position: absolute; left: .5rem; right: .5rem; bottom: -1px;
  height: 3px; background: var(--yellow); border-radius: 3px 3px 0 0;
}

/* ── El catálogo ────────────────────────────────────────────── */
/* El checklist entero de un tipo, desplegado. Se lee, no se toca: acá se mira
   qué se controla, y cambiarlo se hace publicando una versión nueva. */
.checklist { padding: .2rem .25rem 1rem; }
.titulo-seccion {
  font-size: .72rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
  margin: 1rem 0 .4rem; padding-bottom: .25rem;
  border-bottom: 1px solid var(--line-soft);
}
.items { margin: 0; padding-left: 1.4rem; }
.items li { padding: .5rem 0; border-bottom: 1px solid #f0eee8; }
.items li:last-child { border-bottom: 0; }
.items .texto { display: block; font-size: .95rem; }
.items .marcas { display: flex; flex-wrap: wrap; gap: .3rem; margin: .3rem 0 .1rem; }
.marca-item {
  font-size: .7rem; font-weight: 600; letter-spacing: .02em;
  color: var(--muted); background: var(--cement);
  padding: .1rem .4rem; border-radius: 2px;
}
.marca-item.critica { color: #fff; background: var(--no-cumple); }

/* ── Cómo quedó cada ítem de un control ─────────────────────
   **No todos pesan igual.** Un control tiene trece «cumple» y un «no
   cumple», y lo que se busca al abrirlo es justamente el que falló. Con
   las tres marcas igual de prominentes había que leer los catorce.

   Así que lo que cumple se dice en voz baja y lo que no cumple grita: color
   pleno, fondo, y una franja roja en el borde de la fila para que salte al
   recorrer la lista sin leer.

   Clase propia y no `.etiqueta`: aquélla la usan seis pantallas para otra
   cosa, y ya se pisaron dos nombres en este archivo. */
.resultado {
  flex: 0 0 auto; align-self: flex-start;
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .88rem; white-space: nowrap;
}
.resultado .ic { font-size: .95rem; line-height: 1; }
.resultado.ok   { color: var(--cumple); }
.resultado.gris { color: var(--muted); }
.resultado.mal {
  color: var(--no-cumple); font-weight: 700;
  background: #fbeceb; border-radius: var(--radius-sm); padding: .12rem .5rem;
}

/* La franja del borde. `padding-left` compensa los 3 px para que el texto no
   se corra respecto de los ítems que sí cumplen. */
.pregunta.fallo {
  border-left: 3px solid var(--no-cumple);
  padding-left: calc(.25rem + .5rem); margin-left: -.5rem;
}

/* ── El tablero ─────────────────────────────────────────────── */
/* Los atajos de período van antes que las fechas sueltas: «últimos 3 meses» es
   lo que se pide nueve de cada diez veces, y armarlo a mano con dos calendarios
   es trabajo que la pantalla puede ahorrar. */
/* Cuatro columnas iguales y no `flex-wrap`: con envoltura, «Todo» caía solo
   en una segunda línea y quedaba pareciendo otra cosa. Son cuatro opciones de
   lo mismo y tienen que verse como cuatro. */
.periodo { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin-bottom: .6rem; }
.periodo .boton { padding: .65rem .4rem; }
.periodo .boton.elegido {
  background: var(--graphite); color: #fff; border-color: var(--graphite);
}

.graficas { display: grid; gap: 1rem; margin-bottom: 1.5rem; }
.grafica {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: 1rem;
}
.grafica h2 { margin: 0; font-size: 1rem; }
.grafica .pie-grafica {
  margin: .15rem 0 .8rem; color: var(--muted); font-size: .85rem;
}
/* El lienzo necesita alto explícito: Chart.js con `maintainAspectRatio: false`
   crece hasta el alto del contenedor, y un contenedor sin alto colapsa a cero. */
.grafica .lienzo { position: relative; height: 220px; }
.grafica .lienzo.alto { height: 320px; }
/* Diez barras en 320 px quedan a 32 px cada una y con el rotulo pegado a la de
   arriba. En el celular hay lugar de sobra a lo alto: se lo damos. */
@media (max-width: 51.99rem) { .grafica .lienzo.alto { height: 400px; } }
.grafica .lienzo.bajo { height: 130px; }

@media (min-width: 52rem) {
  .graficas { grid-template-columns: repeat(2, 1fr); }
  .grafica.ancha { grid-column: 1 / -1; }
}

@media (min-width: 40rem) {
  .datos { grid-template-columns: 10rem 1fr; }
  /* En el celular la barra corta el nombre de la empresa, así que el título lo
     repite. En el escritorio entra entero arriba y repetirlo es ruido. */
  .solo-celular { display: none; }
}

/* Lo contrario, y hace falta por el armazón híbrido: ahí la empresa la nombra
   la lateral —que sólo existe arriba de 60rem— y el celular queda con la barra
   diciendo la pantalla. Entonces el nombre de la pantalla va en el escritorio y
   el de la empresa en el celular; cada uno donde el otro no está. */
.solo-escritorio { display: none; }
@media (min-width: 60.0625rem) {
  .solo-escritorio { display: block; }
}

/* ── Navegación ─────────────────────────────────────────────────
   Tres destinos y nada más: Estado (cómo está todo), Controlar (ir a un
   elemento) y el tercero según el rol — Empresas para PRAEVIS, Inventario para
   quien carga elementos. Todo lo demás cuelga de esos tres.

   Abajo en el celular y arriba en el escritorio, y no es una preferencia
   estética: el pulgar llega al borde de abajo y no al de arriba. En una
   pantalla que se usa parado y con una sola mano, la navegación que vive
   arriba se toca mal.

   La barra de abajo NO aparece durante el checklist: ahí ya hay una barra
   pegada abajo con el avance y el botón de guardar, y dos barras pegadas al
   mismo borde compiten por el mismo pulgar. Un checklist a medio cargar es un
   flujo enfocado, como un pago: se sale por «volver», no por cambiar de
   sección sin querer. */

.nav-abajo {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--line-soft);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.nav-abajo a {
  flex: 1; position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; min-height: 56px; padding: .3rem;
  font-size: .72rem; font-weight: 600; letter-spacing: .01em;
  color: var(--muted); text-decoration: none;
}
.nav-abajo a svg { width: 22px; height: 22px; }
.nav-abajo a[aria-current=page] { color: var(--graphite); }
/* La marca de "estás acá" es una barra del amarillo de seguridad. El color
   solo no alcanza: quien no distingue bien los grises igual ve la barra. */
.nav-abajo a[aria-current=page]::before {
  content: ''; position: absolute; top: 0; left: 12%; right: 12%;
  height: 3px; background: var(--yellow); border-radius: 0 0 3px 3px;
}
.nav-abajo a:active { background: #f3f1ec; }

/* En el escritorio la navegación va arriba, dentro de la barra. */
.nav-arriba { display: none; gap: .15rem; }
.nav-arriba a {
  font-size: .9rem; font-weight: 600; color: #cfd2d6;
  padding: 0 .8rem; border-radius: var(--radius-sm);
}
.nav-arriba a[aria-current=page] { color: #fff; box-shadow: inset 0 -3px 0 var(--yellow); }

/* Sin esto, la barra de abajo tapa lo último de la página. */
body.con-nav { padding-bottom: 62px; }

@media (min-width: 48rem) {
  .nav-abajo { display: none; }
  .nav-arriba { display: flex; }
  body.con-nav { padding-bottom: 0; }
}

/* ── Hoja de opciones ───────────────────────────────────────────
   Reemplaza al `prompt()` del navegador, que no se puede leer con una mano,
   no dice cuál está elegido y en iOS aparece pegado arriba de todo. Sube
   desde abajo en el celular —donde está el pulgar— y se centra en pantalla
   grande. */

.velo {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: flex-end;
  animation: aparecer .15s ease-out;
}
@keyframes aparecer { from { opacity: 0 } to { opacity: 1 } }

.hoja {
  background: var(--surface); width: 100%;
  border-radius: 14px 14px 0 0;
  padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom, 0));
  max-height: 80vh; overflow-y: auto;
}
.hoja h2 { margin: 0 0 .8rem; font-size: 1.05rem; }
.hoja .opcion {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  min-height: 52px; padding: .6rem .5rem;
  font: inherit; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--line-soft);
  color: inherit; cursor: pointer;
}
.hoja .opcion:last-of-type { border-bottom: 0; }
.hoja .opcion:hover { background: #f6f4ef; }
.hoja .opcion .tilde { color: var(--yellow-dk); font-weight: 700; width: 1.2rem; }
.hoja .opcion .nombre { flex: 1; font-weight: 600; }

@media (min-width: 48rem) {
  .velo { align-items: center; justify-content: center; }
  .hoja { max-width: 26rem; border-radius: var(--radius); }
}

/* ── Panel ──────────────────────────────────────────────────────── */

.numeros { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; margin-bottom: 1rem; }
.numero {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: .8rem;
}
.numero .valor { font-size: 1.7rem; font-weight: 700; line-height: 1.1; }
.numero .rotulo { color: var(--muted); font-size: .82rem; }
.numero.mal .valor { color: var(--no-cumple); }
.numero.ok  .valor { color: var(--cumple); }
.numero.aviso .valor { color: var(--warn); }

@media (min-width: 40rem) { .numeros { grid-template-columns: repeat(4, 1fr); } }

/* Una no conformidad: qué falló, en qué elemento y con qué foto. */
.falla { display: flex; gap: .8rem; padding: .8rem .25rem; border-bottom: 1px solid var(--line-soft); }
.falla:last-child { border-bottom: 0; }
.falla .miniatura {
  width: 56px; height: 56px; flex: none; object-fit: cover;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}
.falla .cuerpo { flex: 1; min-width: 0; }
/* El código es un enlace a la ficha, y se toca: va como chip con la misma
   altura mínima que todo lo demás. */
.falla .encabezado { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.falla .encabezado a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--mono); font-weight: 600; color: inherit; text-decoration: none;
}
.falla .encabezado a:hover { text-decoration: underline; }
.falla .donde { color: var(--muted); font-size: .85rem; }
.falla .obs { font-size: .9rem; margin-top: .2rem; }

.tabla { width: 100%; border-collapse: collapse; font-size: .92rem; }
.tabla th, .tabla td { text-align: left; padding: .5rem .4rem; border-bottom: 1px solid var(--line-soft); }
.tabla th { color: var(--muted); font-size: .82rem; font-weight: 600; }
.tabla td.n, .tabla th.n { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Modo prueba ────────────────────────────────────────────────
   Mientras el rol se elige a mano, tiene que quedar sin lugar a dudas cuál se
   está mirando. Una franja arriba de todo, con el color de la familia del rol
   y el nombre entero.

   Es deliberadamente llamativa: no es decoración, es lo que evita mirar una
   pantalla y sacar conclusiones creyendo que se está viendo otra cosa. El día
   que haya autenticación, esta franja desaparece entera y con ella este bloque
   de estilos. */

.modo-prueba {
  position: sticky; top: 0; z-index: 25;
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .35rem .75rem;
  font-size: .8rem; color: #fff;
  background: var(--praevis-modo);
}
.modo-prueba.praevis { --praevis-modo: #5B3E8E; }   /* violeta: gente de PRAEVIS */
.modo-prueba.cliente { --praevis-modo: #1F6F73; }   /* verde azulado: gente del cliente */

.modo-prueba .etiqueta-modo {
  font-weight: 700; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
  background: rgba(255, 255, 255, .22); padding: .1rem .45rem; border-radius: 3px;
}
.modo-prueba .viendo { opacity: .85; }
.modo-prueba button {
  display: inline-flex; align-items: center; min-height: 44px;
  font: inherit; color: #fff; background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .35); border-radius: 999px;
  padding: 0 .7rem; cursor: pointer;
}
.modo-prueba button:hover { background: rgba(255, 255, 255, .26); }
/* El segundo botón, el de la persona. Va más marcado que el del rol porque es
   el que cambia lo que se ve: con este rol, quién sos decide qué empresas
   tenés. Sólo aparece donde eso es cierto (ver `Roles.eligePersona`). */
.modo-prueba button.persona {
  background: rgba(255, 255, 255, .28); border-color: rgba(255, 255, 255, .6);
}
.modo-prueba button.persona:hover { background: rgba(255, 255, 255, .4); }

/* La barra de la aplicación se pega debajo de la franja, no arriba de todo. */
body.con-prueba .barra { top: var(--modo-alto, 38px); }
body.con-prueba .seccion-titulo.pegajoso { top: calc(var(--barra-alto) + var(--modo-alto, 38px)); }

@media (max-width: 24rem) {
  .modo-prueba .viendo { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   EL PANEL DEL ADMINISTRADOR

   Un armazón aparte, y sólo para el rol «PRAEVIS · administrador».
   Los cuatro roles restantes siguen con la barra de arriba: el inspector
   controla parado frente a un extintor, con el celular en una mano, y esa
   navegación está hecha para el pulgar.

   El administrador es el único que trabaja sentado y con pantalla ancha, y
   es el único que tiene profundidad para mostrar: adentro de una empresa
   hay cinco solapas, más la salida, más los dos destinos globales. Ocho
   cosas no entran arriba en horizontal sin apretarse; al costado entran
   cómodas y —lo que más importa— **se quedan quietas al bajar por la
   tabla**, que es cuando la jerarquía se perdía de vista.

   Abajo de 60rem la lateral se convierte en un botón de menú. NO en una
   barra que se desplaza al costado: una fila que se desplaza esconde
   destinos sin avisar, y lo que no entra, no existe.
   ══════════════════════════════════════════════════════════════ */

body.panel { background: var(--cement); }
body.panel .barra { display: none; }
body.panel .nav-abajo { display: none; }
body.panel.con-nav main { padding-bottom: 1rem; }

.app { display: grid; grid-template-columns: 216px minmax(0, 1fr); min-height: 100vh; }
/* **`min-width: 0` no es adorno.** Un hijo de grid no encoge por debajo de su
   ancho mínimo de contenido, así que una sola línea larga adentro estiraba la
   columna y con ella la página entera: en 390 px el documento medía 516 y se
   corría a lo ancho. Con esto el contenido vuelve a envolver o a recortarse
   como lo hacía antes de que hubiera panel. */
.app > * { min-width: 0; }
body.con-prueba .app { min-height: calc(100vh - var(--modo-alto, 38px)); }

.lateral {
  background: var(--graphite); color: #E8E6E1;
  padding: 1rem 0 1.2rem; display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
body.con-prueba .lateral { top: var(--modo-alto, 38px); height: calc(100vh - var(--modo-alto, 38px)); }

.lateral .logo { padding: 0 1rem 1rem; display: block; }
.lateral .logo img { height: 20px; display: block; }
.lateral .rotulo-panel {
  font-family: var(--mono); font-size: .68rem; color: #8C8981;
  text-transform: uppercase; letter-spacing: .12em; padding: .25rem 1rem 0;
}

.lateral nav { display: flex; flex-direction: column; gap: 2px; padding: 0 .5rem; }
.lateral a {
  display: flex; gap: .6rem; align-items: center; padding: .6rem .65rem;
  border-radius: var(--radius); color: #B9B6AF; text-decoration: none;
  line-height: 1.3; min-height: 44px;
}
.lateral a .txt { display: block; }
.lateral a b { display: block; font-size: 1rem; font-weight: 600; color: #D8D5CF; }
.lateral a small { display: block; font-size: .78rem; color: #8C8981; }
.lateral a svg { width: 18px; height: 18px; flex: 0 0 auto; opacity: .7; }
.lateral a:hover { background: #26282D; }
.lateral a[aria-current="page"] { background: #26282D; }
.lateral a[aria-current="page"] b { color: #FFF; }
.lateral a[aria-current="page"] svg { opacity: 1; color: var(--yellow); }

/* Adentro de una empresa: la salida y el nombre arriba, los destinos
   globales al pie, separados. */
.lateral .volver {
  display: block; padding: 0 1rem .4rem; color: #8C8981;
  text-decoration: none; font-size: .88rem; min-height: 0;
}
.lateral .volver:hover { color: var(--yellow); background: none; }
.lateral .quien {
  padding: 0 1rem .9rem; font-size: 1rem; font-weight: 800; color: #FFF; line-height: 1.25;
}
.lateral .quien .etiqueta { margin-top: .3rem; }
.lateral .global {
  margin-top: auto; padding: .75rem .5rem 0; border-top: 1px solid #32353B;
  display: flex; flex-direction: column; gap: 2px;
}
.lateral .global a b { font-size: .95rem; color: #8C8981; }
.lateral .global a:hover b { color: #D8D5CF; }

/* Quién entró y por dónde se sale, al pie de las tres laterales. `margin-top:
   auto` lo empuja abajo cuando no hay `.global`; cuando lo hay, aquél ya empujó
   y esto queda debajo, que es donde se busca: lo último de la lista. */
.pie-sesion {
  margin-top: auto; padding: .75rem 1rem 0; border-top: 1px solid #32353B;
  display: flex; align-items: center; gap: .5rem;
}
.lateral .global + .pie-sesion { margin-top: 0; border-top: 0; padding-top: .35rem; }
.pie-sesion .quien-soy {
  flex: 1; min-width: 0; font-size: .85rem; color: #8C8981;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pie-sesion .salir {
  flex: none; min-height: 44px; padding: 0 .8rem;
  background: none; border: 1px solid #3a3e45; border-radius: var(--radius-sm);
  color: #D8D5CF; font: inherit; font-size: .9rem; cursor: pointer;
}
.pie-sesion .salir:hover { background: #26282D; color: #FFF; border-color: #4a4e55; }

/* El contenido usa el ancho que haya: las tablas son el producto acá. */
body.panel main { max-width: none; margin: 0; padding: 1.4rem 1.5rem 3rem; }
body.panel main.angosto { max-width: none; }

.hd { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.2rem; flex-wrap: wrap; }
.hd h1 { font-size: 1.4rem; margin: 0; }
.hd .sello { font-family: var(--mono); font-size: .8rem; color: var(--muted); white-space: nowrap; }

/* ── La barra del celular ──────────────────────────────────── */
.barra-movil { display: none; align-items: center; gap: .75rem; padding: .5rem .75rem; }
.barra-movil .logo { padding: 0; }
.barra-movil .quien-corto {
  font-size: 1rem; font-weight: 700; color: #FFF; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.hamburguesa {
  display: flex; align-items: center; gap: .5rem; font: inherit; font-size: 1rem;
  font-weight: 600; cursor: pointer; background: none; color: #E8E6E1;
  border: 1px solid #32353B; border-radius: var(--radius);
  padding: .45rem .7rem; min-height: 44px; flex: 0 0 auto;
}
.hamburguesa:hover { background: #26282D; }

@media (max-width: 60rem) {
  .app { grid-template-columns: minmax(0, 1fr); }
  /* `body.con-prueba .lateral` es más específico que `.lateral`, así que su
     `height: calc(100vh - …)` ganaba acá adentro y la lateral se comía la
     pantalla entera: el contenido quedaba empujado abajo de todo. */
  .lateral, body.con-prueba .lateral {
    position: static; height: auto; top: auto; padding: 0;
  }
  .barra-movil { display: flex; }
  .lateral .logo, .lateral .rotulo-panel, .lateral .volver, .lateral .quien { display: none; }
  .barra-movil .logo { display: block; }
  .lateral nav { display: none; padding: 0 .5rem .6rem; }
  .lateral.abierta nav { display: flex; }
  .lateral .global { display: none; margin-top: 0; padding-bottom: .5rem; }
  .lateral.abierta .global { display: flex; }
  /* El pie va **adentro del menú**, como el resto. Suelto quedaba de franja gris
     fija abajo de la hamburguesa —ocupando alto en todas las pantallas para
     decir algo que no se necesita a cada momento— y es exactamente la franja
     que se sacó de `.seccion-titulo`. Ahí adentro es lo último de la lista, que
     es donde se busca «Salir» en cualquier aplicación que tenga menú. */
  .lateral .pie-sesion { display: none; margin-top: 0; padding-bottom: .6rem; }
  .lateral.abierta .pie-sesion { display: flex; }
  body.panel main { padding: 1rem .85rem 2.5rem; }
}

/* ══════════════════════════════════════════════════════════════
   EL ARMAZÓN HÍBRIDO — la lateral sólo en pantalla ancha

   Para el inspector de PRAEVIS (01/09/2026). La plataforma tiene que
   navegarse igual en todos lados, así que en el escritorio ve la misma
   lateral que el administrador; pero él controla parado, con el celular en
   una mano y a veces con guantes, y ahí sus tres destinos tienen que estar
   bajo el pulgar y no detrás de un botón de menú.

   **Se dibujan los dos armazones y el CSS muestra el que entra**, igual que
   `table.panel-tabla` y `ul.tarjetas-datos`. El corte es el mismo 60rem al
   que la lateral del administrador se pliega en hamburguesa: arriba de ahí
   los dos roles se ven idénticos, abajo cada uno hace lo suyo.
   ══════════════════════════════════════════════════════════════ */

/* Hasta 60rem no hay lateral: la navegación es la barra de arriba y la de
   abajo, que es lo que la página ya trae. Sólo hay que sacar la columna. */
@media (max-width: 60rem) {
  body.panel-ancho .lateral { display: none; }
  body.panel-ancho .app { display: block; }
}

/* Arriba de 60rem se comporta como el panel del administrador. Las reglas se
   repiten en vez de sumar `body.panel-ancho` a los selectores de arriba
   porque aquéllas valen en todos los anchos y éstas no. */
@media (min-width: 60.0625rem) {
  body.panel-ancho { background: var(--cement); }
  body.panel-ancho .barra { display: none; }
  body.panel-ancho .nav-abajo { display: none; }
  body.panel-ancho.con-nav main { padding-bottom: 1rem; }
  body.panel-ancho main { max-width: none; margin: 0; padding: 1.4rem 1.5rem 3rem; }
  body.panel-ancho main.angosto { max-width: none; }
}

/* ── La tabla del panel ──────────────────────────────────────
   **`panel-tabla` y no `datos`**: `.datos` ya existe desde antes como una
   grilla de definiciones (`dl`/`dt`/`dd`) para la ficha del elemento. Al
   reusar el nombre, su `display: grid` ganaba sobre la tabla —que no declara
   `display`— y el encabezado terminaba montado encima de la primera fila.
   Costó un rato encontrarlo porque el HTML estaba bien. */
.tabla-envoltorio { overflow-x: auto; }
table.panel-tabla { width: 100%; border-collapse: collapse; font-size: 1rem; }
table.panel-tabla th, table.panel-tabla td {
  text-align: left; padding: .6rem .75rem;
  border-bottom: 1px solid var(--line-soft); white-space: nowrap;
}
/* **Sin `position: sticky`.** Pegar el encabezado exige un contenedor con alto
   propio y `overflow-y`; acá el envoltorio sólo desplaza en horizontal, así que
   el `thead` se pegaba al viewport y se montaba encima de la primera fila. */
table.panel-tabla thead th {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted); font-weight: 600;
  background: var(--cement); border-bottom: 1px solid var(--line-soft);
}
table.panel-tabla tbody tr:last-child td { border-bottom: 0; }
table.panel-tabla tbody tr.tocable { cursor: pointer; }
table.panel-tabla tbody tr.tocable:hover { background: var(--cement); }
table.panel-tabla td.num, table.panel-tabla th.num {
  text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums;
}
table.panel-tabla td.codigo { font-family: var(--mono); font-weight: 700; }
table.panel-tabla td.nombre { white-space: normal; min-width: 12rem; font-weight: 700; }
table.panel-tabla td.apagado, table.panel-tabla .apagado { color: var(--muted); }

/* Las tarjetas: lo que se ve cuando la tabla no entra. Es, en esencia, lo
   que la aplicación ya hacía antes de tener panel. */
.tarjetas-datos { display: none; list-style: none; margin: 0; padding: 0; }
.tarjetas-datos li { padding: .85rem 1rem; border-bottom: 1px solid var(--line-soft); }
.tarjetas-datos li:last-child { border-bottom: 0; }
.tarjetas-datos .cabeza {
  display: flex; justify-content: space-between; gap: .6rem; align-items: baseline;
}
.tarjetas-datos .cabeza b { font-size: 1.05rem; }
/* Los datos corridos, con puntos medios: sin monoespaciada y sin huecos
   fijos entre columnas invisibles, que era lo que los hacía ver sueltos. */
.tarjetas-datos .linea { margin-top: .3rem; font-size: .95rem; color: var(--muted-2); }
.tarjetas-datos .linea span + span::before {
  content: '·'; margin: 0 .4rem; color: var(--line-soft);
}

@media (max-width: 46rem) {
  .tabla-envoltorio { display: none; }
  .tarjetas-datos { display: block; }
}

/* Los filtros de una tabla del panel usan `.filtros`, la de siempre. No hay
   una clase aparte a propósito: al agregar una que se llamaba igual, su regla
   —más abajo en el archivo— le pasaba por encima a la del tablero y en el
   celular le apilaba las fechas a todo el ancho. Es el segundo nombre que se
   pisa acá: antes fue `.datos`. */

/* La salida vive arriba de la lateral, donde se la busca. En el celular esa
   parte está escondida detrás del botón, así que se repite adentro del
   desplegable — y sólo ahí. */
.lateral .volver-movil { display: none; }
@media (max-width: 60rem) { .lateral .volver-movil { display: flex; } }

/* ── Dos cosas al lado, no una estirada ──────────────────────
   Sólo en el panel y sólo cuando hay ancho de sobra. Una sección de gente
   estirada a 1650 px deja el nombre a la izquierda, los botones pegados al
   borde derecho y un abismo en el medio: hay que barrer con los ojos de
   punta a punta para leer una fila. Al lado entran las dos sin desplazarse
   y cada una se lee de un vistazo.

   `align-items: start` para que una columna corta no estire su tarjeta
   hasta el alto de la otra. */
.dos-columnas { display: grid; gap: 0 1.25rem; align-items: start; }
@media (min-width: 68rem) {
  body.panel .dos-columnas { grid-template-columns: 1fr 1fr; }
}

/* El catálogo: cada tipo con su checklist. Con 28 tipos, una columna obliga
   a desplazarse el doble para ver lo mismo.

   **`break-inside: avoid` va en los ítems, no en la lista.** Puesto en el
   hijo directo —el `ul`— le prohíbe partirse justamente a lo único que hay
   que repartir, y la segunda columna queda vacía. */
@media (min-width: 68rem) {
  body.panel .en-columnas { columns: 2; column-gap: 1.5rem; }
  body.panel .en-columnas > li { break-inside: avoid; }
  /* La línea de separación de la última fila de cada columna sobra. */
  body.panel .en-columnas > li:last-child { border-bottom: 0; }
}

/* «y 4 más», al lado de la primera norma citada. Tenue: dice que hay más sin
   competir con el nombre del decreto. */
.norma .y-mas { color: var(--muted); font-weight: 400; margin-left: .35em; }

/* ══════════════════════════════════════════════════════════════
   ENTRAR

   Las dos pantallas que existen **antes** de la sesión: la de entrar y la de
   elegir la propia clave. No tienen armazón —ni barra, ni lateral, ni
   navegación— porque todavía no hay a dónde ir: lo único que se puede hacer
   acá es entrar.

   Centrada y angosta: se abre igual en el celular parado en planta y en una
   computadora, y en los dos casos lo único que importa son dos campos.
   ══════════════════════════════════════════════════════════════ */

body.entrada {
  background: var(--cement);
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; padding: 1.25rem;
}
body.entrada main { width: 100%; max-width: 24rem; margin: 0; padding: 0; }

.tapa-entrada { text-align: center; margin-bottom: 1.5rem; }
.logo-entrada { height: 34px; display: block; margin: 0 auto .5rem; }
.tapa-entrada .sub { margin: 0; }

/* Las dos formas de entrar. No es una fila de solapas de las que ya hay: éstas
   eligen **qué formulario se muestra**, no a qué pantalla se va, así que se
   ven como un interruptor de dos posiciones y no como una navegación. */
.solapas-entrada {
  display: grid; grid-template-columns: 1fr 1fr; gap: .3rem;
  background: var(--cement); border-radius: var(--radius);
  padding: .25rem; margin-bottom: 1.25rem;
}
.solapas-entrada button {
  font: inherit; font-size: .9rem; font-weight: 600;
  min-height: 44px; padding: .5rem .4rem;
  border: 0; border-radius: calc(var(--radius) - 2px);
  background: transparent; color: var(--muted); cursor: pointer;
}
.solapas-entrada button.elegida { background: var(--surface); color: var(--graphite); }
