/* ════════════════════════════════════════════════════════════════════════════
   GEOPORTAL · CASA DE GOBIERNO — Sistema de diseño
   LOSA INSTITUCIONAL (rediseño 2026-08-21). Cartel antes que sitio web:
   bloques de color a sangre, cero degradados, cero cristal, radio 0 y
   contraste duro. O losa guinda con texto blanco, o losa blanca con texto
   carbón; el gris solo vive como filete de 1 px y como texto secundario.
   Sombra únicamente donde un panel flota sobre el mapa vivo, y plana.
   ════════════════════════════════════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Cabin:wght@600;700&family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,400&family=JetBrains+Mono:wght@400;500;600&display=swap');

/* Bricolage Grotesque — tipografía del nombre "Atlas de Proximidad" (misma que el deck) */
@font-face {
  font-family: 'Bricolage Grotesque';
  src: url('/static/fonts/bricolage-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* ── Marca institucional ─────────────────────────────────────────── */
  --dorado:   #942148;   /* institucional: bordes, acentos, botón secundario — NUNCA texto */
  --dorado-l: #b52d5e;   /* filetes sobre guinda, brillos decorativos */
  --dorado-d: #942148;   /* dorado-TEXTO: 6:1 sobre marfil/blanco */
  --guinda:   #942148;   /* PRINCIPAL: botones, foco, selección (8:1 sobre marfil) */
  --guinda-l: #b52d5e;   /* hover */
  --guinda-d: #7d1840;   /* bandas/topbar/active/drenched (marfil encima: 9.9:1) */
  --gris:     #55585a;
  --marfil:   #ffffff;

  /* ── Paleta extendida (capas y acentos) ──────────────────────────── */
  --naranja1: #f6d84a;
  --naranja2: #f59217;
  --naranja3: #ed6414;
  --rosa1:    #d71f59;
  --rosa2:    #ed046c;
  --azul1:    #73ace8;
  --azul2:    #266ab4;
  --purpura:  #bf4889;
  --verde:    #2ecc71;
  --verde-text: #12753f; /* verde usado como texto sobre claro (5.7:1) */

  /* ── Rampa SECUENCIAL guinda (magnitud) — data-viz y coropletas ────
     Un solo tono, claro→oscuro. Validada con el validador de la skill
     `dataviz` (--ordinal, superficie #ffffff): monotonía de luminosidad,
     ΔL ≥ .06 entre pasos contiguos y extremo claro ≥ 2:1 sobre blanco.
     Sub-rampa de 3 pasos (embudos, medidores): --sq-2 · --sq-4 · --sq-6.
     NO sustituye a la paleta extendida: esa codifica IDENTIDAD (capas,
     categorías); esta codifica CANTIDAD. */
  --sq-0: #ded9d6;   /* cero / sin dato — gris neutro, fuera de la rampa */
  --sq-1: #e0a6bd;
  --sq-2: #cd7a9b;
  --sq-3: #b84f78;
  --sq-4: #9e2352;
  --sq-5: #7d1840;
  --sq-6: #54082a;
  --sq-track: rgba(148,33,72,.11);  /* pista sin llenar de un medidor */

  /* Tipografía del nombre "Atlas de Proximidad" (misma que el deck) */
  --font-brand: 'Bricolage Grotesque', 'Cabin', sans-serif;

  /* ── Superficies — base blanca de trabajo, marfil destacado ──────── */
  --bg:       #f5f2f3;   /* página */
  --bg2:      #efebec;   /* pistas y pozos PEQUEÑOS (barras, tracks) — nunca losas */
  --surface:  #ffffff;   /* losa blanca: paneles, formularios, tablas */
  --surface2: #ffffff;   /* sin tintes intermedios: la separación es el filete */
  --surface3: #ffffff;   /* el marfil #fdf7f9 se retiró con el rediseño de losa */
  --border:   #ded7d9;   /* filete tenue: separación interna, bajo riesgo */
  --border2:  #d6cfd1;   /* filete de separación (valor canónico de la losa) */
  /* Filete DURO. Rol nuevo del rediseño de losa (etapa B): lo que flota sobre
     el mapa vivo o cose instrumentos entre sí no puede colgar de un gris
     claro — sobre Positron (#f5f5f3) un filete #d6cfd1 da 1.3:1 y el panel se
     deshace. Es el mismo carbón del texto, pero como BORDE tiene rol propio y
     por eso token propio, no un `var(--text)` prestado. */
  --rule-hard: #2b2622;
  --border-input: #55585a; /* borde de campo: duro, 7:1 — el campo se ve, no se adivina */
  /* Los tres tokens de "cristal" sobreviven SOLO por compatibilidad de nombres:
     en losa no hay translucidez. Todos apuntan a blanco macizo. */
  --glass:    #ffffff;
  --glass-hi: #ffffff;
  --glass-solid: #ffffff;

  /* ── Alias de superficie usados por modales/constructor de campos ── */
  --bg-panel: var(--surface);
  --bg-input: #ffffff;

  /* ── Texto ───────────────────────────────────────────────────────── */
  --text:     #2b2622;
  --text-2:   #55585a;
  --text-dim: #6f6a60;
  --text-faint: #8a8479;

  /* ── Sombras tintadas a guinda + glow ────────────────────────────── */
  /* ── Sombra: solo para lo que FLOTA sobre el mapa vivo ───────────────
     Plana y sin tinte de color. En el resto del chrome la profundidad la da
     el filete y el corte de color, no el desenfoque. */
  /* FILETE DOBLE — la única forma de anclar un panel sobre un mapa que no
     controlamos. MEDIDO en la página viva (2026-08-21) pintando el lienzo
     entero con cada color extremo que el mapa puede producir y muestreando la
     columna de píxeles del canto:

        canto            Positron #f5f5f3   guinda #942148   morado #7d4f9c
        carbón #2b2622        13.71:1            1.83:1           2.47:1
        blanco #ffffff         1.09:1            8.17:1           6.05:1
        guinda #942148         7.48:1            1.00:1           1.35:1

     Ninguno solo aguanta el 3:1 en las tres situaciones; el par carbón+blanco
     (o guinda+blanco) siempre deja un canto por encima de 6:1. Carbón por
     dentro, blanco por fuera, más la sombra plana. Cero halo, cero tinte. */
  --lift:    0 0 0 1px #ffffff, 0 6px 16px -8px rgba(0,0,0,.34);
  --lift-sm: 0 0 0 1px #ffffff, 0 3px 8px -5px rgba(0,0,0,.28);

  --shadow:    0 6px 16px -8px rgba(0,0,0,.34);
  --shadow-sm: 0 3px 8px -5px rgba(0,0,0,.28);
  /* Los dos "glow" quedan como anillo macizo: mismo nombre, cero halo. */
  --glow-gold: 0 0 0 1px var(--guinda);
  --glow-wine: 0 0 0 1px var(--guinda);
  --ring:      0 0 0 3px rgba(148,33,72,.32);

  /* ── Geometría y movimiento ──────────────────────────────────────── */
  /* Radio 0 en todo el chrome. Los tres tokens siguen existiendo para no
     romper las cuatro pantallas; todos valen 0. El único radio vivo es el de
     una simbología redonda (punto de interés, spinner). */
  --r-sm: 0px;
  --r:    0px;
  --r-lg: 0px;
  /* --ease-spring conserva el nombre pero ya no rebota: en una interfaz de
     jornada completa el rebote se lee como ruido. Ease-out fuerte. */
  --ease-spring: cubic-bezier(.23,1,.32,1);
  --ease-out:    cubic-bezier(.22,.68,0,1);
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* ── Escala de profundidad (z-index) ─────────────────────────────── */
  --z-map: 1;
  --z-readout: 60;   /* lecturas ancladas al mapa (censo): informan, no mandan */
  --z-panel: 100;    /* controles: riel, hoja inferior, búsqueda */
  --z-sidebar: 200;
  --z-toast: 9000;

  color-scheme: light;
}

/* ── Reset ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  font-family: 'Roboto', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* El velo de grano se retiró con el rediseño de losa: el color es plano y
   macizo, y un ruido fijo a z-index 9999 solo ensuciaba los colores de capa. */

::selection { background: rgba(148,33,72,.35); color: var(--text); }

/* ── Scrollbar ─────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--guinda-d);
  border: 2px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--guinda); }

/* ── Tipografías ───────────────────────────────────────────────────── */
.font-cabin { font-family: 'Cabin', sans-serif; font-weight: 700; }
h1, h2, .brand-text { font-family: 'Cabin', sans-serif; font-weight: 700; }
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* Etiqueta institucional reutilizable */
.eyebrow {
  font-family: 'Cabin', sans-serif;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.6px;
  color: var(--dorado-d);
  font-size: 10px;
}

/* ── Botones ───────────────────────────────────────────────────────── */
.btn {
  --btn-bg: var(--surface3);
  --btn-fg: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  text-decoration: none;   /* .btn también se usa sobre <a> (pie de la landing) */
  font-family: 'Roboto', sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .3px;
  color: var(--btn-fg);
  background: var(--btn-bg);
  transition: transform .12s var(--ease-spring),
              box-shadow .2s var(--ease-out),
              filter .15s, background .15s;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
/* Sin `translateY` en hover: una losa no levita. La respuesta al clic sí es
   física — 120 ms de compresión, que es lo que tarda el dedo en soltar. */
.btn:active { transform: scale(.985); }
/* El anillo `--ring` solo (rgba guinda al 30%) da 1.72:1 sobre blanco y 1.06:1
   sobre la banda guinda: no alcanza el 3:1 de WCAG para elementos no textuales.
   El contorno sólido es el indicador real; el halo se queda como refuerzo. */
.btn:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; box-shadow: var(--ring); }

/* Losa de acción: color macizo, sin sombra. El hover no levanta el botón,
   oscurece la losa — el movimiento se reserva para lo que de verdad se mueve. */
.btn-primary   { background: var(--guinda); color: var(--marfil); font-weight: 700; box-shadow: none; }
.btn-primary:hover { background: var(--guinda-l); }
.btn-primary:active { background: var(--guinda-d); }
.btn-secondary { background: var(--surface); color: var(--guinda); border: 1px solid var(--guinda); box-shadow: none; }
.btn-secondary:hover { background: var(--guinda); color: var(--marfil); }
.btn-outline   { background: transparent; border-color: var(--guinda); color: var(--guinda); }
.btn-outline:hover { background: var(--guinda); color: var(--marfil); border-color: var(--guinda); }
.btn-danger    { background: #7d1f1f; color: #fff; border-color: #7d1f1f; }
.btn-danger:hover { background: #5c1616; }
.btn-sm        { padding: 6px 12px; font-size: 12px; }

/* ── Formularios ───────────────────────────────────────────────────── */
.form-group { margin-bottom: 14px; }
.form-label {
  display: block;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: .9px;
}
.form-control {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  /* El campo se ve, no se adivina: --border2 daba 1.28:1 sobre blanco, por
     debajo del 3:1 que WCAG 1.4.11 pide al contorno de un control. */
  border: 1px solid var(--border-input);
  border-radius: var(--r-sm);
  color: var(--text);
  font-family: 'Roboto', sans-serif;
  font-size: 13px;
  transition: border-color .18s, box-shadow .18s, background .18s;
}
/* Los placeholders son pistas legibles, no texto deshabilitado: --text-dim
   alcanza 5:1 sobre --bg-input (AA), --text-faint solo 3.6 (ilegible). */
.form-control::placeholder { color: var(--text-dim); }
.form-control:hover { border-color: rgba(148,33,72,.35); }
.form-control:focus {
  outline: none;
  border-color: var(--guinda);
  background: var(--surface);
  box-shadow: var(--ring);
}
select.form-control { cursor: pointer; }

/* ════════════════════════════════════════════════════════════════════
   MARCA · piezas compartidas por las cuatro pantallas
   El bloque LOGIN (.login-page/.login-card/…) y la LANDING vieja
   (.landing-topbar/.hero-*/.lsec-*/.bsec-*/.scope-*/.landing-footer) se
   eliminaron el 2026-08-21: ninguna clase estaba referenciada por un HTML
   ni por un JS desde el rediseño de la pantalla de acceso (landing.css, `lp-`).
   Se llevaron 25 de los 52 degradados del archivo.
   ════════════════════════════════════════════════════════════════════ */

/* Barra de progreso de lectura (pantalla de acceso) */
.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0;
  background: var(--guinda);
  z-index: 9998;
  transition: width .08s linear;
}

@keyframes cardIn { from { opacity: 0; transform: translateY(12px); } }

/* ── Signo del wordmark "Atlas de Proximidad" (logomark del deck) ──
   Reutilizable: es el emblema de marca en todos los rótulos.
   Escala con width/height del contexto. Por defecto trazos carbón para
   fondos claros; sobre losa guinda se usa la variante marfil. */
.brand-sign {
  flex: none; display: inline-block; vertical-align: middle;
  background: center / contain no-repeat
    url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%20fill='none'%3E%3Ccircle%20cx='24'%20cy='24'%20r='21'%20stroke='rgba(85,88,90,.6)'%20stroke-width='1.4'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='14'%20stroke='rgba(55,166,188,.9)'%20stroke-width='1.4'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='7'%20stroke='rgba(225,99,59,.95)'%20stroke-width='1.4'/%3E%3Cpath%20d='M24%205%20V43%20M5%2024%20H43'%20stroke='rgba(85,88,90,.45)'%20stroke-width='1'/%3E%3Cpath%20d='M24%2020%20L28%2026%20H20%20Z'%20fill='%23E1633B'/%3E%3C/svg%3E");
}
/* Variante marfil: para el signo sobre cualquier losa guinda. */
.topbar .brand-sign,
.lp-topbar .brand-sign,
.lp-brandline .brand-sign,
.lp-footer .brand-sign,
.on-guinda .brand-sign {
  background-image:
    url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%20fill='none'%3E%3Ccircle%20cx='24'%20cy='24'%20r='21'%20stroke='rgba(255,255,255,.6)'%20stroke-width='1.4'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='14'%20stroke='rgba(120,205,222,.9)'%20stroke-width='1.4'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='7'%20stroke='rgba(240,150,110,.95)'%20stroke-width='1.4'/%3E%3Cpath%20d='M24%205%20V43%20M5%2024%20H43'%20stroke='rgba(255,255,255,.45)'%20stroke-width='1'/%3E%3Cpath%20d='M24%2020%20L28%2026%20H20%20Z'%20fill='%23F0966E'/%3E%3C/svg%3E");
}

/* ════════════════════════════════════════════════════════════════════
   LAYOUT MAPA
   ════════════════════════════════════════════════════════════════════ */
.app-layout {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
}

/* ── Topbar ────────────────────────────────────────────────────────── */
.topbar {
  height: 48px;
  /* Sello guinda: la barra firma todas las pantallas de la plataforma */
  background: var(--guinda-d);
  border-bottom: none;
  display: flex;
  align-items: center;
  padding: 0 18px;
  gap: 13px;
  flex-shrink: 0;
  z-index: var(--z-sidebar);
  position: relative;
}
/* Filete dorado que remata el sello */
.topbar::after {
  content: '';
  position: absolute;
  bottom: -2px; left: 0; right: 0;
  height: 2px;
  background: var(--dorado-l);
}
.topbar .emblem {
  width: 24px; height: 24px;
  flex-shrink: 0;
  transition: transform .25s var(--ease-spring);
}
.topbar .emblem:hover { transform: scale(1.1); }
.topbar .brand {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 17px;
  color: var(--marfil);
  letter-spacing: -.005em;
}
.topbar .brand-sep {
  width: 1px;
  height: 20px;
  background: rgba(255,255,255,.35);
  flex-shrink: 0;
}
.topbar .user-badge {
  font-size: 11px;
  color: var(--marfil);
  background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.35);
  border-radius: 0;
  padding: 4px 12px;
  letter-spacing: .3px;
}
.topbar .nav-links { margin-left: auto; display: flex; gap: 2px; flex-shrink: 0; }
.topbar a {
  color: #f0cad8;
  text-decoration: none;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .6px;
  padding: 6px 12px;
  border-radius: 0;
  white-space: nowrap;
  transition: background .15s, color .15s;
  text-transform: uppercase;
}
.topbar a:hover { background: var(--guinda-l); color: var(--marfil); }
.topbar a.active {
  background: var(--marfil);
  color: var(--guinda-d);
  font-weight: 700;
  box-shadow: none;
}
.topbar a.active:hover { background: var(--marfil); color: var(--guinda); }

.map-container {
  display: flex; flex: 1; overflow: hidden;
  /* Ancho vivo del riel: la búsqueda y el censo se anclan a su borde, no a la
     ventana, para que la "L" de chrome (topbar + riel) sea una sola pieza. */
  --rail-w: 252px;
}
.map-container.rail-off { --rail-w: 0px; }
#map { flex: 1; background: var(--bg); }

/* Controles nativos de MapLibre afinados a la marca */
.maplibregl-ctrl-group {
  background: var(--surface) !important;
  border: 1px solid var(--rule-hard) !important;
  border-radius: var(--r-sm) !important;
  box-shadow: var(--lift-sm) !important;
  overflow: hidden;
}
.maplibregl-ctrl-group button { background: transparent !important; }
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--border) !important; }
.maplibregl-ctrl-group button:hover { background: rgba(148,33,72,.10) !important; }
/* El piso de foco global va en `:where()` (especificidad 0) y el `outline:none`
   del vendor lo pisaba: zoom y brújula tabulaban con el halo azul de fábrica.
   Aquí se declara con especificidad propia y se apaga el halo. El contorno va
   por dentro (offset negativo) porque el grupo tiene `overflow:hidden`. */
.maplibregl-ctrl-group button:focus,
.maplibregl-ctrl-group button:focus-visible {
  outline: 2px solid var(--guinda);
  outline-offset: -2px;
  box-shadow: none !important;
}
.maplibregl-ctrl-group button:focus:not(:focus-visible) { outline: none; }
/* La píldora de atribución es del vendor y trae su propio radio con
   especificidad (0,2,0): sin `!important` gana ella y se ve redonda a 390 px. */
.maplibregl-ctrl-attrib,
.maplibregl-ctrl-attrib.maplibregl-compact,
.maplibregl-ctrl-attrib.maplibregl-compact-show {
  background: var(--surface) !important;
  border-radius: 0 !important;
}
.maplibregl-ctrl-attrib a { color: var(--text-dim) !important; }

/* ── Popups del mapa ───────────────────────────────────────────────── */
.maplibregl-popup-content {
  /* Superficie de decisión sobre el mapa: blanco opaco + filete guinda arriba,
     el mismo remate que la topbar y el censo. */
  background: var(--surface) !important;
  border: 1px solid var(--rule-hard) !important;
  border-top: 3px solid var(--guinda) !important;
  border-radius: 0 !important;
  color: var(--text) !important;
  box-shadow: var(--lift) !important;
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  padding: 9px 12px !important;
}
.maplibregl-popup-content b { color: var(--guinda-d); }
.maplibregl-popup-tip { border-top-color: var(--surface) !important; border-bottom-color: var(--guinda) !important; }
.maplibregl-popup-close-button { color: var(--text-dim); font-size: 16px; padding: 0 5px; }
.maplibregl-popup-close-button:hover { background: none; color: var(--guinda); }

/* ════════════════════════════════════════════════════════════════════
   SIDEBAR
   ════════════════════════════════════════════════════════════════════ */
.sidebar {
  width: 340px;
  /* Panel opaco sobre el mapa: el desenfoque de fondo era lo más caro al panear */
  background: var(--surface);
  border-left: 3px solid var(--guinda);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  flex-shrink: 0;
  /* Filete doble: la espina guinda de 3 px firma el panel sobre el basemap
     claro (7.5:1) y el anillo blanco de --lift lo despega de la geometría de
     dato guinda/morada, donde esa misma espina da 1.0:1. */
  box-shadow: var(--lift);
  transition: transform .3s var(--ease-out);
}
.sidebar.hidden { transform: translateX(100%); }
/* Banda guinda: el sello en la cabecera del panel de predio */
.sidebar-header {
  padding: 11px 14px 10px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--guinda-d);
  position: relative;
  flex-shrink: 0;
}
.sidebar-header::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 2px;
  background: var(--guinda-l);
}
.sidebar-id { min-width: 0; }
.sidebar-header :is(h2, h3) {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 14px;
  color: var(--marfil);
  letter-spacing: .2px;
}
.sidebar-sub {
  font-size: 11px;
  color: #f0cad8;
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sidebar-sub:empty { display: none; }
.sidebar-close {
  background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.35);
  color: var(--marfil);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  width: 28px; height: 28px;
  border-radius: 0;
  transition: color .15s, background .15s, transform .15s var(--ease-spring);
}
.sidebar-close:hover { color: var(--guinda-d); background: var(--marfil); }
.sidebar-body { padding: 18px; overflow-y: auto; flex: 1; }

/* ── Info predio — ficha catastral, no tarjeta ─────────────────────
   Filas a hilo, etiqueta a la izquierda, valor alineado. Los datos
   catastrales (id, manzana, lote) van en mono tabular. */
.predio-info {
  background: none;
  border: 0;
  border-top: 1px solid var(--border2);
  border-radius: 0;
  padding: 0;
  margin-bottom: 16px;
  font-size: 12px;
}
.predio-info .pi-row {
  display: flex;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.predio-info .pi-row:last-child { border-bottom: none; }
.predio-info .pi-label { color: var(--text-dim); width: 92px; flex-shrink: 0; font-size: 10px; text-transform: uppercase; letter-spacing: .5px; padding-top: 2px; }
.predio-info .pi-val { color: var(--text); font-weight: 500; }
.predio-info .pi-val.pi-num { font-family: 'JetBrains Mono', monospace; font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── Lista beneficiarios ───────────────────────────────────────────── */
.ben-list { margin-top: 16px; }
.ben-item {
  background: var(--bg2);
  border-radius: var(--r-sm);
  padding: 11px 12px;
  margin-bottom: 7px;
  font-size: 12px;
  border: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  transition: border-color .15s, background .15s;
  animation: rowIn .35s var(--ease-out) both;
}
@keyframes rowIn { from { opacity: 0; transform: translateX(8px); } }
/* El tinte al 5 % daba 1.05:1 sobre la losa: no era señal, era humo. La
   marca de fila recorrida es el filete interior de la izquierda. */
.ben-item:hover { border-color: var(--guinda); box-shadow: inset 3px 0 0 var(--guinda); }
.ben-item .ben-name { font-weight: 600; color: var(--text); }
.ben-item .ben-sexo {
  display: inline-block;
  width: 15px; text-align: center;
  margin-right: 5px;
  font-weight: 700;
  border-radius: 0;
}
.ben-item .ben-sexo-mujer  { color: var(--guinda-l, #b52d5e); }
.ben-item .ben-sexo-hombre { color: var(--azul2, #266ab4); }
.ben-item .ben-numint {
  font-weight: 400; font-size: 10px; color: var(--azul2);
  background: rgba(38,106,180,.10); border-radius: 0;
  padding: 1px 6px; margin-left: 4px; white-space: nowrap;
}
.ben-item .ben-prog { color: var(--text-dim); font-size: 11px; margin-top: 3px; }
.ben-item .ben-entrega {
  font-weight: 600; font-size: 10px; color: var(--guinda, #942148);
  background: rgba(148,33,72,.10); border-radius: 0;
  padding: 1px 6px; margin-left: 4px; white-space: nowrap;
}
.ben-item .ben-nobenef {
  font-weight: 600; font-size: 10px; color: var(--gris-carbon, #55585a);
  background: rgba(85,88,90,.12); border-radius: 0;
  padding: 1px 6px; margin-left: 6px; white-space: nowrap;
}
.ben-estado { font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 0; margin-left: 4px; }
/* "Inscrito" era una pastilla marfil (#f0e6d6), residuo del sistema anterior.
   Pasa a losa guinda profunda con texto marfil: 9.6:1 y dentro de la paleta. */
.ben-estado-inscrito { background: var(--guinda-d); color: var(--marfil); }
.ben-estado-carta    { background: #fbe3ec; color: #942148; }
.ben-item .ben-obs { color: var(--text-dim); font-size: 11px; margin-top: 3px; font-style: italic; }
.ben-item .ben-del {
  background: none;
  border: none;
  /* icono accionable: --text-dim cumple 1.4.11 (≥3:1); --text-faint fallaba (2.6) */
  color: var(--text-dim);
  cursor: pointer;
  font-size: 14px;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  transition: color .15s, transform .15s var(--ease-spring);
  flex-shrink: 0;
}
.ben-item .ben-del:hover { color: var(--guinda-l); transform: scale(1.25); }
.ben-item .ben-del:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; color: var(--guinda-l); }
.ben-item .ben-actions { display: flex; gap: 2px; flex-shrink: 0; }
.ben-item .ben-edit {
  background: none; border: none; color: var(--text-dim); cursor: pointer;
  font-size: 14px; padding: 2px 6px; border-radius: var(--r-sm);
  transition: color .15s, transform .15s var(--ease-spring);
}
.ben-item .ben-edit:hover { color: var(--guinda); transform: scale(1.25); }
.ben-item .ben-edit:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; color: var(--guinda); }
/* Editor en línea del beneficiario */
.ben-edit-form { width: 100%; }
.ben-edit-form .form-label { margin-top: 6px; }
.ben-edit-form .form-control { margin-bottom: 2px; }
.ben-edit-btns { display: flex; gap: 6px; margin-top: 8px; }

/* Tracker de entregas por persona (X de N, historial, registrar/quitar) */
/* El tracker era una caja marfil (#faf7f2) con filete beige: losa blanca con
   el filete canónico. Lo que lo delimita es el canto, no un tinte de fondo. */
.ben-entregas-tracker { margin: 8px 0; padding: 8px; border: 1px solid var(--border2); border-radius: 0; background: var(--surface); }
.tracker-head { font-size: 12px; margin-bottom: 6px; }
/* Punto de entrega pendiente: pista vacía (--bg2, que es justo el token de
   "pozo pequeño"), no un beige. Entregada: losa guinda. */
.tracker-head .dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-left: 3px; background: var(--bg2); border: 1px solid var(--border2); vertical-align: middle; }
.tracker-head .dot.on { background: var(--guinda); border-color: var(--guinda); }
.tracker-row { display: flex; justify-content: space-between; align-items: center; font-size: 12px; padding: 2px 0; }
.tracker-del { border: none; background: transparent; color: #b23a48; cursor: pointer; }
.tracker-add { display: flex; gap: 4px; margin-top: 6px; flex-wrap: wrap; }
.tracker-add input { flex: 1 1 90px; min-width: 90px; }
.tracker-nota { font-size: 12px; color: #55585a; }

/* Advertencia de posible beneficiario duplicado (aparece bajo el formulario de
   alta mientras se escribe el nombre). Informativa, no bloqueante. */
.ben-dup-warn {
  margin: 10px 0 12px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(148,33,72,.45);
  background: rgba(148,33,72,.07);
  font-size: 12px;
  color: var(--text);
  animation: rowIn .3s var(--ease-out) both;
}
.ben-dup-warn .dup-head {
  display: flex; align-items: center; gap: 6px;
  font-weight: 700; color: var(--guinda);
  margin-bottom: 8px; line-height: 1.3;
}
.ben-dup-warn .dup-match { padding: 6px 0; }
.ben-dup-warn .dup-match + .dup-match { border-top: 1px solid rgba(148,33,72,.20); }
.ben-dup-warn .dup-name { font-weight: 600; color: var(--text); }
.ben-dup-warn .dup-prog { color: var(--dorado-d); font-weight: 600; }
.ben-dup-warn .dup-loc  { color: var(--text-dim); font-size: 11px; margin-top: 2px; }
.ben-dup-warn .dup-same {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  border-radius: 0; font-size: 10px; font-weight: 700;
  color: var(--marfil); background: var(--guinda);
}

/* ════════════════════════════════════════════════════════════════════
   PANEL DE CONTROL — riel izquierdo plegable
   Una sola superficie de cristal con espina institucional. Jerarquía:
   riel → secciones (eyebrow + chevron + espina de acento) → controles.
   Acento dorado = consulta · guinda = edición.
   ════════════════════════════════════════════════════════════════════ */
.left-panel {
  position: absolute;
  top: 0;
  left: 0;
  width: 252px;
  height: 100%;
  z-index: var(--z-panel);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Riel opaco: es permanente sobre el mapa y desenfocar el fondo cuesta un re-render por frame */
  background: var(--surface);
  border-right: 0;
  /* El canto del riel es lo único que separa 252 px de instrumentos del
     territorio. Su espina guinda (::after) se lee sobre el basemap claro pero
     desaparece (1.0:1) en cuanto hay un predio guinda debajo; el anillo blanco
     de --lift es el segundo filete que sí se ve ahí (8.2:1). Medido, no
     supuesto — la tabla está en el :root. */
  box-shadow: var(--lift);
  transition: transform .34s var(--ease-out);
}
/* Filete guinda en el borde derecho: cierra la "L" que empieza en la topbar */
.left-panel::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 2px;
  background: var(--guinda);
  pointer-events: none;
}
.left-panel.rail-collapsed { transform: translateX(-100%); }

/* ── Cabecera fija del riel — continúa la banda guinda de la topbar ── */
.rail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  height: 34px;
  padding: 0 8px 0 14px;
  border-bottom: 2px solid var(--guinda-l);
  background: var(--guinda-d);
}
.rail-grab { display: none; }
.rail-title {
  flex: 1;
  font-family: 'Cabin', sans-serif;
  font-weight: 700;
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 2.4px;
  color: var(--marfil);
}
.rail-collapse .rc-mob { display: none; }
.rail-collapse, .rail-reopen {
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.35);
  color: var(--marfil);
  cursor: pointer;
  border-radius: 0;
  transition: background .15s, color .15s, border-color .15s, transform .15s var(--ease-spring);
}
.rail-collapse { width: 25px; height: 25px; font-size: 11px; }
.rail-collapse:hover { background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.55); color: var(--marfil); }
.rail-collapse:focus-visible, .rail-reopen:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }

/* Pestaña para reabrir el riel cuando está plegado */
.rail-reopen {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: var(--z-panel);
  width: 30px; height: 48px;
  font-size: 13px;
  /* Flota sobre el mapa: fondo sólido guinda para verse sobre cualquier zoom */
  background: var(--guinda);
  border-color: var(--marfil);
  box-shadow: var(--lift-sm);
  display: none;
}
.rail-reopen.show { display: flex; }
.rail-reopen:hover { background: var(--guinda-d); border-color: var(--marfil); color: var(--marfil); }

/* ── Zona desplazable de secciones ─────────────────────────────────── */
.rail-body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
}
.rail-body::-webkit-scrollbar { width: 5px; }
.rail-body::-webkit-scrollbar-thumb { background: var(--rule-hard); border-radius: 0; }

/* ── Secciones ─────────────────────────────────────────────────────── */
.left-panel .panel {
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  background: none;
  flex-shrink: 0;
  padding: 0;
  position: relative;
}
/* Sección abierta: un filete guinda a la izquierda del título, no un fondo */
.left-panel .panel:not(.collapsed) > .panel-header { background: none; }

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 11px 12px 8px 14px;
  margin: 0;
  cursor: pointer;
  text-align: left;
  color: inherit;
  transition: background .15s;
}
.panel-header:hover { background: rgba(148,33,72,.045); }
.panel-header :is(h2, h3, h4) {
  position: relative;
  font-family: 'Cabin', sans-serif;
  font-size: 10px;
  font-weight: 700;
  color: var(--guinda-d);
  text-transform: uppercase;
  letter-spacing: 1.6px;
  margin: 0 !important;
  padding-left: 10px;
}
/* Marca de sección: un filete vertical guinda. Lleno = sección abierta. */
.panel-header :is(h2, h3, h4)::before {
  content: '';
  position: absolute; left: 0; top: 1px; bottom: 1px;
  width: 3px; border-radius: 0;
  background: var(--guinda);
  transition: background .18s, opacity .18s;
}
.panel.collapsed .panel-header :is(h2, h3, h4) { color: var(--text-2); }
.panel.collapsed .panel-header :is(h2, h3, h4)::before { background: var(--border2); }
.panel-header:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; border-radius: 0; }
.panel-chevron {
  color: var(--text-2);
  font-size: 11px;
  line-height: 1;
  margin-left: 8px;
  flex-shrink: 0;
  transition: transform .2s var(--ease-out);
}
.panel-header:hover .panel-chevron { color: var(--guinda); }
.panel-body {
  padding: 0 14px 14px;
  max-height: 700px; overflow: hidden;
  transition: max-height .3s var(--ease-out), opacity .22s var(--ease-out), padding .3s var(--ease-out);
}
.panel.collapsed .panel-body { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; }
.panel.collapsed .panel-chevron { transform: rotate(-90deg); }

/* Ritmo del bloque de filtros: la distancia ES el agrupamiento.
   6 px dentro de la escalera (una sola cosa de tres rungs) · 14 px antes de
   la UT, que es una vista transversal y no un cuarto nivel · filete + 14 px
   antes del programa, que ya no recorta territorio sino que resalta. */
#filterPanel .panel-body { display: flex; flex-direction: column; gap: 6px; }
#filterPanel #filterUtRow { margin-top: 8px; }
#filterPanel .filter-divider { margin: 8px 0 2px; }

/* Micro-rótulo de agrupación dentro de una sección (no es un "eyebrow" por
   sección: agrupa controles heterogéneos dentro de una misma). */
.rail-note {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: .9px;
  color: var(--text-dim);
  margin: 2px 0 4px;
}
.panel-body > .rail-note:not(:first-child) { margin-top: 12px; }

/* ── Herramientas del editor ────────────────────────────────────────
   Rejilla de 3: seis herramientas ocupan 2 filas en vez de 6, y el riel
   recupera ~130 px para la cola de trabajo. El estado activo se lee por
   relleno guinda (no por un borde de 1 px). */
.tool-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
  margin-bottom: 6px;
}
.editor-btn {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 9px 11px;
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: var(--r-sm);
  color: var(--text-2);
  cursor: pointer;
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 5px;
  transition: border-color .15s, background .15s, color .15s;
  position: relative;
}
.editor-btn .btn-icon { font-size: 14px; flex-shrink: 0; line-height: 1; }
.editor-btn:hover { border-color: var(--guinda); background: rgba(148,33,72,.06); color: var(--guinda); }
.editor-btn:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
/* Activo = losa guinda: el contorno guinda desaparece contra su propio fondo.
   Se invierte a marfil y se mete dentro de la losa (offset negativo). */
.editor-btn.active:focus-visible,
.editor-btn.tool-danger.active:focus-visible { outline: 2px solid var(--marfil); outline-offset: -4px; }
.editor-btn.active {
  border-color: var(--guinda-d);
  background: var(--guinda);
  color: var(--marfil);
}
.editor-btn:last-of-type { margin-bottom: 0; }

.editor-btn.tool {
  flex-direction: column;
  gap: 4px;
  padding: 8px 3px 7px;
  margin-bottom: 0;
  text-align: center;
}
.editor-btn.tool .btn-icon { font-size: 15px; }
.tool-lbl { font-size: 10px; letter-spacing: .2px; line-height: 1; }
.editor-btn.tool-danger:hover { border-color: #a3283f; background: rgba(163,40,63,.07); color: #a3283f; }
.editor-btn.tool-danger.active { border-color: #7d1f2f; background: #a3283f; color: var(--marfil); }
/* Acciones del dibujo en curso: confirmar / abortar */
.editor-btn-ok { border-color: rgba(18,117,63,.55); color: var(--verde-text); }
.editor-btn-ok:hover { border-color: var(--verde-text); background: rgba(18,117,63,.08); color: var(--verde-text); }
.editor-btn-stop { border-color: rgba(148,33,72,.5); color: var(--guinda); }
.editor-divider {
  height: 1px;
  background: var(--border2);
  margin: 11px 0;
}

/* ── Panel de vértices ─────────────────────────────────────────────── */
#vertexSavePanel {
  margin-top: 8px;
  background: rgba(148,33,72,.06);
  border: 1px solid rgba(148,33,72,.30);
  border-radius: var(--r-sm);
  padding: 11px;
}
#vertexSavePanel .vertex-hint {
  font-size: 11px;
  color: var(--guinda-d);
  margin-bottom: 9px;
  line-height: 1.45;
  padding-left: 2px;
}

/* ── Split inputs ──────────────────────────────────────────────────── */
.split-inputs {
  background: rgba(148,33,72,.10);
  border: 1px solid rgba(148,33,72,.35);
  border-radius: var(--r-sm);
  padding: 11px;
  margin-top: 8px;
}
.split-inputs > .split-title {
  font-size: 10px;
  color: var(--dorado-d);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  margin-bottom: 9px;
}
.split-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.split-row .split-label { font-size: 11px; color: var(--text-2); flex: 1; }
.split-row .split-ctrl {
  display: flex;
  align-items: center;
  background: var(--bg2);
  border: 1px solid var(--border2);
  border-radius: 0;
  overflow: hidden;
}
.split-row .split-ctrl button {
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  width: 22px; height: 28px;
  font-size: 15px;
  line-height: 1;
  transition: background .12s, color .12s;
  padding: 0;
}
.split-row .split-ctrl button:hover { background: rgba(148,33,72,.10); color: var(--guinda); }
.split-row .split-ctrl input[type=number] {
  width: 34px;
  padding: 5px 2px;
  background: none;
  border: none;
  border-left: 1px solid var(--border2);
  border-right: 1px solid var(--border2);
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 600;
  text-align: center;
  -moz-appearance: textfield;
}
.split-row .split-ctrl input[type=number]::-webkit-inner-spin-button,
.split-row .split-ctrl input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; }
/* Es el único punto enfocable del control de división y se quedaba sin
   indicador. El contorno no cabe entre los dos botones cosidos: va por dentro. */
.split-row .split-ctrl input[type=number]:focus { outline: none; box-shadow: inset 0 0 0 2px var(--guinda); }

/* ── UBA selector ──────────────────────────────────────────────────── */
.uba-selector {
  position: absolute;
  top: 64px;
  left: 12px;
  z-index: var(--z-panel);
  display: flex;
  gap: 8px;
  align-items: center;
}
.uba-selector label {
  font-size: 11px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .6px;
}
.uba-selector select {
  background: var(--surface);
  border: 1px solid var(--border-input);
  color: var(--text);
  padding: 7px 10px;
  border-radius: var(--r-sm);
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  box-shadow: none;   /* vive dentro del riel, no flota sobre el mapa */
  transition: border-color .15s;
  cursor: pointer;
}
.uba-selector select:focus { outline: none; border-color: var(--guinda); box-shadow: var(--ring); }

/* ── Sección Capas ──────────────────────────────────────────────────
   La marca de cada capa REPRODUCE cómo se dibuja en el mapa: los lotes son
   rectángulos, las divisiones territoriales son trazos (con su grosor y su
   discontinuidad reales), la sangría repite la contención de la escalera. */
#layerToggle .panel-body { font-size: 12px; }
#layerToggle label {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 0;
  cursor: pointer;
  color: var(--text-2);
  transition: color .15s;
  font-size: 12px;
}
#layerToggle label:hover { color: var(--text); }
#layerToggle label[hidden] { display: none; }
#layerToggle label.lt-lvl.lvl-2 { padding-left: 9px; }
#layerToggle label.lt-lvl.lvl-3 { padding-left: 18px; }
#layerToggle label.lt-lvl.lvl-4 { padding-left: 27px; }

.lt-key { flex-shrink: 0; display: block; }
/* Lote: rectángulo con relleno translúcido y borde propio (como en el mapa) */
.lt-lot {
  width: 15px; height: 11px; border-radius: 0;
  background: color-mix(in srgb, var(--k) 42%, transparent);
  border: 1px solid var(--k);
}
/* Estado "atendido": el lote con casing de tinta */
.lt-state {
  width: 15px; height: 11px; border-radius: 0;
  background: color-mix(in srgb, #7d4f9c 60%, transparent);
  border: 2px solid var(--text);
}
.lt-street { position: relative; width: 15px; height: 11px; }
.lt-street::after { content: ''; position: absolute; left: 0; right: 0; top: 50%;
  border-top: 2px dashed #6b6157; }
.lt-base { width: 15px; height: 11px; border-radius: 0; background: #e6e1dc; border: 1px solid #c9c2bb; }
/* Trazo de división territorial: grosor real (--w) y color real (--k) */
.lt-line { position: relative; width: 15px; height: 11px; }
.lt-line::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: var(--w, 2px); margin-top: calc(var(--w, 2px) / -2); background: var(--k);
}
.lt-line.lt-dash::after {
  height: 0; background: none; border-top: var(--w, 2px) dashed var(--k);
}
/* Punto de interés (capas de contexto: DENUE, datos abiertos). El radio 50%
   NO es chrome: es la forma real del símbolo en el mapa. */
.lt-poi { position: relative; width: 15px; height: 11px; }
.lt-poi::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 6.4px; height: 6.4px; margin: -3.2px 0 0 -3.2px;
  border-radius: 50%; background: var(--k);
}
.lt-count { margin-left: auto; font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-dim); }
#layerToggle input[type=checkbox] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px;
  border: 1px solid var(--border-input);
  border-radius: 0;
  background: var(--surface);
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
#layerToggle input[type=checkbox]:checked {
  background: var(--guinda);
  border-color: var(--guinda);
}
#layerToggle input[type=checkbox]:checked::after {
  content: '✓';
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--marfil); font-weight: 700;
}
#layerToggle input[type=checkbox]:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }

/* ── Panel Seguimiento (pendientes del flujo) ──────────────────────── */
#panelSeguimiento .pend-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
#panelSeguimiento .pend-head .rail-note { margin: 2px 0 0; }
.pend-refresh {
  flex-shrink: 0; background: none; border: 0; cursor: pointer;
  font-size: 10.5px; color: var(--guinda); padding: 2px 0;
  text-decoration: underline; text-underline-offset: 2px;
}
.pend-refresh:hover { color: var(--guinda-d); }
.pend-refresh:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; border-radius: 0; }
.pend-chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0 6px; }
.pend-chip {
  font-size: 10.5px; padding: 3px 9px; border-radius: 0;
  border: 1px solid var(--border2); background: var(--surface);
  color: var(--text-2); cursor: pointer; transition: border-color .15s, color .15s;
}
.pend-chip b { font-family: 'JetBrains Mono', monospace; font-weight: 600; color: var(--text); }
.pend-chip:hover { border-color: var(--guinda); color: var(--guinda); }
.pend-chip.on { background: var(--guinda); color: #fff; border-color: var(--guinda); }
.pend-chip.on b { color: #fff; }
.pend-chip:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
.pend-chip.on:focus-visible { outline: 2px solid var(--marfil); outline-offset: -3px; }
.pend-list { max-height: 240px; overflow-y: auto; }
.pend-item {
  display: flex; justify-content: space-between; align-items: center; gap: 6px;
  padding: 6px 0; border-bottom: 1px solid var(--border);
}
.pend-item:last-child { border-bottom: none; }
.pend-name { font-size: 12px; font-weight: 600; color: var(--text); line-height: 1.25; }
.pend-dir { font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.pend-ver {
  flex-shrink: 0; font-size: 10.5px; border: 1px solid var(--border2); color: var(--guinda);
  background: var(--surface); border-radius: 0; cursor: pointer; padding: 3px 9px;
  transition: border-color .15s, background .15s;
}
.pend-ver:hover { border-color: var(--guinda); background: rgba(148,33,72,.06); }
.pend-ver:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
.pend-empty { font-size: 12px; color: var(--text-dim); padding: 10px 0 2px; }

/* ── Escalera territorial ───────────────────────────────────────────
   Coordinación ⊃ racimo ⊃ UBA. Sin rótulo por fila: cada select ya se
   nombra en su opción por defecto, y dos líneas por nivel costaban 85 px
   del riel diciendo dos veces lo mismo. Lo que queda es la CONTENCIÓN:
   sangría + una escuadra que cuelga cada hijo de su padre.
   La UT y el programa viven fuera de la escalera — son cortes
   transversales, no niveles de la jerarquía. */
.ladder { position: relative; display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.filter-row { display: flex; flex-direction: column; position: relative; }
.ladder .lvl-2 { padding-left: 15px; }
.ladder .lvl-3 { padding-left: 30px; }
/* Escuadra "└": el trazo nace en el borde inferior del control padre y
   entra por el costado del hijo, a media altura. Es la contención dibujada. */
.ladder .lvl-2::before, .ladder .lvl-3::before {
  content: '';
  position: absolute; left: 5px; top: -6px;
  width: 10px; height: 21px;
  border-left: 1.5px solid rgba(148,33,72,.38);
  border-bottom: 1.5px solid rgba(148,33,72,.38);
  border-bottom-left-radius: 3px;
  transition: border-color .18s var(--ease-out), border-width .18s var(--ease-out);
}
.ladder .lvl-3::before { left: 20px; }
/* Rama viva: el escalón que cuelga de un nivel YA elegido se tiñe de guinda
   y engorda. `data-depth` lo pone mapa.js (0 sin recorte · 1 CT · 2 racimo ·
   3 UBA) — un `:has()` global teñía TODA la escalera aunque solo hubiera CT. */
.ladder:not([data-depth="0"]) .lvl-2::before,
.ladder[data-depth="2"] .lvl-3::before,
.ladder[data-depth="3"] .lvl-3::before {
  border-left-color: var(--guinda);
  border-bottom-color: var(--guinda);
  border-left-width: 2px;
  border-bottom-width: 2px;
}
/* Rótulo solo para lectores de pantalla (el select ya lo dice en pantalla) */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.filter-select {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border-input);
  color: var(--text);
  padding: 6px 9px;
  border-radius: 0;
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
/* Contorno sólido: el halo --ring da 1.72:1 sobre blanco y no llega al 3:1. */
.filter-select:focus-visible { outline: 2px solid var(--guinda); outline-offset: 1px; border-color: var(--guinda); }
.filter-select:focus { border-color: var(--guinda); box-shadow: var(--ring); }
.filter-select:hover { border-color: rgba(148,33,72,.4); }
/* Un ámbito elegido deja de ser "todos": se marca en guinda para que el
   operador vea de un golpe que está mirando un recorte, no el territorio. */
.filter-select.is-set {
  border-color: var(--guinda);
  color: var(--guinda-d);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--guinda);
}

/* ── Ámbito vigente ─────────────────────────────────────────────────
   Aparece solo cuando hay recorte. Dice en palabras qué está mirando el
   operador (el nivel efectivo, no la ruta completa: la ruta ya se lee en
   la escalera de arriba) y ofrece la salida. Sustituye al botón suelto
   "Ver todo el territorio", que anunciaba la salida sin nombrar de dónde. */
.scope-now {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 9px 6px 10px;
  background: rgba(148,33,72,.07);
  border: 1px solid rgba(148,33,72,.30);
  border-radius: 0;
}
.scope-now[hidden] { display: none; }
.scope-path {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11.5px; color: var(--guinda-d);
}
.scope-path .sp-lvl {
  font-family: 'Cabin', sans-serif; font-weight: 700;
  font-size: 9px; text-transform: uppercase; letter-spacing: 1.1px;
  /* --text-dim se queda en 4.4:1 sobre el susurro guinda de la franja: por
     debajo del mínimo AA para texto pequeño. --text-2 lo sube a 6:1. */
  color: var(--text-2); margin-right: 6px;
}
.scope-path b { font-weight: 700; }
.scope-clear {
  flex-shrink: 0; border: 0; background: none; padding: 2px 0; cursor: pointer;
  font-family: 'Roboto', sans-serif; font-size: 10.5px; color: var(--guinda);
  text-decoration: underline; text-underline-offset: 2px;
}
.scope-clear:hover { color: var(--guinda-d); }
.scope-clear:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; border-radius: 0; }

/* Filtro por programa (vista temática) */
.filter-divider { height: 1px; background: var(--border2); margin: 3px 0 1px; }
.filter-info {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Roboto', sans-serif;
  font-size: 11px;
  color: var(--text);
  background: rgba(148,33,72,.14);
  border: 1px solid rgba(148,33,72,.45);
  border-radius: 0;
  padding: 5px 9px;
  line-height: 1.35;
}
.filter-info b { color: var(--dorado-d); font-weight: 700; }

/* (`.form-legend` retirado 2026-07-31: era la leyenda del componedor de
   formularios que ya no existe en el código — ver memoria §15.) */
.filter-info.empty {
  background: rgba(148,33,72,.08);
  border-color: rgba(148,33,72,.35);
  color: var(--guinda-d);
}

/* ── Hint de zoom ──────────────────────────────────────────────────
   Ya no flota en el centro del mapa: el censo lo dice en su sitio. Se
   conserva el nodo (mapa.js lo crea) pero fuera de la vista. */
.map-hint { display: none !important; }

/* ════════════════════════════════════════════════════════════════════
   CENSO DE PREDIOS — leyenda y estadística en un mismo objeto
   Qué significa cada color y cuántos predios de ese tipo hay AHORA en el
   encuadre. Se lee mirando el mapa, por eso vive anclado a él y no en el
   riel. Cifras en mono tabular: el registro catastral es un libro de
   cuentas, no una tarjeta de dashboard.
   ════════════════════════════════════════════════════════════════════ */
.census {
  position: absolute;
  left: calc(var(--rail-w) + 14px);
  bottom: 14px;
  z-index: var(--z-readout);
  width: 226px;
  background: var(--surface);
  border: 1px solid var(--rule-hard);
  border-top: 3px solid var(--guinda);
  border-radius: 0;
  box-shadow: var(--lift-sm);
  overflow: hidden;
  transition: left .34s var(--ease-out);
}
.census-head {
  display: flex; align-items: baseline; gap: 8px;
  width: 100%; padding: 9px 11px 8px; cursor: pointer;
  background: none; border: 0; text-align: left; color: inherit;
}
.census-head:hover { background: rgba(148,33,72,.045); }
.census-head:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
.census-title {
  flex: 1;
  font-family: 'Cabin', sans-serif; font-weight: 700;
  font-size: 9.5px; text-transform: uppercase; letter-spacing: 1.5px;
  color: var(--guinda-d);
}
.census-total {
  font-family: 'JetBrains Mono', monospace; font-weight: 600;
  font-size: 15px; color: var(--text); letter-spacing: -.02em;
}
.census-chev { font-size: 9px; color: var(--text-dim); transition: transform .2s var(--ease-out); }
.census.collapsed .census-chev { transform: rotate(-90deg); }
.census-body {
  max-height: 46vh; overflow: hidden auto;
  transition: max-height .28s var(--ease-out), opacity .2s var(--ease-out);
  border-top: 1px solid var(--border);
}
.census.collapsed .census-body { max-height: 0; opacity: 0; border-top-color: transparent; }

.census-list { list-style: none; margin: 0; padding: 6px 11px 4px; }
.census-row {
  display: grid; grid-template-columns: 15px 1fr auto;
  align-items: center; gap: 8px;
  padding: 2.5px 0;
  font-size: 11.5px; color: var(--text-2);
}
.census-row .cr-key {
  width: 15px; height: 11px; border-radius: 0;
  background: color-mix(in srgb, var(--k) 55%, transparent);
  border: 1px solid var(--k);
}
.census-row .cr-key.cr-fabric { background: rgba(143,138,133,.16); border-color: rgba(120,113,105,.55); }
.census-row .cr-n {
  font-family: 'JetBrains Mono', monospace; font-size: 11px; font-weight: 500;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.census-row.is-zero { color: var(--text-dim); }
.census-row.is-zero .cr-n { color: var(--text-dim); }
.census-more {
  display: block; width: calc(100% - 22px); margin: 4px 11px 8px;
  background: none; border: 0; padding: 3px 0; cursor: pointer;
  font-size: 10.5px; color: var(--guinda); text-align: left;
  text-decoration: underline; text-underline-offset: 2px;
}
.census-more:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; border-radius: 0; }
.census-empty { padding: 10px 11px 12px; font-size: 11.5px; color: var(--text-dim); line-height: 1.4; }
.census-states {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  padding: 8px 11px 9px; border-top: 1px solid var(--border);
  background: var(--surface2);
}
.cs-item { display: inline-flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--text-2); }
.cs-mark { width: 15px; height: 11px; border-radius: 0; flex-shrink: 0; }
.cs-att { background: color-mix(in srgb, #7d4f9c 60%, transparent); border: 2px solid var(--text); }
.cs-sel { background: rgba(148,33,72,.14); border: 2px solid var(--guinda); box-shadow: 0 0 0 1.5px rgba(255,255,255,.95); }

/* ════════════════════════════════════════════════════════════════════
   EDICIÓN DE PREDIO (sidebar)
   ════════════════════════════════════════════════════════════════════ */
.predio-edit-section { margin-bottom: 18px; }
.section-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 9px;
  font-size: 11px;
  font-family: 'Cabin', sans-serif;
  color: var(--guinda-d);
  text-transform: uppercase;
  letter-spacing: 1.2px;
}
.link-btn {
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-family: 'Roboto', sans-serif;
  cursor: pointer;
  padding: 3px 8px;
  border-radius: 0;
  transition: color .15s, background .15s;
  text-transform: none;
  letter-spacing: 0;
}
.link-btn:hover { color: var(--guinda); background: rgba(148,33,72,.06); }

.predio-edit-form {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 13px;
}
.predio-edit-form .form-group { margin-bottom: 11px; }
.predio-edit-form .form-label { font-size: 10px; }
.predio-edit-form .form-control { padding: 8px 10px; font-size: 12px; }
.form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.predio-edit-actions { display: flex; gap: 8px; margin-top: 10px; }
.predio-edit-actions .btn { flex: 1; }

/* ── Autocomplete calles ───────────────────────────────────────────── */
.autocomplete-wrap { position: relative; }
.autocomplete-list {
  display: none;
  position: absolute;
  top: 100%; left: 0; right: 0;
  z-index: 500;
  background: var(--surface);
  border: 1px solid var(--rule-hard);
  border-top: none;
  border-radius: 0;
  max-height: 190px;
  overflow-y: auto;
  list-style: none;
  box-shadow: var(--lift);   /* cuelga sobre el mapa: filete doble */
}
.autocomplete-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 11px;
  cursor: pointer;
  font-size: 12px;
  border-bottom: 1px solid var(--border);
  transition: background .12s;
}
.autocomplete-list li:last-child { border-bottom: none; }
.autocomplete-list li:hover { background: rgba(148,33,72,.07); }
/* `.ac-hi` no es un hover decorativo: es la opción que Enter va a confirmar.
   Losa guinda maciza, igual que `.search-item:hover`, y sin transición —
   la navegación con flechas debe responder en el fotograma de la tecla. */
.autocomplete-list li.ac-hi { background: var(--guinda); color: var(--marfil); transition: none; }
.autocomplete-list li.ac-hi .ac-nom { color: var(--marfil); }
.autocomplete-list li.ac-hi .ac-tipo { background: var(--guinda-d); color: var(--marfil); }
.autocomplete-list .ac-tipo {
  font-size: 10px;
  color: var(--dorado-d);
  background: rgba(148,33,72,.16);
  border-radius: 0;
  padding: 2px 6px;
  flex-shrink: 0;
  white-space: nowrap;
}
.autocomplete-list .ac-nom {
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.form-section-title {
  font-family: 'Cabin', sans-serif;
  font-size: 11px;
  color: var(--guinda-d);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  margin-bottom: 13px;
}

/* ── Control segmentado (pastillas): sexo, ¿beneficiario? ─────────────── */
.seg {
  display: flex;
  border: 1px solid var(--border2);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--bg-input);
}
.seg-opt { flex: 1; position: relative; }
.seg-opt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.seg-opt span {
  display: block;
  text-align: center;
  padding: 9px 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  border-left: 1px solid var(--border2);
  transition: background .12s, color .12s;
}
.seg-opt:first-child span { border-left: none; }
.seg-opt:hover span { background: rgba(148,33,72,.07); }
.seg-opt input:checked + span { background: var(--guinda); color: #fff; }
.seg-opt input:focus-visible + span { box-shadow: inset 0 0 0 2px var(--guinda); }

/* ── Filete con micro-título dentro del formulario ───────────────────── */
.form-divider { display: flex; align-items: center; gap: 8px; margin: 4px 0 12px; }
.form-divider::after { content: ""; flex: 1; height: 1px; background: var(--border2); }
.form-divider span {
  font-family: 'Cabin', sans-serif;
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--guinda-d);
}

/* Aclaración en minúsculas dentro de un label en mayúsculas */
.lbl-soft { color: var(--text-dim); text-transform: none; letter-spacing: 0; font-weight: 400; }

/* ════════════════════════════════════════════════════════════════════
   DASHBOARD
   ════════════════════════════════════════════════════════════════════ */
.dash-page { padding: 32px 28px 48px; max-width: 1240px; margin: 0 auto; }
.dash-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 28px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.dash-header::after {
  content: '';
  position: absolute;
  bottom: -1px; left: 0;
  width: 140px; height: 3px;
  background: var(--guinda);
}
.dash-header h1 {
  font-family: 'Cabin', sans-serif;
  font-size: 18px;
  color: var(--guinda-d);
  text-transform: uppercase;
  letter-spacing: 2px;
}
.dash-filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.dash-fsel { width: auto; min-width: 150px; max-width: 220px; padding: 7px 10px; font-size: 12px; }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 28px;
}
.kpi-card {
  --accent: var(--guinda);
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: var(--r);
  padding: 22px 20px;
  position: relative;
  overflow: hidden;
  transition: transform .2s var(--ease-spring), box-shadow .2s, border-color .2s;
  animation: cardIn .5s var(--ease-out) both;
}
.kpi-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--accent);
}
.kpi-card:hover {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.kpi-card .kpi-value {
  font-family: 'Cabin', sans-serif;
  font-weight: 700;
  font-size: 40px;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  line-height: 1;
  margin-bottom: 8px;
  letter-spacing: -1px;
}
.kpi-card .kpi-label {
  font-size: 10px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  font-weight: 500;
}
/* KPI principal destacado (jerarquía) */
/* El KPI principal no se distingue por un halo: es la losa guinda del tablero. */
.kpi-card.hero {
  grid-column: span 2;
  background: var(--guinda);
  border-color: var(--guinda);
}
.kpi-card.hero .kpi-value, .kpi-card.hero .kpi-sub { color: var(--marfil); }
.kpi-card.hero .kpi-value { font-size: 60px; }
.kpi-card.hero .kpi-label { font-size: 11px; color: rgba(255,255,255,.86); }
.kpi-card .kpi-sub {
  margin-top: 10px; font-size: 11.5px; color: var(--text-dim);
  letter-spacing: .2px; line-height: 1.4;
}
@media (max-width: 620px) { .kpi-card.hero { grid-column: span 1; } .kpi-card.hero .kpi-value { font-size: 46px; } }

/* Encabezado de grupo (jerarquía de secciones) */
.section-head {
  display: flex; flex-direction: column; gap: 3px;
  margin: 34px 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.section-head::after {
  content: ''; position: absolute; left: 0; bottom: -1px;
  width: 56px; height: 3px;
  background: var(--guinda);
}
.section-head h2 {
  font-family: 'Cabin', sans-serif; font-weight: 700;
  font-size: 19px; color: var(--text); letter-spacing: -.2px;
}

/* ── Hallazgos clave (insights automáticos) ─────────────────────────── */
.insights-block { margin-bottom: 28px; }
.insights-head {
  display: flex; align-items: baseline; justify-content: space-between;
  flex-wrap: wrap; gap: 8px; margin-bottom: 14px;
}
.insights-hint { font-size: 11px; color: var(--text-dim); letter-spacing: .3px; }
.insights-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 14px;
}
.insight-card {
  --tone: var(--dorado-d);
  display: flex; gap: 14px;
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--tone) 35%, var(--border));
  border-radius: var(--r);
  padding: 16px 18px;
  transition: transform .2s var(--ease-spring), box-shadow .2s, border-color .2s;
  animation: cardIn .5s var(--ease-out) both;
}
.insight-card:hover {
  border-color: var(--tone);
  box-shadow: inset 0 0 0 1px var(--tone);
}
.insight-card.info  { --tone: var(--dorado-d); }
.insight-card.good  { --tone: #1e8b4e; }
.insight-card.warn  { --tone: var(--naranja3); }
.insight-card.alert { --tone: var(--guinda); }
.insight-card .ins-icon {
  flex-shrink: 0;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  font-size: 18px; line-height: 1;
  border-radius: 0;
  color: var(--tone);
  background: color-mix(in srgb, var(--tone) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--tone) 30%, transparent);
}
.insight-card .ins-title {
  font-size: 10px; text-transform: uppercase; letter-spacing: 1px;
  color: var(--text-dim); font-weight: 600; margin-bottom: 4px;
}
.insight-card .ins-value {
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 24px;
  color: var(--tone); line-height: 1.05; letter-spacing: -.5px;
  font-variant-numeric: tabular-nums;
}
.insight-card .ins-metric {
  font-family: 'Roboto', sans-serif; font-weight: 500; font-size: 11px;
  color: var(--text-dim); letter-spacing: 0; text-transform: none;
}
.insight-card .ins-desc {
  font-size: 12px; color: var(--text-2); margin-top: 6px; line-height: 1.5;
}
.chart-foot { font-size: 11.5px; color: var(--text-dim); margin-top: 12px; line-height: 1.5; }

.charts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 22px;
}
.charts-grid--wide { grid-template-columns: 1.5fr 1fr; }
@media (max-width: 760px) { .charts-grid, .charts-grid--wide { grid-template-columns: 1fr; } }
.chart-card {
  background: var(--surface);
  border: 1px solid var(--border2);
  border-radius: var(--r);
  padding: 22px;
}
.chart-card h3 {
  font-family: 'Cabin', sans-serif;
  font-size: 11px;
  color: var(--guinda-d);
  text-transform: uppercase;
  letter-spacing: 1.2px;
  margin-bottom: 16px;
}
.chart-card table th {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .6px;
}

/* Encabezado de tarjeta con controles */
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 6px;
}

/* Banner informativo */
.info-banner {
  background: rgba(245,146,23,.10);
  border: 1px solid rgba(237,100,20,.40);
  color: #8a4a08;
  padding: 11px 14px;
  border-radius: var(--r-sm);
  font-size: 12.5px;
  margin-bottom: 18px;
}

/* Control segmentado (selector de nivel) */
.seg {
  display: inline-flex;
  background: var(--bg2);
  border: 1px solid var(--border2);
  border-radius: var(--r-sm);
  padding: 3px;
  gap: 2px;
}
.seg-btn {
  position: relative;
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-family: 'Roboto', sans-serif;
  font-size: 12px;
  font-weight: 500;
  padding: 6px 13px;
  border-radius: 0;
  cursor: pointer;
  transition: background .25s var(--ease-out), color .18s, transform .12s var(--ease-spring);
  white-space: nowrap;
}
.seg-btn:hover { color: var(--text); }
.seg-btn:active { transform: scale(.96); }
.seg-btn.active {
  background: var(--guinda);
  color: var(--marfil);
  font-weight: 700;
  box-shadow: none;
}

/* Tablas de datos */
.table-wrap { overflow-x: auto; max-height: 440px; overflow-y: auto; border-radius: var(--r-sm); }
.data-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.data-table th {
  position: sticky; top: 0;
  background: var(--rule-hard);
  color: var(--marfil);
  font-size: 10px; text-transform: uppercase; letter-spacing: .6px;
  text-align: left; padding: 10px 10px;
  cursor: pointer; user-select: none;
  border-bottom: 1px solid var(--border2);
  white-space: nowrap;
}
.data-table th.num { text-align: right; }
.data-table th:hover { color: var(--guinda); }
.data-table td { padding: 9px 10px; border-bottom: 1px solid var(--border); color: var(--text-2); }
.data-table td.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
/* 1.07:1 de tinte no se ve en una tabla larga. Filete guinda en la primera
   celda: el mismo recurso que ya usa `.adm-table` en la auditoría. */
.data-table tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--guinda); }
.data-table .nivel-name { color: var(--text); font-weight: 500; }
.data-table .money { color: var(--verde-text); font-weight: 600; }

/* Barras de cobertura */
.cobertura-list { display: flex; flex-direction: column; gap: 12px; padding-top: 4px; }
.cob-row { display: grid; grid-template-columns: 100px 1fr 46px; align-items: center; gap: 10px; font-size: 12px; }
.cob-row .cob-name { color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cob-bar { height: 9px; background: var(--bg2); overflow: hidden; border: 1px solid var(--border2); }
.cob-fill { height: 100%; transition: width .8s var(--ease-out); }
.cob-pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
/* Color plano: la barra codifica magnitud con su LARGO, no con un degradado. */
.cob-fill.low  { background: #7d1840; }
.cob-fill.mid  { background: var(--naranja3); }
.cob-fill.high { background: #1e8b4e; }

/* Grid de montos editables */
.montos-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.monto-item {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 12px 13px;
}
.monto-item label {
  display: block; font-size: 10px; color: var(--dorado-d);
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 8px;
  font-family: 'Cabin', sans-serif;
}
.monto-input-wrap { display: flex; align-items: center; gap: 6px; }
.monto-input-wrap .peso { color: var(--text-dim); font-size: 14px; }
.monto-item input {
  flex: 1; width: 100%;
  background: var(--surface); border: 1px solid var(--border2);
  border-radius: 0; color: var(--text);
  padding: 8px 10px; font-family: var(--font-mono); font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.monto-item input:focus { outline: none; border-color: var(--guinda); box-shadow: var(--ring); }

/* ── Spinner / skeleton ────────────────────────────────────────────── */
.spinner {
  width: 22px; height: 22px;
  border: 2px solid var(--border2);
  border-top-color: var(--guinda);
  border-radius: 50%;
  animation: spin .6s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Esqueleto de carga: bloque plano que late. Sin barrido de brillo — el
   degradado que lo recorría era el último resto del lenguaje de cristal. */
.skeleton {
  background: var(--bg2);
  animation: skeletonPulse 1.4s var(--ease-out) infinite;
}
@keyframes skeletonPulse { 0%, 100% { opacity: 1; } 50% { opacity: .48; } }

/* ── Toast ─────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 26px;
  right: 22px;
  padding: 12px 18px 12px 15px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 500;
  z-index: var(--z-toast);
  opacity: 0;
  transform: translateY(14px) scale(.96);
  transition: opacity .25s, transform .3s var(--ease-spring);
  pointer-events: none;
  max-width: 360px;
  line-height: 1.45;
  border: 1px solid var(--rule-hard);
  background: var(--surface);
  box-shadow: var(--lift);   /* aparece sobre el mapa vivo: filete doble */
}
.toast.show { opacity: 1; transform: translateY(0) scale(1); }
/* El toast aparece SOBRE el mapa vivo (guinda, morado, naranja). Un fondo
   translúcido lo dejaba en 1.37:1 contra la geometría de abajo. La losa es
   siempre opaca; el estado se codifica en el filete izquierdo, que es dato
   de color sobre un canto de 4 px, no un tinte de fondo. */
.toast.success { color: var(--verde-text); border-color: var(--rule-hard); border-left: 4px solid var(--verde-text); background: var(--surface); }
.toast.error   { color: var(--guinda-d);   border-color: var(--rule-hard); border-left: 4px solid var(--guinda);     background: var(--surface); }

/* ════════════════════════════════════════════════════════════════════
   UTILIDADES DE ANIMACIÓN (reveal-on-scroll + stagger)
   ════════════════════════════════════════════════════════════════════ */
/* Entrada corta y con un solo eje: 24 px y 600 ms se leían como una web de
   presentación; una losa aparece, no viaja. `will-change` se retiró porque
   quedaba permanente en decenas de elementos que ya terminaron de animar. */
.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .42s var(--ease-out), transform .42s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.reveal--left  { transform: translateX(-18px); }
.reveal--right { transform: translateX(18px); }
.reveal--scale { transform: scale(.96); }
.reveal.in { opacity: 1; transform: none; }
/* Sin JS: nunca ocultar contenido */
html:not(.js) .reveal { opacity: 1; transform: none; }

/* ── Accesibilidad ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Modales ─────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(43,26,32,.45);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-box {
  /* Marfil destacado: los modales son superficie de decisión */
  background: var(--surface);
  border: 1px solid var(--rule-hard);
  border-radius: 0;
  width: 480px;
  max-width: 95vw;
  max-height: 85vh;
  overflow-y: auto;
  padding: 24px;
}
.modal-title {
  font-family: 'Cabin', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--guinda-d);
  margin: 0 0 16px;
  font-size: 15px;
}
.modal-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* ── Constructor de campos ───────────────────────────────────────────── */
.field-card {
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 10px;
  margin-bottom: 8px;
}
.field-card-row {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}
.field-options-hint {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 2px;
}

/* ── Mis capas ──────────────────────────────────────────────────────── */
.capa-item {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border);
}
.capa-color-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.capa-nombre {
  flex: 1;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.capa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  min-height: 26px;
  background: none;
  border: none;
  color: var(--dorado-d);
  cursor: pointer;
  font-size: 12px;
  padding: 2px 5px;
  border-radius: var(--r-sm);
  transition: background .15s var(--ease-out);
}
.capa-btn:hover { background: var(--bg2); }
.capa-btn:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
/* Ojo activo: formulario resaltado en el mapa (azul institucional) */
.capa-btn.is-active { background: var(--azul2); color: #fff; }

/* ── Formularios en sidebar ──────────────────────────────────────────── */
.form-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 0;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.form-entry-item {
  padding: 4px 0;
  font-size: 11px;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.form-entry-item:hover { color: var(--text); }

/* ════════ BÚSQUEDA GLOBAL ════════
   Anclada al borde del riel, no centrada en la ventana: forma una "L" con la
   topbar y el riel, y deja libre el centro del mapa (que es el contenido). */
.search-box {
  position: absolute; top: 12px; left: calc(var(--rail-w) + 14px);
  z-index: var(--z-panel); width: 340px; max-width: calc(100% - var(--rail-w) - 120px);
  transition: left .34s var(--ease-out);
}
.search-ico-lead {
  position: absolute; left: 12px; top: 11px; z-index: 1;
  color: var(--text-dim); pointer-events: none; line-height: 0;
}
.search-box:focus-within .search-ico-lead { color: var(--guinda); }
.search-input {
  width: 100%; padding: 9px 14px 9px 34px;
  background: var(--surface); border: 1px solid var(--rule-hard); border-radius: var(--r-sm);
  color: var(--text); font-size: 13px; box-shadow: var(--lift-sm);
}
/* El contorno se dibuja HACIA ADENTRO (offset negativo): el campo flota sobre
   el mapa y un anillo por fuera caería sobre geometría que puede ser guinda.
   Y conserva --lift-sm: el filete doble no puede perderse justo al enfocar. */
.search-input:focus-visible { outline: 2px solid var(--guinda); outline-offset: -3px; box-shadow: var(--lift-sm); }
.search-input:focus { border-color: var(--guinda); box-shadow: var(--lift-sm); }
.search-input::placeholder { color: var(--text-dim); }
.search-results {
  margin-top: 6px; background: var(--surface);
  border: 1px solid var(--rule-hard); border-radius: var(--r-sm);
  max-height: 320px; overflow-y: auto; box-shadow: var(--lift);
}
.search-results.hidden { display: none; }
.search-item {
  display: flex; align-items: center; gap: 9px; padding: 8px 12px;
  cursor: pointer; border-bottom: 1px solid var(--border);
}
.search-item:hover { background: var(--guinda); color: var(--marfil); }
/* Los hijos traían color propio (carbón y tenue) y ganaban por especificidad
   sobre la losa guinda del hover: 1.83:1. Se invierten con el padre. */
.search-item:hover .search-txt b,
.search-item:hover .search-txt small { color: var(--marfil); }
.search-ico { font-size: 15px; flex-shrink: 0; }
.search-txt { display: flex; flex-direction: column; min-width: 0; }
.search-txt b { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-txt small { font-size: 11px; color: var(--text-dim); }
.search-empty { padding: 10px 12px; font-size: 12px; color: var(--text-dim); }
/* Barra de "marcar entrega" en el buscador */
.search-markbar {
  display: flex; align-items: center; gap: 8px; padding: 7px 12px; flex-wrap: wrap;
  /* Banda permanente, no hover: el tinte al 6 % solo ensuciaba el blanco.
     Losa blanca con filete guinda a la izquierda y regla dura abajo. */
  background: var(--surface); box-shadow: inset 3px 0 0 var(--guinda);
  border-bottom: 1px solid var(--rule-hard);
  font-size: 11px; color: var(--gris-carbon, #55585a); position: sticky; top: 0; z-index: 1;
}
.search-marksel {
  flex: 1; min-width: 120px; font-size: 12px; padding: 3px 6px;
  border: 1px solid var(--border2); border-radius: var(--r-sm);
  background: var(--glass-solid, #fff); color: var(--text);
}
.search-markdate {
  font-size: 12px; padding: 2px 5px; border: 1px solid var(--border2);
  border-radius: var(--r-sm); background: var(--glass-solid, #fff); color: var(--text);
}
/* Check por resultado (palomear entrega) */
.search-check {
  flex-shrink: 0; width: 26px; height: 26px; padding: 0; line-height: 1;
  font-size: 17px; cursor: pointer; border-radius: 0;
  border: 1px solid var(--border2); background: var(--glass-solid, #fff);
  color: var(--gris-carbon, #55585a);
}
.search-check.on { color: #fff; background: var(--guinda, #942148); border-color: var(--guinda, #942148); }
.search-check:disabled { opacity: .5; cursor: default; }
/* Botón editar por resultado */
.search-edit {
  flex-shrink: 0; width: 26px; height: 26px; padding: 0; line-height: 1;
  font-size: 14px; cursor: pointer; border-radius: 0; margin-left: auto;
  border: 1px solid var(--border2); background: var(--glass-solid, #fff);
  color: var(--gris-carbon, #55585a);
}
.search-edit:hover { color: var(--guinda, #942148); border-color: var(--guinda, #942148); }

/* Marcar el reparto activo desde un resultado del buscador */
.search-mark { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.search-accept {
  flex-shrink: 0; padding: 3px 10px; font-size: 12px; line-height: 1.4; cursor: pointer;
  border-radius: 0; border: 1px solid var(--guinda, #942148);
  background: var(--guinda, #942148); color: #fff;
}
.search-accept:disabled { opacity: .5; cursor: default; }
.search-done {
  display: flex; align-items: center; gap: 6px; margin-left: auto;
  font-size: 11px; font-weight: 600; color: var(--guinda, #942148); white-space: nowrap;
}
.search-undo {
  padding: 0; border: 0; background: none; cursor: pointer;
  font-size: 11px; color: var(--gris-carbon, #55585a); text-decoration: underline;
}
.search-mark + .search-edit, .search-done + .search-edit { margin-left: 6px; }
.search-markbar-off { color: var(--gris-carbon, #55585a); font-style: italic; }

/* ════════ RESPONSIVE (tablet) ════════ */
@media (max-width: 1100px) {
  .map-container { --rail-w: 232px; }
  .left-panel { width: 232px; }
  .census { width: 200px; }
}
@media (max-width: 900px) {
  .search-box { width: auto; right: 62px; max-width: none; }
  .sidebar { width: 380px !important; }
  .topbar .brand-sep { display: none; }
  .topbar { padding-left: 12px; padding-right: 8px; gap: 10px; }
}

/* ════════════════════════════════════════════════════════════════════
   CELULAR (≤700px) — HOJA INFERIOR, no el escritorio encogido
   En 390 px el riel lateral se comía dos tercios del mapa. Aquí el mapa
   ocupa TODA la pantalla y el control sube desde abajo en dos posiciones:
   asomado (solo la cabecera, que es el asa) y abierto (68vh). Reutiliza
   el mismo botón/estado que el plegado de escritorio — sin JS nuevo.
   ════════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  .map-container { --rail-w: 0px; }

  .topbar { height: 44px; padding: 0 8px 0 12px; gap: 8px; }
  .topbar .emblem { width: 20px; height: 20px; }
  /* El wordmark completo no cabe junto a la navegación en 390 px; el emblema
     sigue firmando la pantalla y "Atlas" conserva el nombre. */
  .topbar .brand { font-size: 14px; white-space: nowrap; }
  .topbar .brand .brand-rest { display: none; }
  .topbar .user-badge { display: none; }
  .topbar .nav-links {
    gap: 0; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .topbar .nav-links::-webkit-scrollbar { display: none; }
  .topbar a { font-size: 10px; letter-spacing: .4px; padding: 5px 8px; }

  /* Búsqueda: banda superior del mapa, a todo lo ancho. Los controles
     nativos de MapLibre bajan por debajo de esa banda: con el buscador a todo
     lo ancho, el «+» del zoom quedaba tapado y no había forma de acercarse
     salvo con los dedos. La escala se sube para no chocar con el censo. */
  .maplibregl-ctrl-top-right { margin-top: 46px; }
  .maplibregl-ctrl-bottom-right { margin-bottom: 4px; }
  .search-box { top: 8px; left: 10px; right: 10px; width: auto; max-width: none; }
  .search-input { font-size: 16px; padding: 11px 14px 11px 34px; } /* 16px evita el zoom de iOS */
  .search-ico-lead { top: 13px; }
  .search-results { max-height: 46vh; }

  /* El riel se convierte en hoja inferior */
  .left-panel {
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; height: auto; max-height: 68vh;
    border-right: 0; border-top: 3px solid var(--guinda);
    border-radius: 0;
    /* Mismo filete doble que en escritorio: el canto blanco por fuera de la
       banda guinda es lo que aguanta cuando hay predios guinda debajo. */
    box-shadow: 0 0 0 1px #ffffff, 0 -6px 16px -8px rgba(0,0,0,.34);
    transform: none;
    transition: max-height .3s var(--ease-out);
  }
  .left-panel::after { content: none; }
  /* "Plegado" en celular = asomado: solo el asa queda a la vista */
  .left-panel.rail-collapsed { transform: none; max-height: 40px; }
  .rail-reopen { display: none !important; }

  .rail-head {
    height: 40px; padding: 0 10px 0 14px;
    border-radius: 0;
    position: relative;
  }
  .rail-grab {
    display: block; position: absolute;
    top: 5px; left: 50%; transform: translateX(-50%);
    width: 34px; height: 3px; border-radius: 0;
    background: rgba(255,255,255,.45);
  }
  .rail-title { font-size: 10px; letter-spacing: 2px; }
  .rail-collapse { width: 40px; height: 30px; border-radius: 0; }
  .rail-collapse .rc-desk { display: none; }
  .rail-collapse .rc-mob { display: block; transition: transform .28s var(--ease-out); }
  .left-panel.rail-collapsed .rail-collapse .rc-mob { transform: rotate(180deg); }

  .rail-body { padding-bottom: env(safe-area-inset-bottom, 0px); }
  .panel-body { padding-left: 16px; padding-right: 16px; }
  .tool-grid { grid-template-columns: repeat(3, 1fr); gap: 7px; }
  .pend-list { max-height: 30vh; }

  /* ── Censo vs. hoja de control: quién gana el borde inferior ─────────
     Los dos están anclados abajo, así que hay que decidir. La regla:
     LA HOJA MANDA, EL CENSO INFORMA.
       · Hoja asomada  → el censo es una tarjeta completa sobre el mapa,
         apoyada encima del asa. Se recorta a 244 px para no morder la
         escala gráfica de MapLibre, que vive en la esquina opuesta.
       · Hoja abierta  → el censo NO desaparece (su cifra es justo la
         respuesta a lo que estás tocando en CAPAS): se pliega a su
         cabecera y sube a apoyarse en el canto de la hoja. Deja de ser
         control y pasa a ser lectura — por eso no se puede desplegar
         mientras la hoja esté arriba. */
  .census {
    left: 10px; right: 10px; width: auto;
    bottom: 48px;
    max-width: 244px;
    transition: bottom .3s var(--ease-out);
  }
  .census-body { max-height: 30vh; }

  .map-container:has(.left-panel:not(.rail-collapsed)) .census {
    bottom: calc(68vh + 8px);
  }
  .map-container:has(.left-panel:not(.rail-collapsed)) .census .census-body {
    max-height: 0; opacity: 0; border-top-color: transparent;
  }
  .map-container:has(.left-panel:not(.rail-collapsed)) .census .census-head {
    pointer-events: none; cursor: default;
  }
  .map-container:has(.left-panel:not(.rail-collapsed)) .census .census-chev {
    opacity: 0;
  }

  /* Ficha del predio: hoja a pantalla completa (el formulario es largo) */
  .sidebar { width: 100% !important; max-width: 100%; border-left: 0; }
  .sidebar-body { padding: 16px 16px calc(24px + env(safe-area-inset-bottom, 0px)); }

  /* Controles nativos de MapLibre fuera del alcance del pulgar-asa */
  .maplibregl-ctrl-bottom-right { bottom: 44px; }
}

/* Cuando la ficha del predio está abierta en celular, la hoja de control
   estorba: se retira hasta que el operador la vuelva a pedir. */
@media (max-width: 700px) {
  .map-container:has(.sidebar:not(.hidden)) .left-panel,
  .map-container:has(.sidebar:not(.hidden)) .census,
  .map-container:has(.sidebar:not(.hidden)) .search-box { display: none; }
}

/* ════════════════════════════════════════════════════════════════════
   MAPA — microanimaciones (entrada de paneles, popups, búsqueda)
   ════════════════════════════════════════════════════════════════════ */
/* El riel entra UNA vez, como una pieza. Ocho retardos escalonados sobre
   secciones que no son una secuencia era ruido: retrasaba el primer control
   útil 400 ms en cada carga. */
@keyframes railIn { from { opacity: 0; transform: translateX(-8px); } }
.left-panel { animation: railIn .28s var(--ease-out) both; }

/* Popups de MapLibre */
.maplibregl-popup-content { animation: popIn .16s var(--ease-out) both; }
@keyframes popIn { from { opacity: 0; transform: scale(.96); } }

/* ════════════════════════════════════════════════════════════════════════════
   CENTRO DE MANDO TERRITORIAL — consola de una sola pantalla 2026-08-19

   QUÉ CAMBIÓ Y POR QUÉ (rediseño con `ui-ux-pro-max` + `dataviz`):
   La consola anterior medía 1697 px de alto en un viewport de 854: eran DOS
   pantallas. Un centro de mando que obliga a hacer scroll para saber cuánto
   dinero se está ejerciendo no es un centro de mando, es un informe largo.
   Ahora la consola es una REJILLA DE ALTO FIJO (100dvh, `overflow:hidden`) de
   tres franjas, y cada franja negocia su alto con las otras:

     01 PULSO      auto        · la tira de cifras que encabeza todo
     02 TERRITORIO 1fr         · avance · mapa · comparativa (el mapa manda)
     03 POLÍTICA   clamp(...)  · cinco instrumentos en una cubierta

   Dónde salieron los ~840 px: la tarjeta «Inversión estimada» (que era 3/4
   de aire) se disolvió en la tira de cifras; «Calles» y «Predios» eran el
   mismo instrumento a dos escalas y ahora son UN módulo con conmutador; el
   perfil por sexo pasó de tres medidores apilados a una sola barra de partes;
   y los rótulos de bahía bajaron de 28 px a 17. Ningún dato se perdió.

   REGLA DE COLOR (intacta desde el rediseño anterior): TODA superficie de dato
   sigue siendo BLANCA. La rampa --sq-* y la categórica de 4 slots ya validadas
   con `dataviz` no cambian ni un dígito: el oscuro es bisel, jamás fondo de
   gráfica. El color codifica dato; el cromo es guinda, blanco y carbón.
   ════════════════════════════════════════════════════════════════════════════ */
.ck-app {
  height: 100vh; height: 100dvh; overflow: hidden; display: flex; flex-direction: column;
  /* Bastidor: tokens locales de la consola (no contaminan el resto del sistema) */
  --chassis:     #2b2622;              /* carbón de la identidad, usado como superficie */
  /* Se retiró #3a2430: era un tono intermedio guinda→carbón, o sea un
     degradado congelado en un color. La pila queda en dos valores: banda
     guinda de la topbar y, de ahí para abajo, carbón. */
  --chassis-top: #2b2622;
  /* Filete de 1 px entre instrumentos: era gris claro y se perdía. Ahora es el
     propio carbón del bastidor, así que la separación entre dos instrumentos
     blancos es un CORTE de color y no un tinte. */
  --hair:        #2b2622;
  --bezel:       var(--guinda-l);      /* marcas de esquina del escenario */
  --bay-ink:     #ffffff;              /* rótulo sobre el bastidor — 14.7:1 */
  --bay-dim:     rgba(255,255,255,.74);/* nota sobre el bastidor — 8:1 */
}
.ck-app .topbar { flex-shrink: 0; }
.ck-title {
  flex: 1; text-align: center; margin: 0;
  font-family: 'Cabin', sans-serif; font-weight: 700;
  letter-spacing: 4px; font-size: 13px; color: var(--marfil);
}
.ck-clock { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2; margin-right: 4px; }
.ck-clock-date { font-size: 10px; color: #e9b9cb; letter-spacing: .5px; text-transform: capitalize; }
.ck-clock-time { font-family: 'JetBrains Mono', monospace; font-size: 14px; color: var(--marfil); font-weight: 600; }

/* ── Barra de ámbito: UNA fila de filtros por encima de TODO lo que scopea.
      Va montada en el bastidor: topbar guinda → filtros carbón → consola. ── */
.ck-filterbar {
  flex-shrink: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 14px;
  background: var(--chassis-top);
  border-bottom: 1px solid rgba(255,255,255,.30);
}
.ck-fb-label {
  font-family: 'Cabin', sans-serif; font-weight: 700;
  font-size: 10px; text-transform: uppercase; letter-spacing: 1.6px;
  color: var(--bay-dim); margin-right: 2px;
}
.ck-filterbar .dash-fsel, .ck-filterbar .form-control {
  background: var(--surface); border-color: var(--surface); color: var(--text);
}
.ck-filterbar .btn-outline {
  color: var(--bay-ink); border-color: var(--bay-ink); background: transparent;
}
.ck-filterbar .btn-outline:hover { background: var(--marfil); color: var(--chassis); border-color: var(--marfil); }
.ck-fb-spacer { flex: 1; }
.ck-scope-pill {
  font-family: 'JetBrains Mono', monospace; font-weight: 600; font-size: 11.5px;
  color: var(--chassis); background: var(--bay-ink);
  padding: 5px 13px; border-radius: 0; letter-spacing: .4px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── La consola: rejilla de tres franjas que NO scrollea ──────────────────
      El alto de la cubierta inferior es la única medida fija; el mapa se
      queda con lo que sobre. Por debajo de cierto viewport la rejilla se
      suelta y vuelve a scrollear (ver §Responsive) — vale más scroll que
      instrumentos aplastados hasta lo ilegible. */
.cockpit {
  /* La cubierta pedía 14 px más de los que tenía en un viewport de 900:
     dos instrumentos recortaban su pie. Se le dan, y salen del riel del mapa
     (que tiene 1fr de sobra), no de la tipografía. */
  --deck-h: clamp(232px, 32dvh, 302px);
  flex: 1; min-height: 0; overflow: hidden;
  display: grid;
  grid-template-rows: auto minmax(232px, 1fr) var(--deck-h);
  gap: 9px;
  padding: 10px 12px 12px;
  background: var(--chassis);
  transition: opacity .18s var(--ease-out);
}
.ck-band { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 0; }

/* ── Rótulo de franja: un filete de 17 px, no una cabecera ───────────────── */
.ck-rail {
  display: flex; align-items: center; gap: 9px; height: 17px; margin: 0 0 5px; padding-left: 1px;
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 10px;
  letter-spacing: 2.2px; text-transform: uppercase; color: var(--bay-ink);
  min-width: 0;
}
.ck-rail h2 { font: inherit; margin: 0; white-space: nowrap; }
.ck-rail-n {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: .5px; color: var(--marfil); background: var(--guinda);
  padding: 2px 6px; flex-shrink: 0; font-variant-numeric: tabular-nums;
}
.ck-rail-rule { flex: 1; height: 1px; background: rgba(255,255,255,.16); min-width: 12px; }
.ck-rail-note {
  font-family: 'Roboto', sans-serif; font-weight: 400; font-size: 10px;
  letter-spacing: .2px; text-transform: none; color: var(--bay-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46%;
}

/* ── Cara de instrumento: fondo blanco partido por filetes de 1 px ───────── */
.ck-face {
  display: flex; flex-direction: column; gap: 1px;
  background: var(--hair); border-radius: var(--r-sm);
  border-top: 3px solid var(--guinda);
  overflow: hidden; min-height: 0;
}
.ck-slot {
  background: var(--surface); padding: 9px 13px 10px;
  display: flex; flex-direction: column; min-width: 0; min-height: 0;
  position: relative;
  /* La consola es de alto fijo: cuando un instrumento no cabe, su contenido se
     desplaza DENTRO de la ranura. Antes lo recortaba `overflow:hidden` de la
     cara y el último renglón (el pie de "Alcance institucional", el de
     "Calidad del dato") desaparecía sin avisar. */
  overflow: hidden auto;
  scrollbar-width: thin;
}
/* La barra se ve SIEMPRE que hay desplazamiento: una ranura recortada sin
   barra es indistinguible de una ranura completa. */
.ck-slot::-webkit-scrollbar { width: 6px; }
.ck-slot::-webkit-scrollbar-thumb { background: var(--rule-hard); }
.ck-slot::-webkit-scrollbar-track { background: var(--bg2); }
.ck-slot-grow { flex: 1; }
.ck-chead { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 6px; }
/* Ranura angosta: los controles no caben junto al rótulo, bajan a su renglón. */
.ck-chead-stack { flex-direction: column; align-items: stretch; gap: 7px; }
.ck-chead-stack .ck-tools { margin-left: 0; flex-wrap: wrap; }
.ck-h {
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 11px;
  letter-spacing: 1.5px; text-transform: uppercase; color: var(--text);
  margin: 0; padding-left: 10px; position: relative; min-width: 0;
}
.ck-h::before {
  content: ''; position: absolute; left: 0; top: 1px; bottom: 1px;
  width: 3px; border-radius: 0; background: var(--guinda);
}
.ck-sub { font-size: 11px; color: var(--text-dim); margin: 0 0 7px; padding-left: 10px; line-height: 1.4; }
.ck-sub b { color: var(--text); font-weight: 600; }
.ck-tools { display: flex; align-items: center; gap: 5px; margin-left: auto; flex-shrink: 0; }
.ck-tgrp { display: flex; gap: 5px; }
.ck-foot { margin-top: auto; padding-top: 5px; font-size: 10px; color: var(--text-dim); line-height: 1.4; }
.ck-empty { color: var(--text-dim); font-size: 12px; padding: 10px 0; }

/* Conmutadores de vista (Tabla · Mensual/Acumulado · Personas/Inversión…) */
.ck-vbtn {
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 9.5px;
  letter-spacing: .9px; text-transform: uppercase; cursor: pointer;
  background: var(--surface); color: var(--text-2);
  /* Canto duro: --border2 daba 1.28:1 sobre la losa blanca y el conmutador se
     adivinaba. WCAG 1.4.11 pide 3:1 al contorno de un control. */
  border: 1px solid var(--rule-hard); border-radius: 0;
  padding: 0 10px; height: 22px; line-height: 1; white-space: nowrap;
  display: inline-flex; align-items: center; transition: background .15s var(--ease-out), color .15s var(--ease-out), border-color .15s var(--ease-out);
}
.ck-vbtn:hover { background: rgba(148,33,72,.08); border-color: var(--guinda); }
.ck-vbtn[aria-pressed="true"] { background: var(--guinda); border-color: var(--guinda); color: var(--marfil); }
.ck-vbtn:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
.ck-nivelsel {
  font-family: 'Roboto', sans-serif; font-size: 11px; color: var(--text);
  background: var(--surface); border: 1px solid var(--rule-hard); border-radius: 0;
  padding: 0 7px; height: 22px; cursor: pointer; max-width: 130px;
}
.ck-nivelsel:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }

/* Lienzo de gráfica: alto explícito y canvas absoluto — Chart.js con
   `maintainAspectRatio:false` crece sin freno si el contenedor es flexible. */
.ck-canvas-wrap { position: relative; width: 100%; }
.ck-canvas-wrap > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
/* El lienzo se queda con el alto que sobra de la ranura, con un piso propio. */
.ck-cw-grow { flex: 1; min-height: 118px; }
.ck-cmp-wrap { flex: 1; min-height: 200px; }

/* Vista de tabla de una gráfica */
.ck-tbl { margin-top: 8px; max-height: 210px; overflow: auto; }
.ck-tbl table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.ck-tbl th {
  text-align: left; font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 9.5px;
  letter-spacing: .9px; text-transform: uppercase; color: var(--marfil);
  padding: 5px 7px; border-bottom: 0; position: sticky; top: 0; background: var(--rule-hard);
}
.ck-tbl td { padding: 5px 7px; border-bottom: 1px solid var(--border); color: var(--text-2); }
.ck-tbl th.num, .ck-tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.ck-tbl td.num { color: var(--text); }
/* Caja que scrollea DENTRO de una ranura (tabla de predios del conmutador) */
.ck-scrollbox { flex: 1; min-height: 0; overflow: auto; margin-top: 1px; }
.ck-scrollbox::-webkit-scrollbar { width: 8px; }
.ck-scrollbox::-webkit-scrollbar-thumb { background: var(--rule-hard); border-radius: 0; }

/* ── 01 · PULSO: la tira de cifras ────────────────────────────────────────
      Un puñado de números titulares NO es una gráfica (regla de `dataviz`):
      es una hilera de fichas. La cifra madre va bañada en guinda a la
      izquierda y las cinco fichas de contexto en blanco a su derecha. */
.ck-kpi {
  display: grid; grid-template-columns: minmax(214px, 268px) minmax(0, 1fr); gap: 1px;
  background: var(--hair); border-radius: var(--r-sm);
  border-top: 3px solid var(--guinda); overflow: hidden;
}
.ck-kpi-hero {
  position: relative; padding: 9px 15px 10px;
  display: flex; flex-direction: column; justify-content: center; min-width: 0;
}
.ck-drench {
  background: var(--guinda-d);
  color: var(--marfil); overflow: hidden;
}
.ck-drench::after {
  content: ''; position: absolute; right: -52px; top: -46px;
  width: 190px; height: 190px; pointer-events: none; opacity: .16;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2048%2048'%20fill='none'%3E%3Ccircle%20cx='24'%20cy='24'%20r='21'%20stroke='%23ffffff'%20stroke-width='.8'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='14'%20stroke='%23ffffff'%20stroke-width='.8'/%3E%3Ccircle%20cx='24'%20cy='24'%20r='7'%20stroke='%23ffffff'%20stroke-width='.8'/%3E%3Cpath%20d='M24%202%20V46%20M2%2024%20H46'%20stroke='%23ffffff'%20stroke-width='.6'/%3E%3C/svg%3E");
  background-size: contain; background-repeat: no-repeat;
}
.ck-eyebrow {
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 9.5px;
  letter-spacing: 1.5px; text-transform: uppercase; color: #f0cad8; margin: 0 0 3px;
  position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Cifra madre: cifras PROPORCIONALES (tabular-nums afloja un número grande) */
.ck-hero {
  font-family: 'Cabin', sans-serif; font-weight: 700;
  font-size: clamp(34px, 2.6vw, 44px); line-height: .95; letter-spacing: -1.2px;
  color: var(--marfil); margin: 0; position: relative;
}
.ck-hero-l { font-size: 10px; letter-spacing: .4px; color: #f0cad8; margin: 3px 0 0; position: relative; line-height: 1.3; }

/* Fichas de contexto: cinco columnas iguales, una cifra cada una */
.ck-sats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1px; background: var(--hair); min-width: 0; }
.ck-sat {
  background: var(--surface); padding: 9px 13px 10px; min-width: 0;
  display: flex; flex-direction: column; justify-content: center;
}
.ck-sat-l { font-size: 9px; text-transform: uppercase; letter-spacing: .7px; color: var(--text-dim); margin: 0 0 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-sat-v { font-family: 'Cabin', sans-serif; font-weight: 700; font-size: clamp(19px, 1.5vw, 25px); line-height: 1.05; color: var(--text); letter-spacing: -.4px; }
.ck-sat-s { font-size: 9.5px; color: var(--text-dim); margin-top: 3px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-sat-s b { color: var(--text-2); font-weight: 600; font-variant-numeric: tabular-nums; }
/* Micro-pista: una cobertura del 1 % no se ve como relleno, pero SÍ se ve
   como una marca mínima sobre una pista. El número manda; la pista sitúa. */
.ck-sat-track { height: 4px; border-radius: 0; background: var(--sq-track); margin-top: 6px; overflow: hidden; }
.ck-sat-track i { display: block; height: 100%; border-radius: 0; background: var(--guinda); min-width: 3px; }

/* ── Etapas del trámite: partes de UN todo (el padrón), no un embudo ──────
      Antes cada barra se escalaba contra la MAYOR, así que «480» se veía a
      media pantalla de «969» y la lectura de proporción salía falsa. Ahora
      todas comparten la escala del total: el ancho ES el porcentaje. */
.ck-fn { display: flex; flex-direction: column; gap: 7px; margin-top: 1px; }
.ck-fn-row { display: grid; grid-template-columns: 68px minmax(0, 1fr) 76px; align-items: center; gap: 8px; }
.ck-fn-lbl { font-size: 9.5px; text-transform: uppercase; letter-spacing: .6px; color: var(--text-2); }
.ck-fn-track { height: 14px; display: flex; align-items: center; background: var(--sq-track); border-radius: 0; overflow: hidden; }
.ck-fn-bar { display: block; height: 100%; border-radius: 0; transition: width .55s var(--ease-out); }
.ck-fn-val { text-align: right; font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ck-fn-val small { font-family: 'Roboto', sans-serif; font-weight: 400; font-size: 9.5px; color: var(--text-dim); margin-left: 3px; }
.ck-fn-zero { color: var(--text-dim); }

/* ── Medidor de proporción (alcance institucional) ───────────────────────── */
.ck-meter + .ck-meter { margin-top: 8px; }
.ck-meter-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.ck-meter-l { font-size: 9.5px; text-transform: uppercase; letter-spacing: .7px; color: var(--text-dim); }
.ck-meter-v { font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 15px; color: var(--text); font-variant-numeric: tabular-nums; }
.ck-meter-v small { font-family: 'Roboto', sans-serif; font-weight: 400; font-size: 11px; color: var(--text-dim); }
/* El % viaja pegado a la fracción, en una losa guinda: es la lectura que se
   compara entre los tres medidores y así no necesita renglón propio. */
.ck-meter-v b {
  font-family: var(--font-mono); font-weight: 600; font-size: 10px;
  color: var(--marfil); background: var(--guinda); padding: 1px 5px; margin-left: 6px;
}
.ck-meter-track { height: 7px; border-radius: 0; background: var(--sq-track); margin-top: 5px; overflow: hidden; }
/* min-width: un 1 % con relleno 0 px se lee como «no hay dato». Siempre marca. */
.ck-meter-fill { display: block; height: 100%; border-radius: 0; background: var(--sq-5); min-width: 3px; transition: width .6s var(--ease-out); }
.ck-meter-note { font-size: 9.5px; color: var(--text-dim); margin-top: 3px; }

/* ── Barra de partes: sexo y concurrencia de apoyos ──────────────────────
      Hueco de 2 px de superficie ENTRE segmentos (nunca un borde dibujado). */
.ck-stack { display: flex; gap: 2px; height: 17px; margin-top: 5px; }
.ck-stack i { display: block; height: 100%; min-width: 3px; }
.ck-stack i:first-child { border-radius: 0; }
.ck-stack i:last-child { border-radius: 0; }
.ck-part + .ck-part { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--border); }
.ck-part-l { font-size: 9.5px; text-transform: uppercase; letter-spacing: .7px; color: var(--text-dim); margin: 0; }
.ck-legend-row { display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 7px; }
.ck-leg-item { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; color: var(--text-2); max-width: 100%; }
.ck-leg-item i { width: 9px; height: 9px; border-radius: 0; flex-shrink: 0; }
.ck-leg-item b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ── Calidad del dato: estado con icono + etiqueta, nunca color solo ────── */
.ck-dq { display: flex; flex-direction: column; gap: 5px; }
.ck-dq-row {
  display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; align-items: center; gap: 9px;
  /* #fcfbfb sobre blanco es 1.01:1: un fondo que no existe. Losa blanca; lo
     que separa una fila de otra es el filete, y el estado ya va en el icono. */
  padding: 6px 9px; border: 1px solid var(--border); border-radius: 0; background: var(--surface);
}
.ck-dq-ic {
  width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: #fff; background: var(--text-dim); flex-shrink: 0;
}
/* El `!` blanco sobre --naranja3 daba 3.26:1 (falla AA de texto). El naranja
   se conserva como dato; la tinta pasa a carbón, que da 6.5:1. */
.ck-dq-row.warn .ck-dq-ic { background: var(--naranja3); color: #2b2622; }
.ck-dq-row.ok .ck-dq-ic { background: var(--verde-text); }
.ck-dq-l { font-size: 11px; color: var(--text-2); min-width: 0; line-height: 1.25; }
.ck-dq-l small { display: block; font-size: 9.5px; color: var(--text-dim); }
.ck-dq-v { font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 14px; color: var(--text); font-variant-numeric: tabular-nums; }

/* ── Tabla compacta dentro de una ranura ─────────────────────────────────── */
.ck-table { font-size: 11px; }
.ck-table td { padding: 5px 6px; }
.ck-table th { padding: 6px 6px; position: sticky; top: 0; background: var(--surface); z-index: 1; }

/* ── El escenario: el mapa con su bisel ─────────────────────────────────── */
.ck-stage {
  position: relative; background: var(--surface); border-radius: var(--r-sm);
  border-top: 3px solid var(--guinda); overflow: hidden; min-height: 0;
  display: grid; grid-template-rows: auto minmax(0, 1fr);
}
.ck-stage::before, .ck-stage::after {
  content: ''; position: absolute; top: 46px; bottom: 8px; width: 8px;
  pointer-events: none; z-index: 2;
}
.ck-stage::before { left: 8px;  border-left: 1px solid var(--bezel); }
.ck-stage::after  { right: 8px; border-right: 1px solid var(--bezel); }
.ck-map-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 8px 13px 7px; border-bottom: 1px solid var(--border);
}
.ck-scope-title { font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 17px; color: var(--text); letter-spacing: .3px; }
.ck-scope-sub { font-size: 10.5px; color: var(--guinda-d); margin-top: 1px; letter-spacing: .3px; }
.ck-map-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
.ck-map-tag {
  font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 9px;
  letter-spacing: 1.2px; text-transform: uppercase; color: var(--marfil);
  background: var(--guinda); padding: 3px 9px; border-radius: 0; white-space: nowrap;
}
.ck-map-hud {
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; color: var(--text-dim);
  letter-spacing: .2px; white-space: nowrap;
}
.ck-map-hud b { color: var(--guinda-d); font-weight: 600; }
#ckMap { width: 100%; height: 100%; min-height: 0; }
.ck-map-legend {
  position: absolute; left: 16px; bottom: 14px; z-index: 3;
  background: var(--surface); border: 1px solid var(--rule-hard);
  padding: 7px 10px 8px; box-shadow: var(--lift-sm);
}
.ck-leg-title { display: block; font-family: 'Cabin', sans-serif; font-weight: 700; font-size: 9px; text-transform: uppercase; letter-spacing: 1px; color: var(--guinda-d); margin-bottom: 5px; }
.ck-scale { display: flex; }
.ck-scale i { display: block; width: 32px; height: 9px; }
.ck-scale i:first-child { border-radius: 0; }
.ck-scale i:last-child { border-radius: 0; }
.ck-scale-lbls { display: flex; margin-top: 3px; }
.ck-scale-lbls span { width: 32px; font-size: 8px; color: var(--text-dim); text-align: center; font-variant-numeric: tabular-nums; }
/* Popup del mapa del cockpit: el mismo filete doble del mapa grande — el
   coropleto de UBAs llega hasta --sq-6, donde un filete claro se disuelve. */
.ck-popup .maplibregl-popup-content { background: var(--surface); color: var(--text); border: 1px solid var(--rule-hard); border-top: 3px solid var(--guinda); border-radius: 0; font-size: 12px; box-shadow: var(--lift); }
.ck-popup .maplibregl-popup-content b { color: var(--guinda-d); }
.ck-popup .maplibregl-popup-tip { border-top-color: var(--surface); border-bottom-color: var(--guinda); }

/* ── 02 · TERRITORIO: avance | mapa | comparativa ─────────────────────────
      Los dos railes son fijos y el mapa se queda con TODO lo que sobre —
      al revés de como estaba, donde la comparativa colgaba bajo el mapa y
      empujaba la cubierta inferior fuera de la pantalla. */
.ck-terr { display: grid; grid-template-columns: 292px minmax(0, 1fr) 330px; gap: 9px; min-height: 0; }

/* ── 03 · CUBIERTA INFERIOR: cinco instrumentos, una sola cara ────────────
      Los anchos NO son iguales: los rótulos de programa son largos y las
      barras de calle necesitan recorrido; la calidad del dato y el ritmo
      de altas caben en menos. */
/* Cabecera de instrumento en la cubierta: el rótulo NO se parte en tres
   renglones ni se lo comen los conmutadores. Con nowrap en el rótulo y
   flex-wrap en la fila, los botones bajan a su propio renglón SOLO en las
   columnas donde no caben — sin media queries por columna. */
.ck-deck-face .ck-chead { flex-wrap: wrap; row-gap: 6px; }
.ck-deck-face .ck-h { white-space: nowrap; }
.ck-deck-face .ck-tools { margin-left: auto; }

.ck-deck-face {
  display: grid; grid-template-columns:
    minmax(0, 1.16fr) minmax(0, 1.02fr) minmax(0, .92fr) minmax(0, .8fr) minmax(0, .9fr);
  gap: 1px;
  background: var(--hair); border-radius: var(--r-sm);
  border-top: 3px solid var(--guinda); overflow: hidden; min-height: 0;
}

/* ── Responsive ──────────────────────────────────────────────────────────
      Tres umbrales, y uno de ALTO. La rejilla de pantalla única solo se
      sostiene si hay alto real: por debajo de ~800 px el mapa quedaría en
      una rendija, así que la consola vuelve a scrollear con alturas
      cómodas. Es una degradación deliberada, no un descuido. */
@media (max-width: 1500px) {
  .ck-terr { grid-template-columns: 264px minmax(0, 1fr) 300px; }
  .ck-kpi { grid-template-columns: minmax(190px, 236px) minmax(0, 1fr); }
}
@media (max-width: 1300px) {
  /* Ya no caben cinco instrumentos en una fila ni tres columnas de territorio:
     la consola suelta el alto fijo y vuelve a ser una página que scrollea.
     TRAMPA: no basta con `grid-template-rows: auto`. Las caras de instrumento
     llevan `overflow:hidden`, así que su tamaño mínimo automático es CERO y
     una pista `auto` se deja aplastar por un contenedor de alto definido —
     la cubierta perdía su segunda fila entera (recortada, no scrolleable) y
     los botones de arriba quedaban tapados por lo que sobresalía. Con flex y
     `flex-shrink: 0` cada franja conserva su alto de contenido. */
  .cockpit { display: flex; flex-direction: column; overflow-y: auto; }
  .cockpit > * { flex-shrink: 0; }
  .ck-terr { grid-template-columns: 268px minmax(0, 1fr); grid-template-rows: minmax(340px, 48vh) auto; }
  .ck-stage { grid-row: 1; grid-column: 2; }
  .ck-terr > .ck-face:first-child { grid-row: 1; grid-column: 1; }
  .ck-terr > .ck-face:last-child { grid-row: 2; grid-column: 1 / -1; }
  .ck-cmp-wrap { height: 300px; flex: none; }
  .ck-deck-face { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ck-cw-grow { flex: none; height: 216px; }
  .ck-slot { padding: 11px 14px 12px; }
}
@media (max-width: 900px) {
  /* Teléfono / tablet vertical: MAPA PRIMERO, información alrededor debajo. */
  .ck-band-terr { order: -1; }
  .ck-kpi { grid-template-columns: minmax(0, 1fr); }
  .ck-sats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ck-terr { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(290px, 44vh) auto auto; }
  .ck-stage { grid-row: 1; grid-column: 1; }
  .ck-terr > .ck-face:first-child { grid-row: 2; grid-column: 1; }
  .ck-terr > .ck-face:last-child { grid-row: 3; grid-column: 1; }
  .ck-cmp-wrap { height: 290px; }
  .ck-deck-face { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .cockpit { padding: 10px 10px 26px; gap: 13px; }
  .ck-title { display: none; }
  .ck-clock { display: none; }
  .ck-app .topbar { height: auto; padding: 7px 12px; gap: 9px; flex-wrap: wrap; }
  .ck-app .topbar .user-badge { max-width: 46vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ck-app .topbar .nav-links { margin-left: auto; }
  .ck-filterbar { padding: 8px 10px; gap: 7px; }
  .ck-filterbar .dash-fsel { flex: 1 1 44%; min-width: 0; max-width: none; }
  .ck-fb-spacer { display: none; }
  .ck-scope-pill { flex: 1 1 100%; text-align: center; }
  .ck-sats { grid-template-columns: minmax(0, 1fr); }
  .ck-hero { font-size: 44px; }
  .ck-fn-row { grid-template-columns: 62px minmax(0, 1fr) 70px; }
  /* La nota de franja no cabe junto al rótulo en un teléfono: baja a su propia
     línea. El alto FIJO de 17 px existe solo para que las franjas arranquen
     alineadas en escritorio; aquí ya es una columna, así que se suelta. */
  .ck-rail { flex-wrap: wrap; row-gap: 3px; height: auto; }
  .ck-rail-note { flex: 1 0 100%; order: 3; white-space: normal; max-width: none; }
  .ck-chead { flex-wrap: wrap; }
  .ck-tools { margin-left: 0; }
  /* En un lienzo angosto la atribución de OSM/CARTO se estira hacia la
     izquierda hasta meterse bajo la leyenda. Es obligación de licencia que
     quede legible: la leyenda sube por encima de su franja. */
  .ck-map-legend { bottom: 40px; }
  /* Objetivo táctil de 44 px también cuando el puntero se declara fino
     (navegador de escritorio en ventana estrecha, emuladores, pruebas E2E). */
  .ck-vbtn { min-height: 44px; padding: 0 13px; font-size: 11px; }
  .ck-nivelsel { min-height: 44px; font-size: 12px; }
  .ck-filterbar .form-control, .ck-filterbar .btn { min-height: 44px; }
}
/* Poco alto: la pantalla única dejaría el mapa en una rendija. Mejor scroll.
   Mismo motivo que arriba para usar flex y no pistas `auto`. */
@media (min-width: 1301px) and (max-height: 800px) {
  .cockpit { display: flex; flex-direction: column; overflow-y: auto; }
  .cockpit > * { flex-shrink: 0; }
  .ck-terr { grid-template-rows: minmax(392px, 56vh); }
  .ck-cw-grow { flex: none; height: 188px; }
  .ck-cmp-wrap { flex: none; height: 300px; }
}
.cockpit::-webkit-scrollbar { width: 10px; }
.cockpit::-webkit-scrollbar-thumb { background: rgba(255,255,255,.18); border-radius: 0; }
.cockpit::-webkit-scrollbar-track { background: transparent; }

/* ── Encendido de la consola: las franjas entran una tras otra, una sola vez.
      Fuera de `no-preference` no se declara animación: el contenido nace
      visible y nada depende de que una transición llegue a correr. */
@media (prefers-reduced-motion: no-preference) {
  .ck-band { animation: ckBoot .42s var(--ease-out) both; }
  .ck-band-pulso { animation-delay: .02s; }
  .ck-band-terr { animation-delay: .09s; }
  .ck-band-deck { animation-delay: .15s; }
  @keyframes ckBoot { from { opacity: 0; transform: translateY(9px); } }
}


/* ════════════════════════════════════════════════════════════════════
   ADAPTACIÓN TÁCTIL — campo / tablet
   Se detecta el MÉTODO DE ENTRADA, no el tamaño de pantalla: un puntero
   grueso (dedo, lápiz) agranda los objetivos a ≥44px; el puntero fino
   (mouse/trackpad) conserva el panel denso de escritorio sin cambios.
   ════════════════════════════════════════════════════════════════════ */
@media (pointer: coarse) {
  /* Botones de acción de panel: 👁 ⬇ ✏ 🗑, toggles, ✕ de tarjetas de campo */
  .capa-btn { min-width: 44px; min-height: 44px; font-size: 15px; }

  /* Eliminar beneficiario */
  .ben-item .ben-del { min-width: 44px; min-height: 44px; padding: 6px 12px; font-size: 16px; }

  /* Flechas del riel (plegar / reabrir) */
  .rail-collapse, .rail-reopen { width: 44px; height: 44px; font-size: 14px; }

  /* Filas de capas y formularios: alto cómodo para el dedo */
  .capa-item, .form-list-item { min-height: 44px; gap: 9px; }

  /* Toggles de capa: fila alta + checkbox más grande (la palomita se recentra sola) */
  #layerToggle label { min-height: 44px; padding: 4px 0; gap: 12px; }
  #layerToggle input[type=checkbox] { width: 22px; height: 22px; }
  #layerToggle input[type=checkbox]:checked::after { font-size: 13px; }
  #layerToggle .lt-dot { width: 11px; height: 11px; }

  /* Cabeceras de sección plegables */
  .panel-header { min-height: 44px; }

  /* Botones y controles de formulario/filtro/búsqueda: alto de toque cómodo */
  .btn, .btn-sm, .editor-btn { min-height: 44px; }
  .form-control, .filter-select, .search-input { min-height: 44px; font-size: 14px; }

  /* Conmutadores de vista del centro de mando (Tabla · Mensual/Acumulado ·
     Personas/Inversión · Mejor/Peor) y el selector de nivel territorial. */
  .ck-vbtn { min-height: 44px; padding: 0 12px; font-size: 11px; }
  .ck-nivelsel { min-height: 44px; font-size: 12px; }
  .filter-select { padding: 10px 12px; }
  .seg-opt span { min-height: 44px; display: flex; align-items: center; justify-content: center; }

  /* Más aire entre filas de filtro para evitar toques accidentales */
  .filter-row { margin-bottom: 4px; }
}

/* ════════════════════════════════════════════════════════════════════
   MIRA FIJA Y MUELLE DE TRAZO — trazar predios con el pulgar
   El dedo no puede hacer hover y además TAPA el punto que señala. Por eso
   la mira no sigue al dedo: se queda quieta y lo que se arrastra es el
   mapa. Todo esto solo existe con puntero grueso — en escritorio el
   editor conserva su clic de siempre y este bloque no aplica.
   ════════════════════════════════════════════════════════════════════ */
/* Ocultos SIEMPRE por defecto: en escritorio no existen, y en táctil los
   enciende el editor al entrar a un modo de trazo. */
.mira,
.editor-dock { display: none; }

@media (pointer: coarse) {
  .mira.is-on,
  .editor-dock.is-on { display: block; }

  .mira {
    position: absolute;
    z-index: var(--z-panel);
    transform: translate(-50%, -50%);
    /* Nunca intercepta el gesto: el pulgar arrastra el mapa POR DEBAJO. */
    pointer-events: none;
  }
  .mira-cruz {
    display: block; width: 48px; height: 48px;
    fill: none; stroke: var(--text-2); stroke-width: 1.6;
    /* Se lee igual sobre el basemap claro que sobre un predio saturado. */
    filter: drop-shadow(0 0 2px rgba(255,255,255,.95));
    transition: stroke .12s ease;
  }
  .mira-cruz .mira-punto { fill: var(--text-2); stroke: none; }

  /* El estado del enganche usa los MISMOS colores que el anillo del mapa:
     guinda = esquina del vecino · naranja = punto sobre su arista. */
  .mira[data-kind="vertex"] .mira-cruz,
  .mira[data-kind="mid"]    .mira-cruz { stroke: #942148; stroke-width: 2.4; }
  .mira[data-kind="vertex"] .mira-punto,
  .mira[data-kind="mid"]    .mira-punto { fill: #942148; }
  .mira[data-kind="edge"]   .mira-cruz { stroke: #ed6414; stroke-width: 2.4; }
  .mira[data-kind="edge"]   .mira-punto { fill: #ed6414; }
  .mira[data-kind="guide"]  .mira-cruz { stroke: #b52d5e; }
  .mira[data-kind="guide"]  .mira-punto { fill: #b52d5e; }

  /* Chip: dice EN PALABRAS a qué se va a enganchar. Es la pieza que sustituye
     al hover — sin él, confirmar un vértice sigue siendo un acto de fe. */
  .mira-chip {
    position: absolute; top: 34px; left: 50%; transform: translateX(-50%);
    white-space: nowrap;
    padding: 4px 9px; border-radius: 0;
    font-size: 11px; font-weight: 700; letter-spacing: .3px;
    color: #ffffff; background: var(--text);
    box-shadow: var(--lift-sm);
  }
  .mira-chip:empty { display: none; }
  .mira-chip[data-kind="vertex"],
  .mira-chip[data-kind="mid"]   { background: #942148; }
  .mira-chip[data-kind="edge"]  { background: #ed6414; }
  .mira-chip[data-kind="guide"] { background: #b52d5e; }

  /* ── Muelle ─────────────────────────────────────────────────────────
     Los controles del trazo salen del riel y bajan al pulgar. Mientras
     está encendido, la hoja de control se pliega (editor-movil.js). */
  .editor-dock {
    position: absolute; z-index: var(--z-panel);
    left: 10px; right: 10px;
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  }
  .dock-contador {
    display: block; margin: 0 auto 6px; width: max-content;
    padding: 3px 10px; border-radius: 0;
    font-size: 11px; font-weight: 700; letter-spacing: .4px;
    color: #ffffff; background: var(--text);
  }
  .dock-fila {
    display: grid; grid-template-columns: 1fr auto auto auto; gap: 6px;
    padding: 6px; border-radius: 0;
    background: var(--surface);
    border: 1px solid var(--rule-hard);
    box-shadow: var(--lift);
  }
  .dock-btn {
    min-height: 56px; min-width: 56px;
    border: 1px solid var(--border2); border-radius: 0;
    background: #ffffff; color: var(--text);
    font-family: inherit; font-size: 17px; font-weight: 700;
    cursor: pointer; -webkit-tap-highlight-color: transparent;
  }
  .dock-btn:active { transform: translateY(1px); }
  .dock-btn-main {
    background: #942148; border-color: #942148; color: #ffffff;
    font-size: 15px; letter-spacing: .3px;
  }
  .dock-btn-ok   { background: #1f6f4a; border-color: #1f6f4a; color: #ffffff; }
  .dock-btn-stop { color: #942148; }
  .dock-btn:disabled { opacity: .4; cursor: default; }

  /* Con el muelle encendido, el censo estorba justo donde va el pulgar. */
  .map-container:has(.editor-dock.is-on) .census { display: none; }

  /* El aviso vive en la esquina inferior — justo encima del muelle. Se sube por
     encima de él: un mensaje que tapa el botón que hay que pulsar es peor que
     no dar el mensaje. */
  /* 116px = alto medido del muelle (contador + fila de 56 px) + aire. */
  body:has(.editor-dock.is-on) .toast {
    bottom: calc(116px + env(safe-area-inset-bottom, 0px));
    left: 10px; right: 10px; max-width: none;
  }
}

/* ═══ Panel de Auditoría (admin.html) ══════════════════════════════════════
   LOSA INSTITUCIONAL (etapa B, 2026-08-21). La auditoría era la última
   pantalla con lenguaje viejo: cajas de filete gris claro (1.28:1 sobre
   blanco, invisibles), tintes rgba de guinda al 5-12 % haciendo de "fondo
   suave" y cifras en Roboto proporcional. Aquí cada instrumento es una LOSA
   con canto duro, la separación entre losas es un CORTE (carbón o guinda) y
   toda cifra es JetBrains Mono tabular: un expediente es un libro de cuentas.
   La barra de acciones (`.adm-toolbar`, `.adm-tb-*`, `.adm-rango-pill`,
   `.adm-date`, `.adm-filters`) se eliminó: la sustituyó `.adm-ctl` en el
   rediseño de 2026-08-02 y ningún HTML ni JS la referenciaba.
   ══════════════════════════════════════════════════════════════════════════ */
.adm-main { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 24px 60px; max-width: 1180px; margin: 0 auto; width: 100%; }

/* Toda cifra de la auditoría, en mono tabular: las columnas de la bitácora se
   leen en vertical y una Roboto proporcional las desalinea. */
.adm-page .tnum,
.adm-page .adm-count,
.adm-page .adm-exec-val,
.adm-page .adm-card-num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Doble sello: sección marfil con banda de cabecera guinda + filete dorado */
.adm-section {
  background: var(--surface); border: 1px solid var(--rule-hard);
  border-radius: var(--r-lg); padding: 18px 20px; margin-bottom: 22px;
  overflow: hidden;
}
.adm-sec-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  background: var(--guinda-d);
  border-bottom: none;
  margin: -18px -20px 14px; padding: 12px 20px;
}
.adm-sec-head h2 { font-family: 'Cabin', sans-serif; font-size: 14px; font-weight: 700; color: var(--marfil); letter-spacing: 1px; text-transform: uppercase; margin: 0; }
.adm-sub { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--text-2); margin: 18px 0 10px; font-weight: 700; }
.adm-count { color: var(--guinda); }

/* ── Tira de conteos: UNA regleta, no seis cajitas sueltas ────────────────
   Las cajas de filete claro no se veían y el conjunto se leía como seis
   objetos. Ahora es un solo bloque con canto carbón, partido por cortes de
   1 px del mismo carbón: las cifras quedan cosidas en una regleta y el chip
   activo se distingue por ser losa guinda, no por un tinte. */
.adm-chips {
  display: flex; flex-wrap: wrap; gap: 1px; margin-bottom: 14px;
  background: var(--rule-hard); border: 1px solid var(--rule-hard);
  width: fit-content; max-width: 100%;
}
.adm-chip {
  font-size: 12px; color: var(--text-2); background: var(--surface);
  border: 0; border-radius: 0; padding: 7px 13px;
}
.adm-chip b { color: var(--text); font-size: 14px; font-weight: 700; }
/* El color de la cifra codifica el TIPO de acción — el mismo código que la
   insignia de cada fila de la bitácora. Es dato, no cromo. */
.adm-chip.ch-total b { color: var(--guinda-d); }
.adm-chip.ch-crear b { color: var(--verde-text); }
.adm-chip.ch-editar b { color: var(--azul2); }
.adm-chip.ch-eliminar b { color: var(--guinda); }

/* Panel ejecutivo: dos lecturas nominales + la serie por día */
.adm-exec { display: flex; gap: 16px; flex-wrap: wrap; margin: 4px 0 10px; }
.adm-exec-cards { display: flex; gap: 10px; }
.adm-exec-card { background: var(--surface); border: 1px solid var(--rule-hard);
  border-left: 4px solid var(--guinda); border-radius: 0; padding: 8px 14px; min-width: 150px; }
.adm-exec-label { font-size: 10px; color: var(--text-2); text-transform: uppercase; letter-spacing: .9px; font-weight: 700; }
.adm-exec-val { font-size: 18px; font-weight: 600; color: var(--guinda-d); letter-spacing: -.02em; }
.adm-serie { display: flex; align-items: flex-end; gap: 4px; height: 74px; }
.adm-bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.adm-bar-fill { width: 70%; background: var(--sq-4); border-radius: 0; min-height: 2px; }
.adm-bar-lbl { font-family: var(--font-mono); font-size: 9px; color: var(--text-2); margin-top: 3px; }
.adm-chip-btn { cursor: pointer; }

/* Tablas */
.adm-tablewrap { overflow-x: auto; }
.adm-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.adm-table th {
  text-align: left; padding: 8px 10px; color: var(--marfil);
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  background: var(--rule-hard); border-bottom: 0; white-space: nowrap;
}
.adm-table td { padding: 9px 10px; border-bottom: 1px solid var(--border); color: var(--text-2); vertical-align: top; }
/* La fila señalada no se tiñe: se marca con un tope de color en el canto
   izquierdo. Un rgba al 5 % sobre blanco es indistinguible del blanco (1.05:1)
   y encima ensucia el papel del expediente. Carbón = el puntero está aquí. */
.adm-table tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--rule-hard); }
/* Fila del reparto activo: especificidad por encima del :hover para que el
   tope guinda no se apague al pasar el mouse. */
.adm-table tbody tr.adm-ent-actual td:first-child,
.adm-table tbody tr.adm-ent-actual:hover td:first-child { box-shadow: inset 4px 0 0 var(--guinda); }
.adm-table tbody tr.adm-ent-actual td { color: var(--text); font-weight: 600; }
.adm-ent-radio { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; cursor: pointer; }
.adm-nowrap { white-space: nowrap; }
.adm-dim { color: var(--text-dim); }
.adm-empty { color: var(--text-dim); font-size: 12px; padding: 18px 10px; text-align: center; }

/* Desglose por racimo/usuario */
.adm-desglose { margin: 10px 0 4px; }
.adm-desglose-table td, .adm-desglose-table th { text-align: center; }
.adm-desglose-table td:first-child, .adm-desglose-table th:first-child { text-align: left; }
/* El disparador de la fila es un <button> real dentro de la celda de encabezado,
   no `role="button"` sobre el <tr>: ese rol sustituía al de fila y desarmaba la
   tabla para un lector de pantalla. Así el teclado funciona sin listener propio. */
.adm-desg-btn {
  border: 0; background: none; padding: 0; cursor: pointer;
  font-family: 'Roboto', sans-serif; font-size: 12.5px; font-weight: 600;
  color: var(--guinda-d); text-decoration: underline; text-underline-offset: 2px;
}
.adm-desg-btn:hover { color: var(--guinda); }
.adm-desglose-table th[scope="row"] { text-align: left; font-weight: 400; padding: 9px 10px; }
.adm-maplink { color: var(--guinda, #942148); text-decoration: underline; font-weight: 600; }
.adm-maplink:hover { text-decoration: underline; }

/* Duplicados (padrón completo) */
.adm-hint { font-size: 12px; color: var(--text-2); margin: 2px 0 8px; }
.adm-dup-cluster { border: 1px solid var(--rule-hard); border-radius: 0; padding: 6px 10px; margin-bottom: 6px; }
.adm-dup-cluster summary { cursor: pointer; }
.adm-dup-cluster[open] { border-left: 4px solid var(--guinda); }
.adm-dup-table { margin-top: 6px; }

/* Insignia de acción — el color codifica el TIPO de movimiento (dato). */
.adm-badge { display: inline-block; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 0; white-space: nowrap; }
.adm-badge.ac-crear    { color: #0d1a10; background: var(--verde); }
.adm-badge.ac-editar   { color: #06121f; background: var(--azul1); }
.adm-badge.ac-eliminar { color: var(--marfil); background: var(--guinda); }
.adm-badge.ac-dividir  { color: var(--text); background: var(--naranja2); }
.adm-badge.ac-deshacer { color: var(--text); background: var(--surface); border: 1px solid var(--rule-hard); }

/* ── Chequeos de consistencia: losa con tope de estado ────────────────────
   El tinte rosa/verde del fondo se retiró. El estado lo dice el TOPE de la
   losa (4 px guinda si hay incidencias, carbón si está limpia) y la cifra;
   el papel siempre es blanco, como en el resto del expediente. */
.adm-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.adm-card {
  background: var(--surface); border: 1px solid var(--rule-hard);
  border-top: 4px solid var(--rule-hard); border-radius: 0; padding: 12px 14px;
}
.adm-card.warn { border-top-color: var(--guinda); }
.adm-card.ok   { border-top-color: var(--verde-text); }
.adm-card-num { font-size: 30px; font-weight: 600; line-height: 1; color: var(--text); letter-spacing: -.03em; }
.adm-card.warn .adm-card-num { color: var(--guinda); }
.adm-card.ok .adm-card-num { color: var(--verde-text); }
.adm-card-title { font-size: 12.5px; color: var(--text-2); margin: 6px 0 8px; }
.adm-card-ok { font-size: 11.5px; color: var(--verde-text); font-weight: 600; }
.adm-card-det summary { font-size: 11.5px; color: var(--guinda-d); cursor: pointer; font-weight: 600; }
.adm-card-det ul { margin: 8px 0 0; padding-left: 16px; }
.adm-card-det li { font-size: 11.5px; color: var(--text-2); margin: 3px 0; }

/* ── Usuarios: la cuenta es una losa; su conteo, un contador macizo ──────── */
.adm-users { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.adm-user {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--surface); border: 1px solid var(--rule-hard); border-radius: 0;
  padding: 10px 12px; margin-bottom: 7px;
}
.adm-user-name { font-size: 13px; font-weight: 600; color: var(--text); }
.adm-user-meta { font-size: 11px; color: var(--text-2); margin-top: 2px; }
.adm-user-mov {
  flex-shrink: 0; min-width: 30px; text-align: center; font-weight: 600; font-size: 13px;
  color: var(--marfil); background: var(--guinda); border-radius: 0; padding: 4px 9px;
}
/* Cuenta sin actividad: contador vacío, no un contador guinda con un 0. */
.adm-usercol:last-child .adm-user-mov { color: var(--text-2); background: var(--surface); box-shadow: inset 0 0 0 1px var(--rule-hard); }

@media (max-width: 760px) {
  .adm-users { grid-template-columns: 1fr; }
  .adm-sec-head { align-items: flex-start; }
}

/* ═══ Auditoría · rediseño 2026-08-02 ══════════════════════════════════════
   Expediente de trabajo, no tablero decorativo: barra de control única arriba,
   riel de apartados a la izquierda y el flujo de secciones a la derecha.
   ═════════════════════════════════════════════════════════════════════════ */
.adm-page .adm-main { max-width: 1420px; }
/* La barra de control es sticky: sin este margen, saltar a un apartado desde
   el índice dejaba su cabecera guinda escondida detrás de la barra. */
.adm-page .adm-section { scroll-margin-top: 172px; }
@media (max-width: 760px) { .adm-page .adm-section { scroll-margin-top: 12px; } }

/* ── Barra de control (periodo + ámbito) ───────────────────────────────── */
.adm-ctl {
  position: sticky; top: 0; z-index: 30;
  display: grid; gap: 10px;
  background: var(--surface); border: 1px solid var(--rule-hard);
  border-radius: 0; padding: 12px 16px; margin-bottom: 18px;
  /* Se queda fija mientras el expediente corre por debajo. Lo que la separa
     del contenido es un zócalo carbón macizo, no un desenfoque. */
  box-shadow: 0 3px 0 0 var(--rule-hard);
}
.adm-ctl-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.adm-ctl-k {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 1px;
  color: var(--guinda-d); font-weight: 700; min-width: 58px;
}
.adm-f { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-2); }
.adm-f-k { color: var(--text-2); white-space: nowrap; text-transform: uppercase; font-size: 10px; letter-spacing: .8px; font-weight: 700; }
.adm-f .form-control { width: auto; min-width: 132px; }

/* Selector de periodo: una regleta de cinco losas cosidas por cortes de 1 px.
   Tres estados, tres losas macizas y ningún tinte: reposo blanco, puntero
   carbón, elegido guinda. `overflow: hidden` recortaba el contorno de foco,
   por eso el padding deja el hueco y el offset negativo lo trae adentro. */
.adm-presets {
  display: inline-flex; gap: 1px; border: 1px solid var(--rule-hard);
  border-radius: 0; overflow: hidden; padding: 2px; background: var(--rule-hard);
}
.adm-preset {
  border: 0; background: var(--surface); color: var(--text-2);
  font-family: 'Roboto', sans-serif; font-size: 12px; font-weight: 500;
  padding: 7px 13px; cursor: pointer; white-space: nowrap;
  transition: background .15s var(--ease-out), color .15s var(--ease-out);
}
.adm-preset:focus-visible { outline: 2px solid var(--guinda); outline-offset: -2px; border-radius: 0; }
.adm-preset:hover { background: var(--rule-hard); color: var(--marfil); }
/* Con el puntero encima el preset es losa carbón: el contorno guinda cae a
   1.84:1 contra ella. Cuando coinciden hover y foco, el contorno se invierte. */
.adm-preset:hover:focus-visible { outline-color: var(--marfil); }
.adm-preset.is-on { background: var(--guinda); color: var(--marfil); font-weight: 700; }
.adm-preset.is-on:hover { background: var(--guinda-l); }

.adm-state {
  margin: 0; font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
  color: var(--marfil); background: var(--rule-hard); border: 0;
  border-radius: 0; padding: 6px 13px; justify-self: start;
  font-variant-numeric: tabular-nums;
}

/* ── Rejilla: riel de apartados + flujo ────────────────────────────────── */
.adm-grid { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 20px; align-items: start; }
.adm-flow { min-width: 0; }

.adm-rail { position: sticky; top: 176px; }
.adm-rail-k {
  font-size: 10px; text-transform: uppercase; letter-spacing: 1.2px;
  color: var(--text-dim); font-weight: 700; margin: 0 0 8px 10px;
}
/* El índice es UNA pieza: losa blanca con canto carbón, partida por cortes de
   1 px del mismo carbón. Suelto sobre el papel de la página, cinco enlaces con
   2 px de aire entre sí no se leían como un solo instrumento. */
.adm-rail-list {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 1px;
  background: var(--rule-hard); border: 1px solid var(--rule-hard);
}
.adm-rail-list a {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; align-items: center; gap: 8px;
  padding: 9px 10px; border-radius: 0; background: var(--surface);
  color: var(--text-2); text-decoration: none; font-size: 13px;
  border-left: 2px solid transparent;
  transition: background .15s var(--ease-out), color .15s var(--ease-out), border-color .15s var(--ease-out);
}
/* El puntero levanta la entrada a losa blanca sobre el papel de la página
   (#f5f2f3) y le clava la espina guinda: un corte, no un gris intermedio. */
.adm-rail-list a:hover { background: var(--surface); color: var(--guinda-d); border-left-color: var(--guinda); }
/* El apartado abierto es una losa guinda, no un tinte: sobre papel blanco un
   rgba al 9 % no marca posición, y el índice es lo único que la marca. */
.adm-rail-list a.is-current {
  background: var(--guinda); color: var(--marfil);
  border-left-color: var(--guinda-d); font-weight: 700;
}
.adm-rail-list a.is-current .adm-rail-n { color: rgba(255,255,255,.82); }
.adm-rail-list a.is-current .adm-rail-v { color: var(--marfil); }
.adm-rail-n { font-family: var(--font-mono); font-size: 11px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.adm-rail-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm-rail-v { font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--guinda-d); }

/* ── Cabecera de sección sobre la banda guinda ─────────────────────────── */
.adm-sec-n {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; letter-spacing: .5px;
  color: var(--guinda-d); background: var(--marfil); padding: 2px 6px;
  font-variant-numeric: tabular-nums;
}
.adm-sec-rule { flex: 1; height: 1px; background: rgba(255,255,255,.25); min-width: 12px; }
.adm-sec-note { font-size: 11.5px; color: rgba(255,255,255,.72); }
.adm-sec-head .adm-count { color: var(--marfil); font-weight: 700; font-size: 13px; }
.adm-sec-head .btn-outline {
  border-color: rgba(255,255,255,.5); color: var(--marfil); background: transparent;
}
.adm-sec-head .btn-outline:hover { background: rgba(255,255,255,.14); border-color: var(--marfil); }
.adm-sec-head :where(a, button):focus-visible { outline-color: var(--marfil); }

/* ── Panel ejecutivo ───────────────────────────────────────────────────── */
.adm-exec { display: block; margin: 0 0 14px; }
.adm-exec-body { display: grid; grid-template-columns: minmax(0, 1fr) 190px; gap: 16px; align-items: stretch; }
.adm-exec-cards { display: grid; gap: 8px; align-content: start; }
.adm-exec-card { min-width: 0; display: grid; gap: 2px; }
.adm-exec-val { font-size: 16px; overflow-wrap: anywhere; }

.adm-chart { margin: 0; background: var(--surface); border: 1px solid var(--rule-hard); border-radius: 0; padding: 10px 12px; }
.adm-chart-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.adm-lbl { font-family: 'Cabin', sans-serif; font-size: 11px; color: var(--text); text-transform: uppercase; letter-spacing: 1.2px; font-weight: 700; }
.adm-chart-key { font-family: var(--font-mono); font-size: 11px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.adm-vbtn {
  margin-left: auto; border: 1px solid var(--rule-hard); background: var(--surface);
  color: var(--text); font-family: 'Cabin', sans-serif; font-size: 10px; font-weight: 700;
  letter-spacing: .9px; text-transform: uppercase;
  padding: 5px 11px; border-radius: 0; cursor: pointer;
  transition: background .15s var(--ease-out), color .15s var(--ease-out);
}
.adm-vbtn:hover { background: var(--rule-hard); color: var(--marfil); }
.adm-vbtn[aria-expanded="true"] { background: var(--guinda); border-color: var(--guinda); color: var(--marfil); }
.adm-serie { height: 96px; }
/* `display` de clase gana al `[hidden]` de la hoja del navegador: sin esto,
   ocultar la gráfica o el botón de plegado por atributo no surtía efecto. */
.adm-serie[hidden], .adm-exec[hidden], .btn[hidden], .adm-chip[hidden] { display: none; }
/* Cada columna se apoya en su propio pie carbón: la línea de base no puede ir
   en `.adm-serie` porque el rótulo vive DENTRO de la columna, y un día de
   valor 0 sin pie se lee como dato faltante en vez de como cero. */
.adm-bar-fill { background: var(--sq-4); box-shadow: 0 1px 0 var(--rule-hard); transition: background .15s var(--ease-out); }
.adm-bar:hover .adm-bar-fill { background: var(--guinda-d); }
.adm-bar-lbl.is-hidden { visibility: hidden; }
.adm-serie-vacia { padding: 30px 0; text-align: center; font-size: 12px; }
.adm-serie-tbl { max-height: 220px; overflow-y: auto; }

/* Chips: ahora son <button>, deben verse como los <span> hermanos */
button.adm-chip {
  font-family: 'Roboto', sans-serif; line-height: 1.35;
  display: inline-flex; align-items: center; gap: 5px;
}
.adm-chip-btn:hover { background: var(--bg); }
/* Sin `outline: none`: el chip recibe el foco justo al activarse (admin.js lo
   devuelve tras repintar), y anularlo dejaba a quien navega con teclado sin
   cursor exactamente en el momento de actuar. El filtro activo es una LOSA
   guinda dentro de la regleta blanca — un corte, no un tinte al 12 %. */
.adm-chip-btn.active { background: var(--guinda); color: var(--marfil); font-weight: 500; }
.adm-chip-btn.active b { color: var(--marfil); }
.adm-chip-btn.active:hover { background: var(--guinda-l); }

/* ── Aviso de bitácora recortada ───────────────────────────────────────── */
.adm-trunc {
  margin: 0 0 12px; padding: 10px 14px;
  border-radius: 0;
  border: 1px solid var(--rule-hard); border-left: 4px solid var(--guinda);
  background: var(--surface); color: var(--text); font-size: 12.5px; line-height: 1.5;
}
.adm-trunc b { color: var(--guinda-d); }

/* ── Bitácora ──────────────────────────────────────────────────────────── */
/* Salida de la bitácora: invisible hasta que el teclado llega a ella, y
   entonces losa guinda a ancho de columna — se ve antes de entrar al pozo. */
.adm-skip-ledger:focus,
.adm-skip-ledger:focus-visible {
  display: block; padding: 9px 14px; margin-bottom: 8px;
  background: var(--guinda-d); color: var(--marfil);
  font-size: 12px; font-weight: 700; letter-spacing: .3px; text-decoration: none;
  outline: 2px solid var(--marfil); outline-offset: -4px;
}
.adm-ledger { max-height: 620px; overflow: auto; border: 1px solid var(--rule-hard); border-radius: 0; }
.adm-ledger:focus-visible { outline: 2px solid var(--guinda); outline-offset: 2px; }
.adm-ledger .adm-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--rule-hard); border-bottom: 0;
}
.adm-fecha { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.adm-hora { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.adm-maplink { font-size: 11.5px; white-space: nowrap; }

/* ── Estados de carga y de error, por apartado ─────────────────────────── */
.adm-skel { display: grid; gap: 8px; padding: 6px 0; }
.adm-skel span, .adm-skel-row span {
  display: block; height: 14px;
  background: var(--bg2);
  animation: skeletonPulse 1.3s var(--ease-out) infinite;
}
.adm-skel span:nth-child(2) { width: 78%; }
.adm-skel span:nth-child(3) { width: 55%; }
.adm-skel-row td { padding: 10px; }

.adm-fail { padding: 16px; text-align: center; }
.adm-fail p { font-size: 12.5px; color: var(--guinda-d); margin-bottom: 10px; }

/* ── Reporte de calidad plegable ───────────────────────────────────────── */
.adm-snap { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 12px; }
.adm-snap summary { cursor: pointer; list-style: revert; }
.adm-snap summary .adm-sub { display: inline; margin: 0; }

/* ── Formulario de entregas ────────────────────────────────────────────── */
.adm-entform { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 14px; }
.adm-entfield { flex: 1 1 150px; min-width: 140px; }
.adm-entfield .form-label { font-size: 12px; letter-spacing: .6px; color: var(--text-2); }
.adm-entfield-wide { flex: 2 1 220px; }
.adm-req { color: var(--guinda); }
.adm-pill-ok, .adm-pill-off {
  display: inline-block; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 0;
}
/* Losa maciza para lo vigente, papel con filete para lo dado de baja: el
   estado se lee de un vistazo sin depender de un tinte del 12 %. */
.adm-pill-ok { color: var(--marfil); background: var(--verde-text); }
.adm-pill-off { color: var(--text-2); background: var(--surface); box-shadow: inset 0 0 0 1px var(--rule-hard); }
/* `opacity: .6` sobre --text-2 caía a 2.9:1 y volvía ilegible la fila dada de
   baja. El estado ya lo dice la insignia; el texto no se apaga. */
.adm-table tbody tr.is-baja td { color: var(--text-2); }

/* ── Responsivo ────────────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  .adm-grid { grid-template-columns: minmax(0, 1fr); }
  /* El riel se vuelve una fila de pestañas con scroll horizontal propio */
  .adm-rail { position: static; }
  .adm-rail-k { display: none; }
  /* En columna única el índice es una regleta de pestañas que corre en
     horizontal; sigue siendo una sola pieza cosida por cortes de 1 px. */
  .adm-rail-list {
    grid-auto-flow: column; grid-auto-columns: max-content;
    overflow-x: auto; gap: 1px; padding-bottom: 0;
  }
  .adm-rail-list a { border-left: 0; border-bottom: 2px solid transparent; }
  .adm-rail-list a.is-current { border-left: 0; border-bottom-color: var(--guinda); }
  .adm-exec-body { grid-template-columns: minmax(0, 1fr); }
  .adm-exec-cards { grid-auto-flow: column; grid-auto-columns: 1fr; }
}

@media (max-width: 760px) {
  /* La topbar de la auditoría llevaba el wordmark completo y empujaba la
     navegación fuera de la pantalla en 390 px. Se suelta en dos renglones,
     igual que en el centro de mando. */
  .adm-page .topbar { height: auto; padding: 7px 12px; gap: 9px; flex-wrap: wrap; }
  .adm-page .topbar .nav-links { margin-left: auto; }
  .adm-page .ck-title { display: none; }
  .adm-main { padding: 14px 12px 44px; }

  .adm-ctl { position: static; padding: 10px 12px; box-shadow: none; }
  .adm-ctl-k { min-width: 0; }
  .adm-f .form-control { min-width: 0; width: 100%; }
  .adm-f { flex: 1 1 130px; }
  .adm-presets { flex: 1 1 100%; justify-content: space-between; }
  .adm-preset { flex: 1; padding: 8px 6px; text-align: center; }
  .adm-exec-cards { grid-auto-flow: row; }
  .adm-ledger { max-height: none; }
  .adm-sec-note { display: none; }
  /* La regleta de conteos se parte en dos renglones; si los chips no se
     estiran, el carbón del fondo asoma como un bloque negro al final de la
     fila corta. Ocupan todo el ancho y el corte sigue siendo de 1 px. */
  .adm-chips { width: 100%; }
  .adm-chip { flex: 1 1 auto; justify-content: center; text-align: center; }
}

/* Táctil: los controles de la barra y los chips deben poderse tocar */
@media (pointer: coarse) {
  .adm-preset { min-height: 44px; }
  .adm-chip-btn { min-height: 44px; }
  .adm-vbtn { min-height: 44px; }
  .adm-rail-list a { min-height: 44px; }
  .adm-maplink { min-height: 44px; display: inline-flex; align-items: center; }
  .adm-preset, .adm-chip-btn, .adm-vbtn, .adm-rail-list a, .adm-maplink { touch-action: manipulation; }
}

@media (prefers-reduced-motion: reduce) {
  .adm-skel span, .adm-skel-row span { animation: none; }
}

/* ── Aviso de "servidor viejo" (health-check.js) ─────────────────────────────── */
.stale-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 16px;
  background: #942148;               /* guinda institucional */
  color: #ffffff;                    /* marfil */
  font-size: 13.5px;
  line-height: 1.35;
}
.stale-banner span { flex: 1; }
.stale-banner code {
  background: rgba(255, 255, 255, .16);
  padding: 1px 6px;
  border-radius: 0;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12.5px;
}
.stale-banner button {
  flex: none;
  background: transparent;
  border: 0;
  color: #ffffff;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  opacity: .85;
}
.stale-banner button:hover { opacity: 1; }


/* ════════════════════════════════════════════════════════════════════════════
   CAPA BASE UI/UX
   Reglas transversales de las 4 pantallas — ver docs/reglas-ui-ux.md.
   Va AL FINAL a propósito: con la misma especificidad debe ganar sobre las
   reglas de componente escritas arriba (p. ej. el 14px táctil de los campos).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Foco visible en TODO lo enfocable ────────────────────────────────
   Antes solo lo tenían los componentes que alguien recordó. Un enlace de la
   topbar, una opción de leyenda o un <summary> quedaban sin marca: el operador
   que navega con teclado perdía el cursor. Este es el piso; los componentes
   que ya definen su propio `--ring` lo siguen sobrescribiendo por orden. */
:where(a, button, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--guinda);
  outline-offset: 2px;
  border-radius: 0;
}
/* Sobre fondo guinda (topbar) el anillo guinda no se ve: se invierte a blanco. */
/* Sobre losa guinda el anillo guinda no se ve: se invierte a blanco. */
.topbar :where(a, button):focus-visible,
.on-guinda :where(a, button):focus-visible {
  outline-color: var(--marfil);
}
/* Campos: `.form-control:focus { outline: none }` (0,2,0) gana al piso de
   arriba, que va en `:where()` y no tiene especificidad. El campo se quedaba
   con el halo `--ring` como único indicador y ese halo da 1.72:1 sobre blanco
   — por debajo del 3:1 que WCAG 1.4.11 exige. El contorno sólido vuelve. */
.form-control:focus-visible,
.uba-selector select:focus-visible,
.monto-item input:focus-visible {
  outline: 2px solid var(--guinda);
  outline-offset: 1px;
}
/* Foco sobre losa guinda: el anillo guinda desaparece (1:1). Se invierte a
   blanco y, en las regletas cosidas, se dibuja HACIA ADENTRO para no montarse
   sobre la losa vecina. */
.adm-preset.is-on:focus-visible,
.adm-chip-btn.active:focus-visible,
.adm-rail-list a.is-current:focus-visible {
  outline: 2px solid var(--marfil);
  outline-offset: -3px;
}
.adm-vbtn[aria-expanded="true"]:focus-visible,
.ck-vbtn[aria-pressed="true"]:focus-visible {
  outline-color: var(--marfil);
  outline-offset: -3px;
}
/* El foco por ratón no debe pintar anillos, pero :focus nunca queda desnudo. */
:focus:not(:focus-visible) { outline: none; }

/* ── 2 · Salto al contenido ───────────────────────────────────────────────
   Primer tabulador de cada página: brinca la topbar y el riel de control. */
.skip-link {
  position: absolute;
  top: 0; left: 0;
  z-index: 10000;
  transform: translateY(-120%);
  padding: 10px 18px;
  background: var(--guinda-d);
  color: var(--marfil);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .3px;
  text-decoration: none;
  border-radius: 0;
  transition: transform .18s var(--ease-out);
}
.skip-link:focus { transform: translateY(0); outline: 2px solid var(--marfil); outline-offset: -4px; }

/* Variante de .sr-only que reaparece al recibir foco (skip links, atajos) */
.sr-only-focusable:focus,
.sr-only-focusable:focus-visible {
  position: static; width: auto; height: auto; margin: 0;
  overflow: visible; clip: auto; clip-path: none; white-space: normal;
}

/* ── 3 · Sin retardo de 300 ms al tocar ───────────────────────────────────
   Safari/Chrome móvil esperan por un posible doble-toque de zoom. En una
   captura de campo ese cuarto de segundo por toque se siente como lag. */
:where(a, button, label, select, summary, input[type="checkbox"], input[type="radio"],
       .btn, .editor-btn, .ck-vbtn, .dock-btn, .pend-chip, .capa-btn, .panel-header) {
  touch-action: manipulation;
}

/* ── 4 · Deshabilitado: mismo lenguaje en todas partes ────────────────────
   Opacidad .45 (rango Material .38–.5) + cursor bloqueado + sin hover. */
:where(button, .btn, .editor-btn, .ck-vbtn, input, select, textarea):disabled,
:where(button, .btn, .editor-btn)[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
  box-shadow: none;
}
:where(.btn, .editor-btn, .ck-vbtn):disabled:hover { transform: none; filter: none; }

/* Solo-lectura ≠ deshabilitado: sigue siendo legible y seleccionable. */
:where(input, textarea)[readonly] {
  background: var(--bg2);
  cursor: default;
  opacity: 1;
}

/* ── 5 · Anclas bajo la topbar fija ───────────────────────────────────────
   Sin esto, "Conocer más" deja el título de la sección debajo de la barra. */
:target { scroll-margin-top: 84px; }
.landing [id] { scroll-margin-top: 64px; }

/* ── 6 · "Salir" como botón real ──────────────────────────────────────────
   Era <a href="#">: para un lector de pantalla se anunciaba como enlace a la
   misma página. Ahora es <button> y hereda el aspecto de la barra. */
.topbar .nav-links button {
  font-family: 'Roboto', sans-serif;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: #f0cad8;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .6px;
  padding: 6px 12px;
  border-radius: 0;
  white-space: nowrap;
  text-transform: uppercase;
  transition: background .15s, color .15s;
}
.topbar .nav-links button:hover { background: rgba(255,255,255,.14); color: var(--marfil); }
/* Acción de salida: separada del resto de la navegación (no es un destino más). */
.topbar .nav-links .nav-exit { margin-left: 8px; box-shadow: inset 0 0 0 1px rgba(255,255,255,.28); }

/* ── 7 · Movimiento reducido: cerrar los huecos que deja la duración ──────
   Anular la duración no basta: los `.reveal` arrancan con opacity 0 y un
   transform, así que sin transición se quedaban invisibles o desplazados. */
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal--left, .reveal--right, .reveal--scale {
    opacity: 1 !important;
    transform: none !important;
  }
  .btn:hover, .editor-btn:hover, .ck-card:hover { transform: none !important; }
}

/* ── 8 · Tabla ancha: el scroll va DENTRO, nunca en la página ─────────────
   Regla `horizontal-scroll`: en 390 px una tabla de auditoría empujaba el
   body y descuadraba toda la pantalla. */
.adm-tablewrap, .ck-tbl, .table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ── 9 · Ajustes táctiles que faltaban ───────────────────────────────────── */
@media (pointer: coarse) {
  /* 16px es el umbral por debajo del cual iOS Safari hace zoom al enfocar un
     campo — y al salir deja el mapa descuadrado. No es estética: es la única
     forma de que enfocar un input no mueva el encuadre. */
  .form-control, .filter-select, .search-input,
  input[type="text"], input[type="number"], input[type="date"],
  input[type="password"], input[type="tel"], input[type="email"], select, textarea {
    font-size: 16px;
  }

  /* Chips y píldoras accionables del riel y del centro de mando */
  .pend-chip, .scope-clear, .census-more, .link-btn { min-height: 44px; }

  /* Pasos ± de los cortes de división: el dedo no acierta un cuadro de 24px */
  .split-row .split-ctrl button { min-width: 44px; min-height: 44px; font-size: 18px; }
  .split-row .split-ctrl input[type=number] { min-height: 44px; font-size: 16px; }

  /* Cerrar el panel lateral y el botón de refrescar pendientes */
  .sidebar-close, .pend-refresh { min-width: 44px; min-height: 44px; }

  /* Selectores del centro de mando: barra de ámbito y nivel de la comparativa */
  .dash-fsel, .ck-nivelsel { min-height: 44px; }
}

/* ── 10 · Gráficas: estados vacío y de error ─────────────────────────────
   Un canvas sin datos se veía como un marco de ejes en blanco — indistinguible
   de "todavía cargando" o de "se rompió". */
.ck-canvas-wrap .ck-empty, .chart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 96px;
  padding: 16px;
  text-align: center;
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.5;
}
.ck-canvas-wrap .ck-empty strong, .chart-empty strong {
  display: block;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
}

/* ════════════════════════════════════════════════════════════════════
   FORMULARIO DE PERSONA (alta de beneficiario + editor en línea)
   Se captura de pie, con el teléfono en una mano: los controles son más
   altos que los del resto del panel (objetivo táctil) y en móvil el texto
   sube a 16px, que es lo que evita el zoom automático de iOS al enfocar.
   ════════════════════════════════════════════════════════════════════ */
.persona-form .form-group { margin-bottom: 12px; }
.persona-form .form-label {
  font-size: 11px;
  color: var(--text-2);          /* 7:1 sobre blanco; --text-dim se leía apagado */
  letter-spacing: .8px;
  margin-bottom: 5px;
}
.persona-form .req { color: var(--guinda); font-weight: 700; }
.persona-form .form-control {
  min-height: 42px;
  font-size: 14px;
}
.persona-form textarea.form-control { min-height: 60px; }
.persona-form .seg-opt span {
  min-height: 42px;
  display: flex; align-items: center; justify-content: center;
  padding: 8px 6px;
  line-height: 1.2;
}
/* Nota de obligatorios: arriba, junto al título — no en la barra de acción,
   donde quedaba flotando encima del último campo. */
.form-req-note {
  font-size: 11.5px;
  color: var(--text-2);
  margin: -6px 0 12px;
}
.form-req-note .req { color: var(--guinda); font-weight: 700; }

/* Filete de sección con aire arriba: separa bloques sin encerrarlos en cajas */
.persona-form .form-divider { margin: 18px 0 12px; }
.persona-form > .form-divider:first-child { margin-top: 2px; }

/* Fila que se colapsa sola: si uno de los dos campos está oculto (fecha de
   carta), el que queda ocupa el ancho completo en vez de dejar un hueco. */
.form-row-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
}

/* Error inline: pegado al campo que falla, nunca en un resumen arriba */
.field-error {
  color: #a32b39;                /* 6.1:1 sobre blanco */
  font-size: 11.5px;
  line-height: 1.35;
  margin-top: 5px;
  font-weight: 500;
}
.field-error::before { content: "⚠ "; }
.persona-form .form-control[aria-invalid="true"] {
  border-color: #a32b39;
  background: #fdf6f6;
}
.persona-form .form-control[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(163,43,57,.22);
}

/* Barra de acción pegada al fondo del panel: el formulario es largo y el botón
   de registrar quedaba fuera de pantalla al llegar a los últimos campos. Fondo
   OPACO: con degradado, el texto de los campos de abajo se leía a través. */
.ben-form-actions {
  position: sticky;
  bottom: 0;
  z-index: 3;
  margin-top: 14px;
  padding: 12px 0;
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.ben-form-actions .btn { width: 100%; min-height: 46px; font-size: 14px; }
.ben-form-actions .btn[disabled] { opacity: .65; cursor: progress; }

/* El control segmentado del formulario compite con el `.seg` del selector de
   nivel del centro de mando, declarado DESPUÉS en esta hoja (inline-flex, con
   padding y fondo propios). Aquí se restituye el de formulario: ancho completo,
   que además agranda el objetivo táctil de Mujer/Hombre e Inscrito/Carta. */
.persona-form .seg {
  display: flex;
  width: 100%;
  padding: 0;
  gap: 0;
  background: var(--bg-input);
}

/* Editor en línea: mismo molde, un punto más compacto dentro de la ficha */
.ben-edit-form.persona-form .form-group { margin-bottom: 10px; }
.ben-edit-form.persona-form .form-divider { margin: 14px 0 10px; }

@media (max-width: 820px), (pointer: coarse) {
  .persona-form .form-control {
    font-size: 16px;             /* < 16px hace que iOS haga zoom al enfocar */
    min-height: 46px;
  }
  .persona-form .seg-opt span { min-height: 46px; font-size: 13px; }
  .ben-form-actions .btn { min-height: 50px; }
}
