/* Registro de Ocurrencias Serenazgo — La Perla
 *
 * Paleta del Observatorio Regional de Seguridad Ciudadana del Callao: azul
 * marino institucional sobre neutros fríos, con los colores semánticos de su
 * leyenda de incidentes.
 *
 * Solo tema claro. La aplicación se usa en la central y en la calle, sobre
 * pantallas y proyecciones distintas, y un solo aspecto hace que lo que ve el
 * operador sea lo mismo que ve el supervisor. */

:root {
  color-scheme: light;

  /* marca */
  --marino: #0b3b7a;
  --marino-oscuro: #072b5a;
  --azul: #1a5bb8;
  --azul-suave: #e4edfa;
  /* Botón de la acción principal. Sin color propio de la municipalidad, el de
     la barra. El subrayado de la sección y la pestaña activas (--subrayado) no
     se declara aquí: cada sitio que lo usa trae su propio valor por defecto. */
  --accion: var(--marino);

  /* neutros */
  --paper: #f4f6f9;
  --surface: #ffffff;
  --surface-2: #edf1f6;
  --ink: #16202c;
  --ink-2: #3a4756;
  --muted: #66717e;
  --line: #dfe4eb;
  --line-strong: #c4ccd6;

  /* semánticos, tomados de la leyenda del Observatorio */
  --robo: #d62828;
  --violencia: #d9730d;
  --emergencia: #17365c;
  --transito: #4c9be8;
  --otros: #9aa3ab;

  /* roles en la aplicación */
  --prev: var(--azul);            /* preventivo, acciones primarias, confirmación */
  --prev-soft: var(--azul-suave);
  --inc: #c05f0c;                 /* incidencias, retención de fotos */
  --inc-soft: #fbeedd;
  --flag: var(--robo);            /* errores y avisos */
  --flag-soft: #fbe4e4;

  --sombra: 0 1px 2px rgba(22, 32, 44, .06), 0 8px 24px -16px rgba(22, 32, 44, .3);
  --radio: 4px;
}

* { box-sizing: border-box; }

/* La página es una columna: arriba el ingreso o la aplicación, que crecen, y
   abajo el pie, que ocupa solo su alto. Así el pie queda al fondo de la
   pantalla cuando el contenido es corto, y al final del contenido cuando es
   largo, sin barra de desplazamiento cuando todo cabe. */
body {
  margin: 0;
  display: flex; flex-direction: column; min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

button, input, select { font: inherit; color: inherit; }

/* ------------------------------------------------------------------ acceso */

.acceso {
  flex: 1 0 auto;
  display: grid;
  place-items: center;
  /* Con el escudo encima de la caja son dos filas. Sin align-content las pistas
     se estiran y el escudo se va al centro de la mitad de arriba, lejos del
     formulario; centrando el bloque entero quedan juntos y a la misma altura. */
  align-content: center;
  gap: 28px;
  padding: 24px;
}
.gore-acceso {
  width: min(260px, 70%); height: auto;
  /* El SVG ya viene en el azul institucional, así que no hace falta pintarlo. */
}
.acceso-caja {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 4px solid var(--marino);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 34px 32px 32px;
  width: min(400px, 100%);
}
/* En caja mixta, como en la barra. A 23px y en negrita el nombre ya se lee
   solo: el espaciado que pedían las mayúsculas aquí sobra. */
.acceso-caja h1 {
  margin: 0 0 4px; font-size: 23px; font-weight: 700;
  color: var(--marino);
}
.acceso-caja .sub { margin: 0 0 26px; color: var(--muted); font-size: 13px; }
/* La caja de ingreso es casi toda vacío: con el ritmo apretado de los
   formularios de trabajo se veía aplastada, así que aquí respira algo más. */
.acceso-caja label { margin-bottom: 14px; }
.acceso-caja label .etiqueta { margin-bottom: 5px; }
.acceso-caja input:not([type="checkbox"]):not([type="radio"]):not(.fecha-oculta) {
  padding: 9px 11px;
}
.acceso-caja button[type="submit"] { padding: 11px; }

/* Botón con aspecto de enlace: «¿Olvidaste tu contraseña?» y «Volver». */
.acceso-caja .enlace {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--accion); font: inherit; font-size: 13px; font-weight: 600;
}
.acceso-caja .enlace:hover { text-decoration: underline; }
/* A la derecha, bajo la contraseña, y dejando aire antes de «Entrar». */
.acceso-caja .olvido { display: block; margin: -4px 0 18px auto; }
.acceso-caja .volver { margin-bottom: 18px; }

/* Recuperar acceso: el mismo marco que el ingreso, con texto en vez de campos. */
#cajaRecuperar h1 { margin-bottom: 10px; }
#cajaRecuperar .texto { margin: 0 0 14px; color: var(--muted); font-size: 14px; line-height: 1.55; }
#cajaRecuperar .pasos { margin: 0 0 4px; padding-left: 20px; font-size: 14px; line-height: 1.5; }
#cajaRecuperar .pasos li { margin-bottom: 6px; }
#cajaRecuperar .nota-pie {
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12.5px; line-height: 1.5;
}

/* ----------------------------------------------------------------- armazón */

.app { display: none; flex: 1 0 auto; grid-template-rows: auto 1fr; }
.app.visible { display: grid; }

/* ------------------------------------------------------------------- pie -- */

/* Pie de todas las pantallas: el nombre de la plataforma a la izquierda, y a
   la derecha los escudos del Gobierno Regional y del Observatorio, en gris
   para que acompañen sin competir con los colores de cada municipalidad. */
/* 52px de alto en total (10 + 31 + 10 + el borde): lo manda el escudo del
   Gobierno Regional, que es lo más alto. */
.pie-sitio {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px 26px;
  padding: 10px 30px;
  background: var(--surface); border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12px;
}
.pie-texto { display: flex; flex-wrap: wrap; gap: 4px 22px; }
.pie-logos { display: flex; align-items: center; gap: 16px; }
.pie-gore { height: 31px; width: auto; }
.pie-observatorio {
  height: 27px; width: auto;
  padding-left: 16px; border-left: 1px solid var(--line-strong);
}
@media (max-width: 640px) {
  .pie-sitio { justify-content: center; text-align: center; padding: 10px 16px; }
  .pie-texto { justify-content: center; }
  .pie-gore { height: 27px; }
  .pie-observatorio { height: 22px; }
}

.barra {
  display: flex; align-items: center; gap: 22px;
  padding: 0 24px; min-height: 60px;
  background: var(--marino);
  color: #fff;
}
/* Franja bajo la barra, del acento al color de detalle: la ola turquesa a lima
   del panel de Bellavista. Solo aparece si la municipalidad define ese color.
   Va como borde y no encima de la barra para no tapar el subrayado de la
   sección activa, que cae justo en el borde inferior. */
.barra.con-detalle {
  border-bottom: 4px solid;
  border-image: linear-gradient(90deg, var(--azul), var(--detalle)) 1;
}
/* Escudo y nombre de la municipalidad, en el extremo izquierdo. La línea a la
   derecha separa la identidad de quien trabaja de la navegación; antes la ponía
   el rótulo «Serenazgo», que ya no está. */
.muni {
  display: flex; align-items: center; gap: 11px; min-width: 0;
  padding-right: 22px; border-right: 1px solid rgba(255, 255, 255, .22);
}
/* Los logos vienen en versión para fondo oscuro, como el del Gobierno
   Regional: van directo sobre la barra, sin recuadro. */
.muni-logo { height: 38px; width: auto; flex: none; }
/* El logotipo que trae el nombre escrito es apaisado y su letra pequeña no se
   lee a la altura de un escudo: un poco más alto, sin salirse de la barra. */
.muni-logo.con-nombre { height: 44px; }
/* Ancho para que «Municipalidad de Bellavista» quepa en una línea, como La
   Perla y Mi Perú; un nombre más largo (Carmen de La Legua - Reynoso) pasa a
   dos líneas en lugar de comerse la barra. */
.muni-nombre {
  font-weight: 600; font-size: 14px; line-height: 1.2;
  max-width: 28ch;
}

/* El escudo del Gobierno Regional, en el sitio que el escudo municipal deja
   libre cuando entra el administrador. El archivo ya viene en blanco: sobre el
   azul de la barra no lleva el recuadro claro que sí necesitan los escudos
   municipales. */
.gore-barra {
  /* Como el escudo municipal: lleva tres líneas de texto, y más bajo que esto
     no se leen. */
  height: 36px; width: auto; flex: none;
  padding-right: 22px; border-right: 1px solid rgba(255, 255, 255, .22);
}
@media (max-width: 860px) {
  .muni-nombre { display: none; }
  .muni { padding-right: 14px; }
}
.barra .empuje { margin-left: auto; }
/* El usuario: un botón con quién entró, que abre Administración y Cerrar
   sesión. */
.usuario { position: relative; }
.usuario-boton {
  display: inline-flex; align-items: center; gap: 8px;
  font: inherit; font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: #fff; background: rgba(255, 255, 255, .16);
  border: 1px solid rgba(255, 255, 255, .28); border-radius: 3px;
  padding: 8px 12px; cursor: pointer;
}
.usuario-boton:hover, .usuario-boton[aria-expanded="true"] { background: rgba(255, 255, 255, .26); }
.usuario-boton:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.usuario-flecha {
  width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor; transition: transform .15s;
}
.usuario-boton[aria-expanded="true"] .usuario-flecha { transform: rotate(180deg); }
.usuario-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 50;
  min-width: 200px; padding: 6px 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  box-shadow: 0 8px 24px rgba(15, 30, 50, .18);
}
.usuario-menu button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; font: inherit; font-size: 14px;
  padding: 9px 16px; border: 0; background: none; color: var(--ink); cursor: pointer;
}
.usuario-menu button:hover, .usuario-menu button:focus-visible { background: var(--surface-2); outline: none; }
.usuario-menu button + button { border-top: 1px solid var(--line); }
.menu-icono {
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
/* Cerrar sesión, en rojo: texto e icono. */
.usuario-menu .menu-peligro { color: #c62828; }
.usuario-menu .menu-peligro:hover, .usuario-menu .menu-peligro:focus-visible { background: #fdecea; }
.barra .boton {
  background: #fff; border-color: #fff; color: var(--marino); font-weight: 600;
}
.barra .boton:hover { background: var(--azul-suave); }

/* Navegación sobre el azul de la marca: subrayado, no relleno, como en el
   Observatorio. */
.nav { display: flex; gap: 6px; align-self: stretch; }
.nav-boton {
  border: 0; background: none; cursor: pointer;
  color: rgba(255, 255, 255, .78);
  padding: 0 6px; border-bottom: 3px solid transparent;
}
.nav-boton:hover { color: #fff; }
.nav-boton[aria-current="true"] {
  color: #fff; font-weight: 600; border-bottom-color: var(--subrayado, #fff);
}
.nav-boton:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }

/* La administración trae su propia barra lateral dentro del panel. */
.cuerpo-admin { display: grid; grid-template-columns: 1fr; min-height: 0; margin: -26px -30px -60px; }
@media (min-width: 900px) { .cuerpo-admin { grid-template-columns: 240px 1fr; } }
.panel-catalogo { padding: 26px 30px 60px; min-width: 0; }

/* Bandeja: código, registro, alerta y sector en una sola línea. Partidos en
   dos («MLPE-2026-INC-» / «000003») se leían como dos datos. */
.tabla-bandeja td:nth-child(-n+4) { white-space: nowrap; }

/* Historial de actividades. */
.tabla-historial td { vertical-align: top; }
.historial-cuando { white-space: nowrap; font-variant-numeric: tabular-nums; }
.historial-cuando span { display: block; color: var(--muted); font-size: 12px; }
.historial-accion { display: block; font-weight: 600; color: var(--ink); }
.historial-detalle { display: block; color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.historial-ip { font-family: ui-monospace, Consolas, monospace; font-size: 12.5px; white-space: nowrap; }
.historial-alerta .historial-accion { color: var(--peligro, #b3261e); }
.historial-pie { display: flex; align-items: center; gap: 14px; margin-top: 12px; }

.lateral {
  border-right: 1px solid var(--line);
  background: var(--surface);
  padding: 18px 0;
}
.lateral h2 {
  font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 6px; padding: 0 22px;
}
.lateral h2:not(:first-child) { margin-top: 22px; }
.lateral button {
  display: block; width: 100%; text-align: left;
  padding: 8px 22px; border: 0; background: none; cursor: pointer;
  border-left: 3px solid transparent; color: var(--ink-2);
}
.lateral button:hover { background: var(--surface-2); }
.lateral button[aria-current="true"] {
  background: var(--surface-2); color: var(--ink);
  font-weight: 600; border-left-color: var(--prev);
}

.panel { padding: 26px 30px 60px; min-width: 0; }
/* Administración dibuja cada pantalla dentro de un div propio
   (administracion.js), así que su cabecera queda un nivel más abajo. */
.panel > header, .panel-catalogo > header, .panel-catalogo > div > header { margin-bottom: 20px; }
.panel h1, .panel-catalogo h1 { margin: 0 0 4px; font-size: 22px; letter-spacing: -.015em; }
/* Sin tope de ancho: el texto ocupa el panel entero, como la tabla o el
   formulario que tiene debajo. Cortarlo a media pantalla dejaba un hueco a la
   derecha que se leía como un error. */
.descripcion { margin: 0; color: var(--muted); }

/* ------------------------------------------------------------- bandeja -- */

.cabecera-bandeja {
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.cabecera-bandeja > :last-child { margin-left: auto; }
/* Descargar y «Nuevo registro» juntos, a la derecha. La descarga va en botón
   secundario: la acción de todos los días es levantar un parte. */
.acciones-bandeja { display: flex; gap: 8px; flex-wrap: wrap; }

/* Bandeja de registros: pestañas y botones en una sola franja, con la línea
   de las pestañas como borde inferior de toda la cabecera. En pantalla
   angosta los botones suben a su propia fila, sin perder esa línea. */
.panel:has(> .cabecera-bandeja.compacta) { padding-top: 16px; }
.cabecera-bandeja.compacta {
  display: grid; align-items: end; gap: 0 22px; margin-bottom: 12px;
  grid-template-columns: 1fr auto;
  grid-template-areas: "pestanas acciones";
  border-bottom: 1px solid var(--line-strong);
}
.cabecera-bandeja.compacta > .pestanas { grid-area: pestanas; border-bottom: 0; margin: 0 0 -1px; }
.cabecera-bandeja.compacta > .acciones-bandeja { grid-area: acciones; margin: 0; padding-bottom: 6px; justify-content: flex-end; }
.cabecera-bandeja.compacta .pestana { padding: 8px 14px; }
@media (max-width: 760px) {
  .cabecera-bandeja.compacta {
    grid-template-columns: 1fr;
    grid-template-areas: "acciones" "pestanas";
    row-gap: 6px;
  }
}

.pestanas { display: flex; gap: 4px; border-bottom: 1px solid var(--line-strong); margin-bottom: 16px; }
/* Diseño → Categorías y las fichas: la pestaña ya nombra la lista, así que su
   pantalla no repite el título. */
.sub-pestanas > header > h1 { display: none; }
.sub-pestanas > header { margin-bottom: 20px; }
.pestana {
  border: 0; background: none; cursor: pointer; color: var(--muted);
  padding: 9px 16px; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.pestana:hover { color: var(--ink); }
.pestana[aria-selected="true"] {
  color: var(--ink); font-weight: 600; border-bottom-color: var(--subrayado, var(--inc));
}

.filtros {
  display: grid; gap: 8px 10px; margin-bottom: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radio); padding: 9px 12px 10px;
}
.filtros label { margin: 0; }
.filtros label .etiqueta { margin-bottom: 2px; font-size: 10.5px; }
.filtros input:not([type="checkbox"]):not([type="radio"]):not(.fecha-oculta),
.filtros select { padding: 4px 8px; }
/* La casilla sola, centrada a la altura de los campos de al lado. */
.filtros input[type="checkbox"] { margin: 8px 0 0; }

tr.clicable { cursor: pointer; }
tr.clicable:hover td { background: var(--surface-2); }

/* Columna de selección, al final de la fila. Estrecha y centrada: es un mando,
   no un dato. */
.celda-casilla { width: 1%; text-align: center; white-space: nowrap; cursor: default; }
.celda-casilla input { width: auto; min-width: 0; }

/* Solo se ve cuando hay algo marcado, encima de la tabla. */
.barra-seleccion {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 10px; padding: 9px 12px;
  background: var(--azul-suave); border: 1px solid var(--azul);
  border-radius: var(--radio); font-weight: 600;
}

/* El borrado es definitivo: el botón lo dice con el color de error, el mismo
   que ya usa la aplicación para avisar de lo que salió mal. */
.boton.peligro {
  background: var(--flag); border-color: var(--flag); color: #fff; font-weight: 600;
}
.boton.peligro:hover { background: #b02020; border-color: #b02020; }

.pie-bandeja {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 10px;
}
.paginacion { display: flex; gap: 6px; }

.celda-clasificacion { display: inline-flex; align-items: baseline; gap: 8px; }
.punto-categoria {
  flex: none; width: 9px; height: 9px; border-radius: 50%;
  transform: translateY(-1px);
}

.marca.cerrado { background: var(--prev-soft); color: var(--prev); }

/* ---------------------------------------------------------- formulario -- */

.formulario { display: flex; flex-direction: column; gap: 16px; max-width: 1000px; }
/* La pantalla del registro entera mide lo que el formulario —la cabecera, los
   avisos y los botones terminan donde terminan los campos— y va centrada. */
.hoja-formulario { max-width: 1000px; margin: 0 auto; }
/* Una lista suelta (sectores, entidades...) y su texto miden lo mismo. */
.ancho-lista { max-width: 520px; }

.bloque {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radio); padding: 16px 18px 18px; margin: 0;
}
.bloque > legend {
  font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); padding: 0 6px; margin-left: -6px;
}
.bloque:disabled, .bloque[disabled] { opacity: .7; }

.rejilla {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
/* Sin esto, un desplegable de texto largo estira su columna y las demás
   quedan angostas: todas las celdas deben poder encogerse por igual. */
.rejilla > * { min-width: 0; }
/* Arranca una fila nueva, alineada a la primera columna, sea cual sea el
   número de columnas que la pantalla deje. */
.rejilla > .fila-nueva { grid-column-start: 1; }
.rejilla label { margin: 0; }

.pista { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; }
/* Al lado de lo que acompaña, no debajo: el «(tú)» junto al usuario. */
.pista.en-linea { display: inline; margin: 0 0 0 4px; }

/* ---------------------------------------------------------------- mapa -- */

.campo-ancho { grid-column: 1 / -1; margin-top: 14px; }
.campo-ancho > .etiqueta {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}

.mapa-caja {
  border: 1px solid var(--line-strong); border-radius: var(--radio);
  overflow: hidden; background: var(--surface-2);
}
.mapa { height: 340px; width: 100%; }
@media (max-width: 640px) { .mapa { height: 260px; } }

.mapa-barra {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 12px; border-top: 1px solid var(--line);
  background: var(--surface);
}
.mapa-lectura { margin: 0; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.mapa-etiqueta {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.mapa-valor {
  font-family: "Consolas", ui-monospace, monospace; font-size: 13.5px;
  font-variant-numeric: tabular-nums; color: var(--ink);
  background: var(--surface-2); padding: 2px 7px; border-radius: 3px;
}
.mapa-sin-punto { color: var(--muted); font-size: 13px; }
.mapa-pie { margin-left: auto; display: flex; gap: 6px; }

.mapa-caido .mapa {
  display: grid; place-items: center; padding: 20px;
  background: var(--surface-2);
}
.mapa-mensaje { margin: 0; color: var(--muted); text-align: center; max-width: 46ch; }

.maplibregl-ctrl-group { border: 1px solid var(--line-strong) !important; }

/* ------------------------------------------------------------- cámaras -- */

/* Mapa a la izquierda, formulario a la derecha: se toca el mapa y se ve al lado
   cómo se llenan X e Y. En pantallas angostas van uno debajo del otro. */
.camaras-cuerpo {
  display: grid; gap: 18px; align-items: start;
  grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr);
}
@media (max-width: 900px) { .camaras-cuerpo { grid-template-columns: 1fr; } }
.mapa.mapa-camaras { height: 420px; }
@media (max-width: 640px) { .mapa.mapa-camaras { height: 300px; } }
.camaras-form { margin: 0; }

/* Cada cámara, un punto con el color de la municipalidad y borde blanco: se
   distingue del mapa y del punto naranja de la que se está cargando. */
.punto-camara {
  width: 14px; height: 14px; border-radius: 50%; cursor: pointer;
  background: var(--azul); border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .35), 0 1px 4px rgba(0, 0, 0, .3);
}

.coordenada-lectura {
  margin: 12px 0 0; padding: 8px 10px; border-radius: 4px;
  background: var(--surface-2); color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.coordenada-lectura.coordenada-error { background: var(--flag-soft); color: var(--flag); }
.acciones-form { display: flex; gap: 8px; margin-top: 14px; }
.acciones-form [hidden] { display: none; }
tr.fila-editando td { background: var(--azul-suave); }

textarea {
  width: 100%; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 3px;
  padding: 8px 10px; font: inherit; resize: vertical;
}

.casillas { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.casilla { display: flex; align-items: center; gap: 8px; margin: 0; cursor: pointer; }
.casilla input { width: auto; }

/* Hasta dos hechos en «¿Qué ocurrió?», uno debajo del otro. */
.hecho + .hecho { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--line-strong); }
.hecho-cabecera { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hecho-titulo {
  display: block; margin-bottom: 8px; font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
}
.hecho-cabecera .hecho-titulo { margin-bottom: 0; }
.hecho-cabecera + .rejilla { margin-top: 8px; }
.hecho-agregar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 4px; }
.hecho-agregar .pista { margin: 0; }
/* En la bandeja, los dos hechos de un parte, uno por línea. */
.celda-hechos { display: flex; flex-direction: column; gap: 4px; }

/* Datos complementarios de Robo / Hurto. */
.robo-tipo {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; background: var(--paper); border-radius: var(--radio);
}
.robo-origen {
  font-size: 12px; padding: 2px 10px; border-radius: 999px;
  background: var(--azul-suave); color: var(--ink-2, var(--ink));
}
.robo-subtitulo { margin: 18px 0 10px; font-size: 15px; }
.robo-victima { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.robo-victima label { margin: 0; flex: 1 1 140px; max-width: 220px; }
.robo-victima .boton { flex: none; }
.robo-separador { border: 0; border-top: 1px solid var(--line); margin: 18px 0 0; }
.robo-pregunta { display: block; margin: 14px 0 6px; font-size: 13px; color: var(--muted); }
.robo-modalidad { max-width: 480px; margin-top: 14px; }
.robo-modalidad label { margin: 0; }
.opciones-linea { display: flex; flex-wrap: wrap; gap: 8px 22px; }

/* Elegir varios (selectorMultiple en comun.js): buscador, lista y etiquetas. */
.multi-caja { position: relative; }
.multi-lista {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
  margin: 2px 0 0; padding: 4px 0; list-style: none;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radio); box-shadow: var(--sombra);
  max-height: 240px; overflow-y: auto;
}
.multi-lista li { padding: 7px 12px; cursor: pointer; display: flex; justify-content: space-between; gap: 12px; }
/* El cargo, a la derecha y en gris: solo de referencia, no se agrega. */
.multi-detalle { flex: none; color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.multi-lista li.marcado { background: var(--azul-suave); }
/* Selector de una sola opción: el cargo de quien se eligió, dentro del campo,
   a la derecha. El campo deja ese espacio libre para que el nombre no lo pise. */
.multi.unico .multi-caja > input[type="text"] { padding-right: 9.5em; } /* le gana a la regla general de inputs */
.unico-detalle {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  color: var(--muted); font-size: 12.5px; white-space: nowrap; pointer-events: none;
}
.multi-lista li.multi-vacio { color: var(--muted); cursor: default; }
.multi-fichas { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.multi-fichas:empty { display: none; }
.ficha {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px 2px 3px 10px; font-size: 13px; line-height: 1.4;
  background: var(--azul-suave); border: 1px solid var(--line-strong); border-radius: 999px;
}
.ficha-quitar {
  width: auto; border: 0; background: none; cursor: pointer;
  padding: 0 7px; font-size: 16px; line-height: 1; color: var(--muted);
}
.ficha-quitar:hover { color: var(--flag); }
/* Un parte cerrado que no se puede tocar: las etiquetas se leen, no se quitan. */
.ficha-quitar:disabled { display: none; }
.ficha:has(.ficha-quitar:disabled) { padding-right: 10px; }
.desplegado { display: grid; gap: 18px; }
/* Un <div> y no un <label>: dentro hay un buscador y varios botones, y un
   label le mandaría a su control cada clic en una ×. */
.desplegado .etiqueta {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}

.eleccion-rama { display: flex; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }

.acciones-pie {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line);
  max-width: 1000px;
}
.acciones-pie .descripcion { flex-basis: 100%; font-size: 13px; }

/* ------------------------------------------------------------- disposición */

.columnas { display: grid; gap: 16px; align-items: start; }
@media (min-width: 1100px) { .columnas.n2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .columnas.n3 { grid-template-columns: repeat(3, 1fr); } }

.columna {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radio);
  display: flex; flex-direction: column;
  min-width: 0;
}
.columna > h3 {
  margin: 0; padding: 10px 14px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-strong);
  border-radius: var(--radio) var(--radio) 0 0;
  font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted);
  display: flex; justify-content: space-between; gap: 10px;
}
.columna > h3 .cuenta { font-variant-numeric: tabular-nums; }

.lista { list-style: none; margin: 0; padding: 0; max-height: 460px; overflow-y: auto; }
.lista li {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px 6px 14px;
  border-bottom: 1px solid var(--line);
}
.lista li:last-child { border-bottom: 0; }
.lista li.sel { background: var(--prev-soft); }
.lista li.inactivo .texto { color: var(--muted); text-decoration: line-through; }

.lista .texto {
  flex: 1; min-width: 0; text-align: left;
  background: none; border: 0; padding: 2px 0; cursor: pointer;
  overflow-wrap: anywhere;
}
.lista li.hoja .texto { cursor: default; }
.lista .acciones { display: flex; gap: 2px; opacity: .35; flex: none; }
.lista li:hover .acciones, .lista li.sel .acciones { opacity: 1; }

.vacio { padding: 18px 14px; color: var(--muted); font-size: 13px; }

/* ------------------------------------------------------------- ventanas -- */

/* <dialog> nativo: se encarga solo del centrado, del fondo, de Escape y de no
   dejar tocar lo de atrás mientras está abierta. */
.ventana {
  border: 1px solid var(--line-strong); border-radius: var(--radio);
  background: var(--surface); color: var(--ink);
  padding: 20px 22px; width: min(420px, calc(100vw - 32px));
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}
.ventana::backdrop { background: rgba(15, 23, 35, .45); }
.ventana-titulo { margin: 0 0 6px; font-size: 17px; }
.ventana .descripcion { margin: 0 0 14px; }
.ventana-campos { display: grid; gap: 12px; grid-template-columns: 1fr 1fr; }
.ventana-campos label { margin: 0; }
.ventana-error { color: var(--flag); margin-top: 10px; }
.ventana-pie { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

@media (max-width: 420px) { .ventana-campos { grid-template-columns: 1fr; } }

/* Subir datos: la ventana necesita más ancho que una de dos campos, y el
   resultado puede listar cientos de filas, así que su tabla se desplaza sola. */
.ventana.ventana-ancha { width: min(720px, calc(100vw - 32px)); }
.subida-reglas {
  margin: 14px 0 0; padding-left: 18px; color: var(--ink-2); font-size: 13px; line-height: 1.5;
}
.subida-reglas a { color: var(--azul); }
.subida-resultado p { margin: 0 0 8px; }
.subida-ok { color: #1d6b3a; font-weight: 600; }
.subida-mal { color: var(--flag); font-weight: 600; margin-top: 14px !important; }
.subida-tabla { max-height: 260px; overflow-y: auto; margin-bottom: 6px; }
.subida-tabla td { vertical-align: top; font-size: 13px; }

/* --------------------------------------------------------------- controles */

.icono {
  border: 1px solid transparent; background: none; cursor: pointer;
  width: 24px; height: 24px; border-radius: 3px;
  display: grid; place-items: center; color: var(--muted);
  font-size: 13px; line-height: 1; padding: 0;
}
.icono:hover { background: var(--surface-2); color: var(--ink); border-color: var(--line); }
.icono:disabled { opacity: .3; cursor: default; }
.icono.marcada { color: var(--inc); }

.boton {
  border: 1px solid var(--line-strong); background: var(--surface);
  border-radius: 3px; padding: 6px 12px; cursor: pointer; color: var(--ink);
}
.boton:hover { background: var(--surface-2); }
.boton.primario {
  background: var(--accion); border-color: var(--accion); color: #fff; font-weight: 600;
}
/* Oscurecido a partir del color de acción, sea cual sea: así una municipalidad
   no necesita declarar también el tono del hover. */
.boton.primario:hover {
  background: color-mix(in srgb, var(--accion) 85%, #000);
  border-color: color-mix(in srgb, var(--accion) 85%, #000);
}

/* «+ Nuevo registro». El signo se dibuja con dos barras y no con el carácter
   «+», que en cada fuente cae a otra altura y nunca queda centrado con el
   texto. Toma el color del texto del botón. */
.boton-alta { display: inline-flex; align-items: center; gap: 8px; }
.mas { position: relative; flex: none; width: 12px; height: 12px; }
.mas::before, .mas::after {
  content: ""; position: absolute; background: currentColor; border-radius: 1px;
}
.mas::before { left: 0; right: 0; top: 5px; height: 2px; }
.mas::after  { top: 0; bottom: 0; left: 5px; width: 2px; }
.boton:disabled { opacity: .5; cursor: default; }

.agregar { padding: 8px; border-top: 1px solid var(--line); display: flex; gap: 6px; }
.agregar input { flex: 1; min-width: 0; }

/* Selector amplio a propósito: enumerar los tipos uno por uno ya dejó fuera
   input[type=date], que quedaba con el ancho por defecto del navegador
   mientras el resto llenaba su columna.

   Se excluye .fecha-oculta y no es un detalle: por ser tan amplio, este
   selector le ganaba en especificidad (0,2,1 contra 0,1,0) y le imponía
   width:100% al input de fecha que debe medir 1px. Como va position:absolute,
   ese 100% se medía contra el ancho de la ventana y estiraba el documento
   cientos de píxeles a la derecha; el scrollbar horizontal que aparecía se
   comía 15px de alto y hacía que min-height:100vh tampoco cupiera, sacando
   también el vertical. Dos barras de desplazamiento sobre una página que cabía
   de sobra. */
input:not([type="checkbox"]):not([type="radio"]):not(.fecha-oculta), select, textarea {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 3px;
  padding: 6px 9px; width: 100%; min-width: 0;
}
input.no-valido { border-color: var(--flag); background: var(--flag-soft); }

/* Campo con botón pegado a la derecha (la fecha y su calendario). */
.campo-compuesto { display: flex; min-width: 0; }
.campo-compuesto.con-adjunto > input { border-radius: 3px 0 0 3px; }
.boton-adjunto {
  flex: none; width: 34px;
  border: 1px solid var(--line-strong); border-left: 0; border-radius: 0 3px 3px 0;
  background: var(--surface-2); cursor: pointer; font-size: 14px; line-height: 1;
  padding: 0;
}
.boton-adjunto:hover { background: var(--azul-suave); }
.boton-adjunto:disabled { opacity: .5; cursor: default; }
.fecha-oculta {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); border: 0;
}
input:focus-visible, select:focus-visible, button:focus-visible {
  outline: 2px solid var(--prev); outline-offset: 1px;
}
label { display: block; margin-bottom: 12px; }
label .etiqueta {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}

/* ------------------------------------------------------------------ tablas */

.tabla-envoltura {
  overflow-x: auto; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radio);
}

/* Usuarios y accesos: la municipalidad cuyas cuentas se ven debajo, y el
   título de esas cuentas. */
tbody tr.elegida td { background: var(--azul-suave); }
.subtitulo { font-size: 17px; margin: 0 0 12px; }
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 8px 14px; border-bottom: 1px solid var(--line); }
thead th {
  font-size: 10.5px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase;
  color: var(--muted); background: var(--surface-2);
  border-bottom: 1px solid var(--line-strong); white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr.inactivo td { color: var(--muted); }
tbody tr.inactivo td:first-child { text-decoration: line-through; }
td.acciones-celda { text-align: right; white-space: nowrap; }
/* Los iconos de acción, en fila y no uno debajo de otro: .icono es display:grid
   para centrar su símbolo, y eso lo vuelve un bloque que ocupa el ancho entero. */
td.acciones-celda .icono { display: inline-grid; vertical-align: middle; margin-left: 4px; }

/* Campos del formulario: dos columnas de casillas, estrechas y centradas, para
   poder recorrer la tabla de arriba abajo sin cruzar la fila entera. */
.tabla-campos th.col-marca, .tabla-campos td.col-marca { width: 120px; text-align: center; }
.tabla-campos td.col-marca input {
  width: auto; flex: none; margin: 0; cursor: pointer;
  accent-color: var(--marino); transform: scale(1.2);
}
.tabla-campos td.col-marca input:disabled { cursor: not-allowed; opacity: .4; }
/* Apagado no es lo mismo que dado de baja: se atenúa, pero no se tacha. */
.tabla-campos tr.campo-apagado td { color: var(--muted); }
.tabla-campos tr.campo-apagado strong { font-weight: 500; }
td input, td select { min-width: 110px; }

.marca {
  display: inline-block; font-size: 10.5px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 2px; white-space: nowrap;
}
.marca.retencion { background: var(--inc-soft); color: var(--inc); }
.marca.apagado { background: var(--surface-2); color: var(--muted); }
/* «No operativo»: un vehículo o una cámara fuera de servicio salta a la vista. */
.marca.alerta { background: var(--flag-soft); color: var(--flag); }
/* Casilla con su nombre al lado, dentro de una celda (Diseño → Vehículos). */
.casilla-campo { display: inline-flex; align-items: center; gap: 6px; margin: 0; white-space: nowrap; cursor: pointer; }
td .casilla-campo input { min-width: 0; }

/* Una marca que además es botón: la de cada clave, que se pulsa para
   cambiarla. Hereda el tamaño y el color de la marca; solo hay que quitarle lo
   que el navegador le pone por ser <button>. */
.marca.pulsable {
  border: 1px solid transparent; font: inherit; font-size: 10.5px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}
.marca.pulsable:hover { border-color: currentColor; }

/* ------------------------------------------------------------------ avisos */

.aviso {
  position: fixed; right: 20px; bottom: 20px; z-index: 20;
  max-width: 380px; padding: 12px 16px;
  border-radius: var(--radio); box-shadow: var(--sombra);
  border-left: 3px solid;
}
.aviso.ok { background: var(--prev-soft); color: var(--prev); border-color: var(--prev); }
.aviso.mal { background: var(--flag-soft); color: var(--flag); border-color: var(--flag); }

.nota {
  border-left: 3px solid var(--inc); background: var(--inc-soft);
  padding: 12px 16px; border-radius: 0 var(--radio) var(--radio) 0;
  /* Aire arriba y abajo: pegada al texto o a la tabla de al lado se leía como
     parte de ellos y no como un aviso aparte. */
  margin: 18px 0 22px; color: var(--ink); line-height: 1.55;
}
.nota:first-child { margin-top: 0; }

[hidden] { display: none !important; }

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

td.mono, .mono {
  font-family: "Consolas", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------- habilitacion -- */

.casilla-habilitar {
  width: auto; flex: none; margin: 0 2px 0 0; cursor: pointer;
  accent-color: var(--marino);
}
.lista .casilla-habilitar + .texto { padding-left: 2px; }
.lista-suelta li { padding-left: 12px; }
.lista li.inactivo .casilla-habilitar { opacity: .6; }

/* ------------------------------------------------------------ dashboard -- */

/* Una sola paleta para todas las municipalidades: la barra de arriba lleva la
   marca de cada una, pero las cifras se leen igual en todas. Validada con el
   comprobador de paletas (daltonismo y contraste).
     · magnitud: una escala de azul, más es más oscuro;
     · identidad: incidencias naranja, preventivo verde agua;
     · énfasis: el pico de una serie en ámbar.
   El texto nunca va en el color de la serie. Los mismos valores están en
   web/mapa.js (COLOR), porque el mapa pinta en un lienzo y no lee CSS. */
.dashboard {
  --dv-tinta: #16202c;
  --dv-tinta-2: #4b5563;
  --dv-tenue: #66717e;
  --dv-linea: #dfe4eb;
  --dv-pista: #eef1f5;
  --dv-tarjeta: #ffffff;
  --dv-azul-100: #cde2fb;
  --dv-azul-200: #9ec5f4;
  --dv-azul-300: #6da7ec;
  --dv-azul-450: #2a78d6;
  --dv-azul-550: #1c5cab;
  --dv-azul-700: #0d366b;
  --dv-inc: #eb6834;
  --dv-prev: #1baf7a;
  --dv-ambar: #eda100;
  --dv-radio: 8px;
  color: var(--dv-tinta);
}
.panel:has(> .dashboard) { padding-top: 16px; }

/* ---- pestañas, arriba de los filtros: los filtros cambian según la pestaña */
.dv-pestanas {
  display: flex; gap: 2px; overflow-x: auto;
  background: var(--dv-tarjeta); border: 1px solid var(--dv-linea);
  border-radius: var(--dv-radio); padding: 0 6px; margin-bottom: 10px;
}
/* «Corte al …» a la derecha de las pestañas; en rojo si la data no es de este mes. */
.dv-corte {
  margin: 0 8px 0 auto; align-self: center; flex: none; white-space: nowrap;
  font-size: 13px; color: var(--dv-tenue);
}
.dv-corte strong { color: var(--dv-tinta); font-weight: 600; font-variant-numeric: tabular-nums; }
.dv-corte.atrasado, .dv-corte.atrasado strong { color: #c62828; }
.dv-pestana {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  border: 0; background: none; cursor: pointer; color: var(--dv-tenue);
  padding: 11px 14px 9px; border-bottom: 3px solid transparent; font: inherit; font-size: 14.5px;
}
.dv-pestana:hover { color: var(--dv-tinta); }
.dv-pestana[aria-current="true"] {
  color: var(--dv-tinta); font-weight: 600; border-bottom-color: var(--dv-azul-450);
}
.dv-pestana .dv-icono { width: 18px; height: 18px; }

/* ---- filtros */
.dv-filtros {
  display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end;
  background: var(--dv-tarjeta); border: 1px solid var(--dv-linea);
  border-radius: var(--dv-radio); padding: 10px 14px 12px; margin-bottom: 14px;
}
.dv-filtro { display: flex; flex-direction: column; gap: 3px; min-width: 170px; flex: 1 1 170px; max-width: 280px; }
.dv-filtro.ancho { max-width: 420px; flex-basis: 260px; }
.dv-filtro .etiqueta {
  font-size: 10.5px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--dv-tenue);
}
.dv-filtro select, .dv-filtro input:not([type="checkbox"]):not([type="radio"]):not(.fecha-oculta) { padding: 5px 8px; }
.dv-periodo { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.dv-periodo select { flex: 1 1 200px; }
/* Con :not(.fecha-oculta) para ganarle al selector general de inputs, que
   les pone width:100%. */
.dv-periodo input[type="month"]:not(.fecha-oculta) { width: auto; flex: 1 1 130px; }
.dv-a { color: var(--dv-tenue); }
/* Personalizado: atajo, desde «a» hasta, en una sola línea. */
.dv-filtro.rango { max-width: 760px; flex: 2 1 620px; }
.dv-filtro.rango .dv-periodo { flex-wrap: nowrap; }
.dv-filtro.rango .dv-periodo select { flex: 1 1 200px; min-width: 0; }
.dv-filtro.rango .dv-periodo input[type="month"]:not(.fecha-oculta) { flex: 0 1 175px; min-width: 140px; }
@media (max-width: 720px) {
  .dv-filtro.rango { flex-basis: 100%; }
  .dv-filtro.rango .dv-periodo { flex-wrap: wrap; }
}

/* Categoría como árbol */
.dv-arbol { position: relative; }
.dv-arbol-boton {
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 3px; padding: 5px 28px 5px 8px;
  position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dv-arbol-boton::after {
  content: ""; position: absolute; right: 10px; top: 50%; margin-top: -4px;
  width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.dv-arbol-panel {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0;
  width: min(440px, 92vw); max-height: 420px; display: flex; flex-direction: column;
  background: var(--dv-tarjeta); border: 1px solid var(--line-strong);
  border-radius: var(--dv-radio); box-shadow: var(--sombra); padding: 8px;
}
.dv-arbol-panel input { margin-bottom: 6px; }
.dv-arbol-lista { overflow-y: auto; }
.dv-arbol-grupo {
  margin: 8px 0 2px; padding: 0 6px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--dv-tenue);
}
.dv-arbol-fila { display: flex; align-items: center; padding-left: calc((var(--nivel) - 1) * 16px); border-radius: 4px; }
.dv-arbol-fila[style*="--nivel:0"] { padding-left: 0; }
.dv-arbol-fila:hover { background: var(--dv-pista); }
.dv-arbol-fila.elegida { background: var(--azul-suave); font-weight: 600; }
.dv-arbol-flecha {
  flex: none; width: 24px; height: 28px; border: 0; background: none; cursor: pointer;
  color: var(--dv-tenue); font-size: 12px; display: inline-grid; place-items: center;
}
.dv-arbol-nombre {
  flex: 1; text-align: left; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit; padding: 5px 6px 5px 0;
}

/* ---- contenido */
.dv-contenido { transition: opacity .15s; }
.dv-contenido.cargando { opacity: .55; pointer-events: none; }
.dv-vacio { margin: 0; padding: 28px 8px; text-align: center; color: var(--dv-tenue); }

.dv-tarjeta {
  background: var(--dv-tarjeta); border: 1px solid var(--dv-linea);
  border-radius: var(--dv-radio); padding: 16px 18px; min-width: 0;
}
.dv-tarjeta-cab { display: flex; align-items: flex-start; gap: 10px 16px; flex-wrap: wrap; margin-bottom: 12px; }
.dv-tarjeta-cab > :last-child:not(:first-child) { margin-left: auto; }
.dv-tarjeta h2 { margin: 0; font-size: 17px; letter-spacing: -.01em; color: var(--dv-tinta); }
.dv-sub { margin: 2px 0 0; font-size: 12.5px; color: var(--dv-tenue); }

.dv-rejilla { display: grid; gap: 14px; }
/* Mes arriba a lo ancho, una columna al costado y dos tarjetas abajo. */
.dv-r-detalle, .dv-r-recursos {
  grid-template-columns: 1fr 1fr minmax(260px, .8fr);
  grid-template-areas: "mes mes lado" "uno dos lado";
}
/* Recursos: responsables a la izquierda en todo el alto; en el medio,
   vehículos y capacidad operativa lado a lado, y personal debajo de los dos. */
.dv-r-recursos {
  grid-template-columns: 1fr .5fr .5fr minmax(260px, .8fr);
  grid-template-areas: "mes uno cap lado" "mes dos dos lado";
}
.a-cap { grid-area: cap; }
/* Incidencias: la columna derecha se parte en alto impacto (arriba, el doble
   de alto) y medio de detección (abajo, compacto). La fila del medio separa
   las dos alturas sin mover la de «por mes» ni la de abajo. */
.dv-r-incidencias { grid-template-areas: "mes mes lado" "uno dos lado" "uno dos medio"; }
.a-medio { grid-area: medio; }
.dv-r-mapa {
  grid-template-columns: minmax(0, 1.7fr) minmax(280px, 1fr);
  grid-template-areas: "mapa hora" "mapa dia";
}
.a-mes { grid-area: mes; } .a-lado { grid-area: lado; } .a-uno { grid-area: uno; } .a-dos { grid-area: dos; }
.a-mapa { grid-area: mapa; } .a-hora { grid-area: hora; } .a-dia { grid-area: dia; }
@media (max-width: 1100px) {
  .dv-r-detalle, .dv-r-recursos {
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "mes mes" "lado lado" "uno dos";
  }
  .dv-r-incidencias { grid-template-areas: "mes mes" "lado medio" "uno dos"; }
  .dv-r-recursos { grid-template-areas: "mes mes" "lado lado" "uno cap" "dos dos"; }
  .dv-r-mapa { grid-template-columns: 1fr; grid-template-areas: "mapa" "hora" "dia"; }
}
@media (max-width: 720px) {
  .dv-r-detalle, .dv-r-recursos { grid-template-columns: 1fr; grid-template-areas: "mes" "lado" "uno" "dos"; }
  .dv-r-incidencias { grid-template-areas: "mes" "lado" "medio" "uno" "dos"; }
  .dv-r-recursos { grid-template-areas: "mes" "lado" "uno" "cap" "dos"; }
}

/* ---- iconos y tonos */
.dv-icono { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; flex: none; }
.dv-kpi-icono {
  flex: none; width: 52px; height: 52px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: #e6effb; color: var(--dv-azul-550);
}
.tono-inc .dv-kpi-icono { background: #fdebe3; color: #b8481c; }
.tono-prev .dv-kpi-icono { background: #e1f5ec; color: #11795a; }
.tono-ambar .dv-kpi-icono { background: #fdf2d6; color: #a86f00; }

/* ---- KPI */
.dv-kpis { display: grid; gap: 14px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .dv-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .dv-kpis { grid-template-columns: 1fr; } }
.dv-kpi {
  background: var(--dv-tarjeta); border: 1px solid var(--dv-linea); border-radius: var(--dv-radio);
  padding: 18px 20px 14px; display: flex; flex-direction: column; gap: 6px; min-width: 0;
}
.dv-kpi-fila { display: flex; align-items: center; gap: 16px; padding-bottom: 12px; border-bottom: 1px solid var(--dv-linea); }
.dv-kpi-valor {
  font-size: clamp(26px, 2.6vw, 38px); font-weight: 700; letter-spacing: -.02em;
  color: var(--dv-tinta); line-height: 1.1; min-width: 0; overflow-wrap: anywhere;
}
.dv-kpi-titulo { margin: 6px 0 0; font-size: 15px; font-weight: 600; color: var(--dv-tinta); }
.dv-kpi-apoyo { margin: 0; font-size: 13px; color: var(--dv-tinta-2); }
.dv-kpi-barra { height: 8px; border-radius: 4px; background: var(--dv-pista); overflow: hidden; }
.dv-kpi-barra span { display: block; height: 100%; border-radius: 4px; background: var(--dv-azul-450); }
.tono-inc .dv-kpi-barra span { background: var(--dv-inc); }
.tono-prev .dv-kpi-barra span { background: var(--dv-prev); }
.dv-kpi-periodo {
  margin: auto 0 0; padding-top: 6px; font-size: 11.5px; color: var(--dv-tenue);
  letter-spacing: .02em;
}
/* Variación en 6 y 12 meses, cerca de lo de arriba (no pegada al periodo):
   la comparación a la izquierda y el porcentaje a la derecha, con color solo
   en el símbolo y el número (verde sube, rojo baja). */
.dv-vars {
  display: flex; flex-direction: column; gap: 3px;
  margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--dv-linea);
}
.dv-var { margin: 0; display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 13.5px; }
.dv-var strong { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--dv-tinta-2); white-space: nowrap; }
.dv-var-etiqueta { color: var(--dv-tinta-2); }
/* «36 registros menos»: el número en color, la palabra en tinta. */
.dv-var-valor { white-space: nowrap; }
.dv-var-unidad { color: var(--dv-tinta-2); }
.dv-var.sube strong { color: #1a7a43; }
.dv-var.baja strong { color: #b42323; }
.dv-var.sin-base strong { color: var(--dv-tenue); font-weight: 600; }

/* ---- columnas */
/* Área del gráfico arriba, eje de abajo debajo; con eje vertical, una columna
   más a la izquierda. Aire arriba: la cifra de la columna más alta queda por
   encima de ella. */
.dv-columnas {
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto;
  padding-top: 20px;
}
.dv-columnas.con-eje { grid-template-columns: auto minmax(0, 1fr); padding-top: 10px; }
.dv-plot {
  position: relative; height: var(--dv-alto);
  display: grid; grid-template-columns: repeat(var(--dv-n), minmax(0, 1fr)); gap: 2px;
  border-bottom: 1px solid var(--line-strong);
}
/* Líneas guía, detrás de las columnas y apenas visibles. */
.dv-guia { position: absolute; left: 0; right: 0; height: 0; border-top: 1px solid var(--dv-linea); }
.dv-col {
  position: relative; min-width: 0; display: flex; flex-direction: column;
  justify-content: flex-end; align-items: center; cursor: default;
}
.dv-col-valor { font-size: 11.5px; font-weight: 600; color: var(--dv-tinta); padding-bottom: 3px; white-space: nowrap; }
.dv-col-barra {
  display: block; width: min(78%, 46px); min-height: 1px;
  background: var(--dv-azul-300); border-radius: 4px 4px 0 0;
}
.dv-col:hover .dv-col-barra { filter: brightness(.88); }
.dv-col-barra.e1 { background: var(--dv-azul-100); }
.dv-col-barra.e2 { background: var(--dv-azul-200); }
.dv-col-barra.e3 { background: var(--dv-azul-300); }
.dv-col-barra.e4 { background: var(--dv-azul-450); }
.dv-col-barra.e5 { background: var(--dv-azul-700); }
.dv-col.pico .dv-col-barra { background: var(--dv-ambar); }

/* Eje vertical: la cifra a la altura de su línea guía. */
.dv-ejey { position: relative; min-width: 2.6em; padding-right: 8px; }
.dv-ejey span {
  position: absolute; right: 8px; transform: translateY(50%);
  font-size: 11px; color: var(--dv-tenue); font-variant-numeric: tabular-nums; line-height: 1;
}

/* Eje de abajo: cada etiqueta centrada bajo su columna, aunque sea más ancha
   que ella («00:00» sobre una columna angosta). La primera y la última se
   recuestan hacia adentro para no salirse del gráfico. */
.dv-ejex {
  display: grid; grid-template-columns: repeat(var(--dv-n), minmax(0, 1fr)); gap: 2px;
  padding-top: 5px; font-size: 11px; color: var(--dv-tenue); line-height: 1.25;
}
.dv-ejex > span { display: flex; justify-content: center; min-width: 0; white-space: nowrap; }
.dv-columnas.con-eje .dv-ejex > span.inicio { justify-content: flex-start; }
.dv-columnas.con-eje .dv-ejex > span.fin { justify-content: flex-end; }
.dv-ejex > span > span { text-align: center; }
.dv-ejex small { display: block; font-size: 10px; }

/* ---- barras horizontales */
/* Una sola rejilla para todas las filas (subgrid): la columna del nombre mide
   lo que el nombre más largo, con un tope, y todas las barras empiezan en el
   mismo punto, sin un hueco vacío en las tarjetas anchas. */
.dv-barras { display: grid; grid-template-columns: fit-content(40%) 1fr auto; gap: 8px 12px; }
.dv-barra-fila {
  grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center;
}
.dv-barra-nombre { font-size: 13px; color: var(--dv-tinta); line-height: 1.25; overflow-wrap: anywhere; }
.dv-barra-pista { height: 14px; background: var(--dv-pista); border-radius: 4px; overflow: hidden; }
.dv-barra-pista span { display: block; height: 100%; background: var(--dv-azul-450); border-radius: 4px; }
.dv-barra-fila:hover .dv-barra-pista span { background: var(--dv-azul-550); }
.dv-barra-valor { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 3ch; text-align: right; }/* Filas que se abren en su detalle (clase → subcategorías). */
.dv-barra-fila.elegible { cursor: pointer; border-radius: 6px; padding: 0 4px; }
.dv-barra-fila.elegible:hover { background: #f1f5fb; }
.dv-barra-fila.elegible:hover .dv-barra-nombre { color: var(--dv-azul-550); }
/* Clase con delitos de alto impacto: el mismo ámbar de esa tarjeta. */
.dv-barra-fila.tono-ambar .dv-barra-pista span { background: var(--dv-ambar); }
.dv-barra-fila.tono-ambar:hover .dv-barra-pista span { background: #c98500; }
.dv-barra-fila.elegible.tono-ambar:hover .dv-barra-nombre { color: #9a6400; }
.dv-barra-fila.elegible:focus-visible { outline: 2px solid var(--dv-azul-450); outline-offset: 1px; }
.dv-volver {
  flex: none; padding: 5px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--dv-linea); background: var(--dv-tarjeta);
  font: inherit; font-size: 13px; font-weight: 600; color: var(--dv-azul-550);
}
.dv-volver:hover { background: #f1f5fb; border-color: var(--dv-azul-200); }
.dv-volver[hidden] { display: none; }

/* ---- torta */
.dv-torta { display: flex; align-items: center; justify-content: center; gap: 16px 28px; flex-wrap: wrap; }
.dv-torta-dibujo { width: 150px; height: 150px; flex: none; overflow: visible; }
.dv-torta-porcion { stroke: #fff; stroke-width: 1; transition: opacity .12s; }
.dv-torta-porcion:hover { opacity: .85; }
.dv-torta-leyenda { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.dv-torta-leyenda li {
  display: grid; grid-template-columns: 12px auto auto auto; align-items: baseline; gap: 4px 10px;
  font-size: 13px; color: var(--dv-tinta);
}
.dv-torta-leyenda i { width: 12px; height: 12px; border-radius: 3px; align-self: center; }
.dv-torta-leyenda strong { font-size: 15px; font-variant-numeric: tabular-nums; }
.dv-torta-leyenda small { font-size: 12px; color: var(--dv-tenue); font-variant-numeric: tabular-nums; }

/* ---- barra de fechas del mapa: una línea fina, con la ventana que se
   arrastra y se estira. */
.dv-rango {
  display: flex; align-items: center; gap: 12px; margin-top: 6px; min-height: 22px;
  font-size: 12px; color: var(--dv-tenue); font-variant-numeric: tabular-nums; user-select: none;
}
.dv-rango-fechas { flex: none; min-width: 12.5em; color: var(--dv-tinta-2); }
.dv-rango-cuenta { flex: none; white-space: nowrap; }
.dv-rango-pista {
  position: relative; flex: 1; min-width: 80px; height: 6px; border-radius: 3px;
  background: var(--dv-pista); cursor: pointer; touch-action: none;
}
.dv-rango-ventana {
  position: absolute; top: -3px; height: 12px; min-width: 4px; box-sizing: border-box;
  background: rgba(42, 120, 214, .28); border: 1.5px solid var(--dv-azul-450); border-radius: 4px;
  cursor: grab;
}
.dv-rango.arrastrando .dv-rango-ventana { cursor: grabbing; background: rgba(42, 120, 214, .4); }
.dv-rango-ventana:focus-visible { outline: 2px solid var(--dv-azul-450); outline-offset: 2px; }
/* Los bordes salen un poco hacia afuera: con un solo día la ventana es
   angosta y aun así se pueden agarrar. */
.dv-rango-asa {
  position: absolute; top: -4px; width: 8px; height: 17px; box-sizing: border-box;
  background: #fff; border: 1.5px solid var(--dv-azul-450); border-radius: 3px; cursor: ew-resize;
}
.dv-rango-asa.izq { left: -6px; }
.dv-rango-asa.der { right: -6px; }

/* ---- reparto (medio de detección): dos columnas, con las filas repartidas
   en el alto. (Sin «safe»: no se combina con space-evenly, y con él el
   navegador descartaba la regla y estiraba la fila a todo el alto.) */
.dv-reparto {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 22px;
  align-content: space-evenly;
}
/* Todo centrado en la fila: cuadrito, nombre, cifra y porcentaje. */
.dv-reparto li {
  display: grid; grid-template-columns: 10px minmax(0, 1fr) auto auto; align-items: center; gap: 8px;
  padding: 3px 0; font-size: 13px;
}
.dv-reparto i { width: 10px; height: 10px; border-radius: 2px; }
.dv-reparto-nombre { color: var(--dv-tinta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dv-reparto strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.dv-reparto small { font-size: 11.5px; color: var(--dv-tenue); font-variant-numeric: tabular-nums; min-width: 4.5ch; text-align: right; }
.dv-reparto li.cero { opacity: .5; }
/* En lista (vehículos por tipo, o pocos medios): una columna, letra algo mayor. */
.dv-reparto.lista { grid-template-columns: minmax(0, 1fr); }
.dv-reparto.lista li { font-size: 14px; line-height: 1.3; padding: 6px 0; gap: 12px; }
.dv-reparto.lista i { width: 12px; height: 12px; border-radius: 3px; }
.dv-reparto.lista strong { font-size: 15px; }
/* Fila que se abre (vehículos por tipo → por placa), como las barras que se despliegan. */
.dv-reparto li.elegible { cursor: pointer; border-radius: 6px; padding-left: 6px; padding-right: 6px; }
.dv-reparto li.elegible:hover { background: #f1f5fb; }
.dv-reparto li.elegible:hover .dv-reparto-nombre { color: var(--dv-azul-550); }
.dv-reparto li.elegible:focus-visible { outline: 2px solid var(--dv-azul-450); outline-offset: 1px; }

/* ---- capacidad operativa: un bloque por recurso, con el icono a la
   izquierda y, a su lado, el nombre arriba y la cifra debajo (así el nombre
   no se corta en una tarjeta angosta). Los bloques se reparten el alto, con
   una línea entre ellos. */
.dv-capacidad {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-auto-rows: 1fr; align-content: stretch;
}
/* El icono a la derecha, a la altura de las dos líneas (nombre y cifra). */
.dv-capacidad li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto;
  align-content: center; column-gap: 14px; row-gap: 2px; padding: 10px 0;
}
.dv-capacidad li + li { border-top: 1px solid var(--dv-linea); }
.dv-capacidad .dv-icono {
  grid-column: 2; grid-row: 1 / 3; align-self: center; justify-self: end;
  width: 34px; height: 34px; stroke-width: 1.6; color: var(--dv-azul-450);
}
.dv-capacidad-titulo { grid-column: 1; grid-row: 1; }
.dv-capacidad-cifra { grid-column: 1; grid-row: 2; }
.dv-capacidad-titulo { font-size: 14px; line-height: 1.3; color: var(--dv-tinta); }
.dv-capacidad-cifra { display: flex; align-items: baseline; gap: 10px; white-space: nowrap; }
/* Cifra y porcentaje del mismo tamaño que en «Vehículos desplegados», al lado. */
.dv-capacidad strong { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--dv-tinta); }
.dv-capacidad small { font-size: 11.5px; color: var(--dv-tenue); font-variant-numeric: tabular-nums; }

/* ---- tabla de calor */
.dv-desborde { overflow-x: auto; }
table.dv-calor { border-collapse: separate; border-spacing: 2px; width: 100%; }
.dv-calor th, .dv-calor td { border: 0; padding: 8px 10px; }
.dv-calor thead th {
  background: none; text-transform: none; letter-spacing: 0; font-size: 12.5px;
  font-weight: 600; color: var(--dv-tinta-2); text-align: center;
}
.dv-calor tbody th { font-size: 13px; font-weight: 500; white-space: nowrap; color: var(--dv-tinta); }
.dv-calor td { text-align: center; font-weight: 600; font-variant-numeric: tabular-nums; border-radius: 2px; }
.dv-calor .e0 { background: var(--dv-pista); color: var(--dv-tenue); font-weight: 400; }
.dv-calor .e1 { background: var(--dv-azul-100); color: var(--dv-tinta); }
.dv-calor .e2 { background: var(--dv-azul-200); color: var(--dv-tinta); }
.dv-calor .e3 { background: var(--dv-azul-300); color: var(--dv-tinta); }
.dv-calor .e4 { background: var(--dv-azul-450); color: #fff; }
.dv-calor .e5 { background: var(--dv-azul-700); color: #fff; }

/* ---- listas de cifras (alto impacto, modalidades, entidades) */
.dv-cifras { display: flex; flex-direction: column; gap: 10px; }
.dv-cifra {
  display: grid; grid-template-columns: minmax(64px, auto) 52px 1fr; gap: 12px; align-items: center;
  padding: 10px 12px; border-radius: var(--dv-radio); background: #f7f9fc;
  border-left: 4px solid var(--dv-azul-450);
}
.dv-cifra.tono-ambar { border-left-color: var(--dv-ambar); }
.dv-cifra.tono-prev { border-left-color: var(--dv-prev); }
.dv-cifra-valor { font-size: 30px; font-weight: 700; letter-spacing: -.02em; line-height: 1; }
.dv-cifra .dv-kpi-icono { width: 44px; height: 44px; }
.dv-cifra-texto { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.dv-cifra-texto strong { font-size: 14px; }
.dv-cifra-texto small { font-size: 12px; color: var(--dv-tenue); }


/* ---- mapa */
.dv-mapa-marco { position: relative; }
/* Barra «Intensidad» del calor, sobre + y −, del mismo ancho que esos botones. */
.dv-intensidad {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 29px; padding: 6px 0 5px; background: #fff;
}
.dv-intensidad[hidden] { display: none !important; }
/* Con :not(.fecha-oculta) para ganarle a la regla general de inputs, que les
   pone borde, fondo y ancho completo. */
.dv-intensidad > input[type="range"].dv-intensidad-barra:not(.fecha-oculta) {
  /* Vertical: arriba es más intensidad. */
  writing-mode: vertical-lr; direction: rtl;
  width: 16px; min-width: 0; height: 96px; margin: 0; padding: 0;
  border: 0; background: none; cursor: ns-resize;
  accent-color: #d03b3b;
}
.dv-intensidad-valor { font-size: 10px; font-weight: 600; color: var(--dv-tinta); font-variant-numeric: tabular-nums; }
.dv-mapa { border-color: var(--dv-linea); }
.mapa.dv-mapa-lienzo { height: 520px; }
@media (max-width: 1100px) { .mapa.dv-mapa-lienzo { height: 440px; } }
@media (max-width: 640px) { .mapa.dv-mapa-lienzo { height: 340px; } }
/* Pantalla completa: la tarjeta entera, y el mapa se queda con todo el alto
   que dejan el título y la barra de fechas. */
.a-mapa:fullscreen {
  display: flex; flex-direction: column; overflow: hidden;
  padding: 16px 20px; border: 0; border-radius: 0; background: var(--dv-tarjeta, #fff);
}
.a-mapa:fullscreen > .dv-tarjeta-cab { flex: none; }
.a-mapa:fullscreen > :last-child { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.a-mapa:fullscreen .dv-mapa-marco { flex: 1; min-height: 0; }
.a-mapa:fullscreen .dv-mapa, .a-mapa:fullscreen .mapa.dv-mapa-lienzo { height: 100%; }
.a-mapa:fullscreen .dv-sub, .a-mapa:fullscreen .dv-rango { flex: none; margin-top: 8px; }
/* El detalle de un punto no se estira hasta abajo: mide lo que su contenido,
   con un tope de la mitad del alto; si no entra, se desplaza por dentro. */
.a-mapa:fullscreen .dv-detalle { bottom: auto; max-height: 50%; }
.dv-mapa-mandos {
  position: absolute; top: 10px; left: 10px; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
}
.dv-leyenda-mapa {
  display: flex; gap: 12px; background: rgba(255, 255, 255, .92); border-radius: 6px;
  padding: 5px 10px; font-size: 12.5px; box-shadow: 0 1px 3px rgba(22, 32, 44, .15);
}
.dv-leyenda-mapa span { display: inline-flex; align-items: center; gap: 6px; }
.dv-leyenda-mapa i { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.15); }
.dv-leyenda-mapa i.tono-inc { background: var(--dv-inc); }
.dv-leyenda-mapa i.tono-prev { background: var(--dv-prev); }
/* Detalle de un punto: un panel a la derecha del mapa, con todo su alto, que
   se desplaza por dentro. Deja libre la franja de abajo, donde va la
   atribución de OpenStreetMap. */
.dv-mapa { position: relative; }
.dv-detalle {
  /* Empieza debajo del botón de pantalla completa, para no taparlo. */
  position: absolute; z-index: 3; top: 50px; right: 10px; bottom: 38px;
  width: min(360px, calc(100% - 20px)); overflow-y: auto;
  background: #fff; border: 1px solid #dfe4eb; border-radius: 8px;
  box-shadow: 0 6px 24px rgba(22, 32, 44, .22);
}
.dv-detalle-cuerpo { padding: 12px 14px 14px; }
.dv-detalle-cerrar {
  position: sticky; top: 0; float: right; z-index: 1;
  width: 32px; height: 32px; margin: 4px 4px -36px 0;
  border: 0; border-radius: 6px; background: rgba(255, 255, 255, .9);
  font-size: 20px; line-height: 1; color: #4b5563; cursor: pointer;
}
.dv-detalle-cerrar:hover { background: #eef1f5; color: #16202c; }
.dv-popup { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; color: #16202c; }
/* Aire a la derecha para el botón ×, que flota encima. */
.dv-popup-cab { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-right: 30px; }
.dv-popup-cab strong { font-size: 13.5px; }
.dv-popup-tipo {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  padding: 1px 7px; border-radius: 3px; background: #e6effb; color: #1c5cab;
}
/* ‹ 2 de 23 ›: recorrer los partes que comparten la coordenada. */
.dv-casos {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 12px; font-weight: 600; color: #4b5563; white-space: nowrap;
}
.dv-casos button {
  width: 24px; height: 24px; display: inline-grid; place-items: center;
  border: 1px solid #c4ccd6; border-radius: 5px; background: #fff; cursor: pointer;
  font-size: 16px; line-height: 1; color: #16202c; padding: 0 0 2px;
}
.dv-casos button:hover { background: #eef1f5; }
.dv-casos > span { padding: 0 4px; font-variant-numeric: tabular-nums; }
.dv-detalle:focus { outline: none; }
.dv-popup-tipo.tono-inc { background: #fdebe3; color: #b8481c; }
.dv-popup-tipo.tono-prev { background: #e1f5ec; color: #11795a; }
.dv-popup-datos {
  display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0;
  padding: 6px 0; border-top: 1px solid #dfe4eb; border-bottom: 1px solid #dfe4eb;
}
.dv-popup-datos dt { color: #66717e; }
.dv-popup-datos dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }
.dv-popup-descarga .etiqueta {
  display: block; font-size: 10.5px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: #66717e; margin-bottom: 2px;
}
.dv-popup-descarga p { margin: 0; white-space: pre-line; line-height: 1.45; }
.dv-ver { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--dv-tenue); }

/* ---- conmutador */
.dv-conmutador {
  display: inline-flex; border: 1px solid var(--line-strong); border-radius: 6px;
  overflow: hidden; background: var(--dv-tarjeta);
}
.dv-conmutador button {
  border: 0; background: none; cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--dv-tinta-2); padding: 6px 12px;
}
.dv-conmutador button + button { border-left: 1px solid var(--line-strong); }
.dv-conmutador button[aria-pressed="true"] { background: var(--dv-azul-700); color: #fff; }
.dv-conmutador button:disabled { opacity: .45; cursor: not-allowed; }

/* ---- todo en una pantalla (escritorio)
   En escritorio cada pestaña cabe entera en la ventana, sin desplazar la
   página: el dashboard toma el alto que dejan la barra y el pie, las tarjetas
   se lo reparten en dos filas, y los gráficos y el mapa se estiran a su
   tarjeta en vez de tener un alto fijo. Si en una ventana bajita algo no
   entra, se desplaza dentro de su propia tarjeta, no la página.
   En pantallas angostas o muy bajas sigue el diseño de arriba, que se lee
   desplazando: apretar seis tarjetas en un celular no deja ver ninguna. */
@media (min-width: 1101px) and (min-height: 620px) {
  body:has(.dashboard) { height: 100vh; }
  body:has(.dashboard) .app.visible { flex: 1 1 0; min-height: 0; grid-template-rows: auto minmax(0, 1fr); }
  .panel:has(> .dashboard) {
    min-height: 0; overflow: hidden; display: flex; flex-direction: column;
    padding-top: 12px; padding-bottom: 12px;
  }
  .dashboard { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .dv-pestanas, .dv-filtros { flex: none; margin-bottom: 10px; }
  .dv-pestana { padding-top: 9px; padding-bottom: 7px; }
  .dv-filtros { padding-top: 8px; padding-bottom: 10px; }
  .dv-contenido { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .dv-contenido > .dv-rejilla, .dv-contenido > .dv-kpis { flex: 1; min-height: 0; gap: 12px; }
  .dv-kpis, .dv-rejilla { grid-template-rows: repeat(2, minmax(0, 1fr)); }
  /* Incidencias y Preventivo: el gráfico por mes se lee bien más bajo; la
     fila de abajo (por clase o categoría, y turno × sector) necesita el alto
     para mostrar sus filas sin desplazarse. */
  .dv-r-detalle { grid-template-rows: minmax(0, 45fr) minmax(0, 55fr); }
  /* Mes 45 % y abajo 55 %, igual que las demás; a la derecha, alto impacto
     ~70 % y medio de detección ~30 %. */
  .dv-r-detalle.dv-r-incidencias { grid-template-rows: minmax(0, 45fr) minmax(0, 25fr) minmax(0, 30fr); }

  .dv-tarjeta { display: flex; flex-direction: column; min-height: 0; overflow: hidden; padding: 12px 16px; }
  .dv-tarjeta-cab { flex: none; margin-bottom: 8px; }
  .dv-tarjeta > :last-child { flex: 1; min-height: 0; overflow: auto; }

  .dv-kpi { min-height: 0; overflow: hidden; padding: 14px 18px 10px; }
  .dv-kpi-fila { padding-bottom: 10px; }

  /* Las columnas llenan el alto de su tarjeta. */
  .dv-columnas { grid-template-rows: minmax(0, 1fr) auto; }
  .dv-plot { height: auto; min-height: 0; }

  /* La torta toma el alto de su tarjeta, con un tope. */
  .dv-torta { flex-wrap: nowrap; }
  .dv-torta-dibujo { width: auto; height: 78%; max-height: 170px; min-height: 0; aspect-ratio: 1; }
  .dv-torta { gap: 16px 40px; }
  /* Mínimo: la tabla se estira al alto de la tarjeta si sobra espacio. */
  .dv-calor th, .dv-calor td { padding: 3px 8px; }
  /* La tabla de calor estira sus filas hasta el alto de la tarjeta. */
  .dv-calor-caja { display: flex; flex-direction: column; }
  .dv-calor-caja > .dv-desborde { flex: 1; min-height: 0; }
  table.dv-calor { height: 100%; }
  .dv-calor thead th { height: 1px; }
  /* Las barras se reparten el alto de la tarjeta, y la barra engorda con la
     fila. Pocas barras quedan agrupadas al centro vertical de la tarjeta; al
     agregarse, las filas se achican hasta su mínimo y recién entonces
     aparece la barra de desplazamiento («safe» evita que el centrado
     esconda las primeras filas cuando ya no entran). */
  .dv-barras {
    display: grid; grid-auto-rows: minmax(24px, 52px); gap: 4px 14px;
    align-content: safe center;
    /* Más ancho para el nombre: «Personas en riesgo y emergencia» en una
       sola línea en vez de dos. */
    grid-template-columns: fit-content(44%) 1fr auto;
  }
  /* Las barras nunca piden desplazamiento horizontal; solo vertical si son muchas. */
  .dv-tarjeta > .dv-barras { overflow-x: hidden; }
  .dv-barra-fila .dv-barra-pista { height: clamp(14px, 55%, 26px); }
  /* Las cifras (alto impacto, modalidades principales) se reparten el alto
     de su tarjeta en partes iguales. */
  .dv-cifras { display: grid; grid-auto-rows: minmax(56px, 1fr); gap: 8px; }
  /* Cifra, icono y texto crecen con el alto de la fila (cqh = % del alto
     de la fila), con un mínimo y un tope. */
  .dv-cifra {
    padding: 8px 14px; container-type: size;
    grid-template-columns: minmax(64px, auto) auto 1fr; gap: 12px 18px;
  }
  .dv-cifra-valor { font-size: clamp(30px, 42cqh, 60px); justify-self: center; text-align: center; }
  .dv-cifra .dv-kpi-icono { width: clamp(44px, 60cqh, 84px); height: clamp(44px, 60cqh, 84px); }
  .dv-cifra .dv-kpi-icono .dv-icono { width: 50%; height: 50%; }
  .dv-cifra-texto strong { font-size: clamp(14px, 17cqh, 22px); }
  .dv-cifra-texto small { font-size: clamp(12px, 12cqh, 16px); }

  /* El mapa ocupa lo que deja la nota de abajo. */
  .a-mapa > :last-child { display: flex; flex-direction: column; overflow: hidden; }
  .dv-mapa-marco { flex: 1; min-height: 0; }
  .dv-mapa, .mapa.dv-mapa-lienzo { height: 100%; }
  .a-mapa .dv-sub, .a-mapa .dv-rango { flex: none; margin-top: 6px; }
}

/* ---- tooltip */
.dv-tip {
  position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none;
  background: var(--dv-tinta, #16202c); color: #fff; font-size: 12.5px;
  padding: 5px 9px; border-radius: 5px; box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
  max-width: 280px;
}