/* DIAlpr — tema OSCURO por defecto, claro por preferencia del usuario.
   Revision de fatiga visual (2026-10-04, aprobada en lamina): grafito #15181C en vez de negro y texto gris claro
   #D4D7DC en vez de blanco (11:1 en vez de 21:1, que deslumbra en turnos largos); texto oscuro sobre los rellenos
   claros; cian solo para lo interactivo; minimo 12 px; movimiento limitado. Medidas en el scratchpad de esa sesion. */
@font-face{font-family:'Gruppo';src:url('fonts/gruppo-400-latin.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Montserrat';src:url('fonts/montserrat-variable-latin.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
/* Letra de la placa del diseno: Jost 400 (OFL) con la J sin descendente, renombrada por la licencia; se sirve local
   porque en el punto de acceso de la unidad no hay internet. */
@font-face{font-family:'Placa LPR';src:url('fonts/placa-lpr-400-latin.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'License Plate';src:url('fonts/license-plate-400.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap} /* letra de la placa desde 2026-10-02; licencia en fonts/LICENCIAS.md */
@font-face{font-family:'Placa CO Digitos';src:url('fonts/placa-co-digitos.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0030-0039} /* digitos propios de la placa (B3, tools/fuente_placa); las letras siguen en License Plate */
:root{
  --primary:#33B9EA; --primary-600:#2AA6D4; --primary-700:#1F8FBA;  /* 7,1:1 sobre la superficie */
  --bg:#15181C; --surface:#1E2227; --surface-2:#272C32; --surface-3:#22262B;
  --text:#D4D7DC; --text-2:#A1A7AF; --text-3:#C3C8CE; --border:#33393F;
  --success:#5BA35E; --warning:#E0A030; --error:#E5484D; --info:#8A9099;
  --chrome:#1A1D21; --chrome-2:#1E2227; --chrome-3:#2B3036; --chrome-border:#2B3036;
  --chrome-text:#C3C8CE; --chrome-muted:#9AA0A8;
  /* Rellenos con su texto: oscuro sobre cian/verde/ambar (7,8 / 5,5 / 8,0:1); blanco solo sobre el rojo oscuro (5,6:1) */
  --on-fill:#0B1A22; --error-fill:#C62828; --error-text:#FF8A80; --disabled:#6E757D;
  --ok-fill:#5BA35E; --on-ok:#10210F; --warn-fill:#E0A030; --on-warn:#1F1300;
  --font:'Montserrat',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --font-title:'Gruppo','Montserrat',system-ui,sans-serif;
  /* Pila del sistema: JetBrains Mono nunca se sirvio (no esta en fonts/ y el punto de acceso no tiene internet) */
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,'DejaVu Sans Mono','Liberation Mono',monospace;
  --shadow:0 1px 3px rgba(0,0,0,.4); --shadow-lg:0 12px 32px rgba(0,0,0,.5);
  --radius:12px; --radius-sm:8px; --sb:264px; --sb-collapsed:72px; --nav:64px;
}
:root[data-theme="light"]{
  --bg:#F3F4F6; --surface:#FFFFFF; --surface-2:#F9FAFB; --surface-3:#F3F4F6; --text:#111827; --text-2:#6B7280; --text-3:#374151; --border:#E5E7EB;
  --primary:#0077A8; --primary-600:#00668F; --primary-700:#005578; /* el #00AEEF daba 2,5:1 sobre blanco en titulos y KPI */
  --success:#4CAF50; --warning:#FF9800; --error:#F44336; --info:#3B82F6;
  --on-fill:#fff; --error-text:#C62828; --disabled:#80868E;
  --chrome:#0F172A; --chrome-2:#1E293B; --chrome-3:#334155; --chrome-border:#233047; --chrome-text:#CBD5E1; --chrome-muted:#94A3B8;
  --shadow:0 1px 2px rgba(16,24,40,.06),0 1px 3px rgba(16,24,40,.1); --shadow-lg:0 12px 32px rgba(16,24,40,.14);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%;max-width:100vw;overflow-x:hidden}
body{font-family:var(--font);background:var(--bg);color:var(--text);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.01em}
h1,h2,.pagehead h2,.secttl,.brand .name,.tabbar .tab{font-family:var(--font-title);letter-spacing:.01em}
code,.mono{font-family:var(--mono)}
[hidden]{display:none!important}
*:focus-visible{outline:2px solid var(--primary);outline-offset:2px}

/* scrollbars 8px, en gris: una barra cian en cada panel competia con lo interactivo */
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-track{background:var(--surface)}
::-webkit-scrollbar-thumb{background:#3A4048;border-radius:4px}
::-webkit-scrollbar-thumb:hover{background:#4A515A}
*{scrollbar-width:thin;scrollbar-color:#3A4048 var(--surface)}
:root[data-theme="light"] ::-webkit-scrollbar-thumb{background:#C4C9D0} :root[data-theme="light"] *{scrollbar-color:#C4C9D0 var(--surface)}

/* ---------- layout ---------- */
.layout{display:flex;flex-direction:column;height:100vh}
/* Header: FULL-WIDTH arriba, carbon de la marca (#231F20) con el logo en blanco en los dos temas y en todos los anchos.
   Antes era un degradado blanco->oscuro: la mancha blanca a la izquierda deslumbraba sobre el fondo oscuro (2026-10-04). */
.navbar{display:flex;align-items:center;gap:14px;padding:0 18px 0 12px;height:var(--nav);flex:0 0 var(--nav);
  background:var(--carbon);border-bottom:1px solid #33393F;z-index:9999}
/* Cuerpo: sidebar (EnterpriseNavbar) DEBAJO del header, a la izquierda + contenido */
.body{display:flex;flex:1;min-height:0;overflow:hidden}
.sidebar{z-index:1050;width:var(--sb);flex:0 0 var(--sb);background:var(--chrome);color:var(--chrome-text);display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--chrome-border);transition:width .3s,flex-basis .3s}
.layout.collapsed .sidebar{width:var(--sb-collapsed);flex:0 0 var(--sb-collapsed)}
.content{flex:1;min-width:0;overflow:auto;padding:22px;background:var(--bg)}

/* ---------- sidebar ---------- */
.navbar .brand{display:flex;align-items:center;gap:10px;flex:0 0 auto}
.navbar .brand img{display:block}
.navbar .brand .orglogo,.logo-prev .orglogo{height:34px;width:auto;max-width:150px;object-fit:contain;object-position:left center;filter:brightness(0) invert(1);opacity:.9}
/* Vista previa del logo en Configuracion: el mismo fondo y filtro del encabezado, para ver lo que saldra. */
.logo-prev{background:#231F20;border-radius:8px;padding:10px 14px;display:inline-flex}
.navbar .brand .mark{width:34px;height:34px;border-radius:9px;background:linear-gradient(135deg,var(--primary),#22D3EE);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:14px;flex:0 0 34px}
.navbar .brand .name{font-weight:800;font-size:18px;color:#E0E2E5;white-space:nowrap;line-height:1.05}
.navbar .brand .name small{display:block;font-size:12px;font-weight:500;color:var(--chrome-muted)}
.navwrap{flex:1;overflow-y:auto;overflow-x:hidden;padding:12px 10px 4px}
.navgroup .lbl{font-size:12px;text-transform:uppercase;letter-spacing:.09em;color:var(--chrome-muted);padding:14px 10px 6px;font-weight:700}
.layout.collapsed .navgroup .lbl{opacity:0;height:10px;padding:6px}
.navitem{display:flex;align-items:center;gap:12px;padding:10px 11px;border-radius:10px;color:var(--chrome-text);cursor:pointer;font-weight:500;font-size:13.5px;position:relative}
.navitem svg{width:19px;height:19px;flex:0 0 19px;opacity:.85}
.navitem span{white-space:nowrap;overflow:hidden}
.layout.collapsed .navitem span{display:none}
.layout.collapsed .navitem{justify-content:center;padding:11px}
.navitem:hover{background:var(--chrome-3);color:#fff}
.navitem.active{background:color-mix(in srgb,var(--primary) 22%,transparent);color:#E6E8EB}
.navitem.active::before{content:"";position:absolute;left:0;top:8px;bottom:8px;width:3px;border-radius:0 3px 3px 0;background:var(--primary)}
.navitem.active svg{opacity:1;color:var(--primary)}
.navitem .badge{margin-left:auto;background:var(--error-fill);color:#fff;border-radius:999px;font-size:12px;padding:1px 7px;font-weight:700}
.layout.collapsed .navitem .badge{position:absolute;top:4px;right:4px;margin:0}
.sidebar .foot{padding:12px 14px;border-top:1px solid var(--chrome-border);font-size:12px;color:var(--chrome-muted);white-space:nowrap;overflow:hidden}
.layout.collapsed .sidebar .foot{display:none}

/* ---------- navbar ---------- */
.navbar .toggle{background:transparent;border:none;border-radius:9px;padding:7px;cursor:pointer;color:#C3C8CE;display:flex}
.navbar .toggle:hover{background:rgba(255,255,255,.06)}
.navbar .toggle svg{width:18px;height:18px}
.navbar .title{font-size:16px;font-weight:700;color:#E0E2E5}
.navbar .sp{flex:1}
/* Botones del encabezado: relleno carbon solido, sin vidrio ni brillo (el espejo blanco sobre el carbon deslumbraba). */
.navbar .nbtn.turno{font-size:13px;padding:8px 12px;white-space:nowrap} .navbar .nbtn.turno.abierto{border:1px solid rgba(91,163,94,.6)}
.navbar .nbtn{border:none;color:var(--chrome-text);border-radius:12px;padding:8px;cursor:pointer;display:flex;position:relative;
  background:var(--carbon-2);transition:background .15s,color .15s}
.navbar .nbtn:hover{background:var(--carbon-3);color:#E6E8EB}
.navbar .nbtn svg{width:19px;height:19px}
.navbar .nbtn .cnt{position:absolute;top:-5px;right:-5px;background:var(--error-fill);color:#fff;font-size:11px;font-weight:800;border-radius:999px;min-width:17px;height:17px;display:flex;align-items:center;justify-content:center;padding:0 4px}
.navbar #notifBtn svg{width:22px;height:22px} .navbar #notifBtn.hay{color:var(--error)} /* baliza: se enciende con notificaciones sin leer */
/* SOS: blanco sobre rojo oscuro (5,6:1). Abierto, solo el contorno; late mientras el Central no lo atiende (.atendido). */
.navbar .nbtn.sos{background:var(--error-fill);color:#fff;font-weight:700;letter-spacing:.06em;padding:8px 14px;font-size:13px}
.navbar .nbtn.sos:hover{background:#B02020;color:#fff}
.navbar .nbtn.sos.abierto{background:transparent;border:2px solid var(--error);color:var(--error-text)}
.navbar .nbtn.sos.abierto:not(.atendido){animation:sos-latido 1.2s ease-in-out infinite}
@keyframes sos-latido{0%,100%{box-shadow:0 0 0 0 rgba(229,72,77,.55)}50%{box-shadow:0 0 0 6px rgba(229,72,77,0)}}
/* Botón de usuario: mismo relleno carbon que los botones del encabezado */
.usermenu{display:flex;align-items:center;gap:10px;padding:5px 10px 5px 6px;border-radius:12px;cursor:pointer;color:var(--chrome-text);
  background:var(--carbon-2);transition:background .15s}
.usermenu:hover{background:var(--carbon-3)}
.usermenu .av{width:34px;height:34px;border-radius:50%;background:var(--primary);color:var(--on-fill);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px}
.usermenu .who{line-height:1.15}
.usermenu .who .n{color:#E0E2E5;font-weight:700;font-size:13px} .usermenu .who .r{color:#A1A7AF;font-size:12px;text-transform:capitalize}
.usermenu>svg{color:#A1A7AF;width:16px;height:16px}
/* Móvil (<= 640 px): el encabezado tiene que caber en 390 px. Medido 2026-09-23: con el logo a 150 px, hueco de 14 px y el
   chip de usuario con nombre y flecha, el chip quedaba 19 px fuera de la pantalla en TODAS las vistas. */
@media(max-width:640px){
  .navbar{gap:8px;padding:0 10px 0 6px} .navbar .brand .orglogo{max-width:110px} .navbar .nbtn{padding:7px} .navbar .nbtn svg{width:18px;height:18px}
  .usermenu{gap:0;padding:4px} .usermenu .who,.usermenu>svg{display:none}
  /* 2026-10-23: a 390 px la barra no cabia y el avatar quedaba cortado. Consola, mapa y ventana aparte ya estan en el menu */
  #panelBtn,#mapBtn,#mapaVentanaBtn{display:none}
  /* filtros: cada control ocupa el ancho de la pantalla en vez de alinearse a la derecha dejando huecos */
  .frow{justify-content:stretch} .frow>*{flex:1 1 100%;min-width:0;max-width:none!important}
  .frow select,.frow .dt,.frow .searchbox,.frow .searchbox input{width:100%;min-width:0}
  .frow .daterange{display:flex} .frow .daterange button{flex:1;justify-content:center;padding:0 6px}
}
/* Tarjeta de usuario/notificaciones: sin bordes, vidrio con degradado translúcido + desenfoque del fondo */
.dropdown{position:absolute;right:16px;top:56px;width:250px;border:none;border-radius:14px;z-index:1300;overflow:hidden;color:var(--text);
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 92%,transparent) 0%,color-mix(in srgb,var(--surface) 70%,transparent) 100%);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3);
  box-shadow:0 18px 44px rgba(0,0,0,.45),0 0 0 1px rgba(255,255,255,.04) inset;animation:toast-in .18s cubic-bezier(.2,.8,.2,1)}
:root[data-theme="light"] .dropdown{box-shadow:0 18px 44px rgba(16,24,40,.18),0 0 0 1px rgba(255,255,255,.6) inset}
.dropdown .uh{padding:16px 16px 12px;border:none;background:linear-gradient(180deg,color-mix(in srgb,var(--primary) 14%,transparent),transparent)} .dropdown .uh .n{font-family:var(--font-title);font-size:16px;letter-spacing:.06em;font-weight:400} .dropdown .uh .e{color:var(--text-2);font-size:12px;text-transform:capitalize}
.dropdown>div[style*="border-bottom"]{border-bottom:none!important}
.dropdown .mi{display:flex;align-items:center;gap:10px;padding:11px 14px;cursor:pointer;font-size:13.5px;font-weight:500;color:var(--text)}
.dropdown .mi:hover{background:color-mix(in srgb,var(--primary) 12%,transparent)} .dropdown .mi svg{width:17px;height:17px;color:var(--text-2)}
.dropdown .mi.danger{color:var(--error)} .dropdown .mi.danger svg{color:var(--error)}
.dropdown select{background:var(--surface-2)}

/* ---------- componentes ---------- */
.pagehead{display:flex;align-items:center;gap:12px;margin-bottom:18px}
.pagehead h2{font-size:26px;font-weight:600;color:var(--text)} .pagehead .desc{color:var(--text-2);font-size:13px}
.pill{font-size:12px;padding:3px 9px;border-radius:999px;font-weight:600;display:inline-flex;align-items:center;gap:5px;background:var(--surface-2);color:var(--text-3)}
.pill.ok{background:rgba(76,175,80,.18);color:#81C784} .pill.bad{background:rgba(244,67,54,.18);color:#EF9A9A} .pill.warn{background:rgba(255,152,0,.18);color:#FFB74D}
:root[data-theme="light"] .pill.ok{color:#047857} :root[data-theme="light"] .pill.bad{color:#B91C1C} :root[data-theme="light"] .pill.warn{color:#B45309}
.grid{display:grid;gap:16px}
.cols-2{grid-template-columns:repeat(2,1fr)} .cols-3{grid-template-columns:repeat(3,1fr)} .cols-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:1200px){.cols-4{grid-template-columns:repeat(2,1fr)}} @media(max-width:1000px){.cols-3,.cols-2{grid-template-columns:1fr}}
@media(max-width:860px){.sidebar{position:fixed;left:0;top:var(--nav);bottom:0;width:var(--sb);flex-basis:var(--sb);transform:translateX(-100%);transition:transform .25s;z-index:50}.layout.collapsed .sidebar{width:var(--sb);flex-basis:var(--sb)}.layout.mobopen .sidebar{transform:none}.cols-4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.cols-4{grid-template-columns:1fr}}

/* tarjeta = bi-card (hover resalta borde en primary) */
.card{background:var(--surface);border:none;border-radius:var(--radius);box-shadow:var(--shadow)}
.card .hd{display:flex;align-items:center;gap:10px;padding:14px 18px} .card .hd h3{font-size:14px;color:var(--text-3);text-transform:uppercase;letter-spacing:.04em} .card .hd .sp{flex:1}
.card .bd{padding:18px} .card.pad{padding:18px}
.kpi{background:var(--surface);border:none;border-radius:var(--radius);padding:22px 18px;box-shadow:var(--shadow);text-align:center}
.kpi .v{font-size:34px;font-weight:800;letter-spacing:-.02em;color:var(--text)} .kpi .k{color:var(--text-3);font-size:12px;text-transform:uppercase;letter-spacing:.05em;font-weight:600;margin-top:4px}

.btn{font-family:inherit;font-size:13.5px;font-weight:600;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface-2);color:var(--text);padding:9px 15px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;transition:.12s;white-space:nowrap}
.btn:hover{border-color:var(--primary);color:var(--primary)} .btn.primary{background:var(--primary);border-color:transparent;color:var(--on-fill)} .btn.primary:hover{background:var(--primary-600);color:var(--on-fill)}
.btn.danger{background:var(--error-fill);border-color:transparent;color:#fff} .btn.ghost{background:transparent;border-color:transparent;color:var(--text-2)} .btn.ghost:hover{color:var(--primary)}
.btn.ok{background:var(--ok-fill);border-color:transparent;color:var(--on-ok)} .btn.warn{background:var(--warn-fill);border-color:transparent;color:var(--on-warn)}
.btn.sm{padding:6px 11px;font-size:12.5px} .btn svg{width:16px;height:16px}
/* Deshabilitado: color explicito y no opacidad (a ,5 el texto quedaba en 2,7:1 y parecia un fallo de pintado) */
.btn[disabled],.btn.primary[disabled],.btn.ok[disabled],.btn.warn[disabled],.btn.danger[disabled],.btn[disabled]:hover{opacity:1;cursor:not-allowed;color:var(--disabled);background:var(--surface-2);border-color:var(--border)}

/* tabla = data-table (th accent-black + texto primary) */
table{width:100%;border-collapse:collapse;font-size:13px;font-variant-numeric:tabular-nums}
/* cifras de ancho fijo donde se comparan numeros y horas: no bailan al refrescar */
.kpi,.map-stats,.platestrip,.acard,.alcol,.pager,.msg .b .h,.tr-hora{font-variant-numeric:tabular-nums}
/* Titulos de columna SIEMPRE centrados en toda tabla (bloque C, requisito 14): ninguna regla ni estilo en linea los
   alinea a otro lado; las celdas conservan su alineacion. */
th,thead th{text-align:center;padding:11px 14px;color:var(--text-2);font-weight:600;background:transparent;white-space:nowrap;font-size:12px;text-transform:uppercase;letter-spacing:.02em}
tbody td{padding:11px 14px;vertical-align:middle;color:var(--text);text-align:center}
tbody tr:hover{background:var(--surface-2)} .mono-cell{font-family:var(--mono);font-weight:700}

label{display:block;font-size:12.5px;font-weight:600;color:var(--text-3);margin:14px 0 6px}
input,select,textarea{width:100%;font-family:inherit;font-size:14px;padding:10px 12px;border-radius:var(--radius-sm);border:1px solid transparent;background:var(--surface-2);color:var(--text)}
input::placeholder{color:var(--text-2)}
input:focus,select:focus,textarea:focus{outline:2px solid color-mix(in srgb,var(--primary) 40%,transparent);border-color:var(--primary)}
.formrow{display:grid;grid-template-columns:1fr 1fr;gap:14px} .help{font-size:12px;color:var(--text-2);margin-top:5px}
.range{display:flex;align-items:center;gap:12px} .range input[type=range]{flex:1;padding:0;accent-color:var(--primary)} .range .val{font-family:var(--mono);font-weight:700;min-width:56px;text-align:right;color:var(--primary)}

/* Interruptor UNICO del proyecto (bloque C 2026-10-16, requisito 19): 36 x 20 px (la proporcion 11:6 del de siempre,
   44 x 24, a la altura de una linea de texto), perilla de 14 px y sin el margen de los <label> (14 px arriba), que lo
   hacia ver alto y descolgado en las filas. Todo toggle es <label class="switch"><input type="checkbox"><span class="sl">. */
.switch{--sw-w:36px;--sw-h:20px;--sw-k:14px;position:relative;display:inline-block;width:var(--sw-w);height:var(--sw-h);flex:0 0 var(--sw-w);margin:0;vertical-align:middle;box-sizing:border-box} .switch input{display:none}
.switch .sl{position:absolute;inset:0;background:var(--surface-3);border:1px solid var(--border);border-radius:999px;transition:.15s;cursor:pointer}
.switch .sl:before{content:"";position:absolute;width:var(--sw-k);height:var(--sw-k);left:2px;top:calc((var(--sw-h) - 2px - var(--sw-k)) / 2);background:#fff;border-radius:50%;transition:.15s}
.switch input:checked+.sl{background:var(--primary);border-color:transparent} .switch input:checked+.sl:before{transform:translateX(calc(var(--sw-w) - 2px - var(--sw-k) - 4px))}

.empty{text-align:center;color:var(--text-2);padding:40px 16px} .empty svg{width:28px;height:28px;padding:16px;box-sizing:content-box;border-radius:50%;background:var(--surface-2);color:var(--text-3);margin-bottom:12px}
.empty>div{color:var(--text-3);max-width:52ch;margin:0 auto}
/* ===== Capas (z-index) — escala única: contenido/mapa 0 · sidebar 1050 · navbar 1100 · dropdown 1300 · modal 2000 · alerta a pantalla completa 3000 · toast 4000.
   Leaflet pone z-index 400-1000 a sus panes/controles: se AÍSLA el contexto de cada mapa (isolation) para que
   esos valores no salgan del contenedor y el mapa no tape header, popups ni alertas. */
.mapwrap,#geoMap,#mapFull,.leaflet-container{position:relative;z-index:0;isolation:isolate}
.navbar{position:relative;z-index:1100}
/* Modales en vidrio (mismo lenguaje que toasts y tarjeta de usuario): sin bordes, degradado translúcido,
   desenfoque del fondo, sombra suave y anillo interior sutil. El velo de fondo también desenfoca la app. */
.modal-bg{position:fixed;inset:0;background:rgba(0,0,0,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;z-index:2000;padding:20px;animation:modal-veil .16s ease-out}
.modal{border:none;border-radius:16px;width:540px;max-width:100%;max-height:90vh;overflow:auto;color:var(--text);
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 94%,transparent) 0%,color-mix(in srgb,var(--surface) 78%,transparent) 100%);
  -webkit-backdrop-filter:blur(22px) saturate(1.3);backdrop-filter:blur(22px) saturate(1.3);
  box-shadow:0 24px 64px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.05) inset;animation:toast-in .2s cubic-bezier(.2,.8,.2,1)}
:root[data-theme="light"] .modal{box-shadow:0 24px 64px rgba(16,24,40,.22),0 0 0 1px rgba(255,255,255,.7) inset}
.modal .hd{display:flex;align-items:center;padding:18px 22px 14px;border:none;background:linear-gradient(180deg,color-mix(in srgb,var(--primary) 12%,transparent),transparent)} .modal .hd h3{flex:1;font-size:19px;font-family:var(--font-title);color:var(--text);letter-spacing:.04em}
.modal .bd{padding:20px 22px} .modal .ft{display:flex;justify-content:flex-end;gap:10px;padding:14px 22px 18px;border:none;position:sticky;bottom:0;
  background:linear-gradient(0deg,color-mix(in srgb,var(--surface) 96%,transparent) 55%,transparent)} /* el pie flota sobre el contenido al hacer scroll, sin línea */
@keyframes modal-veil{from{opacity:0}to{opacity:1}}

.video{aspect-ratio:16/9;background:#000;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;color:var(--text-2);overflow:hidden;font-size:13px}
.video video,.video img{width:100%;height:100%;object-fit:contain}
.video.vista-estirada video{object-fit:fill} /* flujo de vista: se estira a la proporcion del principal (el contenedor ya la tiene) */
.placas{display:flex;flex-wrap:wrap;gap:8px}
.placa{font-family:var(--mono);font-weight:700;font-size:15px;padding:6px 11px;border-radius:8px;background:var(--surface-2);border:1px solid var(--border);color:var(--text)}
.placa.bad{border-color:var(--error);color:#EF9A9A}
.alerta{display:flex;gap:11px;align-items:center;padding:12px;border-radius:10px;background:rgba(255,152,0,.08);margin-bottom:9px} /* sin barra lateral de color (criterio del usuario) */
.alerta.hi{background:rgba(244,67,54,.09)}
.alerta .t{font-weight:700} .alerta .s{color:var(--text-2);font-size:12px}
.rolechip{font-size:12px;padding:2px 9px;border-radius:999px;background:color-mix(in srgb,var(--primary) 18%,transparent);color:var(--primary);font-weight:700;text-transform:capitalize}

/* alertas por columnas (despacho) */
.alerts-tbl td.fecha{white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--text-2)}
.alerts-tbl tr.a-row{cursor:pointer}
.alerts-tbl .sevdot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:7px;vertical-align:middle;background:var(--info)} /* fondo de respaldo: el color real llega en linea */
/* El color del punto lo pone el front desde /sistema > Notificaciones (estilo en linea). La clase prio-* da solo la FORMA:
   Critica es un rombo, para que no dependa del color distinguirla de Alta (los dos son rojos). */
.alerts-tbl .sevdot.prio-critical{border-radius:1px;transform:rotate(45deg);width:9px;height:9px}
/* Rotulo de prioridad (prioHTML en views.js): Baja gris neutro, Media ambar, Alta rojo, Critica relleno rojo con rombo;
   las cuatro con la misma forma de insignia. Sin barras laterales de color (criterio del usuario): rotulo y punto.
   Tipografia FIJA (familia, tamano, peso, alto de linea, relleno, sin mayusculas ni espaciado): la insignia es identica
   en una pestana (que usa la fuente de titulos), una cabecera, una tabla o una ficha; no hereda nada del contenedor. */
.prio{display:inline-flex;align-items:center;gap:6px;font-family:var(--font);font-size:12.5px;font-weight:600;line-height:18px;
  padding:2px 10px;border-radius:999px;white-space:nowrap;letter-spacing:normal;text-transform:none;vertical-align:middle;
  --p-info:#A1A7AF;--p-warn:#E8B24A;--p-high:#FF8A80}
:root[data-theme="light"] .prio{--p-info:#6B7280;--p-warn:#9A5B00;--p-high:#C62828}
.prio-info{color:var(--p-info);background:color-mix(in srgb,var(--p-info) 14%,transparent)}
.prio-warning{color:var(--p-warn);background:rgba(224,160,48,.14)}
.prio-high{color:var(--p-high);background:rgba(229,72,77,.16)}
.prio-critical{color:#fff;background:var(--error-fill,#C62828)}
.prio-critical::before{content:"";width:7px;height:7px;background:#fff;transform:rotate(45deg);border-radius:1px}
/* Lo que no es prioridad (Sin alerta, Sistema, Autorizados) va en la misma insignia, en gris neutro (prioHTML). */
.prio-neutra{color:var(--text-3);background:var(--surface-2)}
.alerts-tbl tr.a-det td{background:var(--surface-2);padding:0}
.alerts-tbl .det{padding:12px 16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
.alerts-tbl .det .f{font-size:12px;color:var(--text-2);text-transform:uppercase;letter-spacing:.03em} .alerts-tbl .det .vv{font-weight:600}

#alertaFull{position:fixed;inset:0;z-index:3000;background:rgba(10,12,14,.7);display:none;flex-direction:column;align-items:center;justify-content:center;color:#fff;text-align:center;padding:24px}
#alertaFull.show{display:flex}

.login{min-height:100vh;display:flex;align-items:center;justify-content:center;background:radial-gradient(1200px 600px at 25% 0%,#1a1a1a,#000);padding:20px}
.login .box{background:var(--surface);border:1px solid var(--border);border-radius:18px;box-shadow:var(--shadow-lg);width:390px;max-width:100%;padding:34px}
.login .brand{display:flex;align-items:center;justify-content:center;border:none;height:auto;padding:0 0 10px} .login .brand img{display:block;margin:0 auto} .login .brand .name{color:#fff}
.login h2{text-align:center;margin-bottom:4px} .login .sub{text-align:center;color:var(--text-2);font-size:13px;margin-bottom:18px}
.login .err{background:rgba(244,67,54,.15);color:#EF9A9A;padding:10px 12px;border-radius:9px;font-size:13px;margin-top:12px}

/* ---------- Panel operación/despacho ---------- */
.kpi.mini{padding:13px 14px} .kpi.mini .v{font-size:22px} .kpi.mini .k{font-size:12px;margin-top:1px}
.panel-main{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;margin:16px 0;align-items:start}
@media(max-width:1100px){.panel-main{grid-template-columns:1fr}}
.videowrap{position:relative;isolation:isolate;background:#000;border-radius:var(--radius);overflow:hidden;display:flex;align-items:center;justify-content:center;height:64vh}
.videowrap video,.videowrap img{width:100%;height:100%;object-fit:contain;display:block} /* aspecto real de la cámara (bandas antes que deformar/recortar) */
.videowrap .ph{color:var(--text-2);font-size:13px}
/* Tira de placas al pie del video: capa translucida uniforme, justo de la altura de las fichas (usuario, 2026-09-25).
   Antes era un degradado que se fundia con la imagen y las placas perdian contraste sobre escenas claras. */
/* Borde superior en degradado (usuario, 2026-10-15): la capa se desvanece en sus primeros 14 px en vez de cortar con una
   linea; por eso el relleno de arriba es 18 px. */
.platestrip{position:absolute;left:0;right:0;bottom:0;display:flex;gap:10px;overflow-x:auto;padding:18px 12px 10px;background:rgba(0,0,0,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);-webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 14px);mask-image:linear-gradient(to bottom,transparent 0,#000 14px)}
.platestrip:empty{display:none}
/* video cargado (playEval): la tira de placas EN VIVO no aplica a un video procesado y tapaba la barra del reproductor */
.videowrap.con-controles .platestrip{display:none}
.platestrip::-webkit-scrollbar{height:6px}
.platestrip .pc{flex:0 0 auto;text-align:center}
/* Tira de rostros (FaceScan modo continuo): columna a la derecha del video, del borde superior a la tira de placas
   (el JS fija `bottom` con su alto); el selector de camara va a la izquierda junto a Marca deteccion. Dos renglones como
   la tira de placas: «Mujer · 35A» (o nombre corto) y la hora, enteros (usuario, 2026-10-15). */
/* Borde izquierdo en degradado como el de la tira de placas: se desvanece en 14 px (relleno izquierdo 22 px). */
.facestrip{position:absolute;right:0;top:0;bottom:0;width:138px;display:flex;flex-direction:column;gap:10px;overflow-y:auto;overflow-x:hidden;padding:10px 8px 10px 22px;background:rgba(0,0,0,.62);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);-webkit-mask-image:linear-gradient(to right,transparent 0,#000 14px);mask-image:linear-gradient(to right,transparent 0,#000 14px);box-sizing:border-box;z-index:400}
.facestrip:empty{display:none}
.videowrap.con-controles .facestrip{display:none}
.facestrip::-webkit-scrollbar{width:6px}
.facestrip .fc{flex:0 0 auto;text-align:center;cursor:pointer;border-radius:8px;padding:3px}
.facestrip .fc:hover{outline:2px solid #fff;outline-offset:-1px}
.facestrip .fc img,.facestrip .fc .fc-vacia{width:100px;height:100px;object-fit:cover;border-radius:6px;background:#111;display:block;margin:0 auto}
.facestrip .fc .fc-vacia{font-size:12px;color:#94a3b8;line-height:100px}
.facestrip .fc.alarma{box-shadow:0 0 0 2px #E5484D} .facestrip .fc.aviso{box-shadow:0 0 0 2px #E0A030}
.facestrip .fc .q{font-size:12px;color:#fff;font-weight:700;margin-top:4px;line-height:1.3;white-space:nowrap}
.facestrip .fc .t{font-size:12px;color:#cbd5e1;margin-top:2px;line-height:1.3;font-variant-numeric:tabular-nums}
/* Rejilla de rostros en el sitio del mapa (facial encendido, usuario 2026-10-16): tapa el mapa con celdas del mismo
   tamano que la tira (CELDA_ROSTRO en views.js: 106 x 144, hueco 10, relleno 10). --cols lo fija el JS segun el
   tamano real; se llena por filas, la mas reciente arriba a la izquierda. */
.mapwrap.con-rostros #mapPanel{visibility:hidden}
.mapwrap.con-rostros .mapa-pop{display:none}
/* Con la rejilla, los indicadores del mapa van en una franja encima (bloque C, 2026-10-16), cada uno en una linea;
   siempre en dos filas de dos (en una sola, a 1366 o 1600 px, se cortaban «Coincidencias» y «Cámaras activas»). La rejilla
   empieza donde acaba la franja (views.js fija su top con la altura real) y rejillaRostros mide el alto que queda. El
   boton de otra ventana ya esta en la barra. */
.mapwrap.con-rostros .map-stats{top:0;left:0;right:0;transform:none;width:auto;max-width:none;min-height:46px;box-sizing:border-box;flex-wrap:wrap;justify-content:space-evenly;align-content:center;gap:4px 0;padding:8px 12px;border-radius:var(--radius) var(--radius) 0 0;background:var(--surface);box-shadow:none;backdrop-filter:none;z-index:2}
.mapwrap.con-rostros .map-stats .s{display:flex;align-items:baseline;gap:6px;white-space:nowrap;padding:0 10px}
.mapwrap.con-rostros .map-stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));justify-items:center}
.mapwrap.con-rostros .map-stats .s + .s{padding-left:10px;border-left:0}
.mapwrap.con-rostros .map-stats .s:nth-child(2n){border-left:1px solid rgba(255,255,255,.12);justify-self:stretch;justify-content:center}
.mapwrap.con-rostros .map-stats .s:nth-child(2n+1){justify-self:stretch;justify-content:center}
.mapwrap.con-rostros .map-stats .s b{font-size:16px;display:inline}
.mapwrap.con-rostros .map-stats .s span{font-size:12px;letter-spacing:.02em}
:root[data-theme="light"] .mapwrap.con-rostros .map-stats{background:var(--surface);box-shadow:none}
.mapwrap.con-rostros .facegrid{top:46px;border-radius:0 0 var(--radius) var(--radius)} /* top: la altura real de la franja (views.js) */
.facegrid{position:absolute;inset:0;z-index:1;display:grid;grid-template-columns:repeat(var(--cols,3),106px);grid-auto-rows:144px;gap:10px;padding:10px;justify-content:center;align-content:start;overflow-x:hidden;overflow-y:auto;background:#1E2227;border-radius:var(--radius);box-sizing:border-box}
.facegrid::-webkit-scrollbar{width:6px}
.facegrid .fc{width:106px;height:144px;box-sizing:border-box;overflow:hidden;text-align:center;cursor:pointer;border-radius:8px;padding:3px}
.facegrid .fc:hover{outline:2px solid #fff;outline-offset:-1px}
.facegrid .fc img,.facegrid .fc .fc-vacia{width:100px;height:100px;object-fit:cover;border-radius:6px;background:#111;display:block;margin:0 auto}
.facegrid .fc .fc-vacia{font-size:12px;color:#94a3b8;line-height:100px}
.facegrid .fc.alarma{box-shadow:0 0 0 2px #E5484D} .facegrid .fc.aviso{box-shadow:0 0 0 2px #E0A030}
.facegrid .fc .q{font-size:12px;color:#fff;font-weight:700;margin-top:4px;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.facegrid .fc .t{font-size:12px;color:#cbd5e1;margin-top:2px;line-height:1.3;font-variant-numeric:tabular-nums}
/* Placa del diseno (placaSVG): un solo dibujo para la tira, la miniatura, la ficha, la alerta y la tripulacion; cada
   sitio fija solo el alto. Color del vehiculo en --f/--t (colorFicha). */
.placa-lpr{display:block;height:34px;width:auto;max-width:100%;aspect-ratio:107.05/56.21;flex:none;font-family:'Placa CO Digitos','License Plate','Placa LPR',var(--font);font-weight:400}
/* En las tablas (placaTabla): el dibujo centrado y el numero debajo en la fuente normal. La celda es .placa-celda y no
   .placa (la pastilla de la ficha, con fondo y borde: encajonaba el dibujo, 2026-10-15). */
.placa-lpr.tbl{display:block;height:32px;margin:0 auto}
.alerts-tbl td.placa-celda{white-space:nowrap;text-align:center;padding-top:5px;padding-bottom:4px}
.placa-celda .placa-txt{display:block;font-family:var(--font);font-size:12px;font-weight:600;letter-spacing:.08em;color:var(--text-2);margin-top:2px;line-height:1.1}
/* Evidencia por evento: la fila desplegada no es la cuadricula de la alerta sino miniaturas + piezas + acciones. */
.alerts-tbl .det.ev-det{display:block}
.ev-minis{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 10px} .ev-minis:empty{display:none}
.ev-minis img{height:96px;width:auto;max-width:220px;object-fit:contain;background:#000;border-radius:8px;border:1px solid var(--border);cursor:pointer}
.ev-piezas td,.ev-piezas th{font-size:12.5px}
/* Sistema: tablas de lectura (engines, avisos del equipo) alineadas a la izquierda como el resto de la tarjeta; un aviso
   atendido se atenua; el contador de repeticiones es una pastilla pequena junto al titulo. */
.alerts-tbl.tbl-izq td{text-align:left}
.alerts-tbl tr.aviso-ok td{opacity:.55}
.pill.aviso-n{font-family:var(--mono);font-size:12px;padding:1px 7px;vertical-align:middle}
.platestrip .pc .placa-lpr{cursor:pointer;border-radius:4px}
.platestrip .pc .placa-lpr:hover{filter:brightness(1.12);outline:2px solid #fff;outline-offset:1px}
/* Alarma: marco rojo alrededor de la celda (placa + hora). padding y margen negativo iguales: el espaciado no cambia. */
.platestrip .pc.alarma,.platestrip .pc.aviso{border-radius:10px;padding:3px 4px 2px;margin:-3px -4px -2px}
.platestrip .pc.alarma{box-shadow:0 0 0 2px #E5484D} .platestrip .pc.aviso{box-shadow:0 0 0 2px #E0A030} /* borde sin resplandor */
.platestrip .pc .t{font-size:12px;color:#cbd5e1;margin-top:3px}
.mapwrap{position:relative;height:64vh}
#mapPanel{width:100%;height:64vh;border-radius:var(--radius)}
#mapFull{width:100%;height:72vh;border-radius:var(--radius);border:1px solid var(--border)}
.leaflet-container{background:#0b1220;font-family:var(--font)}
.syncpill{font-size:12px;font-weight:700;padding:2px 8px;border-radius:999px}
.syncpill.ok{background:rgba(76,175,80,.18);color:#81C784} .syncpill.no{background:rgba(255,152,0,.18);color:#FFB74D}

/* KPIs sobrepuestos al mapa (como DiA map dashboard) */
/* Tarjetas del mapa: una sola fila centrada entre el zoom y el boton de ventana (usuario, 2026-10-15: «las tarjetas
   están recortadas»). Antes se centraban descontando un panel lateral de 340 px que ya no existe y quedaban en ~200 px
   con barra. */
.map-stats{position:absolute;top:12px;left:50%;transform:translateX(-50%);width:max-content;max-width:calc(100% - 100px);z-index:500;display:flex;flex-wrap:nowrap;gap:18px;align-items:center;background:rgba(17,17,17,.82);backdrop-filter:blur(6px);padding:9px 20px;border-radius:12px;box-shadow:var(--shadow-lg)}
:root[data-theme="light"] .map-stats{background:rgba(255,255,255,.9)}
.map-stats .s{text-align:center;line-height:1.1;padding:0 4px;position:relative}
.map-stats .s + .s{border-left:1px solid rgba(255,255,255,.12);padding-left:18px} .map-stats .s b{font-size:20px;font-weight:800;display:block} .map-stats .s span{font-size:12px;color:var(--text-2);text-transform:uppercase;letter-spacing:.04em}
.map-stats .s.ev b{color:var(--text)} .map-stats .s.al b{color:var(--warning)} .map-stats .s.cam b{color:var(--success)}

/* Selector de temas de mapa (estilo DiA MapDashboard) — sin carto, sin bordes */
.mapthemes{position:absolute;bottom:12px;left:12px;z-index:670;display:flex;flex-direction:row;align-items:flex-end} /* el panel se abre a la derecha del boton: hacia arriba lo tapaba el de capas */
.mapthemes .tbtn{width:38px;height:38px;border-radius:9px;background:rgba(17,17,17,.85);color:var(--primary);border:none;cursor:pointer;font-size:17px;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-lg);backdrop-filter:blur(6px)}
.mapthemes .tbtn:hover{background:var(--primary);color:var(--on-fill)}
.mapthemes .tpanel{margin-left:8px;background:rgba(17,17,17,.94);border-radius:10px;padding:6px;display:none;backdrop-filter:blur(8px);box-shadow:var(--shadow-lg);min-width:132px}
.mapthemes .tpanel.show{display:block}
.mapthemes .topt{display:block;width:100%;background:none;border:none;color:#e5e7eb;padding:8px 12px;text-align:left;cursor:pointer;border-radius:7px;font-size:12.5px;font-family:var(--font)}
.mapthemes .topt:hover{background:rgba(255,255,255,.09)} .mapthemes .topt.active{background:var(--primary);color:var(--on-fill);font-weight:700}
/* Mapa base sin internet (views.js, mapaBase): el fondo del contenedor es el del tema mientras llegan las teselas,
   la atribucion (obligatoria, ODbL) en el tono del mapa y el aviso de "mapa no instalado" abajo al centro: arriba esta
   la barra de cifras del mapa. */
.leaflet-container.mapa-oscuro{background:#15181C} .leaflet-container.mapa-claro{background:#E4E7EA}
.mapa-oscuro .leaflet-control-attribution{background:rgba(21,24,28,.82);color:#8A9099}
.mapa-claro .leaflet-control-attribution{background:rgba(255,255,255,.82);color:#5E646C}
.leaflet-control-attribution{font-size:12px}
.mapa-aviso{position:absolute;bottom:34px;left:50%;transform:translateX(-50%);z-index:640;max-width:calc(100% - 32px);
  padding:6px 12px;border-radius:8px;background:var(--surface);color:var(--text-2);border:1px solid var(--border);
  font-size:12.5px;line-height:1.35;text-align:center;pointer-events:none;box-shadow:var(--shadow-lg)}
.leaflet-control-zoom a{background:rgba(17,17,17,.85)!important;color:#e5e7eb!important;border:none!important}

/* fila inferior del panel: alertas + mensajería */
.panel-bottom{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;margin-top:16px}
.panel-bottom.solo{grid-template-columns:1fr} /* "Sin video": las alertas suben al bloque principal */
.card.tall{height:64vh;display:flex;flex-direction:column;min-height:0} .card.tall>#palertas{flex:1;min-height:0;overflow:auto} /* alertas a toda la altura del video */
@media(max-width:1100px){.panel-bottom{grid-template-columns:1fr}}
.msg{display:flex;gap:10px;padding:11px;border-radius:10px;background:var(--surface-2);margin-bottom:9px}
.msg .ico{width:34px;height:34px;border-radius:9px;background:color-mix(in srgb,var(--primary) 18%,transparent);color:var(--primary);display:flex;align-items:center;justify-content:center;flex:0 0 34px}
.msg .dot{flex:0 0 10px;width:10px;height:10px;border-radius:50%;margin-top:5px;background:var(--info);box-shadow:0 0 0 3px color-mix(in srgb,var(--info) 22%,transparent)} /* prioridad del mensaje */
.msg .dot.warn{background:var(--warning);box-shadow:0 0 0 3px color-mix(in srgb,var(--warning) 22%,transparent)} .msg .dot.bad{background:var(--error);box-shadow:0 0 0 3px color-mix(in srgb,var(--error) 22%,transparent)}
/* títulos de las tarjetas del panel: Gruppo en el color del texto (el cian queda para lo que se pulsa) */
.card .hd.panel-hd h3{font-family:var(--font-title);font-size:17px;color:var(--text);text-transform:uppercase;letter-spacing:.06em;font-weight:700}
/* tabla de alertas del panel: sync como punto, fecha en dos líneas, ubicación clicable */
.alerts-tbl th{white-space:nowrap} .alerts-tbl.panel td{vertical-align:middle;padding-top:7px;padding-bottom:7px}
.alerts-tbl.panel td.fecha{line-height:1.15;white-space:nowrap} .alerts-tbl.panel td.fecha b{display:block;font-weight:600;color:var(--text);font-variant-numeric:tabular-nums} .alerts-tbl.panel td.fecha small{color:var(--text-2);font-size:12px}
.alerts-tbl .syncdot{display:inline-block;width:8px;height:8px;border-radius:50%;border:1.5px solid var(--text-2);opacity:.5;vertical-align:middle}
.alerts-tbl .syncdot.ok{background:var(--success);border-color:var(--success);opacity:1;box-shadow:0 0 0 3px color-mix(in srgb,var(--success) 20%,transparent)}
.alerts-tbl td.ubic{color:var(--text-2);font-size:12px;font-family:var(--mono);white-space:nowrap}
/* DESCRIPCIÓN de /eventos (requisito 14): una línea con elipsis (texto completo en el title) y se queda con el ancho
   sobrante; TIPO va a su contenido. max-width:0 + width:100% es lo que deja cortar una celda en una tabla automática.
   Solo en escritorio: en el teléfono la fila es una tarjeta y la celda se lee entera. */
.alerts-tbl td.desc{color:var(--text-2)}
@media(min-width:641px){ .alerts-tbl td.desc{max-width:0;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .alerts-tbl.panel td.tipo{white-space:nowrap} }
.alerts-tbl.panel td.ubic.has{color:var(--primary)} .alerts-tbl.panel td.ubic.has:hover,.alerts-tbl.panel td[data-act]:hover,.alerts-tbl.panel td.tipo:hover{text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--primary) 55%,transparent);text-underline-offset:3px}
.msg .ico svg{width:17px;height:17px} .msg .b{flex:1} .msg .b .t{font-weight:700;font-size:13px} .msg .b .x{color:var(--text-2);font-size:12px} .msg .b .h{color:var(--text-2);font-size:12px;margin-top:3px}

/* Acciones de fila (esquema facescan: iconos ghost con color semántico, sin fondo/borde) */
.rowacts{display:inline-flex;align-items:center;justify-content:center;gap:14px}
.iac{background:none;border:none;padding:0;margin:0;cursor:pointer;color:var(--text-2);display:inline-flex;line-height:0;transition:color .12s,filter .12s}
.iac svg{width:20px;height:20px;display:block}
.iac:hover{color:var(--text-3)}
.iac.edit{color:var(--primary)} .iac.edit:hover{filter:brightness(1.28)}
.iac.del{color:var(--error)} .iac.del:hover{filter:brightness(1.28)}
.iac.go{color:var(--success)} .iac.go:hover{filter:brightness(1.28)}
.iac.stop{color:var(--warning)} .iac.stop:hover{filter:brightness(1.28)}
.iac.view{color:var(--text-3)} .iac.view:hover{color:var(--primary)}
.iac[disabled]{color:var(--disabled);cursor:default}

/* Subtítulo de sección (vistas combinadas, p.ej. Cámaras + analítica) */
.secttl{font-size:19px;font-weight:600;color:var(--text);margin:30px 0 8px}

/* Analítica: lista compacta (dentro de una card, sin recuadros por módulo) */
.analist{display:flex;flex-direction:column}
.ali{display:flex;align-items:center;gap:16px;padding:13px 4px}
.ali + .ali{border-top:1px solid rgba(255,255,255,.055)}
.alx{flex:1;min-width:0}
.aln{font-size:14px;font-weight:600;color:var(--text)}
.ald{font-size:12.5px;color:var(--text-2);margin-top:2px}
.alr{display:flex;align-items:center;gap:18px;flex:0 0 auto}
.linkbtn{background:none;border:none;padding:0;cursor:pointer;color:var(--primary);font-size:13px;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.linkbtn svg{width:16px;height:16px}
.linkbtn:hover{filter:brightness(1.2)}
[data-theme="light"] .ali + .ali{border-top-color:rgba(0,0,0,.07)}

/* Barra de filtros homogénea (eventos / alertas) — estilo facescan, alineada a la derecha.
   Todos los controles a la MISMA altura (--fh). */
:root{--fh:42px}
.filters{display:flex;flex-direction:column;align-items:stretch;gap:10px;margin:0 0 16px}
.frow{display:flex;align-items:center;justify-content:flex-end;gap:10px;flex-wrap:wrap}
.filters input,.filters select{height:var(--fh);box-sizing:border-box}
.filters select{width:auto;min-width:150px}
.searchbox{position:relative;display:inline-flex;align-items:center}
.searchbox svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--text-2);pointer-events:none}
.searchbox input{padding-left:34px;width:210px}
.searchbox.sm input{width:130px}
/* Selectores NATIVOS (calendario de datetime-local, listas de <select>): el navegador los pinta según
   color-scheme; se alinean al tema (oscuro/claro) y al azul del proyecto (accent-color). Sin esto salían blancos. */
:root{color-scheme:dark;accent-color:var(--primary)}
:root[data-theme="light"]{color-scheme:light}
.filters .dt{width:auto;min-width:186px;font-family:var(--font);color:var(--text)}
.filters .dt:focus,.filters select:focus{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--primary) 45%,transparent)}
.filters .dt::-webkit-calendar-picker-indicator{filter:invert(.7);cursor:pointer;opacity:.6}
.filters .dt::-webkit-calendar-picker-indicator:hover{opacity:1}
/* Barra de filtros unica (barraFiltrosHTML, bloque C 2026-10-16): arriba a la derecha el rango y las dos fechas, a la
   misma altura; debajo, buscador y selectores se reparten TODO el ancho (el buscador pesa el doble), sin huecos. */
.frow.f-fechas{justify-content:flex-end}
.filters .daterange{height:var(--fh)}
.f-fecha{display:inline-flex;align-items:center;gap:8px;margin:0;font-weight:400;font-size:12.5px;color:var(--text-2);white-space:nowrap} .f-fecha .dt{flex:1 1 auto;min-width:150px}
.frow.f-campos{justify-content:stretch}
.frow.f-campos>*{flex:1 1 170px;min-width:0;max-width:none}
.frow.f-campos>.searchbox{flex:2 1 260px}
.frow.f-campos select,.frow.f-campos .searchbox input,.frow.f-campos>.dt{width:100%;min-width:0}
.frow.f-campos>.chk,.frow.f-campos>.btn{flex:0 0 auto}

/* Botones rápidos de rango de fecha (segmentado) */
.daterange{display:inline-flex;align-items:stretch;background:linear-gradient(160deg,color-mix(in srgb,var(--surface-2) 92%,transparent),color-mix(in srgb,var(--surface-2) 70%,transparent));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 0 0 1px rgba(255,255,255,.04) inset;border-radius:var(--radius-sm);padding:3px;gap:2px;height:32px;box-sizing:border-box}
.daterange button{display:inline-flex;align-items:center;background:none;border:none;color:var(--text-2);font-size:12px;padding:0 10px;border-radius:6px;cursor:pointer;white-space:nowrap;transition:background .12s,color .12s}
.daterange button:hover{color:var(--text)}
.daterange button.active{background:var(--primary);color:var(--on-fill)}

/* Tabs internos (Sistema) */
.tabbar{display:flex;gap:4px;margin:0 0 18px;border-bottom:1px solid var(--border);flex-wrap:wrap}
.tabbar .tab{background:none;border:none;color:var(--text-2);font-size:14px;font-weight:600;padding:10px 16px;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .12s,border-color .12s}
.tabbar .tab:hover{color:var(--text)}
.tabbar .tab.active{color:var(--primary);border-bottom-color:var(--primary)}
/* Sistema (2026-10-23): 12 pestanas en una fila; si no caben, se desplazan de lado en vez de partirse en dos filas */
.tabbar.compacta{flex-wrap:nowrap;gap:0;overflow-x:auto;scrollbar-width:none} .tabbar.compacta::-webkit-scrollbar{display:none}
.tabbar.compacta .tab{padding:10px 12px;white-space:nowrap;flex:0 0 auto}
/* Dentro de una pestana de Sistema la pestana ya dice el nombre: sin el titulo grande; la cabecera queda solo si trae botones */
#sysTab .pagehead h2{display:none} #sysTab .pagehead:not(:has(.btn)){display:none}
/* Formularios de ajustes en rejilla: grupos con subtitulo, campos de 280 px o mas */
.camposgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:0 16px} .camposgrid.c4{grid-template-columns:repeat(auto-fill,minmax(220px,1fr))} .camposgrid.c2{grid-template-columns:repeat(auto-fill,minmax(380px,1fr))} .camposgrid label{margin-top:12px}
.radios{display:flex;gap:24px;flex-wrap:wrap} .radios label{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;white-space:nowrap;font-size:14px;color:var(--text)}
.radios input[type=radio]{width:auto;margin:0;accent-color:var(--primary)}
.grupottl{font-size:13px;font-weight:700;color:var(--text);margin:6px 0 0} .grupottl~.grupottl{margin-top:22px}

/* Matriz de permisos (RBAC) */
.permmx{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-top:8px}
.permgrp{background:var(--surface-2);border-radius:var(--radius-sm);padding:12px 14px}
.permgrp .pgh{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-2);margin-bottom:8px}
.permit{display:flex;align-items:center;gap:9px;padding:5px 0;font-size:13.5px;color:var(--text);cursor:pointer}
.permit input{width:16px;height:16px;flex:0 0 16px;accent-color:var(--primary);cursor:pointer}

/* Fase F — mapa: marcadores por estado, control de capas, tarjetas sobre el mapa */
#mapFull{height:calc(100vh - var(--nav) - 88px);min-height:420px}
.gpspin span{display:block;width:14px;height:14px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 2px rgba(0,0,0,.35)}
.maplayers{position:absolute;bottom:58px;left:12px;z-index:660;display:flex;flex-direction:column-reverse}
.maplayers .mlbtn{width:38px;height:38px;border-radius:9px;background:rgba(17,17,17,.85);color:var(--primary);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-lg);backdrop-filter:blur(6px)}
.maplayers .mlbtn:hover{background:var(--primary);color:var(--on-fill)}
.maplayers .mlbtn svg{width:19px;height:19px}
.maplayers .mlpanel{margin-bottom:8px;background:rgba(17,17,17,.94);border-radius:10px;padding:9px 12px;display:none;flex-direction:column;gap:5px;min-width:140px;backdrop-filter:blur(8px);box-shadow:var(--shadow-lg)}
.maplayers .mlpanel.show{display:flex}
.maplayers .mlh{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--text-2);font-weight:700;margin-bottom:2px}
.maplayers label{display:flex;align-items:center;gap:8px;font-size:12.5px;color:#e5e7eb;cursor:pointer}
.maplayers label input{width:15px;height:15px;accent-color:var(--primary);margin:0}
[data-theme="light"] .maplayers .mlbtn{background:rgba(255,255,255,.9)} [data-theme="light"] .maplayers .mlpanel{background:rgba(255,255,255,.95)} [data-theme="light"] .maplayers label{color:#111}

/* ===== Toasts (avisos): apilados abajo a la derecha, con icono por tipo, entrada suave y cierre al clic ===== */
#toastHost{position:fixed;right:16px;top:calc(var(--nav) + 10px);z-index:4000;display:flex;flex-direction:column;gap:10px;align-items:flex-end;pointer-events:none;max-width:min(420px,calc(100vw - 32px))}
.toast{pointer-events:auto;display:flex;align-items:center;gap:12px;padding:12px 16px 12px 12px;border-radius:14px;border:none;color:var(--text);font-size:13px;font-weight:500;line-height:1.35;max-width:100%;cursor:pointer;
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 92%,transparent) 0%,color-mix(in srgb,var(--surface) 72%,transparent) 100%);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3);
  box-shadow:0 14px 36px rgba(0,0,0,.4),0 0 0 1px rgba(255,255,255,.04) inset;animation:toast-in .22s cubic-bezier(.2,.8,.2,1)}
:root[data-theme="light"] .toast{box-shadow:0 14px 36px rgba(16,24,40,.16),0 0 0 1px rgba(255,255,255,.6) inset}
.toast .ic{flex:0 0 30px;width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff}
.toast .ic svg{width:16px;height:16px;stroke:#fff} .toast.ok .ic svg,.toast.warn .ic svg,.toast.info .ic svg{stroke:#14181C} /* trazo oscuro sobre los rellenos claros */
.toast .tx{flex:1;min-width:0;overflow-wrap:anywhere}
.toast{font-family:var(--font)} /* Montserrat en el cuerpo del aviso */
.toast .tt{display:block;font-family:var(--font-title);font-size:14px;font-weight:400;letter-spacing:.08em;text-transform:uppercase;color:var(--text);margin-bottom:1px;line-height:1.2} /* Gruppo en el título */
.toast .tx{font-size:13px;color:var(--text-2)}
.toast.ok .ic{background:var(--success)} .toast.warn .ic{background:var(--warning)} .toast.bad .ic{background:var(--error)} .toast.info .ic{background:var(--info)}
.toast.ok{background-image:linear-gradient(160deg,color-mix(in srgb,var(--success) 16%,color-mix(in srgb,var(--surface) 92%,transparent)),color-mix(in srgb,var(--surface) 72%,transparent))}
.toast.warn{background-image:linear-gradient(160deg,color-mix(in srgb,var(--warning) 16%,color-mix(in srgb,var(--surface) 92%,transparent)),color-mix(in srgb,var(--surface) 72%,transparent))}
.toast.bad{background-image:linear-gradient(160deg,color-mix(in srgb,var(--error) 18%,color-mix(in srgb,var(--surface) 92%,transparent)),color-mix(in srgb,var(--surface) 72%,transparent))}
.toast.info{background-image:linear-gradient(160deg,color-mix(in srgb,var(--info) 16%,color-mix(in srgb,var(--surface) 92%,transparent)),color-mix(in srgb,var(--surface) 72%,transparent))}
.toast .bar{position:absolute;left:14px;right:14px;bottom:0;height:2px;border-radius:2px;background:transparent;overflow:hidden}
.toast .bar i{display:block;height:100%;width:100%;background:currentColor;transform-origin:left;animation:toast-bar linear forwards}
.toast{position:relative} .toast.ok .bar i{color:var(--success)} .toast.warn .bar i{color:var(--warning)} .toast.bad .bar i{color:var(--error)} .toast.info .bar i{color:var(--info)}
.toast.out{animation:toast-out .18s ease-in forwards}
@keyframes toast-in{from{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:none}}
@keyframes toast-out{to{opacity:0;transform:translateY(-6px)}}
@keyframes toast-bar{from{transform:scaleX(1)}to{transform:scaleX(0)}}

/* ===== Mapa: popups y paneles en VIDRIO (mismo lenguaje que modales, toasts y tarjeta de usuario) ===== */
.leaflet-popup-content-wrapper{border:none;border-radius:14px;color:var(--text);padding:0;
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 92%,transparent) 0%,color-mix(in srgb,var(--surface) 72%,transparent) 100%);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3);
  box-shadow:0 18px 44px rgba(0,0,0,.45),0 0 0 1px rgba(255,255,255,.05) inset}
:root[data-theme="light"] .leaflet-popup-content-wrapper{box-shadow:0 18px 44px rgba(16,24,40,.18),0 0 0 1px rgba(255,255,255,.6) inset}
.leaflet-popup-content{margin:0;padding:14px 16px;font-family:var(--font);font-size:13px;line-height:1.4;min-width:210px}
.leaflet-popup-tip{background:color-mix(in srgb,var(--surface) 90%,transparent);box-shadow:none}
.leaflet-popup-close-button{color:var(--text-2)!important;font-size:18px!important;padding:6px 8px 0 0!important;font-family:var(--font)}
.leaflet-popup-close-button:hover{color:var(--text)!important}
.mpop .mt{font-family:var(--font-title);font-size:17px;letter-spacing:.06em;color:var(--text);text-transform:uppercase;line-height:1.1;padding-right:14px}
.mpop .mt.mono{font-family:var(--mono);letter-spacing:.02em;text-transform:none;font-weight:800;font-size:19px}
.mpop .ms{display:flex;align-items:center;gap:6px;margin-top:8px;flex-wrap:wrap}
.mpop .mx{color:var(--text-2);font-size:12px;margin-top:8px} .mpop .mx b{color:var(--text-3);font-weight:600}
.mpop .ma{margin-top:12px;display:flex;gap:8px}
/* paneles flotantes del mapa (KPIs, tema, capas) con el mismo vidrio */
.map-stats,.mapthemes .tpanel,.maplayers .mlpanel{border:none;
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 92%,transparent) 0%,color-mix(in srgb,var(--surface) 70%,transparent) 100%);
  -webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3);
  box-shadow:0 14px 36px rgba(0,0,0,.4),0 0 0 1px rgba(255,255,255,.05) inset}
:root[data-theme="light"] .map-stats,:root[data-theme="light"] .mapthemes .tpanel,:root[data-theme="light"] .maplayers .mlpanel{box-shadow:0 14px 36px rgba(16,24,40,.16),0 0 0 1px rgba(255,255,255,.6) inset}
.mapthemes .topt,.maplayers label{color:var(--text)} :root[data-theme="light"] .map-stats .s + .s{border-left-color:rgba(0,0,0,.08)}
.mapthemes .tbtn,.maplayers .mlbtn{background:color-mix(in srgb,var(--surface) 88%,transparent);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}

/* ===== /sistema > Sistema: KPIs con medidor y tablas clave-valor ===== */
.kpi.sys{text-align:center;padding:18px 20px}
.sysana{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px} .sysana .chip{margin:0;font-size:12px;padding:2px 8px;cursor:default} .kpi.sys .v{font-size:30px} .kpi.sys .sub{font-size:12px;color:var(--text-2);margin-top:7px}
.sbar{height:6px;background:var(--surface-2);border-radius:4px;overflow:hidden;margin-top:10px} .sbar i{display:block;height:100%;border-radius:4px;background:var(--primary);transition:width .3s}
table.kv td{padding:9px 6px;border-top:1px solid var(--border);vertical-align:top;text-align:left} table.kv tr:first-child td{border-top:none}
table.kv td:first-child{color:var(--text-2);width:40%;font-size:12px;text-transform:uppercase;letter-spacing:.04em;font-weight:600}
.sysgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;align-items:start} @media(max-width:1000px){.sysgrid{grid-template-columns:1fr}}

/* ===== /panel: marcador de placa sobre el video (canvas + miniatura + botón), sutil para no estorbar al operador ===== */
.pov{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:400}
.povbtn{position:absolute;top:10px;left:10px;z-index:500;width:36px;height:36px;border-radius:9px;border:none;cursor:pointer;color:#cbd5e1;background:rgba(0,0,0,.55);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center}
.povbtn:hover{color:#fff} .povbtn.on{color:var(--primary);box-shadow:0 0 0 1px color-mix(in srgb,var(--primary) 70%,transparent) inset}
.povbtn svg{width:18px;height:18px}
/* Marca deteccion como UN control: boton con el modo elegido + menu al lado (2026-09-25) */
.povsel{position:absolute;top:10px;left:10px;z-index:500} .povsel[hidden]{display:none} .povsel .povbtn{position:static}
/* Solo el icono (usuario, 2026-09-25: interfaz limpia); el nombre del modo se ve en el menu al pulsar y en el titulo del boton */
.povbtn.wide{width:36px;height:36px;padding:0;display:inline-flex;align-items:center;justify-content:center;color:#cbd5e1} .povbtn.wide.on{color:var(--primary)}
.povbtn.wide #povLbl,.povbtn.wide .caret{display:none}
.povmenu{position:absolute;top:40px;left:0;background:rgba(0,0,0,.88);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,.14);border-radius:10px;padding:4px;min-width:200px;display:flex;flex-direction:column;gap:2px;box-shadow:0 12px 30px rgba(0,0,0,.5)}
.povmenu .povtit{font-size:12px;color:#9CA3AF;text-transform:uppercase;letter-spacing:.05em;padding:6px 10px 2px}
.povmenu[hidden]{display:none} .povmenu button{background:transparent;border:none;color:#e5e7eb;text-align:left;padding:8px 10px;border-radius:7px;font-size:13px;cursor:pointer}
.povmenu button:hover{background:rgba(255,255,255,.1)} .povmenu button.on{color:var(--primary);font-weight:700}
/* Miniatura del evento sobre el video (2026-09-25): fondo solido, recorte con borde y la placa como ficha de 24 px
   CENTRADA con el color del vehiculo como relleno (colorFicha; sin color, azul del proyecto; alerta: borde rojo). La version anterior -letra blanca de 15 px sobre degradado
   translucido- se veia bonita y se leia con esfuerzo. Mock aprobado: evaluacion/modal/mock_marca_propuesta.png */
.pthumb{position:absolute;top:54px;left:10px;z-index:450;pointer-events:none;background:rgba(0,0,0,.78);border:1px solid rgba(255,255,255,.18);border-radius:10px;padding:6px;display:flex;flex-direction:column;align-items:center;gap:5px;opacity:0;transition:opacity .25s;max-width:200px}
.pthumb.show{opacity:1} .pthumb img{width:186px;height:auto;max-height:84px;object-fit:contain;border-radius:6px;display:block;background:transparent;border:1px solid rgba(255,255,255,.25)}
.pthumb .pl{--f:#00AEEF;--t:#fff;font-family:var(--mono);font-weight:900;font-size:24px;letter-spacing:.08em;line-height:1.1;text-align:center;color:var(--t);background:var(--f);border:2px solid rgba(0,0,0,.6);border-radius:6px;padding:3px 8px;width:100%;box-sizing:border-box}
.pthumb .pl.oscuro{border-color:rgba(255,255,255,.55)}
.pthumb .pl.tipo{font-family:var(--font-title);font-size:14px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#fff;background:rgba(229,72,77,.92);border:0;border-radius:8px;padding:6px 10px;box-shadow:none}
.pthumb .pl.conplaca{background:none;border:0;padding:0;border-radius:12px} .pthumb .pl .placa-lpr{height:auto;width:186px} /* con placa: el dibujo entero; el borde rojo de .hit lo rodea */
.pthumb .pl.hit{box-shadow:0 0 0 3px #E5484D;animation:af-blink 1.2s steps(2) 3} /* alerta: conserva el color del carro y el borde rojo la marca */
.pthumb .pm{font-size:12px;color:#e5e7eb;text-align:center;font-family:var(--mono);width:100%}

/* ===== Alerta a pantalla completa: tarjeta operativa en vidrio. Título centrado · fila: texto (placa, cámara, hora, lista, nota) con el
   recorte de la placa JUSTO al lado · rostros (si hay) · escena completa · botones centrados. Tamaños en vh: cabe sin scroll. ===== */
#alertaFull{padding:16px}
/* Superficie opaca y oscura en los dos temas (texto #D4D7DC fijo, no el token): sin vidrio, que dejaba ver la tabla debajo. */
.acard{width:min(900px,100%);max-height:calc(100vh - 32px);overflow:hidden;border-radius:20px;padding:18px 26px 20px;color:#D4D7DC;text-align:left;display:flex;flex-direction:column;
  background:#1E2227;box-shadow:0 20px 50px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.06) inset;animation:toast-in .2s cubic-bezier(.2,.8,.2,1)}
.acard.crit{box-shadow:0 20px 50px rgba(0,0,0,.5),0 0 0 2px #E5484D inset}
.acard .big{text-align:center;font-size:min(4vw,3.4vh,30px);font-weight:900;color:#FF6B6B;line-height:1.1;font-family:var(--font-title);letter-spacing:.12em;margin-bottom:1.4vh}
/* El parpadeo de la alerta critica: 3 ciclos y queda fijo (antes infinito). */
.acard.crit .big{animation:af-blink 1.2s steps(2) 3} @keyframes af-blink{50%{opacity:.5}}
.acard .pend{font-family:var(--font);font-size:13px;font-weight:700;color:#FFB74D;vertical-align:middle;margin-left:8px;letter-spacing:0}
.acard .ar1{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:16px 24px;flex:none}
.acard .at{min-width:0}
/* CABECERA FIJA: la placa a la izquierda y el recorte a la derecha con TAMANO FIJO, pase lo que pase con el texto.
   Antes .ar1 era un flex con wrap: una nota larga (las de la Lista Situacional traen 300-700 caracteres) ensanchaba la
   columna de texto, el recorte caia debajo y se estiraba al ancho, borroso; la escena se aplastaba y los botones
   quedaban encima (medido el 2026-09-25 con los eventos de la noche anterior, evaluacion/modal/). Ahora: la nota vive
   en .abody, que es lo unico que hace scroll; la escena tiene alto fijo y los botones no se mueven. */
.acard .aplaca{height:min(13vw,10.4vh,90px)} /* placa del diseno; antes texto mono de hasta 48 px */
.acard .kv{display:grid;grid-template-columns:auto 1fr;gap:.5vh 16px;font-size:min(15px,1.9vh);align-items:baseline}
.acard .kv div:nth-child(odd){color:#A1A7AF;text-transform:uppercase;font-size:12px;letter-spacing:.05em}
.acard .acrop{width:min(260px,38vw);height:min(120px,17vw);flex:none} .acard .acrop[hidden]{display:none} .acard .acrop img{width:100%;height:100%;object-fit:contain;border-radius:10px;background:transparent;display:block}
.acard .abody{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;margin-top:1vh;padding-right:4px}
.acard .abody .kv div:nth-child(even){overflow-wrap:anywhere;min-width:0}
.acard .arf{display:flex;gap:10px;align-items:center;justify-content:center;flex-wrap:wrap;margin-top:1.4vh} .acard .arf[hidden]{display:none}
.acard .arf .lbl{width:100%;text-align:center;color:#A1A7AF;text-transform:uppercase;font-size:12px;letter-spacing:.05em;margin-bottom:-2px}
.acard .arf figure{margin:0;display:flex;flex-direction:column;align-items:center;gap:3px}
.acard .arf img{height:min(72px,9vh);width:auto;border-radius:9px;background:#000;display:block;box-shadow:0 0 0 1px rgba(255,255,255,.12)}
.acard .arf figcaption{font-family:var(--mono);font-size:12px;color:#CBD5E1;letter-spacing:.04em}
.acard .ascene{margin-top:1.4vh;flex:none} .acard .ascene[hidden]{display:none} .acard .ascene img{width:100%;height:min(320px,36vh);object-fit:contain;border-radius:12px;background:transparent;display:block}
.acard .af{display:flex;gap:12px;margin-top:1.8vh;flex-wrap:wrap;justify-content:center;flex:none} .acard .af .btn{font-size:15px;padding:10px 22px}
.acard .af .btn:not(.danger):not(.ok):not(.warn):not(.primary){background:rgba(255,255,255,.1);color:#D4D7DC}
.acard .kbd{font-size:15px;opacity:.7;margin-left:8px;line-height:1;padding:0 5px;font-family:var(--mono)}
/* chips de selección (conectores por tipo) */
.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:999px;background:var(--surface-2);color:var(--text-2);margin:2px 5px 2px 0;cursor:pointer;font-size:12px;font-weight:600;white-space:nowrap}
.chip input{display:none} .chip.on{background:color-mix(in srgb,var(--primary) 22%,transparent);color:var(--primary)} .chip.off{opacity:.55;text-decoration:line-through}

/* ===== MÓVIL (<= 860 px): solo ajustes de esta vista; el escritorio no cambia ===== */
.mobback{display:none}
@media(max-width:860px){
  .layout.mobopen .mobback{display:block;position:fixed;inset:var(--nav) 0 0 0;background:rgba(0,0,0,.5);z-index:45}
  .sidebar{box-shadow:0 0 40px rgba(0,0,0,.6)}
  .pagehead{flex-wrap:wrap;gap:8px 12px;align-items:center} .pagehead h2{font-size:22px} .pagehead>div[style*="flex:1"]{display:none} .pagehead .btn{padding:8px 12px;font-size:13px}
  /* panel: video y mapa a una altura que deje ver alertas sin desplazarse tanto */
  .videowrap{height:34vh;min-height:220px} .mapwrap,#mapPanel{height:36vh;min-height:220px}
  .map-stats{gap:10px;padding:6px 10px;top:8px;left:50%;max-width:calc(100% - 16px);box-sizing:border-box} .map-stats .s + .s{padding-left:10px}
  .map-stats .s b{font-size:15px} .map-stats .s span{font-size:12px;letter-spacing:0}
  .platestrip{padding:16px 10px 8px;gap:8px} .platestrip .pc .placa-lpr{height:28px}
  .povbtn{width:32px;height:32px} .povbtn.wide{width:32px;height:32px} .povmenu{top:36px} .pthumb{top:48px;max-width:150px} .pthumb img{width:136px} .pthumb .pl{font-size:19px} .pthumb .pl .placa-lpr{width:136px}
  /* tablas (2026-10-23): el texto se parte para que la tabla quepa en la tablet; antes, una linea por celda dejaba las
     ultimas columnas fuera de la pantalla. Lo que no debe partirse (rotulos, placas, horas) sigue en una linea */
  .alerts-tbl td,.alerts-tbl th{white-space:normal;padding:8px 8px;font-size:12.5px}
  .alerts-tbl td .pill,.alerts-tbl td .chip,.alerts-tbl td .placa-lpr,.alerts-tbl td.mono-cell{white-space:nowrap}
  table.analiticas td:nth-child(2),table.analiticas th:nth-child(2){display:none}
  .card .hd{padding:12px 14px} .card .bd{padding:14px}
  .tabbar .tab{padding:8px 10px;font-size:13px}
  .kpi{padding:16px 16px} .kpi .v{font-size:28px}
  .acard{padding:16px 14px} .acard .ar1{gap:10px 14px}
}

/* ===== TABLET horizontal (861-1200 px): el diseño ya apila video y mapa; alturas y tablas más compactas. Escritorio (>1200) no cambia ===== */
@media(min-width:861px) and (max-width:1200px){
  .videowrap{height:44vh} .mapwrap,#mapPanel{height:40vh}
  .alerts-tbl td,.alerts-tbl th{white-space:nowrap;padding:9px 12px}
  table.analiticas td:nth-child(2){white-space:normal;min-width:260px} /* la descripción sí se parte: que Activa quede a la vista */
  .pagehead h2{font-size:24px}
}

/* Encabezado en móvil/tablet (<=1200 px): mismo carbon que el escritorio, un poco menos de hueco */
@media(max-width:1200px){ .navbar{gap:10px} }

/* icono "i" con explicación emergente (vidrio) */
.tipinfo{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:color-mix(in srgb,var(--primary) 22%,transparent);color:var(--primary);font-family:var(--font);font-size:12px;font-weight:800;font-style:normal;margin-left:6px;cursor:help;position:relative;vertical-align:middle;outline:none}
.tipinfo .tipbox{display:none;position:absolute;left:0;top:22px;z-index:20;width:320px;padding:12px 14px;border-radius:12px;color:var(--text);font-weight:400;font-size:12.5px;line-height:1.45;text-align:left;
  background:linear-gradient(160deg,color-mix(in srgb,var(--surface) 94%,transparent),color-mix(in srgb,var(--surface) 80%,transparent));-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);box-shadow:0 18px 44px rgba(0,0,0,.45),0 0 0 1px rgba(255,255,255,.06) inset}
.tipinfo:hover .tipbox,.tipinfo:focus .tipbox{display:block} .tipinfo .tipbox b{color:var(--primary)}

.acard .afdet{display:flex;gap:8px;align-items:flex-start;margin-top:10px}
.acard .afdet textarea{flex:1;min-height:48px;resize:vertical}

.acard{position:relative}
/* Cerrar la alerta: 40 px a la vista y 48 de AREA TACTIL. Media 34x34 y en la esquina, que en un kiosco
   tactil se falla mucho: 48 es el minimo de Material y supera los 44 de WCAG 2.5.5. El area se amplia con
   un ::after transparente en vez de agrandar el circulo, para no comerse la esquina de la tarjeta.
   touch-action:manipulation quita la espera del doble toque; z-index lo deja por encima pase lo que pase
   con los hermanos, que es un boton que el operador tiene que poder pulsar SIEMPRE. */
.acard .afx{position:absolute;top:10px;right:12px;width:40px;height:40px;border-radius:50%;border:1px solid rgba(255,255,255,.35);background:rgba(0,0,0,.25);color:#fff;font-size:24px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2;touch-action:manipulation;-webkit-tap-highlight-color:transparent}
.acard .afx::after{content:"";position:absolute;inset:-5px;border-radius:50%}
.acard .afx:hover{background:rgba(0,0,0,.45)}
.acard .afx:active{background:rgba(0,0,0,.6);transform:scale(.94)}
.acard .afx:focus-visible{outline:2px solid #fff;outline-offset:2px}
.acard .af{display:flex;flex-wrap:nowrap;gap:10px;align-items:stretch;justify-content:space-between}
.acard .af .btn{flex:1 1 0;text-align:center;justify-content:center;display:inline-flex;align-items:center}
.acard .afdet{flex-direction:column;align-items:stretch}
.acard .afdet .lbl{font-size:14px;opacity:.85;margin-bottom:6px}
.acard .afdet textarea{width:100%;box-sizing:border-box;margin-bottom:8px}
@media (max-width:560px){.acard .af{flex-wrap:wrap}}

.evalbox{position:absolute;left:10px;bottom:10px;z-index:6;background:rgba(0,0,0,.72);color:#fff;border-radius:10px;padding:8px 10px;font-size:12px;max-width:min(560px,80%);pointer-events:auto}
.evalbox .medrow{margin-top:4px} .evalbox b{color:#ffe066}
/* Aforo del video procesado: conteo por linea y sentido hasta el cuadro visible (2026-10-22) */
.aforobox{position:absolute;right:10px;top:52px;z-index:6;font-family:var(--font);background:rgba(0,0,0,.72);color:#fff;border-radius:10px;padding:6px 8px;font-size:12px;min-width:210px;max-width:min(340px,60%);backdrop-filter:blur(4px)}
.aforobox-hd{display:flex;align-items:baseline;gap:6px;width:100%;background:none;border:none;color:#fff;font:inherit;font-weight:600;cursor:pointer;padding:2px 2px}
.aforobox-hd b{font-size:18px;font-variant-numeric:tabular-nums} .aforobox-hd small{color:rgba(255,255,255,.7)} .aforobox-hd .caret{margin-left:auto;color:rgba(255,255,255,.7)}
.aforobox table{width:100%;margin-top:4px;font-size:12px} .aforobox td{padding:3px 2px;border-top:1px solid rgba(255,255,255,.12);color:rgba(255,255,255,.88)}
.aforobox td.n{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums} .aforobox td.n small{color:rgba(255,255,255,.6)}

/* Quien pide menos movimiento al sistema no ve animaciones ni transiciones (latidos, parpadeos, entradas). */
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}

/* Loader de transición entre vistas: centrado (vertical+horizontal) y animado */
@keyframes spin{to{transform:rotate(360deg)}}
.loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;min-height:calc(100vh - var(--nav) - 96px);color:var(--text-2);font-size:14px;animation:fadein .25s ease}
.loading .spin{width:40px;height:40px;border:3px solid var(--border);border-top-color:var(--primary);border-radius:50%;animation:spin .8s linear infinite}
@keyframes fadein{from{opacity:0}to{opacity:1}}

/* Editor de geometría: la escena de la cámara con las líneas de conteo dibujadas encima.
   El canvas va EXACTAMENTE sobre la imagen (mismo rectángulo), porque las coordenadas que se guardan son
   fracciones de ese rectángulo: si se desalinean, la línea se guarda donde no es. */
.geoed{display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start}
.geotabbar{margin-bottom:14px}
.geocnt{display:inline-block;min-width:18px;margin-left:4px;padding:0 6px;border-radius:999px;background:var(--surface-2);color:var(--text-2);font-size:12px}
.geocnt:empty{display:none}
.geohint{margin:8px 2px 0}
.geofila{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:10px;background:var(--surface-2);cursor:pointer;transition:background .12s}
.geofila:hover{background:color-mix(in srgb,var(--primary) 10%,var(--surface-2))}
.geofila>svg{width:16px;height:16px;flex:none;color:var(--text-3);transform:rotate(-90deg)}
.geofila-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.geofila-tx b{font-size:13.5px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.geofila-tx span{font-size:12px;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.geovacio{padding:28px 14px;background:var(--surface-2);border-radius:10px}
/* Alerta en COLUMNA (2026-09-25): ocupa el sitio del mapa en el panel mientras esta abierta; el video sigue entero
   con el vehiculo resaltado (liveDibujar). Cabecera y botones fijos; solo la nota hace scroll. En movil va debajo
   del video (el mapa se oculta igual). Mock aprobado: evaluacion/modal/mock_columna_*.png */
.panel-main .mapwrap[hidden]{display:none}
.alcol{background:#1E2227;border-radius:var(--radius);color:#D4D7DC;padding:14px 16px;display:flex;flex-direction:column;gap:10px;height:64vh;min-height:0;position:relative;box-shadow:0 0 0 1px rgba(255,255,255,.08) inset,0 18px 50px rgba(0,0,0,.45);animation:toast-in .2s cubic-bezier(.2,.8,.2,1)}
.alcol.crit{box-shadow:0 0 0 2px #E5484D inset,0 18px 50px rgba(0,0,0,.45)}
.alcol .alhd{display:flex;align-items:center;gap:8px;flex:none} .alcol .albig{font-family:var(--font-title);font-weight:900;letter-spacing:.12em;color:#FF6B6B;font-size:20px} .alcol.crit .albig{animation:af-blink 1.2s steps(2) 3}
.alcol .alpend{font-size:12px;font-weight:700;color:#FFB74D}
/* La X de cerrar es la MISMA que en la tarjeta a pantalla completa (.acard .afx): mismo tamano, borde, area tactil y
   posicion (arriba a la derecha); la cabecera deja sitio con padding. Unificado a peticion del usuario (2026-09-25). */
.alcol .afx{position:absolute;top:10px;right:12px;width:40px;height:40px;border-radius:50%;border:1px solid rgba(255,255,255,.35);background:rgba(0,0,0,.25);color:#fff;font-size:24px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2;touch-action:manipulation}
.alcol .afx::after{content:"";position:absolute;inset:-5px;border-radius:50%} .alcol .afx:hover{background:rgba(0,0,0,.45)} .alcol .afx:active{background:rgba(0,0,0,.6);transform:scale(.94)} .alcol .afx:focus-visible{outline:2px solid #fff;outline-offset:2px}
.alcol .alhd{padding-right:52px;min-height:36px}
.alcol .alrow{display:grid;grid-template-columns:minmax(0,1fr) 44%;gap:12px;align-items:center;flex:none}
.alcol .alplaca{height:min(84px,8vw)}
.alcol .alcrop{height:84px} .alcol .alcrop[hidden]{display:none} .alcol .alcrop img{width:100%;height:100%;object-fit:contain;border-radius:8px;background:transparent;display:block}
.alcol .alkv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:3px 12px;font-size:13px;flex:none} .alcol .alkv div:nth-child(odd){color:#A1A7AF;text-transform:uppercase;font-size:12px;letter-spacing:.05em;white-space:nowrap} .alcol .alkv div:nth-child(even){overflow-wrap:anywhere;min-width:0}
.alcol .alnota{font-size:13px;line-height:1.45;overflow:auto;min-height:0;flex:0 1 auto;max-height:22vh;overflow-wrap:anywhere;color:#e5e7eb;border-top:1px solid rgba(255,255,255,.1);padding-top:8px;overscroll-behavior:contain}
.alcol .alesc{flex:1 1 auto;min-height:120px;position:relative;display:flex} .alcol .alesc[hidden]{display:none} .alcol .alesc img{width:100%;height:100%;min-height:120px;object-fit:contain;border-radius:10px;display:block;background:#000} .alcol .alesc img[hidden]{display:none} .alcol .alesc span{position:absolute;left:8px;bottom:6px;font-size:12px;color:#cbd5e1;background:rgba(0,0,0,.5);padding:2px 6px;border-radius:6px}
.alcol .albt{display:flex;gap:8px;flex:none} .alcol .albt .btn{flex:1 1 0;justify-content:center;display:inline-flex;align-items:center;font-size:14px;padding:10px 8px} .alcol .albt .btn:not(.ok):not(.danger){background:rgba(255,255,255,.1);color:#D4D7DC} .alcol .kbd{font-size:14px;opacity:.7;margin-left:6px;font-family:var(--mono)}
.alcol .alcola{display:flex;gap:6px;flex-wrap:wrap;flex:none} .alcol .alcola:empty{display:none} .alcol .alcola .pill{background:rgba(255,255,255,.08);color:#FFB74D;border:1px solid rgba(255,183,77,.4);font-family:var(--mono);font-size:12px;cursor:pointer}
@media(max-width:1100px){.alcol{height:auto;max-height:60vh} .alcol .alnota{max-height:18vh} .alcol .alesc img{height:auto;max-height:30vh}}
/* Detalle de evento (verSnapshot): datos a la izquierda, recorte de la placa a la derecha con TAMANO FIJO y su
   proporcion; las notas largas parten palabra y no empujan la imagen. En movil el recorte va encima. */
.evdet{display:grid;grid-template-columns:minmax(0,1fr) 230px;gap:16px 20px;align-items:start}
.evplaca img{width:100%;max-height:140px;object-fit:contain;border-radius:8px;border:1px solid var(--border);background:#000;display:block}
.evkv{display:grid;grid-template-columns:auto minmax(0,1fr);gap:6px 16px;font-size:13px;align-items:baseline}
.evkv div:nth-child(odd){color:var(--muted);white-space:nowrap} .evkv div:nth-child(even){font-weight:500;overflow-wrap:anywhere;min-width:0}
@media(max-width:640px){.evdet{grid-template-columns:1fr} .evplaca{order:-1;max-width:240px}}
.geoesc{position:relative;border-radius:12px;overflow:hidden;background:#000;border:1px solid var(--border);min-height:220px}
.geoesc img{display:block;width:100%;height:auto}
.geoesc canvas{position:absolute;inset:0;width:100%;height:100%;cursor:crosshair;touch-action:none}
.geoph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;text-align:center;padding:20px;
  color:var(--text-2);font-size:13px;background:var(--surface-2)}
.geopanel{display:flex;flex-direction:column;gap:8px;max-height:62vh;overflow:auto;padding:2px}
.geoln{border:1px solid var(--border);border-radius:10px;padding:12px;background:var(--surface-2)}
.geoln.on{border-color:var(--geo-c,var(--primary));box-shadow:0 0 0 1px var(--geo-c,var(--primary)) inset}
.geoln-hd{display:flex;gap:6px;align-items:center;margin-bottom:8px}
.geoln-n{flex:1;font-weight:600;border:1px solid var(--border);border-radius:8px;padding:6px 8px;background:var(--surface)}
.geoln-num{flex:none;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:700;color:#fff;background:var(--geo-c,var(--primary))}
.geolbl{display:block;font-size:12px;font-weight:600;color:var(--text-2);margin:0 0 3px;text-transform:none}
.geoln-dir{display:flex;align-items:center;gap:4px}
.geoln-dir span{flex:none;font-weight:700;color:var(--text-2)}
.geoln-dir input{min-width:0;width:100%;border:1px solid var(--border);border-radius:8px;padding:5px 7px;background:var(--surface)}
.geoln-et.uno{grid-template-columns:1fr}
.geoz-aviso{font-size:12px;color:var(--warning);background:color-mix(in srgb,var(--warning) 12%,transparent);border-radius:8px;padding:6px 8px;margin:0 0 6px}
.geoln select{margin:0 0 8px;width:100%}
.geoln-et{display:grid;grid-template-columns:1fr;gap:6px;margin-bottom:8px}
.geoln-et input{font-size:12px}
@media (max-width:820px){ .geoed{grid-template-columns:1fr} .geopanel{max-height:none} }

/* Barra de dibujo de zonas sobre el mapa: flota encima, sin robarle sitio al mapa ni empujar la vista. */
.geotool{position:absolute;left:50%;transform:translateX(-50%);bottom:18px;z-index:1000;display:flex;gap:8px;align-items:center;
  padding:8px 12px;border-radius:12px;background:var(--surface);border:1px solid var(--border);
  box-shadow:0 8px 24px rgba(0,0,0,.35);font-size:13px;color:var(--text-2);max-width:calc(100% - 24px);flex-wrap:wrap}
.geotool b{color:var(--warning);font-weight:600}

/* Editor de geometría: pestañas de modo (líneas / zonas) y selector de analíticas por zona. */
.geotabs{display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap}
.geotabs .btn.on{background:color-mix(in srgb,var(--primary) 18%,transparent);color:var(--primary)}
.geoz-an{display:flex;flex-wrap:wrap;gap:5px}
.geoz-an .chip{font-size:12px;padding:3px 8px;border:1px solid var(--border)}
.geoz-an .chip.on{border-color:var(--primary);background:color-mix(in srgb,var(--primary) 28%,transparent)}
.geoz-an .chip.on::before{content:"✓";font-weight:700}
.geoesc .geotool{bottom:auto;top:10px;font-size:12px}

/* Aforo: perfil por hora. Barras sencillas, sin librería: son 24 valores y lo que importa es la forma. */
.afhoras{display:flex;align-items:flex-end;gap:3px;height:150px;padding-top:6px}
.afh{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%;min-width:0}
.afh .afb{width:100%;background:var(--primary);border-radius:3px 3px 0 0;opacity:.85;transition:opacity .15s}
.afh:hover .afb{opacity:1}
.afh span{font-size:12px;color:var(--text-2);margin-top:4px;white-space:nowrap}
.aftbl th{font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);padding-bottom:6px}
.aftbl td{padding:5px 10px 5px 0}

/* Gestión de zonas sobre el mapa: lista flotante con renombrar, redibujar y borrar.
   Va encima del mapa y no al lado porque lo que se gestiona se está viendo dibujado debajo. */
.geolist{position:absolute;top:12px;right:12px;z-index:1000;width:280px;max-height:calc(100% - 24px);overflow:auto;
  background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,.35)}
.geolist:empty{display:none}
.geolist-hd{padding:10px 12px 6px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2)}
.geoitem{display:flex;align-items:center;gap:6px;padding:7px 10px;border-top:1px solid var(--border)}
.geoitem-t{flex:1;min-width:0;cursor:pointer;line-height:1.25}
.geoitem-t b{display:block;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.geoitem-t span{font-size:12px;color:var(--text-2)}
.geoitem-t:hover b{color:var(--primary)}
@media(max-width:860px){ .geolist{position:static;width:auto;max-height:none;border-radius:0;box-shadow:none;border:none;border-top:1px solid var(--border)} }

/* Aviso en los parámetros de una analítica cuya configuración real se DIBUJA sobre la escena. */
.modgeo{display:flex;flex-direction:column;gap:8px;padding:12px;margin:0 0 16px;border-radius:10px;
  background:color-mix(in srgb,var(--primary) 10%,transparent);border:1px solid color-mix(in srgb,var(--primary) 30%,transparent)}
.modgeo b{font-size:13px}
.modgeo .btn{margin-right:4px}

/* Ayuda en burbuja sobre una «i»: el modal se lee de un vistazo y el porqué está a un toque.
   Se abre al pasar el cursor Y al tocar (.on), porque en la tableta del puesto no hay cursor. */
.ayuda{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-left:6px;
  border-radius:50%;border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);
  font:600 12px/1 var(--font-title,system-ui);cursor:help;padding:0;vertical-align:middle;position:relative;flex:none}
.ayuda:hover{border-color:var(--primary);color:var(--primary)}
.ayuda-tip{position:fixed;z-index:3000;width:max-content;max-width:min(340px,70vw);max-height:40vh;overflow:auto;padding:9px 11px;border-radius:9px;
  background:var(--surface);color:var(--text);border:1px solid var(--border);box-shadow:0 8px 24px rgba(0,0,0,.4);
  font:400 12px/1.45 system-ui,sans-serif;text-align:left;white-space:normal}
.ayuda.on{border-color:var(--primary);color:var(--primary)}
.campo-sw{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:14px 0 4px}
.campo-sw label{margin:0}
/* El rango, siempre a la vista junto al valor: es lo que permite decidir sin abrir nada. */
.range .rg{font-size:12px;color:var(--text-2);margin-left:8px;white-space:nowrap}

/* Paginador de la lista de eventos. Va DENTRO de la tarjeta, debajo de la tabla, para que el operador vea
   en el mismo sitio lo que esta mirando y cuanto falta. En pantallas estrechas se parte en dos filas en vez
   de encogerse: los botones de pagina tienen que seguir siendo pulsables con el dedo. */
.pager{--pg-h:32px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:12px 18px;border-top:1px solid var(--border)}
.pager:empty{display:none}
.pager .pg-izq{display:flex;align-items:center;gap:10px;min-height:var(--pg-h)}
/* Pie unico (pieHTML, bloque C 2026-10-16): una sola linea, sin partir «Por página», y selector, numero y botones con
   la MISMA altura (--pg-h). Solo en telefono baja a dos lineas (abajo). */
.pager .pg-der{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;margin-left:auto}
.pager .pg-cuenta{color:var(--text-3);font-size:13px;white-space:nowrap}
.pager .pg-tam{display:inline-flex;align-items:center;gap:6px;margin:0;font-size:13px;font-weight:400;color:var(--text-2);white-space:nowrap}
.pager .pg-num{color:var(--text-2);font-size:13px;text-align:center;display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.pager .pg-ir{width:64px;height:var(--pg-h);box-sizing:border-box;padding:0 6px;font-size:13px;line-height:calc(var(--pg-h) - 2px);text-align:center;-moz-appearance:textfield}
.pager .pg-ir::-webkit-outer-spin-button,.pager .pg-ir::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.pager .help{margin-top:0}
/* El select global lleva padding 10px 12px y 14px: en una caja de 32px el texto no cabia y se cortaba (listas y eventos,
   2026-09-24). Aqui el alto manda: padding vertical 0 y linea a la altura de la caja. */
.pager select{height:var(--pg-h);min-width:72px;width:auto;box-sizing:border-box;padding:0 26px 0 10px;font-size:13px;line-height:calc(var(--pg-h) - 2px)}
.pager .btn{height:var(--pg-h);min-height:0;box-sizing:border-box;padding-top:0;padding-bottom:0;white-space:nowrap}
.pager .btn[disabled]{pointer-events:none}
@media(pointer:coarse){.pager{--pg-h:40px} .pager .btn{min-height:40px}}
@media(max-width:640px){.pager .pg-der{flex-wrap:wrap;margin-left:0}}
.pager.bq-pie{border-top:0;padding:14px 0 0}

/* /listas: fila "agregar placa" (placa, comentario, Agregar, Importar CSV). En movil los dos campos van a ancho completo y
   los botones a media anchura; antes el boton de importar quedaba fuera de la pantalla (2026-09-24). */
.hl-add{grid-template-columns:150px 1fr 220px auto auto;align-items:end;gap:10px;margin-bottom:12px}
.hl-add .btn{height:40px}
@media(max-width:640px){.hl-add{grid-template-columns:1fr 1fr} .hl-add>div{grid-column:1/-1} .hl-add .btn{height:auto}}
/* Listas y Personas: la barra unica (.f-fechas arriba, .f-campos debajo) con menos margen; la caja de placa, estrecha. */
.pl-filtros .filters{margin:0 0 6px}
.pl-placa input{text-transform:uppercase;letter-spacing:.08em}
.frow.f-campos>.pl-placa{flex:0 1 150px}
.pl-cuenta{margin:0 0 8px;min-height:18px}
.pl-nonota{margin:0 0 8px}
.pl-tabla td.pl-ficha{text-align:left}
.pl-tabla .pl-geo svg{width:13px;height:13px;vertical-align:-2px;color:var(--accent)}
.pl-tabla .pl-manual{font-size:12px;color:var(--text-2);cursor:help}
/* ficha de la placa por campos (Agregar / Editar placa) */
.fp-ficha{margin-top:6px}
.fp-g{margin-top:10px}
.fp-t{font-size:12px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:.04em;margin-bottom:2px}
.fp-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:0 10px}
.fp-row label{margin-top:4px}
.pl-tabla td.pl-ficha{font-size:12px;color:var(--text)}
.pl-tabla td.pl-coment{color:var(--text-2)}
.pl-tabla .pl-nada{color:var(--text-2)}
/* Listas: pestaña Resumen. Barras en gris neutro sobre un carril de superficie (el color queda para la accion); dos
   columnas de tablas, una en tableta y telefono. */
.pl-vistas{margin:0 0 12px}
.rs-acciones{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 10px;min-height:40px} .rs-acciones .sp{flex:1}
.rs-acciones .btn{min-height:40px}
.rs-cargando{padding:18px 0}
.resumen-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:0 0 14px}
.rs-dim{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px;min-width:0}
.rs-dim h4{margin:0 0 8px;font-size:13px;font-weight:600;color:var(--text)}
.rs-t{width:100%;border-collapse:collapse;font-size:12.5px;font-variant-numeric:tabular-nums}
.rs-t th{font-size:12px;font-weight:600;color:var(--text-2);padding:0 0 6px}
.rs-t td{padding:4px 0;vertical-align:middle;border-top:1px solid var(--border)}
.rs-t tr:first-child td{border-top:0}
.rs-t .rs-v{width:42%;padding-right:10px;color:var(--text);overflow-wrap:anywhere}
.rs-t .rs-b{padding-right:10px;min-width:60px}
.rs-t .rs-b .barra{height:8px;border-radius:2px;background:color-mix(in srgb,var(--text-2) 55%,var(--surface-2));min-width:2px}
.rs-t .rs-n{width:1%;white-space:nowrap;text-align:right;color:var(--text-2)} .rs-t th.rs-n{text-align:center}
/* Fila «Sin dato»: lo que falta del total del filtro en ese campo; mas apagada que las de valor. */
.rs-t .rs-sindato .rs-v{color:var(--text-2);font-style:italic}
.rs-t .rs-sindato .rs-b .barra{background:color-mix(in srgb,var(--text-2) 25%,var(--surface-2))}
.rs-t.rs-uni .rs-n{padding-left:12px}
.rs-t.rs-uni .rs-ult2{display:none}
.rs-op{margin:6px 0 10px}
/* Chip de un filtro sin control en la barra (cuadrante, llega por la URL), con su × para quitarlo. */
.pl-chips:not(:empty){margin-left:8px}
.pl-chip{cursor:default;margin:0;padding:2px 4px 2px 11px}
.pl-chip-x{background:none;border:0;color:inherit;font-size:16px;line-height:1;min-width:28px;min-height:28px;border-radius:999px;cursor:pointer}
.pl-chip-x:hover{color:var(--text);background:var(--surface-3)}
@media(pointer:coarse){ .pl-chip-x{min-width:40px;min-height:40px} }
@media(max-width:860px){ .resumen-grid{grid-template-columns:1fr} }
@media(max-width:640px){ .rs-acciones .btn{width:100%;justify-content:center} .rs-t.rs-uni{font-size:12px} }
/* Telefono: «Última» baja bajo el nombre de la unidad; quedan tres columnas y nada desborda a 390 px. */
@media(max-width:480px){ .rs-t.rs-uni .rs-ult{display:none} .rs-t.rs-uni .rs-ult2{display:block;color:var(--text-2);font-size:12px;margin-top:2px}
  .rs-t.rs-uni .rs-v{width:auto} .rs-dim{padding:10px 12px} }

/* Cuadrantes MNVCC: etiqueta al pasar sobre la cuadrícula y fila agrupada en la lista de zonas */
.leaflet-tooltip.cuadtip{background:rgba(20,24,32,.85);color:#fff;border:0;border-radius:6px;font-size:12px;padding:2px 6px;box-shadow:none}
.leaflet-tooltip.cuadtip::before{display:none}
.geoitem.cuad .geoitem-t b{color:var(--text-2)}

/* ---- Ficha del evento (2026-09-26): placa grande, lista contra lectura, nota, datos compactos ---- */
.ficha{display:grid;gap:16px}
.fhead{display:grid;grid-template-columns:minmax(0,1fr) 184px;gap:16px;align-items:center}
.fhead .evplaca img{width:184px;height:110px;max-height:none;object-fit:contain;border:0;border-radius:10px}
.fplate{font-family:var(--mono);font-size:44px;font-weight:800;line-height:1;letter-spacing:.04em;margin:0 0 8px;overflow-wrap:anywhere} /* sin placa: el tipo de evento */
.fplaca{height:84px;margin:0 0 8px}
.fveh{font-size:15px;color:var(--text-3)}
.fveh .dot{width:12px;height:12px;border-radius:50%;display:inline-block;border:1px solid rgba(128,128,128,.45);vertical-align:-1px;margin-right:6px}
.fmeta{margin-top:10px;font-size:13px;color:var(--text-2);line-height:1.7;overflow-wrap:anywhere}
.fveh b{color:var(--text);font-weight:600} .fveh .sep{margin:0 8px;opacity:.4}
.fmeta b{color:var(--text-3);font-weight:600} .fmeta a{color:var(--primary);text-decoration:none;font-weight:600;white-space:nowrap} .fmeta .sep{margin:0 8px;opacity:.4}
.sec{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);margin:2px 0 -8px}
.cmp{display:grid;grid-template-columns:auto 1fr 1fr;font-size:13.5px;border:1px solid var(--border);border-radius:12px;overflow:hidden}
.cmp>div{padding:8px 12px;border-bottom:1px solid var(--border);min-width:0;overflow-wrap:anywhere} .cmp>div:nth-last-child(-n+3){border-bottom:0}
.cmp .h{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);background:var(--surface-2)}
.cmp .k{color:var(--text-2)} .cmp .dif{color:#FFB74D;font-weight:600} :root[data-theme="light"] .cmp .dif{color:#B45309}
.cmp .n{font-family:var(--mono);font-size:12px;color:var(--text-2);margin-left:6px;font-weight:400}
.resumen{font-size:13px;color:var(--text-3);margin-top:-6px} .resumen b{color:#FFB74D} :root[data-theme="light"] .resumen b{color:#B45309}
.nota{background:var(--surface-2);border-radius:12px;padding:12px 14px} /* sin filo de color a la izquierda (criterio del usuario, 2026-10-01) */
.nota .t{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-2);margin-bottom:4px}
.nota p{margin:0;font-size:14px;line-height:1.5;color:var(--text);overflow-wrap:anywhere}
.nota .ref{margin-top:6px;font-size:12.5px;color:var(--text-2)} .nota .ref b{color:var(--text-3);font-weight:600}
.datos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px 24px;font-size:13px}
.datos>div{display:grid;grid-template-columns:112px minmax(0,1fr);gap:10px;padding:5px 0;border-bottom:1px solid var(--border)}
.datos .k{color:var(--text-2)} .datos .v{color:var(--text-3);overflow-wrap:anywhere} .datos a{color:var(--primary);text-decoration:none;font-weight:600}
.evbox{position:absolute;border:2px solid rgba(0,174,239,.9);border-radius:3px;pointer-events:none} .evbox.evbox-placa{border-color:rgba(255,255,255,.85)}
.evcrit{margin-left:auto;font-family:var(--font-body,inherit);letter-spacing:0;display:inline-flex;align-items:center;float:right;padding-top:4px}
.facciones{display:flex;gap:8px;align-items:center;flex-wrap:wrap;border-top:1px solid var(--border);padding-top:12px} .facciones .sp{flex:1}
.vdcorr{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:12.5px;color:var(--text-2)} .vdcorr[hidden]{display:none}
.acard .acmp{gap:10px;margin-bottom:10px} .acard .acmp .cmp{font-size:13px} .acard .acmp .nota p{font-size:13.5px}
@media(max-width:640px){.fhead{grid-template-columns:1fr} .fhead .evplaca{order:-1} .fplate{font-size:36px} .fplaca{height:68px} .datos{grid-template-columns:1fr}
  .cmp{grid-template-columns:1fr} .cmp .h{display:none} .cmp .k{padding-bottom:2px;border-bottom:0;font-size:12px;text-transform:uppercase;letter-spacing:.05em}
  .cmp>div[data-col]::before{content:attr(data-col) " · ";color:var(--text-2);font-size:12px;text-transform:uppercase;letter-spacing:.05em;font-weight:400}
  .cmp>div[data-col="En la lista"]{border-bottom:0;padding-top:2px;padding-bottom:2px} .facciones .pill{width:100%}}
/* La tarjeta de alarma es oscura en los dos temas: los bloques de la ficha dentro de ella no usan los tokens del tema */
.acard .cmp{border-color:rgba(255,255,255,.14)} .acard .cmp>div{border-color:rgba(255,255,255,.1)} .acard .cmp .h{background:rgba(255,255,255,.06);color:#9CA3AF}
.acard .cmp .k,.acard .sec,.acard .resumen,.acard .nota .t,.acard .nota .ref{color:#9CA3AF} .acard .resumen b,.acard .cmp .dif{color:#FFB74D} .acard .nota{background:rgba(255,255,255,.06)} .acard .nota p{color:#D4D7DC}

/* ---- Central: tablero de flota, vivo multi-unidad, mapa de flota, notificaciones ---- */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px;margin:0 0 14px}
.kpi{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:10px 14px;display:flex;flex-direction:column;gap:2px}
.kpi b{font-family:var(--font-title);font-size:26px;line-height:1.1;color:var(--text)} .kpi span{font-size:12px;color:var(--text-2)}
.kpi.bad b{color:var(--error)}
.panel-main.central{grid-template-columns:1.2fr 1fr}
.panel-bottom.central{display:grid;grid-template-columns:1fr 1fr;gap:16px} .panel-bottom.central .card{min-width:0}
.panel-bottom.central #cardAlertas{grid-column:1/-1}
@media(max-width:1100px){.panel-bottom.central{grid-template-columns:1fr}}
.txt-error{color:var(--error-text)}
.est{display:inline-flex;align-items:center;gap:6px;white-space:nowrap} .est i{width:8px;height:8px;border-radius:50%;flex:none}
.btn.icono{padding:5px 7px} .btn.icono svg{width:16px;height:16px}
table.fija{table-layout:fixed;width:100%} td.una-linea{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vivocard{display:flex;flex-direction:column;height:64vh;overflow:hidden;padding:0}
/* VISTA EN VIVO: cabecera compacta + matriz de mosaicos (1x1, 1x2, 2x2, 2x3, 3x3) que llena el alto disponible */
.vivo{display:flex;flex-direction:column;min-height:0;background:var(--surface)} .vivo.videowall{background:#000;color:#eee}
.vivo.videowall{height:100vh}
/* la cabecera es la misma de las demas tarjetas (.hd.panel-hd): mismo titulo, mismo fondo */
/* La cabecera de la vista en vivo se estila sola (no depende de .card): en el videowall no hay tarjeta y quedaba sin fila,
   con los botones a la izquierda. Titulo con la fuente de titulos; a la derecha Añadir y los botones de ventana. */
.vivo .hd.vivo-hd{display:flex;align-items:center;gap:8px;flex:none;flex-wrap:nowrap;padding:10px 14px} .vivo .hd.vivo-hd .sp{flex:1}
.vivo .hd.vivo-hd h3{margin:0;white-space:nowrap;font-family:var(--font-title);font-size:17px;color:var(--text);text-transform:uppercase;letter-spacing:.06em;font-weight:700}
.vivo-hd .btn.icono{border:0;background:transparent}
.vivo.videowall .hd.vivo-hd{background:#141414} .vivo.videowall .hd.vivo-hd h3{color:#D4D7DC} /* el videowall es oscuro en los dos temas */
.vwin{display:flex;gap:2px;margin-left:8px;padding-left:8px;border-left:1px solid var(--border)} .vwin .btn.icono{border:0;background:transparent}
/* Sobre un mapa a pantalla entera: barra flotante arriba a la derecha; la lista lateral baja para no taparla. */
.vwin.flotante{position:absolute;top:14px;right:14px;z-index:1100;margin:0;padding:2px 4px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-lg)}
.mapa-videowall .flotalist{top:58px;max-height:calc(100% - 72px)} .mapa-suelto .geolist{top:58px;max-height:calc(100% - 70px)} .mapa-suelto .flotalist{top:58px;max-height:calc(100% - 72px)}
.vivo-mat{display:flex;justify-content:flex-end;gap:2px;padding:0 14px 8px;flex:none}
.vivo.videowall .vivo-mat{background:#141414;border-bottom:1px solid #2a2a2a}
.vivo-mat button{background:#222;border:0;color:#aaa;font-size:12px;font-weight:700;padding:4px 10px;border-radius:4px;cursor:pointer;font-family:var(--mono)} .vivo-mat button.on{background:var(--primary);color:var(--on-fill)}

.vivo-grid{display:grid;gap:3px;padding:3px;flex:1;min-height:0;background:#000}
.vtile{position:relative;background:#0b0b0b;border-radius:4px;overflow:hidden;min-height:0;border:2px solid #1e1e1e}
.vtile video{width:100%;height:100%;object-fit:contain;background:#000;display:block}
.vtile canvas.vcajas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.vtile.vivo-ok{border-color:#1e1e1e} .vtile.alarma{border-color:var(--error);box-shadow:inset 0 0 0 1px var(--error);animation:latido 1.2s 3}
.vtile.vacio{display:flex;align-items:center;justify-content:center;border-style:dashed;border-color:#2a2a2a}
.vtile .vadd{background:transparent;border:1px dashed #444;color:#666;font-size:28px;width:56px;height:56px;border-radius:50%;cursor:pointer} .vtile .vadd:hover{color:#fff;border-color:#fff}
.vtop{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;gap:6px;padding:5px 8px;font-size:12px;color:#fff;background:linear-gradient(rgba(0,0,0,.75),rgba(0,0,0,0));pointer-events:none}
.vtop b{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:45%} .vtop .vcam{font-family:var(--mono);color:#bbb} .vtop .sp{flex:1}
.vtop .vmsg{color:#bbb;font-size:12px;white-space:nowrap} .vtile.vivo-ok .vtop .vmsg{color:#A1A7AF}
.vtop .valarma{color:#FF6B6B;font-weight:700;white-space:nowrap}
.vbtns{position:absolute;right:6px;bottom:6px;display:flex;gap:4px;opacity:0;transition:opacity .15s} .vtile:hover .vbtns{opacity:1}
.vbtns button{background:rgba(0,0,0,.65);border:1px solid #444;color:#fff;width:30px;height:26px;border-radius:4px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center} .vbtns button svg{width:15px;height:15px} .vbtns button:hover{background:var(--primary);color:var(--on-fill);border-color:var(--primary)}
.vivo-login{display:flex;align-items:center;justify-content:center;height:100%;color:#ccc;font-size:16px;padding:30px;text-align:center}
.mapleyenda{position:absolute;bottom:14px;left:14px;z-index:500;display:flex;gap:10px;flex-wrap:wrap;background:rgba(17,17,17,.82);backdrop-filter:blur(6px);padding:6px 10px;border-radius:10px;font-size:12px;color:#eee}
.mapleyenda span{display:flex;align-items:center;gap:5px} .mapleyenda i{display:inline-block;width:10px;height:10px;border-radius:50%;border:2px solid #fff}
/* marcador de unidad: relleno = actividad, anillo = comunicacion (verde / gris / rojo), como en CCMAP */
.gpspin.unipin span{width:18px;height:18px;border-width:3px;border-style:solid} .gpspin.unipin.alarma span{animation:latido 1s 3}
@keyframes latido{0%{box-shadow:0 0 0 2px rgba(229,72,77,.5)}70%{box-shadow:0 0 0 12px rgba(229,72,77,0)}100%{box-shadow:0 0 0 2px rgba(229,72,77,0)}}
/* Panel lateral del mapa (unidad y Central). Cabecera SOLO con las pestanas, en una linea y a todo el ancho; los
   filtros van en su propia fila (.fl-filtros) para que nada se solape a ningun ancho (>= 320 px). */
.flotalist{position:absolute;top:14px;right:14px;z-index:1000;width:340px;max-width:calc(100% - 28px);max-height:calc(100% - 28px);overflow:auto;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-lg)}
.fl-hd{display:block;padding:0;border-bottom:1px solid var(--border)}
.fl-filtros{display:flex;gap:8px;align-items:center;padding:8px 12px;border-bottom:1px solid var(--border)}
.fl-filtros[hidden],.fl-filtros>[hidden]{display:none}
.fl-filtros select{flex:1;min-width:0;width:auto;min-height:40px}
.fl-filtros .btn{flex:1;min-height:40px;justify-content:center}
.fl-row{display:flex;align-items:flex-start;gap:10px;min-height:40px;padding:10px 12px;border-bottom:1px solid var(--border);cursor:pointer} .fl-row:hover{background:var(--surface-2)}
.fl-row i{width:14px;height:14px;border-radius:50%;flex:none;border:3px solid #fff;margin-top:3px} .fl-row>div{flex:1;min-width:0}
.fl-row b{display:block;font-size:14px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fl-row-s{font-size:13px;line-height:1.4;color:var(--text-2);margin-top:2px}
/* Pestanas de la lista lateral: una linea, repartidas a partes iguales, 40 px de alto. La lista de zonas es la misma
   de la unidad, pero dentro del panel en vez de flotando sobre el mapa. */
.fl-tabs{display:flex;margin:0;border:none;gap:0;width:100%;flex-wrap:nowrap}
.fl-tabs .tab{flex:1;min-width:0;min-height:40px;padding:0 6px;font-size:13px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.flotalist .geolist{position:static;width:auto;max-height:none;border:none;border-radius:0;box-shadow:none}
.flotalist .geolist[hidden]{display:none}
tr.leido td{color:var(--text-3)}
tr.noleido td{font-weight:600}
.mapa-pop{position:absolute;top:12px;right:12px;z-index:660;border:0;background:rgba(17,17,17,.82);color:#eee;backdrop-filter:blur(6px)} .mapa-pop:hover{color:var(--primary)}
.mapa-pop.lista{right:326px} /* en el mapa de flota la lista de unidades ocupa la esquina derecha */
.map-stats .s.alarma b{color:var(--error)} .map-stats .s b small{font-size:12px;font-weight:600;color:var(--text-2)}
.mapa-videowall{border:0;border-radius:0} .mapa-videowall #mapFull{height:100vh;min-height:0;border:0;border-radius:0}
.mapa-suelto .pagehead{display:none} .mapa-suelto .card{border:0;border-radius:0} .mapa-suelto #mapFull{height:100vh;min-height:0;border:0;border-radius:0}
/* Listas de unidades dentro de un modal: en columnas, no apiladas; el modal tiene sitio de sobra. */
.lista-unidades{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 16px;margin-top:6px}
.lista-unidades label{display:flex;align-items:center;gap:6px;margin:0;font-weight:400;text-transform:none;letter-spacing:0;font-size:13px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lista-unidades input{margin:0}
@media(max-width:640px){.lista-unidades{grid-template-columns:1fr 1fr}}
/* Editor de capas: un bloque por clave (cabecera con selector, sufijo, ayuda y quitar) y una tabla de campos con la
   casilla "imponer" al inicio de cada fila; numeros con unidad y limites; filas repetibles como tabla estandar. */
.cbloques-hd{display:flex;align-items:center;gap:10px;margin:14px 0 6px} .cbloques-hd .sp{flex:1}
.cbloque{border:1px solid var(--border);border-radius:10px;margin:8px 0;background:var(--surface)}
.cbloque-hd{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--border);background:var(--surface-2);border-radius:10px 10px 0 0}
.cbloque-hd select,.cbloque-hd input{margin:0} .cbloque-hd select{max-width:280px;font-weight:600} .cbloque-hd input{max-width:160px} .cbloque-hd .sp{flex:1}
.cbloque-bd{padding:4px 12px 10px}
.cfila{display:grid;grid-template-columns:22px 230px minmax(0,1fr);gap:10px;align-items:center;padding:7px 0;border-bottom:1px solid var(--border)} .cfila:last-child{border-bottom:0}
.cfila .imp{margin:0;width:16px;height:16px} .cfila .clab{font-size:13px;color:var(--text)} .cfila .cctl{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.cfila .cctl select,.cfila .cctl input{margin:0;max-width:320px} .cfila .cctl input[type=number]{max-width:140px} .cfila .cctl input:disabled,.cfila .cctl select:disabled{opacity:.45}
.cfila .clim{font-size:12px;color:var(--text-2);white-space:nowrap}
.ig{display:inline-flex;align-items:stretch} .ig input{border-top-right-radius:0;border-bottom-right-radius:0} .ig .sfx{display:inline-flex;align-items:center;padding:0 10px;border:1px solid var(--border);border-left:0;border-radius:0 8px 8px 0;background:var(--surface-2);font-size:12px;color:var(--text-2);white-space:nowrap}
.chk{display:inline-flex;align-items:center;gap:6px;font-weight:400;text-transform:none;letter-spacing:0;margin:0;font-size:13px} .chk input{margin:0;width:16px;height:16px}
.ctabla{margin:8px 0} .ctabla table{margin-bottom:6px} .ctabla td select,.ctabla td input{margin:0;min-width:110px} .ctabla td .ig input{min-width:80px;max-width:110px}
@media(max-width:640px){.cfila{grid-template-columns:22px 1fr} .cfila .cctl{grid-column:2}}

/* Tabla con titulos y celdas centrados (la primera columna a la izquierda): unidades de la flota, ordenes de la ficha. */
.tbl-centrada th,.tbl-centrada td{text-align:center} .tbl-centrada td:first-child{text-align:left}
/* Ficha de la unidad: acciones por grupos, cada grupo en su fila con su nombre a la izquierda. */
.acciones{display:grid;gap:6px} .acc-grupo{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.acc-grupo .acc-t{width:140px;flex:none;font-size:12px;color:var(--text-2)} .fhead.uni{grid-template-columns:1fr}
/* Tabla de unidades: sin anchos fijos, celdas de una linea; la primera columna toma el sobrante. */
.tbl-unidades{width:100%;table-layout:auto} .tbl-unidades td,.tbl-unidades th{white-space:nowrap;padding-left:10px;padding-right:10px} .tbl-unidades td:first-child{width:100%}
.ficha .datos>div{grid-template-columns:132px 1fr}
/* Menu contextual de acciones (fila de una unidad): mismo estilo que el menu del usuario, anclado al boton. */
.dropdown.ctx{top:auto;right:auto;width:auto;min-width:240px;padding:4px 0 6px} .dropdown .mh{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--text-2);padding:9px 14px 3px;font-weight:600}
.dropdown.ctx .mi{padding:8px 14px;font-size:13px} .tbl-unidades .btn.sm svg{width:14px;height:14px} .tbl-unidades a{color:var(--primary);text-decoration:none;font-weight:600}
.tbl-unidades .btn.icono{padding:5px 7px;border-color:transparent} .tbl-unidades .btn.icono svg{width:16px;height:16px} .tbl-unidades .btn.icono:hover{border-color:var(--border)}

/* ===== Teléfono: revisado en un teléfono emulado de 390x844 (2026-09-30) =====
   - .panel-main.central (dos clases) ganaba a la regla de una columna de .panel-main: el tablero del Central quedaba en
     dos columnas estrechas en el teléfono.
   - La barra superior del Central no cabía: el menú de usuario (salir, tema) quedaba fuera de pantalla. En el teléfono
     se quitan los atajos de placa (+/−, siguen en Listas) y el logo puede encoger. */
@media(max-width:1100px){.panel-main.central{grid-template-columns:1fr}}
@media(max-width:480px){
  .navbar{gap:8px} .navbar #placaMas,.navbar #placaMenos{display:none}
  .navbar .brand{flex:0 1 auto;min-width:0} .navbar .brand .orglogo{max-width:100%}
}
@media(max-width:860px){.map-stats .s span{font-size:12px;letter-spacing:0}}
/* con el dedo: botones, pestañas y el selector de periodo de al menos 40 px */
@media(pointer:coarse){.daterange{height:auto} .daterange button,.tabbar .tab,.btn{min-height:40px} .btn{min-width:40px} .alerts-tbl input[type=checkbox]{width:22px;height:22px}}

/* ===== Teléfono (<=640 px): las tablas se leen como tarjetas. Cada fila es una tarjeta; cada celda, "TÍTULO  valor"
   con el título que app.js copia de la cabecera a data-label. Las celdas sin título (casilla, punto de estado,
   acciones) van sin rótulo; las de ancho completo (detalle desplegado, "sin datos") ocupan la tarjeta.
   !important: aquí se anulan a propósito los ajustes de columna de escritorio (alineación, una línea, bordes). */
@media(max-width:640px){
  .alerts-tbl{border-collapse:separate;min-width:0 !important;width:100% !important}
  .alerts-tbl thead{display:none}
  .alerts-tbl,.alerts-tbl tbody,.alerts-tbl tr{display:block}
  .alerts-tbl tbody tr{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 12px;margin:0 0 10px}
  .alerts-tbl tbody tr{position:relative}
  .alerts-tbl tbody td{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:4px 8px;min-height:30px;padding:5px 0 !important;
    border:none !important;white-space:normal !important;text-align:left !important;width:auto !important;overflow-wrap:anywhere}
  .alerts-tbl tbody td::before{content:attr(data-label);margin-right:auto;padding-right:12px;max-width:45%;text-align:left;color:var(--text-2);font-family:var(--font);
    font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.03em}
  /* primera celda sin título (punto de sincronía, casilla): a la esquina de la tarjeta, sin línea propia */
  .alerts-tbl tbody tr > td:first-child[data-label=""]{position:absolute;top:8px;right:12px;min-height:0;padding:0 !important}
  .alerts-tbl tbody tr:has(> td:first-child[data-label=""]){padding-right:44px}
  .alerts-tbl tbody td[data-label=""]::before{content:none}
  .alerts-tbl tbody td[data-label=""]{justify-content:flex-start;text-align:left !important;flex-wrap:wrap}
  .alerts-tbl tbody td[colspan]{display:block;text-align:left !important}
  .alerts-tbl tbody td:empty{display:none}
  .alerts-tbl tbody tr.a-det{padding:0;overflow:hidden}
}
/* Tablet (641-1200 px, 2026-10-23): una tabla que no cabe a lo ancho pasa a las mismas tarjetas del telefono, en dos
   columnas, en vez de cortar las ultimas columnas. La clase .tarjetas la pone vigilarTablas (app.js) midiendo la tabla */
@media(min-width:641px){
  .alerts-tbl.tarjetas{border-collapse:separate;min-width:0 !important;width:100% !important}
  .alerts-tbl.tarjetas thead{display:none}
  .alerts-tbl.tarjetas,.alerts-tbl.tarjetas tbody,.alerts-tbl.tarjetas tr{display:block}
  .alerts-tbl.tarjetas tbody tr{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 12px;margin:0 0 10px}
  .alerts-tbl.tarjetas tbody tr{position:relative}
  .alerts-tbl.tarjetas tbody td{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:4px 8px;min-height:30px;padding:5px 0 !important;
    border:none !important;white-space:normal !important;text-align:left !important;width:auto !important;overflow-wrap:anywhere}
  .alerts-tbl.tarjetas tbody td::before{content:attr(data-label);margin-right:auto;padding-right:12px;max-width:45%;text-align:left;color:var(--text-2);font-family:var(--font);
    font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.03em}
  /* primera celda sin título (punto de sincronía, casilla): a la esquina de la tarjeta, sin línea propia */
  .alerts-tbl.tarjetas tbody tr > td:first-child[data-label=""]{position:absolute;top:8px;right:12px;min-height:0;padding:0 !important}
  .alerts-tbl.tarjetas tbody tr:has(> td:first-child[data-label=""]){padding-right:44px}
  .alerts-tbl.tarjetas tbody td[data-label=""]::before{content:none}
  .alerts-tbl.tarjetas tbody td[data-label=""]{justify-content:flex-start;text-align:left !important;flex-wrap:wrap}
  .alerts-tbl.tarjetas tbody td[colspan]{display:block;text-align:left !important}
  .alerts-tbl.tarjetas tbody td:empty{display:none}
  .alerts-tbl.tarjetas tbody tr.a-det{padding:0;overflow:hidden}

  .alerts-tbl.tarjetas tbody{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .alerts-tbl.tarjetas tbody tr{margin:0}
  .alerts-tbl.tarjetas td.desc{max-width:none;width:auto;overflow:visible;text-overflow:clip}  /* el max-width:0 de la tabla partia el texto letra por letra */
  .alerts-tbl.tarjetas tbody tr.a-det,.alerts-tbl.tarjetas tbody tr:has(> td[colspan]){grid-column:1/-1}
}


/* Aviso de sonido bloqueado por el navegador (app.js): visible hasta el primer toque o tecla */
/* Sonido de alertas en el menu de usuario: estado y Activar; punto ambar en el avatar mientras el navegador lo bloquee */
.sonido-fila{display:flex;align-items:center;gap:10px;justify-content:space-between}
.sonido-est{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--success)} .sonido-est.off{color:var(--warning)}
.sonido-est svg{width:16px;height:16px}
.usermenu .av{position:relative} .usermenu.sonido-off .av::after{content:"";position:absolute;top:-1px;right:-1px;width:10px;height:10px;border-radius:50%;
  background:var(--warning);border:2px solid var(--surface)}

/* ===== Tripulacion (docs/APP_TRIPULACION.md): telefono del tripulante, esquema de LPR . MOVIL . V05 p. 13 =====
   Sin barras laterales de color: la prioridad va como rotulo sobre la escena y como punto en las barras. */
:root{--placa-amarilla:#FFDC17;--carbon:#231F20;--carbon-2:#2E292A;--carbon-3:#3B3536;--hueso:#F2F0EF;--gris-marca:#B9B2B3}
.layout.trip-layout .sidebar,.layout.trip-layout .mobback{display:none}
.layout.trip-layout .content{background:var(--carbon)} /* carbon de la marca: menos fatiga que el negro puro con las fotos */
/* La app de tripulacion conserva su barra (carbon-2 sobre el contenido carbon). La del resto de la consola es el carbon
   del encabezado general, en todos los anchos (2026-10-04). */
.layout.trip-layout .navbar{background:var(--carbon-2);border-bottom:1px solid var(--carbon-3)}
.layout.trip-layout .navbar .brand .orglogo{opacity:.92}
.layout.trip-layout .navbar .usermenu{background:var(--carbon-3)}
.trip{max-width:560px;margin:0 auto;color:var(--hueso)}
.trip-cab{display:flex;align-items:center;gap:10px;background:var(--carbon-2);border-radius:8px;padding:9px 12px;margin:0 0 14px}
.trip-unidad{font:600 13px var(--font);letter-spacing:.02em;color:var(--hueso)} .trip-cab .sp{flex:1}
.trip-vivo{font-size:12px;font-weight:600;color:var(--gris-marca)} .trip-vivo.ok{color:#7BC67E}
.tr-heroe{display:grid;gap:9px;cursor:pointer;padding:0 0 16px}
.tr-placa{display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap}
.tr-placa .tr-plate{height:90px} /* placa del diseno con el color del vehiculo (antes texto sobre hueso) */
.tr-sinplaca{font:400 26px var(--font-title);color:var(--primary);letter-spacing:.03em;text-align:center}
.tr-crop img{height:52px;max-width:150px;object-fit:contain;border-radius:5px;background:#000} .tr-crop img[hidden]{display:none}
.tr-escena{position:relative;min-height:40px} .tr-escena img{width:100%;display:block;border-radius:8px;background:#000} .tr-escena img[hidden]{display:none}
.tr-prio{position:absolute;right:8px;top:8px;font:700 12px var(--font);letter-spacing:.06em;text-transform:uppercase;color:#fff;padding:5px 9px;border-radius:999px;opacity:.92}
.tr-titulo{font:500 15px var(--font);color:var(--hueso);text-align:center} .tr-ctx{font-size:14px;color:#D6D0D1;text-align:center}
.tr-nota{font-size:13px;color:var(--gris-marca);text-align:center;overflow-wrap:anywhere}
.tr-lista{display:grid;gap:8px}
.tr-sinalerta{text-align:center;color:var(--gris-marca);font-size:14px;padding:18px 0 16px}
/* barras de la maqueta (p. 13): la placa en amarillo de marca; el resto en carbon para no cansar la vista */
.tr-barra{display:flex;align-items:center;gap:10px;background:var(--carbon-2);color:var(--hueso);border-radius:6px;padding:8px 12px 8px 8px;cursor:pointer;min-height:44px}
.tr-barra b{font:700 14px/1 var(--mono);letter-spacing:.04em;white-space:nowrap;background:var(--placa-amarilla);color:var(--carbon);padding:6px 9px;border-radius:4px}
.tr-barra .tr-tipo{flex:1;min-width:0;font:500 13.5px var(--font);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all}
.tr-barra .tr-hora{font:500 13px var(--font);color:var(--gris-marca);font-variant-numeric:tabular-nums} .tr-barra i{width:10px;height:10px;border-radius:50%;flex:0 0 10px} .tr-barra i:empty:not([style]){display:none}
.tr-barra.lectura b{background:var(--carbon-3);color:var(--hueso)} /* lectura normal: placa sin el amarillo de alarma */
.tr-barra:hover{background:var(--carbon-3)}

/* ===== Login del Central (PassControl Cloud Suite) y de la app de tripulacion (LPR Movil), LPR . MOVIL . V05 ===== */
.login.panel{display:grid;grid-template-columns:1.15fr minmax(360px,1fr);padding:0;background:var(--carbon,#231F20)}
.login.panel .foto{position:relative;background:radial-gradient(900px 500px at 30% 20%,#2f2a2b,#231F20 70%);min-height:100vh}
.login.central.con-foto .foto{background:url(fondo-central.jpg) center/cover no-repeat}
/* La moto de espaldas entre vehiculos (p. 13). La foto es apaisada y el panel alto: para llenar todo el alto SIN
   estirarla ni perder los carros de los lados, detras va la misma foto ampliada y desenfocada (cubre el panel) y
   delante la foto nitida a todo el ancho; el fundido une las dos. */
.login.panel .foto{container-type:size}
.login.unidad.con-foto .foto{overflow:hidden;background:#231F20 url(fondo-unidad.jpg) center/cover no-repeat} /* detras: la misma foto cubriendo el panel */
.login.unidad.con-foto .foto::before{content:"";position:absolute;inset:0;z-index:0;background:rgba(35,31,32,.55);backdrop-filter:blur(22px) saturate(1.1);-webkit-backdrop-filter:blur(22px) saturate(1.1)} /* ...desenfocada y atenuada */
.login.unidad.con-foto .foto .banda{position:absolute;inset:0;z-index:1;background:url(fondo-unidad.jpg) center center/120% auto no-repeat;
  --m:linear-gradient(180deg,transparent calc(50% - 33.6cqw),#000 calc(50% - 24cqw),#000 calc(50% + 24cqw),transparent calc(50% + 33.6cqw));
  -webkit-mask-image:var(--m);mask-image:var(--m)} /* delante: la foto nitida a todo el ancho, con sus bordes superior e inferior fundidos en el fondo desenfocado */
.login.unidad.con-foto .foto::after{z-index:2} .login.unidad .foto .titulo-login,.login.unidad .foto .lg-pg-esq{z-index:3}
.login.panel.unidad.con-foto .foto::after{background:
  linear-gradient(180deg,rgba(35,31,32,.35) 0,rgba(35,31,32,0) calc(50% - 22cqw),rgba(35,31,32,0) calc(50% + 20cqw),rgba(35,31,32,.55) 100%),
  linear-gradient(90deg,#231F20 0%,rgba(35,31,32,.35) 12%,rgba(35,31,32,0) 30%,rgba(35,31,32,0) 58%,#231F20 100%)}
.login.panel.con-foto .foto::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,#231F20 0%,rgba(35,31,32,.35) 16%,rgba(35,31,32,0) 34%,rgba(35,31,32,0) 58%,#231F20 100%),linear-gradient(0deg,rgba(0,0,0,.5),transparent 45%)} /* degradado a ambos lados y abajo */
.login.panel .box{width:min(500px,100%);margin:auto;background:transparent;border:none;box-shadow:none;padding:34px 28px}
.login .lg-cs{display:block;height:170px;width:auto;margin:0 auto 22px}
.login .lg-pg-esq{position:absolute;left:32px;top:28px;z-index:3;height:56px;width:auto;filter:brightness(0) invert(1)} /* la empresa, arriba a la izquierda */
/* el titulo va sobre la foto, a la izquierda y a media altura (sobre la franja clara de la imagen de la p. 10) */
.login .titulo-login{position:absolute;left:6%;top:45%;transform:translateY(-50%);z-index:3}
.login.unidad .titulo-login{top:calc(45% + 30px);left:calc(6% + 155px)} /* en la unidad, 30 px mas abajo y 155 px a la derecha (pedido del usuario) */
.login.central .titulo-login{left:calc(6% + 100px)} /* en el Central, 100 px mas a la derecha (pedido del usuario) */
.login .titulo-login .corchete{font-size:clamp(34px,4.2vw,56px);font-weight:700;letter-spacing:.04em;color:#fff;white-space:nowrap;padding:.12em .45em;text-shadow:0 2px 18px rgba(0,0,0,.75),0 0 1px #fff}
.login .titulo-login .corchete::before,.login .titulo-login .corchete::after{border-width:3px} /* corchetes mas gruesos en los titulos del login */ /* Gruppo solo trae 400: el navegador lo engrosa */
.login.panel .sub{font:600 12px var(--font);letter-spacing:.14em;text-transform:uppercase;color:var(--text-2);margin:4px 0 22px}
@media(max-width:860px){.login .lg-cs{height:140px} .login .lg-pg-esq{left:16px;top:16px;height:36px} .login .titulo-login,.login.unidad .titulo-login,.login.central .titulo-login{left:50%;top:58%;transform:translate(-50%,-50%)} .login .titulo-login .corchete{font-size:26px}}
.corchete{display:inline-block;position:relative;padding:.15em .8em;font:400 22px var(--font-title);letter-spacing:.06em;color:#fff}
.corchete::before,.corchete::after{content:"";position:absolute;width:.5em;height:.85em;border:1.5px solid var(--primary)}
.corchete::before{left:0;top:0;border-right:none;border-bottom:none;border-top-left-radius:6px}
.corchete::after{right:0;bottom:0;border-left:none;border-top:none;border-bottom-right-radius:6px}
@media(max-width:860px){.login.panel{grid-template-columns:1fr;grid-template-rows:150px 1fr;align-items:start} .login.panel .foto{min-height:0;height:150px} .login.panel .box{margin:0 auto}}
.login.app{position:relative;background:var(--carbon,#231F20) url(fondo-app.jpg) 68% 35%/cover no-repeat;align-items:stretch;overflow:hidden;min-height:100vh;min-height:100dvh}
.login.app .fondo{position:absolute;inset:0;display:flex;justify-content:center;align-items:flex-start;pointer-events:none}
.login.app .fondo img{width:min(88vw,420px);margin-top:max(7vh,28px);filter:drop-shadow(0 0 28px rgba(0,174,239,.45))}
.login.app .fondo::before{content:"";position:absolute;inset:0;background:rgba(35,31,32,.55)} /* la foto (licencia Adobe, LPR . MOVIL . V05) atenuada bajo el logo */
.login.app .fondo::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(35,31,32,0) 22%,rgba(35,31,32,.7) 44%,#231F20 60%)}
.login.app .fondo img{position:relative;z-index:1}
.login.app .box{position:relative;width:100%;max-width:440px;margin:auto 0 0;background:transparent;border:none;box-shadow:none;padding:0 22px 26px}
.login.app .box::before{content:"";display:block;height:min(52vh,430px)} /* deja ver el logo del fondo */
.login.app .sub{font:400 20px var(--font-title);letter-spacing:.1em;color:var(--primary);text-align:center;margin-bottom:18px}
.login .lg-pie{display:grid;justify-items:center;gap:10px;margin-top:26px;color:var(--text-2);font-size:12px} .login .lg-pie img{height:40px;width:auto;opacity:.85}
.login .lg-pie .lg-pg{height:22px;filter:brightness(0) invert(1);opacity:.7} /* Potential Group: la empresa que comercializa, discreto al pie */
.login .lg-pc{display:block;height:150px;width:auto;margin:0 auto 10px}

/* Persona reconocida (FaceScan fase 2): cara capturada, foto de enrolamiento y datos, sin barras de color. */
.rfila{display:grid;grid-template-columns:120px 120px 1fr;gap:14px;align-items:start;margin:0 0 12px}
.rcara{width:120px;aspect-ratio:1;object-fit:cover;border-radius:10px;border:1px solid var(--border);background:var(--surface-2);display:block}
.rcara.vacia{display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--muted)}
.rdatos{display:flex;flex-direction:column;gap:4px;min-width:0}
.atrcara{font-size:12px;color:var(--text-2);line-height:1.35;margin-top:2px}
figure>.atrcara{text-align:center}
@media (max-width:600px){.rfila{grid-template-columns:1fr 1fr}.rdatos{grid-column:1/-1}.rcara{width:100%}}
/* Personas (FaceScan fase 3): miniatura de la portada en tablas, fotos de la ficha y casillas de 40 px en pantallas tactiles */
.pz-mini{width:36px;height:36px;object-fit:cover;border-radius:6px;border:1px solid var(--border);display:block;background:var(--surface-2)} .pz-mini[title]{cursor:pointer}
.pz-recorte{margin-top:10px;display:flex;flex-direction:column;gap:8px}
.pz-recorte canvas{display:block;max-width:100%;max-height:min(55vh,320px);width:auto;height:auto;margin:0 auto;border-radius:10px;background:var(--surface-2);touch-action:none;cursor:move}
.pz-recorte-ctl{display:flex;align-items:center;gap:10px} .pz-recorte-ctl label{margin:0;white-space:nowrap} .pz-recorte-ctl input{flex:1;min-width:0}
.modal .ft .m-estado{margin-right:auto;align-self:center} .btn.ocupado{cursor:progress;opacity:.75}
.pz-fotos{display:flex;gap:14px;flex-wrap:wrap} .pz-fotos figure{margin:0;display:flex;flex-direction:column;gap:4px;align-items:flex-start}
/* Ficha: cada foto del mismo ancho, con una sola fila de acciones (Portada o «Usar de portada», y Quitar), y «Agregar
   foto» como una casilla más del mismo tamaño. */
.pz-fotos figure.pz-foto{width:140px;flex:0 0 140px} .pz-foto .rcara{width:100%}
.pz-foto-acc{display:flex;align-items:center;justify-content:space-between;gap:6px;width:100%;min-height:28px}
.pz-foto-acc .btn{padding:4px 0;font-size:12px;border:0;min-height:0} .pz-foto-acc .btn.txt-error{color:var(--error)} .pz-foto-acc .help{margin:0}
.pz-foto-nueva{width:100%;aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--border);border-radius:10px;color:var(--text-2);font-size:13px;cursor:pointer;margin:0;text-transform:none;letter-spacing:0;font-weight:600}
.pz-foto-nueva:hover{color:var(--primary);border-color:var(--primary)} .pz-foto-nueva svg{width:20px;height:20px}
.pz-chk{display:flex;flex-wrap:wrap;gap:4px 14px}
/* Regla con repeticion de un desconocido (fase 4a): «[3] veces en [24] [horas]» en una linea. */
.rg-cond{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px} .rg-cond input{width:96px} .rg-cond select{width:auto;min-width:110px} .rg-cond span{color:var(--text-2);font-size:13px}
@media(pointer:coarse){.pz-chk .chk{min-height:40px} .pz-chk .chk input{width:22px;height:22px}}

/* Busqueda forense (#/busqueda): la misma barra .filters de Eventos y Alertas, leida en secuencia de izquierda a
   derecha (rango y fechas; texto, clase, camara, unidad y Buscar; atributos del indice; zona y motivo plegados).
   Tarjetas uniformes: imagen 4:3, tres lineas de altura fija y siempre los mismos dos botones. */
/* La barra unica (.f-fechas, .f-campos); los atributos del indice se reparten el ancho de su fila. */
.bq-filtros #bqAtr select{flex:1 1 160px;max-width:none}
.bq-filtros [hidden]{display:none!important}
.filters .frow>.btn{height:var(--fh);padding:0 20px}
.bq-zona summary{cursor:pointer;color:var(--text-2);font-size:13px;min-height:40px;display:flex;align-items:center;gap:6px;width:max-content;list-style:none}
.bq-zona summary::-webkit-details-marker{display:none}
.bq-zona summary svg{width:16px;height:16px;flex:none;transform:rotate(-90deg);transition:transform .15s}
.bq-zona[open] summary svg{transform:none}
.bq-zona summary:hover{color:var(--text)}
.bq-zona .frow input{width:auto;flex:1 1 160px}
.bq-zona-ctl select{flex:0 0 120px}
.bq-zona-ctl .bq-nota{flex:1 1 200px;min-height:40px;display:flex;align-items:center}
.bq-mapa{position:relative;width:100%;height:280px;margin:0 0 10px;border-radius:var(--radius-sm);overflow:hidden;background:var(--surface-2);cursor:crosshair}
.bq-mapa .gpspin{cursor:grab}
#bqErr:not(:empty){color:var(--error);font-size:13px}
.bq-ref{display:flex;align-items:center;gap:14px;padding:10px 14px;margin-bottom:12px}
.bq-ref-img{width:80px;height:60px;flex:none;border-radius:var(--radius-sm);overflow:hidden;background:var(--surface-2);display:flex;align-items:center;justify-content:center;color:var(--text-2)}
.bq-ref-img img{width:100%;height:100%;object-fit:contain} .bq-ref-img svg{width:22px;height:22px}
.bq-ref-txt{flex:1;min-width:0} .bq-ref-txt .help{margin-top:2px}
.bq-cab{display:flex;align-items:baseline;gap:6px 14px;flex-wrap:wrap;margin:0 0 10px;font-size:13.5px;color:var(--text)}
.bq-nota{font-size:12.5px;color:var(--text-2)}
.bq-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}
.bq-grid>.loading{grid-column:1/-1;min-height:240px} .bq-grid>.empty{grid-column:1/-1}
.bq-card{background:var(--surface);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden;display:flex;flex-direction:column}
.bq-img{aspect-ratio:4/3;background:var(--surface-2);display:flex;align-items:center;justify-content:center;overflow:hidden}
/* contain, no cover (requisito 12): la miniatura es el recorte del objeto con su margen; cover en 4:3 dejaba ver solo el
   34 % central del alto de una persona (cabezas cortadas). El fondo --surface-2 rellena los lados. */
.bq-img img{width:100%;height:100%;object-fit:contain;display:block}
.bq-pend{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--text-2);font-size:12.5px} .bq-pend svg{width:28px;height:28px}
.bq-info{padding:10px 12px 12px;display:flex;flex-direction:column;gap:3px;flex:1}
.bq-t{display:flex;align-items:center;gap:8px;min-height:22px;overflow:hidden;white-space:nowrap} .bq-placa{font-family:var(--font-title);letter-spacing:.05em}
.bq-s{font-size:12.5px;color:var(--text-2);min-height:18px;line-height:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bq-aviso{font-size:12px;padding:2px 8px;border-radius:999px;background:var(--surface-2);color:var(--warning)}
.bq-acc{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:auto;padding-top:8px}
.bq-acc .btn{justify-content:center}
@media(max-width:860px){
  .bq-filtros .frow>*{flex:1 1 100%;min-width:0;max-width:none!important}
  .bq-filtros .frow select,.bq-filtros .frow .dt,.bq-filtros .frow input{width:100%;min-width:0}
  .bq-filtros .frow .daterange{display:flex} .bq-filtros .frow .daterange button{flex:1;justify-content:center;padding:0 6px}
  .bq-filtros .btn.primary{justify-content:center}
  .bq-grid{grid-template-columns:1fr}
  .bq-img{aspect-ratio:16/10}
  .bq-acc .btn{min-height:40px}
  .bq-mapa{height:240px}
}

/* ===== Recorridos por sesion (recorridos.js): pestana de la lista lateral del mapa ===== */
.rec-hd{display:flex;align-items:center;padding:0 4px;border-bottom:1px solid var(--border)}
.rec-filtros{display:flex;gap:8px;padding:8px 12px;border-bottom:1px solid var(--border)} .rec-filtros[hidden]{display:none}
.rec-filtros select{flex:1;min-width:0;width:auto;min-height:40px}
.rec-tabs{margin:0;border:none;gap:0;flex:1;flex-wrap:nowrap;overflow-x:auto} .rec-tabs .tab{padding:6px 10px;font-size:13px;white-space:nowrap;min-height:40px}
.rec-tabw{display:inline-flex;align-items:center;flex:none} .rec-tabs .tab.x{min-width:40px;padding:6px 8px;opacity:.7} .rec-tabs .tab.x:hover{opacity:1;color:var(--primary)}
.rec-lista,.rec-sesion{overflow:auto;max-height:60vh} .rec-lista{padding:0} .rec-sesion{padding:12px}
.rec-row{padding:10px 12px;border-bottom:1px solid var(--border);cursor:pointer;min-height:40px} .rec-row:hover{background:var(--surface-2)}
.rec-row-l1{display:flex;align-items:baseline;gap:8px;min-width:0}
.rec-row-l1 b{flex:1;min-width:0;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rec-uni{flex:none;max-width:45%;font-size:13px;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rec-row-l2{font-size:13px;color:var(--text-2);margin-top:2px}
.rec-vacio{font-size:13px;color:var(--text-2);padding:12px} .rec-sesion .rec-vacio{padding:4px 0}
.rec-nota{font-size:12px;color:var(--text-2);margin-top:8px}
/* Tarjeta de la sesion abierta: titulo, cifras 2x2, chips grises y la fila de reproduccion separada por un borde. */
.rec-card-t{font-size:15px;font-weight:700;line-height:1.35;color:var(--text)}
.rec-metricas{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}
.rec-met{display:flex;flex-direction:column;align-items:center;text-align:center;gap:2px;padding:8px 10px;background:var(--surface-2);border:1px solid var(--border);border-radius:8px;min-width:0}
.rec-met-e{font-size:12px;color:var(--text-2)}
.rec-met-v{font-size:18px;font-weight:600;color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rec-chips{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:10px} .rec-chip-ancho{grid-column:1/-1}
.rec-chip{display:inline-flex;align-items:center;justify-content:center;text-align:center;min-height:28px;padding:2px 10px;border-radius:999px;background:var(--surface-2);border:1px solid var(--border);font-size:12px;color:var(--text-2)}
.rec-play{display:flex;gap:8px;align-items:center;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
.rec-play .btn{flex:none;width:40px;min-width:40px;height:40px;min-height:40px;padding:0;justify-content:center;border-color:var(--border)}
.rec-play select{flex:none;width:auto;min-height:40px}
.rec-play input[type=range]{flex:1;min-width:0;width:auto;padding:0;background:none;border:none;accent-color:var(--primary)}
.rec-hora{flex:none;margin-left:auto;font-size:12px;color:var(--text-2);white-space:nowrap;font-variant-numeric:tabular-nums;text-align:right}
.rec-evs-hd{font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--text-2);margin-top:12px;padding-top:10px;border-top:1px solid var(--border)}
.rec-ev{display:flex;gap:8px;align-items:center;padding:4px 0;min-height:32px;cursor:pointer;opacity:.55} .rec-ev.pasado{opacity:1}
@media(max-width:860px){ .rec-lista,.rec-sesion{max-height:50vh} .mapa-suelto .flotalist,.mapa-videowall .flotalist{max-height:none;top:auto} .flotalist{position:static;width:auto;max-width:none;max-height:none;border-radius:0;box-shadow:none;border:none;border-top:1px solid var(--border)} }

/* ===== Cámaras y analítica (prototipos u_01-u_06 y v_02): fila de una línea, panel «Analíticas · <cámara>» ===== */
/* La tabla de cámaras con el relleno de tableta (12 px) también en escritorio: con 14 px desbordaba 21 px a 1280. */
.tbl-camaras td,.tbl-camaras th{padding-left:12px;padding-right:12px;line-height:normal} /* filas de 47 px, como u_01 */
.tbl-camaras .cam-sel{padding-left:8px;padding-right:0}
.tbl-camaras .cam-nom,.tbl-camaras .cam-uni{display:block;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tbl-camaras .cam-uni{margin-top:2px}
.tbl-camaras .cam-ana{display:flex;align-items:center;gap:8px}
/* Panel: cabecera fija (el panel es largo y al bajar no se pierde de qué cámara es) y una línea por parámetro. */
.modal.modal-fija .hd{position:sticky;top:0;z-index:2;background:linear-gradient(180deg,color-mix(in srgb,var(--primary) 12%,transparent),transparent),linear-gradient(180deg,var(--surface) 88%,color-mix(in srgb,var(--surface) 0%,transparent))}
.ana-cab{display:flex;align-items:center;gap:12px;margin:0 0 6px}
.ana-bloque{padding-left:18px}
.ana-fila{grid-template-columns:minmax(0,1fr) 440px;align-items:center;margin-top:2px;min-height:32px}
.ana-fila>label{margin:0;line-height:1.35} .ana-fila.ana-nota{min-height:0} .ana-nota .help{margin-top:2px}
.ana-ctl{display:flex;align-items:center;gap:10px;min-width:0}
.ana-ctl select{flex:1;min-width:0;padding:7px 10px;font-size:13px}
.ana-ctl .range{flex:1;min-width:0} .ana-ctl .range input{margin:0} .ana-ctl .range .rg{min-width:58px}
.ana-ctl .campo-sw{margin:0;flex:1;justify-content:flex-start}
.ana-origen{width:120px;flex:none;display:flex;align-items:center;gap:6px} .ana-origen .btn{margin-left:auto}
.ana-titulo{font-size:12.5px;font-weight:600;color:var(--text-2);margin:12px 0 2px}
.ana-region-t{display:flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;color:var(--text-3);margin:14px 0 6px}
.ana-region .modgeo{flex-direction:row;align-items:center;gap:14px;margin:0}
.ana-mini{position:relative;width:128px;height:72px;flex:none;border-radius:6px;background:var(--surface-2);overflow:hidden}
.ana-mini i{position:absolute;border:2px solid var(--primary);border-radius:3px;background:color-mix(in srgb,var(--primary) 14%,transparent);box-sizing:border-box}
/* Valores por defecto: la etiqueta de alcance («Por cámara») a la derecha de la etiqueta del campo, sin color. */
.campo-eti{display:flex;align-items:center;gap:6px} .campo-alcance{margin:0;font-weight:400;white-space:nowrap}
@media(max-width:860px){ .ana-fila{grid-template-columns:1fr} .ana-ctl{flex-wrap:wrap} .ana-ctl>:first-child{flex:1 1 100%} .ana-bloque summary{width:auto;align-items:flex-start;padding:11px 0} .ana-bloque summary svg{margin-top:1px} .ana-region .modgeo{flex-wrap:wrap} }

/* /sistema > Notificaciones (requisito 17): solo el nombre del tipo (el código va en el title), columnas a medida y
   una fila por tipo a la misma altura. Los conectores van en fila y saltan de línea solo si no caben; la tabla pide su
   ancho mínimo y se desplaza dentro de la tarjeta en vez de aplastar las columnas (antes una fila medía 140 px y el
   selector de la derecha quedaba cortado). */
.nf-tbl{min-width:1060px;table-layout:fixed}
.nf-tbl td{vertical-align:middle}
.nf-tbl th.nf-tipo{width:190px} .nf-tbl td.nf-tipo{text-align:left;overflow-wrap:anywhere}
.nf-tbl th.nf-prio{width:124px} .nf-tbl td.nf-prio .help{margin:0;white-space:nowrap} .nf-tbl th.nf-col{width:72px} .nf-tbl th.nf-sel{width:190px} .nf-tbl th.nf-son{width:130px} .nf-tbl th.nf-num{width:104px}
.nf-tbl td select{margin:0;width:100%;min-width:0;padding:7px 8px;font-size:13px}
.nf-tbl td.nf-con{text-align:left;min-width:150px} .nf-tbl thead th{white-space:normal;line-height:1.25}
.nf-tbl td.nf-con .chip{margin:2px 4px 2px 0;padding:3px 9px;font-size:12px}

/* /sistema > Almacenamiento (requisito 18): tabla de espacios alineada, prosa en la ayuda y fechas en dos líneas. */
.alm-tbl th.alm-nom{width:260px} .alm-tbl td.alm-nom{text-align:left;white-space:nowrap} .alm-tbl th.alm-cuota{width:150px} .alm-tbl th.alm-acc{width:200px}
.alm-tbl td{vertical-align:middle} .alm-tbl td.alm-uso{text-align:left} .alm-tbl td.alm-acc{text-align:right;white-space:nowrap}
.alm-tbl td select{margin:0;width:auto;min-width:120px}
.alm-cifra{display:flex;align-items:baseline;gap:8px} .alm-cifra b{font-family:var(--font-title);font-size:17px;color:var(--text)} .alm-cifra span{color:var(--text-2);font-size:12px}
.alm-barra{height:5px;background:var(--surface-2);border-radius:3px;overflow:hidden;margin-top:6px;max-width:280px} .alm-barra>div{height:100%}
.alm-extra{margin:4px 0 0}
.alm-pie{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 18px;border-top:1px solid var(--border)}
.alm-pie label{margin:0;display:inline-flex;align-items:center;gap:4px} .alm-pie select{width:auto;min-width:200px;margin:0} .alm-pie .sp{flex:1} .alm-pie .help{margin:0}
/* Retención de datos (Plan 3): plazo y espacio editables por tipo. */
.ret-tbl th.ret-col{width:150px} .ret-tbl th.ret-fecha{width:120px} .ret-tbl input.ret-num{width:96px;margin:0;text-align:center}
.ret-error{color:var(--error);margin:0;padding:8px 18px 0}
.fecha2{display:inline-flex;flex-direction:column;line-height:1.15} .fecha2 b{font-weight:600;color:var(--text);font-variant-numeric:tabular-nums} .fecha2 small{color:var(--text-2);font-size:12px}
.rb-resumen{display:flex;gap:28px;flex-wrap:wrap;align-items:flex-start;margin-bottom:14px} .rb-resumen .help{margin:0 0 2px} .rb-resumen small.help{display:block;margin-top:2px} .rb-resumen .sp{flex:1}
.rb-campos{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:14px 16px;align-items:start}
.rb-campo{display:flex;flex-direction:column;gap:6px;min-width:0} .rb-campo .help{margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rb-campos select,.rb-campos input{margin:0;width:100%;height:40px;box-sizing:border-box;padding:0 10px}
.rb-sw{height:40px;display:flex;align-items:center}
.rb-acc{display:flex;justify-content:flex-end;margin:14px 0 16px}
.rb-cifrado{display:flex;gap:16px;flex-wrap:wrap;align-items:center;margin:0 0 14px;padding:12px 14px;border:1px solid var(--border);border-radius:var(--radius-sm)}
.rb-cif-t{flex:1;min-width:200px;display:flex;align-items:center;gap:4px} .rb-cifrado .help{margin:0 0 2px}

/* Separador «·» y textos secundarios dentro de pestañas y títulos (revision 2026-10-16): la fuente de títulos dibuja el
   punto alto («26.028 ˙ Del Central»). Contadores, «· Del Central» y el separador de un título van en la del cuerpo. */
.tabbar .tab .help,.tabbar .tab [data-cuenta],.sep{font-family:var(--font);letter-spacing:normal}
.tabbar .tab .help{margin:0;font-weight:500}

/* Subtitulo de dos renglones como mucho (Evidencia, columna Alerta: la nota de la lista ocupaba hasta nueve); completo en el title */
.sub2{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--text-2);font-size:12px;line-height:1.35;margin-top:2px}

/* ===== Ver video del evento (video-eventos v2): copia del VideoPlayerModal de facescan sobre el cascarón .modal =====
   Botón «Ver video»: .btn.danger con el Play de lucide (16 px; 14 px en las filas de tabla). El modal lleva línea bajo
   la cabecera y sobre el pie; los estados van centrados con 64 px de aire. Sin colores nuevos. */
.btn.sm[data-video] svg,.btn.sm[data-video-rec] svg{width:14px;height:14px}
.alerts-tbl th.vcel,.alerts-tbl td.vcel{width:1%;white-space:nowrap}   /* la columna de video, al ancho del botón: no estrecha las demás */
@media(min-width:641px){ .alerts-tbl:has(td.vcel) td[data-label="Zona"]{white-space:nowrap} }   /* con la columna de video, «Zona 1» no se parte */
.modal.mvideo .hd{border-bottom:1px solid var(--border);align-items:flex-start}
.modal.mvideo .hd h3{display:flex;flex-direction:column;gap:4px;min-width:0}
.modal.mvideo .vtit{display:flex;align-items:center;min-height:30px;overflow-wrap:anywhere}
.modal.mvideo .vtit .placa-lpr{height:30px}
.modal.mvideo .vsub{font-family:var(--font);font-size:13px;font-weight:400;letter-spacing:0;color:var(--text-2);font-variant-numeric:tabular-nums}
.modal.mvideo .ft{border-top:1px solid var(--border);align-items:center}
.modal.mvideo .ft .vft-izq{margin-right:auto;display:flex} .modal.mvideo .ft .m-estado{display:none}
.vestado{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:64px 0;text-align:center}
.vestado .spin{width:48px;height:48px;border:3px solid var(--border);border-top-color:var(--primary);border-radius:50%;animation:spin .8s linear infinite}
.vestado .vaviso{width:80px;height:80px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:40px;font-weight:700;line-height:1;
  color:var(--warn-fill);background:color-mix(in srgb,var(--warn-fill) 20%,transparent)}
.vestado .vmsg{margin:0;font-weight:600;color:var(--text)} .vestado .help{margin:0;max-width:440px}
.vclip video{display:block;width:100%;aspect-ratio:16/9;background:#000;border-radius:8px}
.vclip .vmeta{display:flex;justify-content:space-between;gap:12px;margin-top:12px;font-size:13px;color:var(--text-2);font-variant-numeric:tabular-nums}
@media(max-width:640px){ .alerts-tbl tbody td.vcel .btn{width:100%;justify-content:center} }

/* Panel › Mensajes (2026-10-23): con «Al Central» y «Difundir» la cabecera no cabe en pantallas de 1440: el titulo no se
   parte y los botones bajan a su propia linea, a la derecha, en vez de salirse de la tarjeta */
.card .hd.hd-msgs{flex-wrap:wrap;row-gap:8px} .card .hd.hd-msgs h3{white-space:nowrap} .card .hd.hd-msgs .btn{white-space:nowrap}
.card .hd.hd-msgs .acc{margin-left:auto;display:flex;gap:8px}

/* Analíticas por grupo (2026-10-23): fila de título en la tabla de Cámaras › Analítica y en los paneles por cámara */
.alerts-tbl tr.grupo-mod td{text-align:left;padding:16px 14px 6px;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
  color:var(--primary);border-bottom:1px solid var(--border)}
.alerts-tbl tbody tr.grupo-mod:hover{background:transparent}
.grupottl.grupo-cam{margin:16px 0 2px;color:var(--primary);font-size:12px;text-transform:uppercase;letter-spacing:.05em}
.grupottl.grupo-cam:first-child{margin-top:4px}
