/* Estilos de la consola. Los valores viven en tokens.css; acá solo se usan.
   Dirección: sala de control nocturna — tinta azulada, cifras tabulares con
   peso, y el único color saturado es el de los estados, con halo luminoso. */

/* ---- Fuentes self-hosted (variables, subset latin) ---------------------- */

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

@font-face {
  font-family: 'Archivo Narrow';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/archivo-narrow-var-latin.woff2') format('woff2');
}

/* ---- Base --------------------------------------------------------------- */

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

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  color: var(--text);
  background: var(--bg);
}

h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: var(--brand-bright); }
img { display: block; }
button { font: inherit; }

/* Cualquier `display` de autor le gana al `[hidden]` de la hoja del navegador:
   sin esto, .panel o .reproductor (display: flex) se siguen viendo con el
   atributo puesto. */
[hidden] { display: none !important; }

/* Una consola que se usa todo el día se navega con teclado. */
:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 2px;
}

/* Horas, conteos y coordenadas no bailan al actualizarse. */
.num { font-variant-numeric: tabular-nums; }

/* Etiqueta de instrumento: versalita espaciada, para rótulos chicos. */
.rotulo {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ---- Layout de la consola ----------------------------------------------- */

.app {
  display: grid;
  height: 100vh;      /* fallback: dvh no resuelve en algunos motores */
  height: 100dvh;
  grid-template-rows: 56px 40px 1fr;
  grid-template-columns: 280px 1fr;
}

/* ---- Header ------------------------------------------------------------- */

.header {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: var(--s5);
  padding: 0 var(--s4);
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}

.header__logo { height: 26px; width: auto; }

.header__nav {
  display: flex;
  gap: var(--s2);
  margin-left: var(--s3);
  align-self: stretch;
}

.header__nav a {
  display: flex;
  align-items: center;
  padding: 0 var(--s3);
  color: var(--text-muted);
  text-decoration: none;
  font-size: var(--text-sm);
  border-bottom: 2px solid transparent;
}

.header__nav a:hover { color: var(--text); }

.header__nav a[aria-current="page"] {
  color: var(--text);
  font-weight: 600;
  border-bottom-color: var(--brand-bright);
}

.header__user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* Latido de conexión: verde respirando mientras el polling está sano,
   rojo fijo cuando se pierde. Movimiento con información, no decorativo. */
.header__conexion {
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--ok);
  box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 60%, transparent);
  animation: latido 2.4s ease-in-out infinite;
}

.header__conexion.is-error {
  background: var(--danger);
  box-shadow: 0 0 8px color-mix(in srgb, var(--danger) 60%, transparent);
  animation: none;
}

@keyframes latido {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* ---- Franja de resumen: una línea de texto, no tarjetas ----------------- */

.resumen {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  padding: 0 var(--s4);
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.resumen__dato { padding-right: var(--s5); }

.resumen__dato + .resumen__dato {
  padding-left: var(--s5);
  border-left: 1px solid var(--border);
}

.resumen strong {
  color: var(--text);
  font-weight: 800;
  font-size: var(--text-lg);
  margin-right: var(--s1);
}

.resumen__conexion {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.resumen__conexion.is-error { color: var(--danger); }

/* ---- Riel de personas --------------------------------------------------- */

.riel {
  overflow-y: auto;
  border-right: 1px solid var(--border);
  background: var(--bg-sunken);
  font-family: var(--font-dense);
}

.riel__buscador {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: var(--s3);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
}

.riel__buscador input {
  width: 100%;
  padding: var(--s2) var(--s3);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--bg);
}

.riel__buscador input::placeholder { color: var(--text-faint); }

.grupo > summary {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  margin-top: var(--s2);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  cursor: pointer;
  user-select: none;
  list-style: none;
}

.grupo > summary::-webkit-details-marker { display: none; }

.grupo > summary::before {
  content: '▸';
  color: var(--text-faint);
}

.grupo[open] > summary::before { content: '▾'; }

.grupo__conteo {
  margin-left: auto;
  font-weight: 400;
  color: var(--text-faint);
}

.persona {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  width: 100%;
  padding: var(--s2) var(--s3) var(--s2) var(--s4);
  background: none;
  border: none;
  border-left: 2px solid transparent;
  text-align: left;
  cursor: pointer;
  color: inherit;
  font-family: inherit;
}

.persona:hover { background: var(--bg-raised); }

.persona.is-selected {
  background: var(--bg-raised);
  border-left-color: var(--estado-fila, var(--brand-bright));
}

.persona__nombre {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--text-sm);
  color: var(--text);
}

.persona__senal {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

/* Punto de estado: el color viene de la BD vía --estado. Siempre acompañado
   del nombre escrito; el color nunca es el único portador de información.
   El halo es la firma visual de la consola: sobre tinta, brilla. */
.estado-dot {
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--estado, var(--border-strong));
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--estado, transparent) 18%, transparent),
    0 0 8px color-mix(in srgb, var(--estado, transparent) 45%, transparent);
  align-self: center;
}

/* Más de 30 min sin reportar: punto atenuado, hueco y sin halo. */
.persona.is-stale .estado-dot {
  background: transparent;
  border: 2px solid var(--estado, var(--border-strong));
  box-shadow: none;
  opacity: 0.5;
}

.persona.is-stale .persona__nombre { color: var(--text-muted); }

.riel__vacio {
  padding: var(--s4);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ---- Mapa: es el suelo, no un widget ------------------------------------ */

.mapa {
  position: relative;
  background: var(--bg);
}

/* Especificidad subida (clase repetida): maplibre-gl.css carga después de
   app.css y trae `.maplibregl-map { position: relative }`, que con igual
   especificidad le ganaba a este `position: absolute` y colapsaba el
   contenedor a 0 de alto (el canvas quedaba recortado por overflow:hidden).
   height/width 100% como respaldo si el positioning llegara a perder. */
.mapa__lienzo.mapa__lienzo {
  position: absolute;
  inset: 0;
  height: 100%;
  width: 100%;
}

/* Aviso sobre el mapa cuando el basemap no carga (DISENO.md: el error
   explica qué pasó, no deja un rectángulo negro y mudo). */
.mapa__aviso {
  position: absolute;
  top: var(--s4);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: var(--s2) var(--s4);
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--danger);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow);
}

/* Botón de tema del mapa (claro/oscuro), como control de MapLibre. */
/* maplibre-gl.css impone Helvetica/Arial a los controles, la atribución y
   los popups del mapa, y se carga después de app.css. Se sube especificidad
   repitiendo la clase para que todo el chrome del mapa use Archivo como el
   resto de la consola. */
.maplibregl-map.maplibregl-map {
  font-family: var(--font);
}

/* Selector de capa del mapa: luna / sol / satélite, apilados como los
   controles nativos de MapLibre. */
.mapa__capa {
  display: grid;
  place-content: center;
  width: 29px;
  height: 29px;
  padding: 0;
  color: var(--text-muted);
  background: var(--bg-raised);
  border: none;
  cursor: pointer;
}

.mapa__capa svg {
  width: 15px;
  height: 15px;
}

.mapa__capa:hover { color: var(--text); }

.mapa__capa[aria-pressed='true'] { color: var(--brand-bright); }

/* Marcador: medallón con iniciales y anillo del color de estado. La foto
   llega con el panel de detalle; las iniciales son el fallback definitivo. */
.marcador {
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: var(--r-pill);
  background: var(--bg-raised);
  border: 3px solid var(--estado, var(--border-strong));
  color: var(--text);
  display: grid;
  place-content: center;
  cursor: pointer;
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--estado, transparent) 22%, transparent),
    0 0 14px color-mix(in srgb, var(--estado, transparent) 40%, transparent),
    0 2px 6px rgba(0, 0, 0, 0.5);
}

.marcador__iniciales {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.marcador.is-stale {
  width: 14px;
  height: 14px;
  border-width: 2px;
  opacity: 0.55;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

.marcador.is-stale .marcador__iniciales { display: none; }

.marcador.is-selected {
  outline: 2px solid var(--brand-bright);
  outline-offset: 2px;
}

/* ---- Leyenda: el glosario de estados, flotando sobre el mapa ------------ */

.leyenda {
  position: absolute;
  bottom: var(--s4);
  left: var(--s4);
  min-width: 168px;
  padding: var(--s3);
  background: color-mix(in srgb, var(--bg-sunken) 88%, transparent);
  backdrop-filter: blur(6px);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
}

.leyenda__titulo {
  color: var(--text-faint);
  margin-bottom: var(--s2);
}

.leyenda__item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  padding: var(--s1) var(--s1);
  background: none;
  border: none;
  color: var(--text);
  font-size: var(--text-sm);
  cursor: pointer;
  text-align: left;
}

.leyenda__item:hover { background: var(--bg-raised); border-radius: var(--r-sm); }

.leyenda__nombre { flex: 1; }

.leyenda__conteo { color: var(--text-faint); font-size: var(--text-xs); }

/* Estado apagado por el filtro: sigue legible, pero claramente fuera. */
.leyenda__item.is-off { opacity: 0.4; }
.leyenda__item.is-off .estado-dot { box-shadow: none; background: transparent;
  border: 2px solid var(--estado, var(--border-strong)); }

.leyenda__zonas {
  margin-top: var(--s2);
  padding-top: var(--s2);
  border-top: 1px solid var(--border);
  border-radius: 0;
  color: var(--text-muted);
}

.leyenda__ir-zona {
  margin-top: var(--s2);
  width: 100%;
  padding: var(--s1) var(--s2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-muted);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  cursor: pointer;
}

.leyenda__seguimiento { color: var(--text-muted); }

/* ---- Panel de detalle: se superpone al mapa, no lo reencuadra ----------- */

.panel {
  position: absolute;
  top: var(--s4);
  right: var(--s4);
  bottom: var(--s4);
  width: 360px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s4);
  overflow-y: auto;
  background: color-mix(in srgb, var(--bg-sunken) 94%, transparent);
  backdrop-filter: blur(6px);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
}

.panel__cerrar {
  position: absolute;
  top: var(--s2);
  right: var(--s3);
  padding: 0;
  font-size: var(--text-lg);
  line-height: 1;
  color: var(--text-faint);
  background: none;
  border: none;
  cursor: pointer;
}

.panel__cerrar:hover { color: var(--text); }

.panel__cabecera {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding-right: var(--s5);
}

/* Mismo medallón que la tarjeta del seguimiento, un paso más grande. */
.panel__medallon {
  flex: none;
  display: grid;
  place-content: center;
  width: 56px;
  height: 56px;
  overflow: hidden;
  border-radius: var(--r-pill);
  border: 3px solid var(--estado, var(--border-strong));
  background: var(--bg-raised);
  color: var(--text);
  font-weight: 700;
}

.panel__medallon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.panel__nombre {
  margin: 0;
  font-size: var(--text-base);
  font-weight: 600;
}

.panel__grupo {
  margin: var(--s1) 0 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.panel__datos {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s2) var(--s4);
  margin: 0;
  font-size: var(--text-sm);
}

.panel__datos dt {
  font-size: var(--text-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-top: 2px;
}

.panel__datos dd {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
}

.panel__exacta {
  font-size: var(--text-xs);
  color: var(--text-faint);
}

/* Historial corto de estados: mismo lenguaje que la leyenda y el reporte —
   punto de color + nombre en gris normal, horas en tabular apagado. */
.panel__historial {
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
}

.historial {
  display: grid;
  gap: var(--s2);
  margin: var(--s2) 0 0;
  padding: 0;
  list-style: none;
}

.historial__item {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  font-size: var(--text-sm);
}

.historial__item .estado-dot { align-self: center; }

.historial__nombre {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.historial__item.is-actual .historial__nombre { font-weight: 600; }

.historial__rango {
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

.panel__cambio {
  display: grid;
  gap: var(--s2);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
}

.panel__cambio select {
  width: 100%;
  padding: var(--s2) var(--s3);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
}

.panel__aviso {
  min-height: 1em;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.btn--bloque {
  margin-top: auto;
  display: block;
  text-align: center;
  text-decoration: none;
}

/* El panel se come el mapa en pantallas chicas: pasa a hoja completa. */
@media (max-width: 900px) {
  .panel {
    inset: 0;
    width: auto;
    border-radius: 0;
  }
}

/* ---- Tarjeta del modo seguimiento: popup sobre la persona centrada ------ */

.tarjeta-seguimiento .maplibregl-popup-content {
  padding: var(--s2) var(--s3);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
}

.tarjeta-seguimiento.maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
.tarjeta-seguimiento.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,
.tarjeta-seguimiento.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip {
  border-top-color: var(--bg-raised);
}
.tarjeta-seguimiento.maplibregl-popup-anchor-top .maplibregl-popup-tip,
.tarjeta-seguimiento.maplibregl-popup-anchor-top-left .maplibregl-popup-tip,
.tarjeta-seguimiento.maplibregl-popup-anchor-top-right .maplibregl-popup-tip {
  border-bottom-color: var(--bg-raised);
}
.tarjeta-seguimiento.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--bg-raised); }
.tarjeta-seguimiento.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--bg-raised); }

.tarjeta-persona {
  display: flex;
  align-items: center;
  gap: var(--s3);
}

/* Medallón: foto real o iniciales, siempre con el anillo del color de
   estado (mismo lenguaje que el marcador). */
.tarjeta-persona__medallon {
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  border: 3px solid var(--estado, var(--border-strong));
  object-fit: cover;
}

.tarjeta-persona__medallon--iniciales {
  display: grid;
  place-content: center;
  background: var(--bg-sunken);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: 700;
}

.tarjeta-persona__nombre {
  margin: 0;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--text);
}

.tarjeta-persona__meta {
  margin: var(--s1) 0 0;
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* ---- Recorridos: toolbar y reproductor ---------------------------------- */

.app--recorridos {
  grid-template-rows: 56px auto 1fr;
  grid-template-columns: 1fr;
}

.mapa--ancho { grid-column: 1 / -1; }

.toolbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s3) var(--s4);
  /* Aire vertical: sin esto los controles quedan pegados al header. */
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}

.toolbar__grupo {
  display: flex;
  align-items: center;
  gap: var(--s2);
}

.toolbar__grupo .rotulo { color: var(--text-faint); }

.toolbar select,
.toolbar input[type="date"] {
  padding: var(--s1) var(--s2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  color-scheme: dark;
}

.toolbar__aviso {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.toolbar__aviso.is-error { color: var(--danger); }

/* ---- Reporte diario por persona ------------------------------------------ */

.app--reporte {
  grid-template-rows: 56px auto 1fr;
  grid-template-columns: 1fr;
}

.reporte {
  overflow-y: auto;
  padding: var(--s5);
  max-width: 920px;
}

.reporte__titulo {
  font-size: var(--text-lg);
  margin-bottom: var(--s1);
}

.reporte__resumen {
  margin-bottom: var(--s4);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.reporte__estados {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-bottom: var(--s5);
  padding: 0;
  list-style: none;
}

.reproductor {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: 1;
  max-width: 560px;
}

.reproductor__play {
  width: 32px;
  height: 32px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: var(--bg-raised);
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-content: center;
}

.reproductor__play:hover { border-color: var(--brand-bright); color: var(--brand-bright); }

.reproductor__linea {
  flex: 1;
  accent-color: var(--brand-bright);
}

.reproductor__reloj {
  font-weight: 700;
  font-size: var(--text-sm);
  min-width: 48px;
}

.reproductor__velocidad {
  padding: var(--s1) var(--s2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
}

.chip-estado {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: 2px var(--s3);
  font-size: var(--text-xs);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--bg-raised);
  white-space: nowrap;
}

/* Marcador del reproductor y extremos de la ruta */
.marcador--play {
  width: 18px;
  height: 18px;
  border-width: 3px;
  display: block;
}

.extremo {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: var(--r-pill);
  border: 2px solid var(--text);
}

.extremo--inicio { background: var(--ok); }
.extremo--fin { background: var(--danger); }

/* ---- Páginas de administración ------------------------------------------ */

.page {
  display: grid;
  grid-template-rows: 56px 1fr;
  height: 100vh;
  height: 100dvh;
}

.page__contenido {
  overflow-y: auto;
  width: 100%;
  max-width: 920px;
  margin: 0 auto;
  padding: var(--s5) var(--s5) var(--s7);
}

/* Tabs segmentados sobre fondo hundido: se leen como un control, no como
   tres links sueltos. Sin íconos, por preferencia. */
.subnav {
  display: inline-flex;
  gap: var(--s1);
  margin-bottom: var(--s5);
  padding: var(--s1);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}

.subnav a {
  padding: var(--s2) var(--s4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-decoration: none;
  border-radius: var(--r-sm);
}

.subnav a:hover { color: var(--text); background: var(--bg-raised); }

.subnav a[aria-current="page"] {
  color: #fff;
  font-weight: 600;
  background: var(--brand-primary);
}

.page__encabezado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  margin-bottom: var(--s4);
}

.page__titulo {
  font-size: var(--text-lg);
  font-weight: 700;
}

.page__bajada {
  max-width: 68ch;
  margin-bottom: var(--s4);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.tabla {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-dense);
  font-size: var(--text-sm);
}

.tabla th {
  text-align: left;
  padding: var(--s2) var(--s3);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  border-bottom: 1px solid var(--border-strong);
}

.tabla td {
  padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.tabla td .estado-dot { display: inline-block; margin-right: var(--s2); }

.tabla tr:hover td { background: var(--bg-raised); }

.tabla a { text-decoration: none; }
.tabla a:hover { text-decoration: underline; }

.tabla .is-inactivo td { color: var(--text-faint); }

.chip {
  display: inline-block;
  padding: 1px var(--s2);
  margin-right: var(--s1);
  font-size: var(--text-xs);
  color: var(--text-muted);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
}

.vacio {
  padding: var(--s5);
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* Cuerpo de un mensaje enviado: respeta los saltos de línea del redactor. */
.mensaje__cuerpo {
  max-width: 68ch;
  margin-bottom: var(--s5);
  white-space: pre-line;
  line-height: var(--leading-body);
}

/* Página de contenido con barra: header, toolbar a sangre (filtros o tabs)
   y contenido desplazable. El mismo esqueleto de recorridos y reportes,
   para que toda la consola se lea igual. */
.app--pagina {
  grid-template-rows: 56px auto 1fr;
  grid-template-columns: 1fr;
}

/* El botón de la toolbar calza en altura con sus inputs. */
.toolbar .btn { padding: var(--s2) var(--s4); }

/* Tabs de administración dentro de la barra: el segmento aporta su propio
   contraste sobre el fondo hundido. */
.toolbar .subnav {
  margin-bottom: 0;
  background: var(--bg);
}

.paginacion {
  display: flex;
  align-items: center;
  gap: var(--s4);
  margin-top: var(--s4);
}

.paginacion__pagina {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ---- Formularios de administración -------------------------------------- */

.formulario { max-width: 640px; }

.formulario .form-error { margin-bottom: var(--s4); }

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s4);
}

.form-grid .campo select,
.form-grid .campo input[type="color"] {
  padding: var(--s2) var(--s3);
  font: inherit;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
}

.form-grid .campo input[type="color"] { height: 40px; padding: var(--s1); }

.campo--opciones {
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--s3);
  display: grid;
  gap: var(--s2);
}

.campo--opciones legend {
  padding: 0 var(--s1);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.campo--opciones label {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--text-sm);
  color: var(--text);
}

.campo--opciones input[type="checkbox"] { accent-color: var(--brand-primary); }

.campo__nota {
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.acciones { margin-top: var(--s5); }

/* ---- Semana del mantenedor de horarios ---------------------------------- */

.tabla--horario {
  max-width: 640px;
  margin-top: var(--s4);
  margin-bottom: var(--s2);
}

.tabla--horario tbody th {
  font-size: var(--text-sm);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}

.tabla--horario input[type="time"] {
  padding: var(--s1) var(--s2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  color-scheme: dark;
}

.tabla--horario input[type="checkbox"] { accent-color: var(--brand-primary); }

/* Un día sin marcar no acepta posiciones: las horas dejan de importar. */
.tabla--horario tr:has(input[type="checkbox"]:not(:checked)) input[type="time"] {
  opacity: 0.4;
}

/* ---- Editor de zonas ----------------------------------------------------- */

.formulario--zona { max-width: none; }

.editor-zona {
  margin-top: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}

.editor-zona__barra {
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding: var(--s2) var(--s3);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
}

.editor-zona__barra .rotulo { color: var(--text-faint); }

.editor-zona__aviso {
  flex: 1;
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.editor-zona__mapa { height: 400px; }

/* ---- Modal de previsualización de zona ---------------------------------- */

.tabla__acciones { text-align: right; }

.modal {
  width: min(720px, 92vw);
  padding: 0;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
}

.modal::backdrop { background: rgba(6, 9, 14, 0.6); }

.modal__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
}

.modal__titulo {
  font-size: var(--text-lg);
  font-weight: 700;
}

.modal__mapa { height: 420px; }

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

/* ---- Formularios y botones ---------------------------------------------- */

.campo { display: grid; gap: var(--s1); }

.campo label {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.campo input {
  padding: var(--s2) var(--s3);
  font: inherit;
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--bg);
}

.btn {
  padding: var(--s3) var(--s4);
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--brand-primary);
  border: none;
  border-radius: var(--r-sm);
  cursor: pointer;
}

.btn:hover { background: var(--brand-primary-hover); }

/* Botón secundario: para acciones de navegación como "Volver". Neutro a
   propósito — el azul de marca queda para la acción principal. */
.btn--secundario {
  display: inline-block;
  padding: var(--s2) var(--s4);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  cursor: pointer;
  text-decoration: none;
}

.btn--secundario:hover {
  background: var(--bg-sunken);
  border-color: var(--text-faint);
}

.btn--texto {
  padding: 0;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
}

.btn--texto:hover { color: var(--text); }

.btn--texto:disabled {
  color: var(--text-faint);
  text-decoration: none;
  cursor: default;
}

.form-error {
  padding: var(--s2) var(--s3);
  font-size: var(--text-sm);
  color: var(--danger);
  background: rgba(249, 112, 102, 0.08);
  border: 1px solid var(--danger);
  border-radius: var(--r-sm);
}

/* ---- Login: el único momento de marca a pantalla completa --------------- */
/* Fondo azul Pocuro con anillos concéntricos apenas visibles: la casa
   observando el territorio. El panel entra una sola vez, con calma. */

.login {
  display: grid;
  place-content: center;
  min-height: 100dvh;
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, var(--brand-lift) 0%, var(--brand-primary) 45%, var(--brand-deep) 100%);
}

.login::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-radial-gradient(
    circle at 78% 24%,
    rgba(255, 255, 255, 0.05) 0 1px,
    transparent 1px 64px
  );
}

.login::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at 78% 24%,
    rgba(255, 255, 255, 0.09),
    transparent 34%
  );
}

.login__panel {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--s4);
  width: 350px;
  padding: var(--s6);
  background: var(--panel-light-bg);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  animation: entrada 480ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes entrada {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.login__logo { height: 42px; width: auto; justify-self: start; }

.login__lema {
  margin-top: calc(-1 * var(--s2));
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--panel-light-muted);
}

/* El panel del login es claro sobre el fondo azul: sus controles se
   escriben aparte del tema oscuro de la consola. */
.login__panel .campo label { color: var(--panel-light-muted); }

.login__panel .campo input {
  color: var(--panel-light-text);
  background: var(--panel-light-bg);
  border-color: var(--panel-light-border);
}

.login__panel .form-error {
  color: var(--panel-light-danger);
  background: rgba(180, 35, 24, 0.06);
  border-color: var(--panel-light-danger);
}

.login__panel :focus-visible { outline-color: var(--brand-primary); }

/* ---- Movimiento: solo el que significa algo ----------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---- Responsive hasta tablet -------------------------------------------- */

@media (max-width: 760px) {
  .app { grid-template-columns: 220px 1fr; }
  .header__nav { display: none; }
}
