/* ============================================================
   SECURITY FORECAST — Hoja de estilos unificada
   Identidad: Centro de Operaciones de Seguridad — panel oscuro,
   estética de tablero ArcGIS Operations Dashboard
   ============================================================ */

/* Oculta visualmente sin ocultar de lectores de pantalla: para el <h1> de
   página en dashboard.html y explorador.html, que hoy no tienen ningún
   encabezado de nivel 1 (el nombre de la página solo vive en <title> y en
   el estado "active" del nav), sin alterar el diseño visual existente. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

:root {
    --void: #0B121C;
    --surface: #111A28;
    --surface-2: #16233A;
    --surface-3: #1C2C42;
    --grid-line: #22314A;
    --grid-line-strong: #33496C;
    --ink: #EAF1FB;
    /* Mismo matiz azul-gris que antes (#6E7F9E), aclarado para cumplir
       WCAG AA (4.5:1) contra el fondo más claro donde aparece (--surface-3).
       El original daba 3.49:1 en ese caso; este valor da ~4.76:1, y se
       mantiene claramente distinto de --ink-soft. */
    --ink-muted: #8497B6;
    --ink-soft: #A9B8D1;

    --signal-cyan: #22B8E0;
    --signal-amber: #FFB020;
    --signal-orange: #F97316;
    --signal-red: #EF4B5D;
    --signal-blue: #4C8DFF;
    --signal-violet: #B57EDC;
    --signal-green: #34D399;
    --signal-teal: #2DD4BF;
    --signal-rose: #F2789F;
    --signal-olive: #8FA31E;
    --info: #2E6FE0;

    --font-display: 'Noto Sans', system-ui, sans-serif;
    --font-body: 'Noto Sans', system-ui, sans-serif;
    --font-mono: 'JetBrains Mono', monospace;

    --radius-xs: 4px;
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-pill: 999px;

    --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.18);
    --shadow-md: 0 8px 20px rgba(0, 0, 0, 0.28);
    --shadow-focus: 0 0 0 3px rgba(34, 184, 224, 0.25);
    --shadow-glow-brand: 0 0 16px rgba(34, 184, 224, 0.08);

    /* Escala de capas (z-index), de menor a mayor prioridad visual —
       usar siempre estos tokens, nunca un número suelto:
       1. --z-map            mapa de Leaflet (capa base; sus popups/tooltips
                              internos quedan contenidos dentro de esta capa
                              porque #map tiene su propio stacking context)
       2. --z-panel          controles flotantes principales sobre el mapa:
                              dock inferior y barra de búsqueda (nunca se
                              solapan entre sí — cuando el dock se expande,
                              la búsqueda se oculta)
       3. --z-side-panel     panel lateral persistente (antecedentes/noticias)
                              — debe verse por encima del dock/búsqueda
       4. --z-overlay        overlays temporales de vida corta: sugerencias
                              de autocompletar, tooltips propios, futuros
                              menús/popovers
       5. --z-header         cabecera — nunca debe quedar tapada por nada */
    --z-map: 0;
    --z-panel: 500;
    --z-side-panel: 600;
    --z-overlay: 700;
    --z-header: 1000;

    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --dur-fast: 150ms;
    --dur-base: 250ms;
    --dur-slow: 450ms;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: var(--font-body);
}

body {
    background: var(--void);
    color: var(--ink);
}

a { color: inherit; }

/* ==========================================================================
   SISTEMA DE MOVIMIENTO — keyframes compartidas
   ========================================================================== */
@keyframes fade-rise-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes scale-pop-in {
    from { opacity: 0; transform: scale(0.5); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes soft-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.45; }
}

::selection {
    background: rgba(34, 184, 224, 0.25);
    color: var(--ink);
}

:focus-visible {
    outline: 2px solid var(--signal-cyan);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ==========================================================================
   PÁGINA DE BIENVENIDA
   ========================================================================== */
/* El hero medía 590px fijos (alto de su contenido), así que el corte de
   pantalla solo caía sobre el límite entre secciones en un viewport de ~662px
   de alto — justo el del zoom 110%. En pantallas más altas asomaba una franja
   de la sección siguiente con las tarjetas cortadas, y en más bajas el hero no
   entraba.
   Se descartó resolverlo con flex-grow sobre el hero: flex-grow reparte
   espacio *sobrante*, y esta página no tiene (el body mide ~1345px porque
   debajo del hero vienen otras tres secciones), así que el hero nunca crecía.
   "proximity" y no "mandatory": mandatory prohíbe posiciones intermedias de
   scroll, de modo que en ventanas donde el hero no cabe el usuario quedaba
   atrapado sin poder ver el resto. */
.landing-body { min-height: 100vh; display: flex; flex-direction: column; scroll-snap-type: y proximity; }
/* 72px es la altura real del nav. Es un valor acoplado a .landing-nav: si
   cambia su padding, hay que actualizarlo acá. Se usa svh (no vh) para que las
   barras de interfaz del navegador móvil no descuadren el cálculo. */
.landing-hero-wrap { min-height: calc(100svh - 72px); }
.landing-hero-wrap, .landing-features { scroll-snap-align: start; }

.landing-nav {
    flex-shrink: 0;
    position: relative;
    z-index: var(--z-header);
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
    padding: 1.1rem 2.5rem; border-bottom: 1px solid var(--grid-line);
    background: var(--void);
}
.landing-nav-clock {
    justify-self: end;
    font-family: var(--font-mono); font-size: 0.85rem; color: var(--ink-soft);
    font-variant-numeric: tabular-nums; letter-spacing: 0.03em;
}
.landing-nav-cta { justify-self: end; }
.landing-logo { display: flex; align-items: center; gap: 0.6rem; justify-self: start; }
.landing-logo-badge {
    width: 34px; height: 34px; border-radius: 8px; background: var(--info);
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 0.85rem; color: #fff; font-family: var(--font-display);
}
.landing-logo-text { font-weight: 600; font-size: 0.95rem; letter-spacing: 0.02em; color: var(--ink); }
.landing-logo-text span { color: var(--ink-muted); font-weight: 400; }
.landing-nav-links { display: flex; gap: 2rem; font-size: 0.85rem; color: var(--ink-soft); }
.landing-nav-links a { display: inline-flex; align-items: center; gap: 0.4rem; color: inherit; text-decoration: none; transition: color var(--dur-base) var(--ease-out); }
.landing-nav-links a svg { width: 15px; height: 15px; flex-shrink: 0; }
.landing-nav-links a:hover { color: var(--ink); }
.landing-nav-links a.active { color: var(--ink); font-weight: 600; }
.landing-nav-cta {
    background: var(--info); color: #fff; border: none; text-decoration: none;
    padding: 0.55rem 1.2rem; border-radius: 7px; font-size: 0.82rem; font-weight: 600;
    display: inline-flex; align-items: center;
    transition: filter var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.landing-nav-cta:hover { filter: brightness(1.12); transform: translateY(-1px); }

.landing-hero-wrap {
    background: var(--void);
    /* Sin min-height: el wrapper toma la altura real de su contenido. Un
       min-height en vh (probado antes) deja un sobrante vacío debajo del
       contenido cuando este es más corto que ese mínimo — esa era la causa
       real del espacio excesivo antes de la siguiente sección. */
    display: flex;
    align-items: center;
    position: relative;
}
.landing-hero {
    /* align-items:end (no center): la columna de texto (479px) y la del
       mapa (393px) tienen alturas distintas. Centradas, el mapa quedaba con
       espacio arriba Y abajo dentro de la fila, y ese sobrante debajo se
       sumaba al padding real — con "end" ambas columnas comparten el mismo
       borde inferior, así que el espacio hacia la siguiente sección es el
       mismo debajo del texto y debajo del mapa, sin depender del viewport. */
    display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 1.8rem; align-items: end;
    max-width: 1180px; margin: 0 auto;
    /* padding-bottom en 4rem: tamaño original, restaurado a pedido. */
    padding: 3.5rem 2.5rem 4rem;
    width: 100%;
}
.landing-badge {
    display: inline-block; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--signal-cyan); background: rgba(34,184,224,0.1); border: 1px solid rgba(34,184,224,0.3);
    padding: 0.3rem 0.75rem; border-radius: 999px; margin-bottom: 1.2rem; font-family: var(--font-mono);
}
.landing-hero h1 {
    font-family: var(--font-display); font-size: 2.5rem; line-height: 1.16; font-weight: 700;
    letter-spacing: -0.01em; margin: 0 0 1rem; color: var(--ink);
}
.landing-hero p.landing-lede { color: var(--ink-soft); font-size: 1.02rem; line-height: 1.6; max-width: 46ch; margin: 0 0 1.6rem; }
.landing-cta-row { display: flex; gap: 0.8rem; margin-bottom: 1.8rem; flex-wrap: wrap; }
.landing-btn-primary {
    background: var(--ink); color: var(--void); border: none; text-decoration: none;
    font-weight: 700; font-size: 0.92rem; padding: 0.85rem 1.6rem; border-radius: 8px;
    display: inline-flex; align-items: center; gap: 0.5rem;
    transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.landing-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 4px 14px rgba(0,0,0,0.35); }
.landing-btn-primary svg { transition: transform var(--dur-base) var(--ease-out); }
.landing-btn-primary:hover svg { transform: translateX(3px); }
.landing-btn-secondary {
    background: transparent; color: var(--ink); border: 1px solid var(--grid-line-strong); text-decoration: none;
    font-weight: 600; font-size: 0.92rem; padding: 0.85rem 1.6rem; border-radius: 8px;
    display: inline-flex; align-items: center;
    transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.landing-btn-secondary:hover { border-color: var(--signal-cyan); transform: translateY(-2px); }
.landing-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.2rem 1.8rem;
}
.landing-stat { display: flex; align-items: center; gap: 0.6rem; }
.landing-stat svg { flex-shrink: 0; color: var(--signal-cyan); }
.landing-stat .stat-num { font-size: 1.15rem; font-weight: 700; color: var(--ink); line-height: 1.1; font-family: var(--font-display); }
.landing-stat .stat-label { font-size: 0.72rem; color: var(--ink-muted); line-height: 1.2; }

.landing-map { border-radius: 10px; overflow: hidden; }
.landing-map img { width: 100%; height: auto; display: block; }

.hero-intro {
    position: absolute; inset: 0; z-index: 2; display: grid; place-items: center;
    padding: 2rem 2.5rem; background: var(--void);
    opacity: 1; visibility: visible;
    transition: opacity 300ms var(--ease-out), visibility 300ms var(--ease-out);
}
.hero-intro-frame {
    position: relative; width: min(100%, 1180px); aspect-ratio: 16 / 9;
    overflow: hidden; border: 1px solid var(--grid-line-strong); border-radius: var(--radius-lg);
    background: #000; box-shadow: var(--shadow-md), var(--shadow-glow-brand);
}
.hero-intro-video { display: block; width: 100%; height: 100%; object-fit: contain; background: #000; }
.hero-intro-close {
    position: absolute; top: 14px; right: 14px; z-index: 3;
    width: 44px; height: 44px; display: grid; place-items: center;
    padding: 0; border: 1px solid rgba(255,255,255,0.45); border-radius: 50%;
    background: rgba(11,18,28,0.88); color: #fff; cursor: pointer;
    box-shadow: 0 4px 16px rgba(0,0,0,0.45);
    transition: background-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.hero-intro-close:hover { background: var(--info); transform: scale(1.05); }
.hero-intro-close:focus-visible { outline: 3px solid var(--signal-cyan); outline-offset: 3px; }
.hero-intro-close svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.landing-hero { transition: opacity 300ms var(--ease-out); }
.intro-active .landing-hero { opacity: 0; visibility: hidden; }
.intro-dismissed .hero-intro { opacity: 0; visibility: hidden; pointer-events: none; }
.intro-dismissed .landing-hero { opacity: 1; visibility: visible; }

.landing-features, .landing-data {
    background: var(--surface); color: var(--ink);
}
.landing-features-inner {
    /* padding-top en 2rem: tamaño original, restaurado a pedido. */
    max-width: 1180px; margin: 0 auto; padding: 2rem 2.5rem 2rem;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.8rem;
}
.landing-feature-card {
    background: var(--surface-2); border: 1px solid var(--grid-line); border-radius: var(--radius-lg);
    padding: 1.8rem 1.6rem;
    box-shadow: var(--shadow-md);
    transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.landing-feature-card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(0,0,0,0.35); }
.landing-feature-icon {
    width: 42px; height: 42px; border-radius: 9px; display: flex; align-items: center; justify-content: center;
    margin-bottom: 1.1rem; background: rgba(46,111,224,0.12);
}
.landing-feature-card h3 { font-family: var(--font-display); font-size: 1.02rem; margin: 0 0 0.5rem; color: var(--ink); }
.landing-feature-card p { font-size: 0.87rem; color: var(--ink-soft); line-height: 1.55; margin: 0 0 0.7rem; }
.landing-feature-card a { font-size: 0.82rem; color: var(--info); text-decoration: none; font-weight: 600; }
.landing-feature-card a:hover { text-decoration: underline; }

.landing-data-eyebrow {
    max-width: 1180px; margin: 0 auto; padding: 0 2.5rem;
    font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--ink-muted);
}
.landing-data-grid {
    max-width: 1180px; margin: 0 auto; padding: 1rem 2.5rem 3.5rem;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.6rem;
}
.landing-data-card {
    background: var(--surface-2); border: 1px solid var(--grid-line); border-radius: var(--radius-lg); overflow: hidden;
    box-shadow: var(--shadow-md);
    transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.landing-data-card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(0,0,0,0.35); }
.landing-data-body time a { color: inherit; text-decoration: underline; }
.landing-data-thumb { height: 70px; background: linear-gradient(135deg, rgba(46,111,224,0.16), var(--surface-3)); position: relative; }
.landing-data-thumb .tag {
    position: absolute; top: 10px; left: 10px; font-size: 0.68rem; padding: 0.2rem 0.55rem; border-radius: 999px;
    background: var(--surface-3); color: var(--info); font-weight: 600;
}
.landing-data-body { padding: 1rem 1.1rem 1.2rem; }
.landing-data-body h4 { margin: 0 0 0.35rem; font-size: 0.9rem; color: var(--ink); font-family: var(--font-display); }
.landing-data-body p { margin: 0; font-size: 0.8rem; color: var(--ink-soft); line-height: 1.5; }
.landing-data-body time { display: block; margin-top: 0.6rem; font-size: 0.72rem; color: var(--ink-muted); }

.landing-footer {
    background: var(--void); padding: 2.2rem 2.5rem;
    display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;
    font-size: 0.78rem; color: var(--ink-muted);
}
.landing-footer .foot-links { display: flex; gap: 1.4rem; }

@media (max-width: 880px) {
    .landing-nav-links { display: none; }
    .landing-hero { grid-template-columns: 1fr; }
    .landing-features-inner, .landing-data-grid { grid-template-columns: 1fr; padding-left: 1.4rem; padding-right: 1.4rem; }
    .landing-hero { padding-left: 1.4rem; padding-right: 1.4rem; }
}

@media (max-width: 480px) {
    .hero-intro { padding: 1.2rem 1rem; }
    .hero-intro-frame { border-radius: var(--radius-md); }
    .hero-intro-close { top: 10px; right: 10px; width: 46px; height: 46px; }
    .landing-stats {
        grid-template-columns: 1fr;
        gap: 1rem;
    }
}

.badge-live i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--signal-cyan);
    box-shadow: 0 0 8px var(--signal-cyan);
    animation: pulse-dot 2.4s ease-in-out infinite;
    display: inline-block;
}

@keyframes pulse-dot {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
    .badge-live i { animation: none; }

    .hero-intro, .landing-hero { transition: none; }

    .view-panel.active, .matrix-cell {
        animation: none;
        opacity: 1;
        transform: none;
    }
    .btn-update-layers.is-loading {
        animation: none;
    }
    .landing-nav-cta, .landing-btn-primary, .landing-btn-secondary,
    .landing-feature-card, .landing-data-card, .landing-btn-primary svg,
    .axis-switch, .axis-switch-knob {
        transition: none;
    }
}

/* ==========================================================================
   DASHBOARD — panel de operaciones (.ops-shell)
   ========================================================================== */
.ops-shell {
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background:
        radial-gradient(ellipse 60% 50% at 80% 0%, rgba(34, 184, 224, 0.05), transparent 60%),
        var(--void);
}

.dashboard-container { display: flex; flex: 1; min-height: 0; }

/* ---------- Tira de indicadores (KPIs) ---------- */
.kpi-strip {
    flex-shrink: 0;
    display: grid;
    /* La 4ta columna (nivel de riesgo provincial) es la información más
       accionable de la franja para un ciudadano, así que ocupa más ancho
       que el resto en vez de repartirse en 5 partes iguales. */
    grid-template-columns: 1fr 1fr 1fr 1.6fr 1fr;
    gap: 1px;
    background: var(--grid-line);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.kpi-tile {
    background: var(--surface);
    padding: 0.7rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    border-left: 2px solid var(--signal-cyan);
}
.kpi-tile-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.kpi-icon { width: 16px; height: 16px; flex-shrink: 0; margin-top: 0.2rem; color: var(--ink-muted); }
.kpi-value {
    font-family: var(--font-mono);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--ink);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.kpi-label {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-muted);
}
.kpi-sublabel {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    color: var(--ink-muted);
    opacity: 0.75;
}
.kpi-sublabel:empty { display: none; }
/* Tarjeta de riesgo provincial: además del color ya existente en el borde,
   un tinte de fondo muy sutil del mismo color y un valor más grande le dan
   más peso visual que al resto de la franja, sin agregar un token nuevo. */
.kpi-tile--riesgo-muy_alto { border-left-color: var(--signal-red); background: rgba(239, 75, 93, 0.08); }
.kpi-tile--riesgo-muy_alto .kpi-value { color: var(--signal-red); font-size: 1.85rem; }
.kpi-tile--riesgo-muy_alto .kpi-icon { color: var(--signal-red); }
.kpi-tile--riesgo-alto { border-left-color: var(--signal-orange); background: rgba(249, 115, 22, 0.08); }
.kpi-tile--riesgo-alto .kpi-value { color: var(--signal-orange); font-size: 1.85rem; }
.kpi-tile--riesgo-alto .kpi-icon { color: var(--signal-orange); }
.kpi-tile--riesgo-medio { border-left-color: var(--signal-amber); background: rgba(255, 176, 32, 0.08); }
.kpi-tile--riesgo-medio .kpi-value { color: var(--signal-amber); font-size: 1.85rem; }
.kpi-tile--riesgo-medio .kpi-icon { color: var(--signal-amber); }
.kpi-tile--riesgo-bajo { border-left-color: var(--signal-green); background: rgba(52, 211, 153, 0.08); }
.kpi-tile--riesgo-bajo .kpi-value { color: var(--signal-green); font-size: 1.85rem; }
.kpi-tile--riesgo-bajo .kpi-icon { color: var(--signal-green); }

/* ---------- Sidebar / panel de control ---------- */
.sidebar {
    width: 320px;
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--grid-line);
    padding: 1.6rem 1.5rem 2rem;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 4px; }

.logo-area { margin-bottom: 1.6rem; padding-bottom: 1.3rem; border-bottom: 1px solid var(--grid-line); }
.logo-link {
    display: block; font-family: var(--font-display); font-size: 1.25rem; font-weight: 700;
    color: var(--ink); text-decoration: none; letter-spacing: -0.01em;
}
.logo-link span { color: var(--signal-cyan); }
.logo-area .hud-coord {
    display: block; margin-top: 0.4rem; font-family: var(--font-mono); font-size: 0.66rem;
    letter-spacing: 0.06em; color: var(--ink-muted);
}

.sidebar-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 1.1rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--grid-line);
}
.sidebar-header h2 {
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.35;
    color: var(--ink);
    margin: 0;
}
.sidebar-header-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 0.1rem;
    color: var(--signal-cyan);
}

.canton-select-row { display: flex; align-items: center; gap: 0.6rem; }
.canton-select-row select { flex: 1; }
.canton-shape-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    color: var(--ink-muted);
    opacity: 0.6;
}

.filters-section h3 {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin: 1.6rem 0 0.85rem;
    letter-spacing: 0.1em;
}

.filter-group { margin-bottom: 0.4rem; }
.filter-group label {
    display: block; font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-muted); margin-bottom: 0.45rem;
}
.filter-group select {
    width: 100%;
    padding: 0.55rem 0.7rem;
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    color: var(--ink);
    border-radius: var(--radius-sm);
    font-size: 0.78rem;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2322B8E0' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
}
.filter-group select:focus { border-color: var(--signal-cyan); outline: none; }
.filter-group input[type="text"],
.filter-group input[type="number"] {
    width: 100%;
    padding: 0.55rem 0.7rem;
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    color: var(--ink);
    border-radius: var(--radius-sm);
    font-size: 0.78rem;
    font-family: var(--font-body);
}
.filter-group input[type="text"]:focus,
.filter-group input[type="number"]:focus { border-color: var(--signal-cyan); outline: none; }
.filter-group input::placeholder { color: var(--ink-muted); }

.filtros-avanzados { margin-top: 0.6rem; }
.filtros-avanzados-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0;
    background: transparent;
    border: none;
    cursor: pointer;
}
.filtros-avanzados-toggle h3 {
    font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--ink-muted); margin: 0;
}
.filtros-avanzados-toggle svg { width: 14px; height: 14px; color: var(--ink-muted); transition: transform 0.2s ease; }
.filtros-avanzados-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.filtros-avanzados-body {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    visibility: hidden;
    transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease-out, visibility 0.3s, margin-top 0.3s;
    margin-top: 0;
}
.filtros-avanzados-toggle[aria-expanded="true"] + .filtros-avanzados-body {
    max-height: 320px;
    opacity: 1;
    visibility: visible;
    margin-top: 0.6rem;
}
.filter-group-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
}
.filter-group-split label { margin-bottom: 0.3rem; }

/* ---------- Selección de ejes (checkboxes personalizados) ---------- */
.axis-selection { margin-top: 0.4rem; }

.axis-selection-grid {
    display: grid;
    /* minmax(0,1fr) y no 1fr: con "1fr" el ancho mínimo lo fija el contenido
       (el nombre de eje más largo), así que las dos columnas terminaban
       desiguales. Con 0 de mínimo, se reparten exactamente por igual. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.3rem;
    margin-bottom: 0.3rem;
}

.check-container {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem;
    border-radius: var(--radius-sm);
    font-size: 0.72rem;
    cursor: pointer;
    transition: background 0.15s ease;
}
.check-container:hover { background: var(--surface-2); }

.check-container input { position: absolute; opacity: 0; width: 0; height: 0; }

/* Interruptor tipo switch: la pastilla toma el color del eje cuando está
   activo y el círculo (con el ícono del eje) se desliza a la derecha; al
   desactivarlo, la pastilla vuelve a un gris neutro y el círculo se va a la
   izquierda. El color no cambia por eje, solo se enciende o se apaga. */
.axis-switch {
    position: relative;
    flex-shrink: 0;
    width: 40px;
    height: 22px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    border: 1px solid var(--grid-line-strong);
    transition: background 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}
.axis-switch-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Oscurecido sobre el color de la pastilla: un solo valor sirve para los
       7 ejes, sin necesidad de declarar un tono extra por color. */
    background: rgba(0, 0, 0, 0.32);
    color: #fff;
    transition: transform 0.2s var(--ease-out), background 0.2s var(--ease-out);
}
.axis-switch-knob svg { width: 10px; height: 10px; }
.check-container input:checked + .axis-switch .axis-switch-knob { transform: translateX(18px); }
.check-container input:not(:checked) + .axis-switch .axis-switch-knob { background: var(--grid-line-strong); }
.check-container input:focus-visible + .axis-switch { outline: 2px solid var(--signal-cyan); outline-offset: 2px; }

.check-container input:checked + .axis-switch--red    { background: var(--signal-red);    border-color: var(--signal-red); }
.check-container input:checked + .axis-switch--blue   { background: var(--signal-blue);   border-color: var(--signal-blue); }
.check-container input:checked + .axis-switch--orange { background: var(--signal-amber);  border-color: var(--signal-amber); }
.check-container input:checked + .axis-switch--purple { background: var(--signal-violet); border-color: var(--signal-violet); }
.check-container input:checked + .axis-switch--teal   { background: var(--signal-teal);   border-color: var(--signal-teal); }
.check-container input:checked + .axis-switch--rose   { background: var(--signal-rose);   border-color: var(--signal-rose); }
.check-container input:checked + .axis-switch--olive  { background: var(--signal-olive);  border-color: var(--signal-olive); }

.axis-label { color: var(--ink-soft); }
.axis-group-label {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.58rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin: 0.6rem 0 0.3rem 0.5rem;
}

/* ---------- Botones ---------- */
.btn-update-layers {
    width: 100%;
    padding: 0.65rem;
    background: transparent;
    border: 1px solid var(--signal-cyan);
    color: var(--signal-cyan);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.78rem;
    margin-top: 1.1rem;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
.btn-update-layers:hover { background: var(--signal-cyan); color: var(--void); box-shadow: 0 0 12px rgba(34, 184, 224, 0.35); }
.btn-update-layers.is-loading { pointer-events: none; animation: button-loading-pulse 1.1s ease-in-out infinite; }
@keyframes button-loading-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 0.85; } }

/* ---------- Enrutamiento ---------- */
.location-input-wrapper { position: relative; }

.input-route-group input {
    width: 100%;
    padding: 0.7rem 0.85rem;
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    color: var(--ink);
    border-radius: var(--radius-sm);
    margin-bottom: 0.55rem;
    outline: none;
    font-size: 0.83rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input-route-group input::placeholder { color: var(--ink-muted); }

.departure-time-label {
    display: block;
    font-size: 0.74rem;
    color: var(--ink-muted);
    margin-bottom: 0.4rem;
}
.departure-time-group { display: flex; gap: 0.5rem; }
.departure-time-group input { min-width: 0; flex: 1; }

.modo-transporte { display: flex; gap: 0.5rem; margin-bottom: 0.9rem; }
.modo-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.5rem 0.3rem;
    border: 1px solid var(--grid-line-strong);
    border-radius: 6px;
    background: var(--surface-2);
    color: var(--ink-muted);
    font-family: var(--font-body);
    font-size: 0.72rem;
    cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.modo-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.modo-btn:hover { color: var(--ink); border-color: var(--signal-cyan); }
.modo-btn.is-activo {
    color: var(--signal-cyan);
    border-color: var(--signal-cyan);
    background: rgba(34, 184, 224, 0.1);
}

/* ---------- Evaluación temporal de la ruta (panel único, nunca 4 tarjetas) ---------- */
.franja-comparacion { margin: 0.5rem 0 0.65rem; }
.franja-titulo {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-muted);
    margin: 0 0 0.5rem;
}
.franja-equivalente {
    padding: 0.6rem 0.75rem;
    background: var(--surface-3);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-sm);
}
.franja-equivalente p { margin: 0 0 0.4rem; font-size: 0.78rem; line-height: 1.45; color: var(--ink-soft); }
.franja-equivalente p:last-of-type { margin-bottom: 0; }
.franja-equivalente-datos { display: flex; gap: 1.4rem; margin-top: 0.55rem; padding-top: 0.55rem; border-top: 1px solid var(--grid-line); }
.franja-equivalente-stat { display: flex; flex-direction: column; gap: 0.15rem; }
.franja-equivalente-stat span { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-muted); }
.franja-equivalente-stat strong { font-size: 0.95rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.franja-aplicar {
    margin-top: 0.75rem;
    padding: 0.4rem 0.8rem;
    background: transparent;
    border: 1px solid var(--signal-cyan);
    color: var(--signal-cyan);
    border-radius: var(--radius-sm);
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease;
}
.franja-aplicar:hover { background: rgba(34, 184, 224, 0.1); }

#origin-input {
    background: rgba(34, 184, 224, 0.05) !important;
    border-color: rgba(34, 184, 224, 0.3) !important;
    color: var(--signal-cyan) !important;
    font-family: var(--font-mono);
    font-size: 0.76rem;
    font-weight: 500;
    cursor: not-allowed;
}

#destination-input:focus {
    border-color: var(--signal-cyan);
    box-shadow: 0 0 0 3px rgba(34, 184, 224, 0.12);
}

/* ---------- Buscador inteligente de destinos (solo Azuay) ---------- */
.dest-search-wrapper { position: relative; }
.dest-suggestions {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: var(--z-overlay);
    list-style: none;
    margin: 0;
    padding: 4px;
    background: rgba(27, 36, 51, 0.98);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45);
    max-height: 280px;
    overflow-y: auto;
}
.dest-suggestion {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.dest-suggestion:hover,
.dest-suggestion.is-active { background: rgba(34, 184, 224, 0.12); }
.dest-suggestion-pin { flex-shrink: 0; display: flex; align-items: center; }
.dest-suggestion-pin svg { width: 14px; height: 14px; }
.dest-suggestion-info { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.dest-suggestion-nombre {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dest-suggestion-detalle { font-size: 0.68rem; color: var(--ink-muted); }
.dest-suggestion-empty {
    padding: 0.6rem 0.65rem;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--ink-muted);
}

.btn-calculate-route {
    width: 100%;
    padding: 0.75rem;
    background: var(--signal-cyan);
    color: var(--void);
    border: none;
    border-radius: var(--radius-sm);
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-calculate-route:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); }
.btn-calculate-route:active { transform: translateY(0); }

.btn-nueva-busqueda {
    width: 100%;
    padding: 0.65rem;
    margin-top: 0.55rem;
    background: transparent;
    color: var(--ink-muted);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-sm);
    font-weight: 600;
    font-size: 0.8rem;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
    display: none;
}
.btn-nueva-busqueda.is-visible { display: block; }
.btn-nueva-busqueda:hover { color: var(--ink); border-color: var(--signal-cyan); }

.route-error { margin-top: 0.6rem; font-size: 0.78rem; color: var(--signal-red); display: none; }
.route-error.is-visible { display: block; }
.route-error.route-error--info { color: var(--ink-muted); }

@keyframes panel-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- Resultado de ruta (Dashboard General) ---------- */
.route-output { margin-top: 1.2rem; display: none; flex-direction: column; gap: 0.85rem; }
.route-output.is-visible { display: flex; animation: panel-in 0.25s ease; }

.route-card {
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-md);
    padding: 0.95rem 1rem;
}
.route-card h4 {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin-bottom: 0.7rem;
}

.route-summary-stats { display: flex; gap: 1.4rem; margin-bottom: 0.9rem; }
.route-summary-stat { display: flex; flex-direction: column; gap: 0.15rem; }
.route-summary-stat span { font-family: var(--font-mono); font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-muted); }
.route-summary-stat strong { font-size: 1.15rem; color: var(--ink); font-variant-numeric: tabular-nums; }

.unified-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.8rem; }

.route-risk-badge {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 0.85rem;
    border-radius: var(--radius-sm);
    font-weight: 700;
    font-size: 0.95rem;
    flex: 1;
}
.route-risk-badge i { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; box-shadow: 0 0 8px currentColor; }
.route-risk-badge--bajo     { background: rgba(52, 211, 153, 0.1);  color: var(--signal-green); }
.route-risk-badge--medio    { background: rgba(255, 176, 32, 0.1);  color: var(--signal-amber); }
.route-risk-badge--alto     { background: rgba(249, 115, 22, 0.12); color: var(--signal-orange); }
.route-risk-badge--muy_alto { background: rgba(239, 75, 93, 0.12);  color: var(--signal-red); }
/* Sin evidencia suficiente no es un quinto nivel de riesgo: es la ausencia de
   nivel. Por eso usa el gris de texto terciario y no un color del semáforo, que
   se leería como "un poco de riesgo". */
.route-risk-badge--sin-evidencia { background: rgba(110, 127, 158, 0.14); color: var(--ink-muted); }
.route-risk-badge i { background: currentColor; }
.risk-badge-text { display: flex; flex-direction: column; gap: 0.1rem; }
.risk-badge-text small { font-size: 0.7rem; font-weight: 500; opacity: 0.8; font-variant-numeric: tabular-nums; }

.unified-mini-stats {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.2rem;
    flex-shrink: 0;
    padding-top: 0.3rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink-muted);
    text-align: right;
    white-space: nowrap;
}
.unified-mini-stats strong { display: block; font-weight: 600; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

/* ---------- Icono redondo por eje (reusado en panel de eventos y detalle) ---------- */
.route-factor-icon {
    width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--font-mono); font-size: 0.56rem; font-weight: 700; color: var(--void);
}

.route-recommendation-card p { font-size: 0.85rem; line-height: 1.6; color: var(--ink-soft); }

.route-ia-body { border-top: 1px solid var(--grid-line); margin-top: 0.9rem; padding-top: 0.85rem; }
.route-ia-body p { font-size: 0.85rem; line-height: 1.6; color: var(--ink-soft); margin: 0; }
.route-ia-body .route-card-header-row { margin-bottom: 0.5rem; }

.route-card-header-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.7rem; gap: 0.6rem; }
.route-card-header-row h4 { margin-bottom: 0; }
.badge-live--sm { font-size: 0.6rem; padding: 0.22rem 0.55rem; gap: 0.32rem; flex-shrink: 0; }

/* ---------- Panel flotante de eventos cercanos (sobre el mapa) ---------- */
@keyframes map-events-in {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}
.evidence-panel {
    position: absolute;
    top: 24px;
    right: 24px;
    width: 300px;
    max-width: calc(100% - 48px);
    max-height: calc(100% - 48px);
    display: flex;
    flex-direction: column;
    z-index: var(--z-side-panel);
    font-family: var(--font-body);
    animation: map-events-in 0.3s ease;
    background: var(--surface-2);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}
.evidence-tabs { display: flex; align-items: center; border-bottom: 1px solid var(--grid-line); flex-shrink: 0; }
.evidence-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: rgba(255, 255, 255, 0.5);
    font-family: var(--font-body);
    font-size: 0.76rem;
    font-weight: 600;
    padding: 0.85rem 0.5rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.evidence-tab:hover { color: var(--ink-soft); }
.evidence-tab.is-activa { color: var(--ink); border-bottom-color: var(--signal-cyan); }
.evidence-tab--alerta:not(.is-activa) { color: var(--signal-amber); }
.evidence-tab--alerta .evidence-tab-count { box-shadow: 0 0 6px var(--signal-orange); }
.evidence-tab-count {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    color: var(--void);
    background: var(--signal-orange);
    border-radius: 10px;
    min-width: 16px;
    padding: 0.02rem 0.32rem;
    text-align: center;
}
.evidence-tab-count:empty { display: none; }
.evidence-collapse {
    flex-shrink: 0;
    background: transparent;
    border: none;
    border-left: 1px solid var(--grid-line);
    color: var(--ink-muted);
    padding: 0.7rem 0.7rem;
    cursor: pointer;
    align-self: stretch;
    display: flex;
    align-items: center;
}
.evidence-collapse svg { width: 14px; height: 14px; transition: transform 0.2s ease; display: block; }
.evidence-collapse[aria-expanded="false"] svg { transform: rotate(180deg); }
.evidence-body {
    padding: 1.125rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}
.evidence-body[hidden] { display: none; }
.evidence-panel-section[hidden] { display: none; }
.evidence-panel-section { display: flex; flex-direction: column; gap: 0.9rem; }
.map-events-desc { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, 0.55); }
.map-events-count-list { list-style: none; display: flex; flex-direction: column; gap: 0.65rem; }
.map-events-count-list li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.82rem; color: var(--ink-soft); }
.map-events-count-list li b { margin-left: auto; color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.map-events-note { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, 0.55); }
.map-events-rango { margin: 0.5rem 0 0; font-size: 12px; font-family: var(--font-mono); color: rgba(255, 255, 255, 0.4); }

.map-events-detail { border-top: 1px solid var(--grid-line); padding-top: 1rem; }
.map-events-detail-tipo { display: flex; align-items: center; gap: 0.6rem; font-size: 0.85rem; font-weight: 600; color: var(--ink); margin-bottom: 0.7rem; }
.map-events-detail-row { display: flex; justify-content: space-between; font-size: 0.8rem; padding: 0.3rem 0; color: var(--ink-soft); }
.map-events-detail-row span:first-child { color: var(--ink-muted); }
.map-events-detail-bar { height: 4px; border-radius: 3px; background: var(--grid-line); overflow: hidden; margin-top: 0.5rem; }
.map-events-detail-bar span { display: block; height: 100%; }

.event-pin-marker {
    position: relative;
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
}
.event-pin-ring {
    position: absolute;
    width: 26px; height: 26px;
    border-radius: 50%;
    opacity: 0.55;
    animation: event-pin-pulse 2.2s ease-out infinite;
}
.event-pin-ring--2 { animation-delay: 1.1s; }
@keyframes event-pin-pulse {
    0% { transform: scale(1); opacity: 0.55; }
    100% { transform: scale(2.1); opacity: 0; }
}
.event-pin-glyph {
    position: relative;
    width: 26px; height: 26px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff;
    border: 2px solid rgba(255,255,255,0.85);
    box-shadow: 0 0 8px rgba(0,0,0,0.5);
    cursor: pointer;
}
.event-pin-glyph svg { width: 15px; height: 15px; }

.leaflet-tooltip.event-label-tooltip {
    background: rgba(27, 36, 51, 0.95);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
    padding: 0.4rem 0.65rem;
    color: var(--ink);
    font-family: var(--font-body);
    white-space: nowrap;
    opacity: 1;
}
.leaflet-tooltip-right.event-label-tooltip::before { border-right-color: rgba(27, 36, 51, 0.95); }
.event-label-tooltip strong { display: block; font-size: 0.74rem; font-weight: 700; }
.event-label-tooltip span { display: block; font-size: 0.66rem; color: var(--ink-muted); margin-top: 0.15rem; }

.event-cluster-icon {
    width: 30px; height: 30px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--font-mono); font-size: 0.72rem; font-weight: 700; color: var(--ink);
    background: rgba(34, 184, 224, 0.85);
    border: 2px solid rgba(255,255,255,0.85);
    box-shadow: 0 0 10px rgba(34, 184, 224, 0.6);
    cursor: pointer;
}

/* ---------- Reportes recientes del Azuay (pestaña "Noticias" del panel de evidencia) ---------- */
.reports-desc { font-size: 0.72rem; line-height: 1.45; color: var(--ink-muted); margin-bottom: 0.8rem; }
.reports-list { display: flex; flex-direction: column; gap: 0.7rem; }
.reports-empty { font-size: 0.8rem; line-height: 1.5; color: var(--ink-muted); }

.report-card {
    background: var(--surface-3);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-md);
    padding: 0.7rem 0.8rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}
.report-eyebrow {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.report-eyebrow-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.report-loc { display: flex; align-items: center; gap: 0.32rem; font-size: 0.76rem; font-weight: 600; color: var(--ink-soft); }
.report-loc svg { width: 13px; height: 13px; flex-shrink: 0; }
.report-top { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
.report-cat {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 0.22rem 0.5rem;
    border-radius: 20px;
    border: 1px solid;
    min-width: 0;
}
.report-cat svg { width: 12px; height: 12px; flex-shrink: 0; }
.report-time { font-family: var(--font-mono); font-size: 0.62rem; color: var(--ink-muted); white-space: nowrap; flex-shrink: 0; }
.report-title { font-size: 0.82rem; font-weight: 600; line-height: 1.4; color: var(--ink); }
.report-cerca {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--signal-amber);
    background: rgba(255, 176, 32, 0.12);
    border: 1px solid rgba(255, 176, 32, 0.4);
    border-radius: 20px;
    padding: 0.2rem 0.55rem;
}
.report-cerca svg { width: 11px; height: 11px; flex-shrink: 0; }
.report-meta { display: flex; flex-direction: column; gap: 0.1rem; font-size: 0.7rem; color: var(--ink-muted); }
.report-link {
    align-self: flex-start;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--signal-cyan);
    text-decoration: none;
    border: 1px solid rgba(34, 184, 224, 0.35);
    border-radius: var(--radius-sm);
    padding: 0.3rem 0.7rem;
    transition: background 0.15s ease;
}
.report-link:hover { background: rgba(34, 184, 224, 0.12); }

/* Skeleton loading de los reportes */
@keyframes report-shimmer {
    0% { background-position: -200px 0; }
    100% { background-position: 200px 0; }
}
.report-skel {
    border-radius: 4px;
    background: linear-gradient(90deg, var(--surface-2) 25%, var(--grid-line) 50%, var(--surface-2) 75%);
    background-size: 400px 100%;
    animation: report-shimmer 1.3s linear infinite;
}
.report-skel--chip { width: 45%; height: 16px; }
.report-skel--titulo { width: 100%; height: 13px; }
.report-skel--meta { width: 65%; height: 11px; }

/* ---------- Cómo se calculó el nivel de la ruta ---------- */
/* Bloque de trazabilidad del indicador: cuántos km del recorrido están en zonas
   de riesgo alto, cuánta cobertura tuvo el análisis y cuál fue el tramo más
   crítico. El tramo crítico se muestra aparte, con su color de nivel, para que
   siga siendo visible sin volver a decidir por sí solo el nivel de la ruta. */
.route-metodologia { display: flex; flex-direction: column; gap: 0.45rem; }
.route-metodologia:empty { display: none; }
.metodo-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8rem;
    font-size: 0.74rem;
    color: var(--ink-muted);
}
.metodo-row b {
    color: var(--ink-soft);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.72rem;
    font-weight: 500;
    text-align: right;
}
.metodo-critico {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin-top: 0.15rem;
    padding: 0.5rem 0.65rem;
    border-left: 3px solid var(--route-color, var(--brand));
    border-radius: var(--radius-sm);
    background: var(--surface-3);
}
.metodo-critico-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-muted);
}
.metodo-critico strong { font-size: 0.82rem; color: var(--route-color, var(--ink)); }
.metodo-critico-eje { font-size: 0.72rem; color: var(--ink-soft); }
.metodo-nota { font-size: 0.68rem; line-height: 1.45; color: var(--ink-muted); margin-top: 0.2rem; }

/* ---------- Rutas alternativas ---------- */
.route-alt-list { display: flex; flex-direction: column; gap: 0.6rem; }
.route-alt-empty { font-size: 0.78rem; color: var(--ink-muted); padding: 0.4rem 0.1rem; }
.route-alt-nota { font-size: 0.7rem; color: var(--ink-muted); line-height: 1.4; padding: 0.1rem 0.1rem 0; }
.route-alt-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.7rem 0.85rem;
    background: var(--surface-3);
    border: 1px solid var(--grid-line-strong);
    border-left: 3px solid var(--route-color, var(--grid-line-strong));
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.route-alt-card:hover { background: var(--surface-4, var(--surface-3)); }
.route-alt-card.is-activa {
    background: rgba(34, 184, 224, 0.1);
    border-color: var(--signal-cyan, #22B8E0);
}
.route-alt-card-label { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.route-alt-card-label strong { font-size: 0.82rem; color: var(--ink-soft); }
.route-alt-card-label span { font-family: var(--font-mono); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-muted); }
.route-alt-card-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.25rem; flex-shrink: 0; }
.route-alt-card-datos { font-family: var(--font-mono); font-size: 0.68rem; color: var(--ink-muted); white-space: nowrap; }
.route-alt-card-risk {
    font-family: var(--font-mono);
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--route-color, var(--ink-muted));
}
.dot.orange { background: var(--signal-amber);  color: var(--signal-amber); }
.dot.purple { background: var(--signal-violet); color: var(--signal-violet); }

/* ---------- Contenido principal ---------- */
.main-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    padding: 1.5rem;
    gap: 1.1rem;
    min-width: 0;
    overflow: hidden;
}

/* ---------- Panel único: Analítica & tendencias ---------- */
.view-panel {
    display: none;
    flex: 1;
    min-height: 0;
    gap: 1.5rem;
}
.view-panel.active { display: flex; animation: fade-rise-in var(--dur-base) var(--ease-out); }
.view-panel[data-view-panel="analitica"] .analytics-section { flex: 0 0 auto; align-self: flex-start; width: 100%; }
.view-panel[data-view-panel="analitica"] { overflow-y: auto; }

.map-section { flex-shrink: 0; }

.map-section {
    flex: 2;
    background: var(--surface);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-lg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    min-height: 0;
    position: relative;
}

.badge-live {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--signal-cyan);
    background: rgba(34, 184, 224, 0.1);
    padding: 0.3rem 0.7rem;
    border-radius: 20px;
    white-space: nowrap;
}

#map {
    width: 100%;
    flex-grow: 1;
    border-radius: var(--radius-md);
    z-index: var(--z-map);
    background: var(--surface-2);
}

/* Popups de Leaflet con la estética del tablero */
.leaflet-popup-content-wrapper {
    background: var(--surface-3);
    color: var(--ink);
    border-radius: var(--radius-sm);
    font-family: var(--font-body);
}
.leaflet-popup-tip { background: var(--surface-3); }
.leaflet-popup-content { font-size: 0.82rem; line-height: 1.5; margin: 0.7rem 0.9rem; }
.leaflet-popup-content strong { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase; display: block; margin-bottom: 0.2rem; }
.leaflet-container a.leaflet-popup-close-button { color: var(--ink-muted); }

.leaflet-bar a { background: var(--surface-3); color: var(--ink); border-color: var(--grid-line-strong) !important; }
.leaflet-bar a:hover { background: var(--surface-2); }

/* Grid de 6 columnas (en vez de 3) para poder armar pares 50/50 (span 3) y
   tríos parejos (span 2) además de anchos completos (span 6), sin depender
   de alturas fijas por posición — cada tarjeta declara su propio tamaño
   según su peso en la jerarquía (--tall/--compact/por defecto), no según
   en qué fila del DOM cayó. */
.analytics-section {
    flex-shrink: 0;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1.5rem;
    /* Sin esto, Grid estira cada tarjeta a la altura de la más alta de su
       fila (ej. "Tendencia mensual" forzada a igualar a "Indicadores del
       cantón"), y Chart.js infla el gráfico para llenar ese alto de más.
       Cada tarjeta ya tiene su propio min-height como piso, así que puede
       tomar solo lo que su contenido necesita. */
    align-items: start;
}

.chart-card {
    background: var(--surface);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-md);
    padding: 1.3rem 1.4rem;
    display: flex;
    flex-direction: column;
    min-height: 340px;
    /* Los items de grid tienen min-width:auto por defecto: sin esto, un
       texto largo dentro de la tarjeta (ej. un nombre de delito) fija un
       ancho mínimo mayor que la columna disponible y desborda toda la
       grilla en viewports angostos, aunque cada hijo interno ya tenga su
       propio min-width:0. */
    min-width: 0;
    /* Ancla para el botón de ampliar (position:absolute), sin afectar el
       flujo normal del resto de la tarjeta. */
    position: relative;
}
.chart-card--full { grid-column: 1 / -1; }
.chart-card--half { grid-column: span 3; }
.chart-card--third { grid-column: span 2; }
.chart-card--tall { min-height: 480px; }
.chart-card--compact { min-height: 300px; }
.chart-card h3 {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
    margin-bottom: 1rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--grid-line);
}
.chart-card h3 em { font-style: normal; color: var(--ink-muted); opacity: 0.7; text-transform: none; letter-spacing: 0; }
/* Envoltorio dedicado para que Chart.js mida el espacio realmente disponible
   (lo que sobra tras título/leyenda/descripción), no la altura total de la
   tarjeta — si el canvas comparte el contenedor flex directamente con esos
   elementos, Chart.js lo dimensiona ignorándolos y el gráfico se desborda. */
.chart-canvas-wrap { position: relative; flex: 1; min-height: 0; }
.chart-canvas-wrap canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.chart-card-desc {
    font-family: var(--font-body);
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--ink-muted);
    margin: -0.4rem 0 0.8rem;
}

/* ---------- Botón "ampliar gráfico" + overlay a pantalla completa ---------- */
/* El botón mueve la tarjeta completa (con su canvas y su instancia de
   Chart.js ya creada) al overlay en vez de duplicar el gráfico: así no hace
   falta volver a pedir datos ni crear una segunda instancia. */
.chart-expand-btn {
    position: absolute;
    top: 1.2rem;
    right: 1.3rem;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-sm);
    color: var(--ink-muted);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
    z-index: 1;
}
.chart-expand-btn svg { width: 14px; height: 14px; }
.chart-expand-btn:hover { color: var(--ink); border-color: var(--signal-cyan); background: var(--surface-2); }
.chart-fullscreen-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(5, 9, 15, 0.88);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4rem 3rem;
}
.chart-fullscreen-overlay[hidden] { display: none; }
.chart-fullscreen-slot { width: 100%; height: 100%; max-width: 1100px; display: flex; }
.chart-fullscreen-slot .chart-card { flex: 1; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); }
/* Dentro del overlay el botón ya no "amplía" (ya está ampliada), pasa a
   ser redundante con el botón de cerrar de arriba: se oculta ahí y no en
   otro lado, para no duplicar affordances de cerrar. */
.chart-fullscreen-slot .chart-expand-btn { display: none; }
.chart-fullscreen-close {
    position: fixed;
    top: 1.5rem;
    right: 1.5rem;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-md);
    color: var(--ink);
    cursor: pointer;
    z-index: 1;
}
.chart-fullscreen-close:hover { border-color: var(--signal-cyan); color: var(--signal-cyan); }

/* ---------- Leyenda tipo "chip" reusada en varios gráficos ---------- */
/* Fila única sin wrap: la leyenda nunca crece en altura sin importar
   cuántas categorías estén activas; si no caben todas, se desliza en
   horizontal en vez de estirar la tarjeta hacia abajo. */
.chart-legend {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.7rem;
    margin: -0.2rem 0 0.7rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 0.3rem;
    scrollbar-width: thin;
    scrollbar-color: var(--grid-line-strong) transparent;
}
.chart-legend::-webkit-scrollbar { height: 4px; }
.chart-legend::-webkit-scrollbar-track { background: transparent; }
.chart-legend::-webkit-scrollbar-thumb { background: var(--grid-line-strong); border-radius: var(--radius-pill); }
.legend-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-soft);
}
.legend-chip i { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }

/* ---------- Dona: distribución por eje ---------- */
.chart-card-donut .donut-body {
    flex-grow: 1;
    display: flex;
    align-items: center;
    gap: 1.1rem;
    min-height: 0;
}
.donut-canvas-wrap {
    position: relative;
    width: 48%;
    flex-shrink: 0;
    aspect-ratio: 1 / 1;
}
.donut-canvas-wrap canvas { width: 100% !important; height: 100% !important; }
.donut-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    text-align: center;
}
.donut-center-value {
    font-family: var(--font-mono);
    font-size: 1.55rem;
    font-weight: 700;
    color: var(--ink);
    line-height: 1;
}
.donut-center-label {
    font-family: var(--font-mono);
    font-size: 0.58rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-muted);
    margin-top: 0.35rem;
}
.donut-legend {
    list-style: none;
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    font-size: 0.78rem;
    color: var(--ink-soft);
}
.donut-legend li { display: flex; align-items: center; gap: 0.5rem; }
.donut-legend li b {
    margin-left: auto;
    font-family: var(--font-mono);
    color: var(--ink);
    font-weight: 600;
    font-size: 0.78rem;
}
.legend-dot { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }

/* ---------- Salud del modelo ---------- */
.modelo-salud-lista {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    gap: 0.7rem;
    min-height: 0;
    overflow-y: auto;
}
.modelo-salud-item {
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--grid-line);
}
.modelo-salud-item:last-child { border-bottom: none; padding-bottom: 0; }
.modelo-eje-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.35rem;
}
.modelo-eje-nombre {
    font-size: 0.74rem;
    color: var(--ink-soft);
    flex-shrink: 0;
    width: 8.6rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.modelo-acc-bar {
    flex: 1;
    height: 6px;
    border-radius: 3px;
    background: var(--surface-2);
    overflow: hidden;
}
.modelo-acc-bar span {
    display: block;
    height: 100%;
    background: var(--signal-cyan);
    border-radius: 3px;
    transition: width var(--dur-slow) var(--ease-out);
}
.modelo-acc-pct {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink);
    width: 2.7rem;
    text-align: right;
    flex-shrink: 0;
}
.modelo-eje-meta {
    font-family: var(--font-body);
    font-size: 0.7rem;
    color: var(--ink-muted);
}

/* ---------- Indicadores por cantón (Fase E) ---------- */
.canton-indicadores-body.skeleton { min-height: 120px; }
.canton-indicadores-grid {
    display: grid;
    grid-template-columns: minmax(140px, 0.8fr) 1.2fr;
    /* Sin esto, Grid estira "Nivel de riesgo" (bloque corto) a la misma
       altura que "Delitos predominantes" (bloque largo) cuando quedan lado
       a lado en pantallas anchas, dejando un vacío debajo del texto corto. */
    align-items: start;
    gap: 1.4rem;
    padding-bottom: 1rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--grid-line);
}
/* min-width:0 porque también es un item de grid (de .canton-indicadores-grid,
   arriba): sin esto, la lista de delitos con nombres largos fija su propio
   ancho mínimo y desborda esta segunda grilla anidada, aunque la de afuera
   (.chart-card) ya esté corregida. */
.canton-indicador-bloque { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; }
.canton-indicador-label {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
}
.canton-indicador-nivel { font-size: 1.3rem; font-weight: 700; }
.canton-indicador-sub { font-size: 0.76rem; color: var(--ink-muted); line-height: 1.5; }
.canton-delitos-lista { gap: 0.55rem; }
/* Barra proporcional al delito más frecuente: reemplaza el punto de color
   fijo (no aportaba información, era el mismo cian en las 8 filas) por una
   referencia visual real de magnitud, con el mismo patrón ya usado en
   "Confiabilidad del modelo" (.modelo-acc-bar). */
.canton-delitos-lista li { display: flex; flex-direction: column; align-items: stretch; gap: 0.3rem; }
.delito-row-top { display: flex; align-items: baseline; gap: 0.6rem; }
.delito-row-top span { flex: 1; min-width: 0; }
.delito-row-top b { flex-shrink: 0; font-family: var(--font-mono); color: var(--ink); font-weight: 600; font-size: 0.78rem; }
.delito-bar { height: 5px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.delito-bar span { display: block; height: 100%; background: var(--signal-cyan); border-radius: 3px; }
/* ---------- Botón "ver más / ver menos" reutilizado en Delitos predominantes ---------- */
.text-expand-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.6rem;
    padding: 0;
    background: transparent;
    border: none;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--signal-cyan);
    cursor: pointer;
}
.text-expand-toggle:hover { color: var(--ink); }
.text-expand-toggle svg { width: 12px; height: 12px; transition: transform 0.2s ease; }
.text-expand-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

/* ---------- Matriz temporal de riesgo ---------- */
.matrix-container {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-height: 0;
    overflow: hidden;
}
/* align-items:stretch (no "center"): las celdas deben llenar la fila
   directamente vía flexbox. "height:100%" en .matrix-cell dependía de que
   un ancestro lejano tuviera alto definido para que el porcentaje resuelva,
   una cadena frágil que se rompió al corregir el estiramiento de
   .analytics-section — con stretch, cada celda toma el alto de su fila sin
   depender de ese porcentaje. */
.matrix-row { display: flex; align-items: stretch; gap: 3px; flex: 1; }
.matrix-row-label {
    width: 24px;
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    color: var(--ink-muted);
    text-align: right;
    padding-right: 2px;
}
.matrix-cell {
    flex: 1;
    /* Sin "height:100%": un alto explícito impediría que align-items:stretch
       de .matrix-row (arriba) estire la celda — con "auto" (el valor por
       defecto), stretch sí puede actuar. */
    border-radius: 2px;
    background: var(--cell-color, var(--surface-3));
    /* Borde sutil para que la cuadrícula se lea como cuadrícula incluso
       cuando muchas celdas caen en "0 casos" y su relleno es casi del
       mismo tono que el fondo de la tarjeta (ej. cantones pequeños). */
    border: 1px solid var(--grid-line);
    transition: transform 0.1s ease;
    opacity: 0;
    animation: fade-rise-in var(--dur-base) var(--ease-out) forwards;
}
.matrix-cell:hover { transform: scale(1.15); }
.matrix-legend {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.6rem;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    color: var(--ink-muted);
}
.matrix-legend-swatch { width: 10px; height: 10px; border-radius: 2px; }

/* ---------- Leaflet Routing Machine: ocultamos su panel por defecto,
   usamos nuestro propio .route-results-panel en el sidebar ---------- */
.leaflet-routing-container { display: none !important; }

/* ---------- Decoración HUD de esquina en el panel del mapa ---------- */
.map-section::before,
.map-section::after {
    content: "";
    position: absolute;
    width: 14px;
    height: 14px;
    border: 1.5px solid rgba(34, 184, 224, 0.35);
    pointer-events: none;
}
.map-section::before { top: 10px; left: 10px; border-right: none; border-bottom: none; }
.map-section::after { bottom: 10px; right: 10px; border-left: none; border-top: none; }

/* ---------- Responsive dashboard ---------- */
@media (max-width: 1080px) {
    .analytics-section { grid-template-columns: 1fr; }
    /* Un grid de 1 columna explícita no "clampea" los span de las tarjetas
       --half/--third/--full: crea columnas implícitas para respetarlos y el
       layout se rompe. Hay que forzar el span a 1 columna acá también. */
    .chart-card--full, .chart-card--half, .chart-card--third { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
    .ops-shell { height: auto; overflow: auto; }
    .dashboard-container { flex-direction: column; height: auto; }
    .sidebar { width: 100%; max-height: none; }
    .main-content { padding: 1rem; overflow: visible; }
    .view-panel.active { min-height: 0; }
    #map { min-height: 320px; }
    .kpi-strip { grid-template-columns: repeat(2, 1fr); }

    /* Antecedentes y reportes ahora viven en un solo panel con pestañas
       (.evidence-panel): ya no compiten por espacio en móvil, así que no
       hace falta desanclar nada ni forzar posición fija. */
    .evidence-panel {
        max-width: calc(100vw - 32px);
    }
}

/* ==========================================================================
   RUTA SEGURA — mapa a pantalla completa + búsqueda flotante + drawer inferior
   ========================================================================== */
.route-shell { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; }
.route-map-full { flex: 1; min-height: 0; position: relative; }
.route-map-full #map { position: absolute; inset: 0; border-radius: 0; }

/* ---------- Barra de búsqueda flotante (antes de calcular una ruta) ----------
   Fondo: --void a 96% de opacidad (rgba(11,18,28,.96)) — más oscuro que las
   tarjetas en flujo (--surface-2) a propósito: es un panel flotando SOBRE el
   mapa, no una tarjeta dentro de un panel ya oscuro, así que necesita más
   contraste/opacidad para sentirse "premium" y no competir con el mapa. */
.route-search-float {
    position: absolute;
    top: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-panel);
    width: min(400px, calc(100% - 32px));
    background: rgba(11, 18, 28, 0.96);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 0.85rem;
    transition: width var(--dur-base) var(--ease-out), padding var(--dur-base) var(--ease-out), opacity 300ms var(--ease-out);
}
.route-search-float .location-input-wrapper { margin-bottom: 0.4rem; }
.route-search-float .input-route-group input { margin-bottom: 0.4rem; padding: 0.55rem 0.7rem; }
.route-search-float .btn-calculate-route { padding: 0.6rem; }
.route-search-float .route-error { margin-top: 0.4rem; }
.route-search-float.is-compact {
    top: 12px;
    left: 12px;
    transform: none;
    width: min(280px, calc(100% - 24px));
    padding: 0.6rem;
}

/* ---------- Guía visual movible de Ruta Segura ---------- */
.route-guide-assistant {
    position: absolute;
    left: 20px;
    top: 20px;
    z-index: var(--z-overlay);
    width: 104px;
    height: 104px;
    touch-action: none;
}
.route-guide-button {
    width: 104px;
    height: 104px;
    padding: 4px;
    overflow: hidden;
    border: 1px solid rgba(34, 184, 224, 0.75);
    border-radius: 28px;
    background: rgba(11, 18, 28, 0.94);
    box-shadow: 0 0 0 4px rgba(34, 184, 224, 0.08), 0 9px 28px rgba(0, 0, 0, 0.46);
    cursor: grab;
    user-select: none;
    -webkit-user-drag: none;
    transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}
.route-guide-button img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 23px;
    object-fit: contain;
    pointer-events: none;
    user-select: none;
    -webkit-user-drag: none;
}
.route-guide-button:hover {
    border-color: #62e9ff;
    box-shadow: 0 0 0 5px rgba(34, 184, 224, 0.13), 0 10px 30px rgba(0, 0, 0, 0.5);
    transform: translateY(-1px);
}
.route-guide-button:active,
.route-guide-assistant.is-dragging .route-guide-button { cursor: grabbing; transform: none; }
.route-guide-button:focus-visible {
    outline: 3px solid rgba(255, 255, 255, 0.94);
    outline-offset: 4px;
}
.route-guide-bubble {
    position: absolute;
    width: min(310px, calc(100vw - 28px));
    padding: 0.85rem;
    border: 1px solid rgba(34, 184, 224, 0.45);
    border-radius: var(--radius-md);
    background: rgba(11, 18, 28, 0.98);
    box-shadow: var(--shadow-md);
    color: var(--ink-soft);
}
.route-guide-bubble[hidden] { display: none; }
.route-guide-step-count {
    margin: 0 0 0.35rem;
    font-family: var(--font-mono);
    color: var(--signal-cyan);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}
.route-guide-message { margin: 0; font-size: 0.84rem; line-height: 1.55; color: var(--ink); }
.route-guide-note { margin: 0.45rem 0 0; font-size: 0.74rem; line-height: 1.45; color: var(--signal-amber); }
.route-guide-actions { display: flex; align-items: center; justify-content: flex-end; gap: 0.45rem; margin-top: 0.8rem; }
.route-guide-actions button {
    padding: 0.42rem 0.62rem;
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--ink-soft);
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
}
.route-guide-actions button:hover,
.route-guide-actions button:focus-visible { color: var(--ink); border-color: var(--signal-cyan); outline: none; }
.route-guide-actions .route-guide-primary { background: rgba(34, 184, 224, 0.14); color: var(--signal-cyan); }
.route-guide-highlight {
    position: relative;
    z-index: calc(var(--z-overlay) - 1) !important;
    outline: 3px solid var(--signal-cyan) !important;
    outline-offset: 4px;
    border-radius: var(--radius-sm);
    box-shadow: 0 0 0 7px rgba(34, 184, 224, 0.14), 0 0 24px rgba(34, 184, 224, 0.32) !important;
}
@media (max-width: 640px) {
    /* #map es absoluto en Ruta Segura; el contenedor necesita una altura
       explícita cuando .ops-shell pasa a height:auto en el breakpoint general. */
    .route-shell { height: calc(100vh - 70px); min-height: 500px; }
    .route-guide-assistant,
    .route-guide-button { width: 88px; height: 88px; }
    .route-guide-button { border-radius: 24px; }
    .route-guide-button img { border-radius: 19px; }
    .route-guide-bubble { width: min(286px, calc(100vw - 24px)); }
}
@media (prefers-reduced-motion: reduce) {
    .route-guide-button { transition: none; }
}

/* ---------- Drawer inferior (resultado de la ruta) ---------- */
.route-drawer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-panel);
    background: rgba(11, 18, 28, 0.96);
    border-top: 1px solid var(--grid-line);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: var(--shadow-md);
}
.route-drawer[hidden] { display: none; }
.route-drawer-handle {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.65rem 1.1rem;
    background: transparent;
    border: none;
    cursor: pointer;
    text-align: left;
}
.route-drawer-handle .route-risk-badge {
    flex: 1;
    padding: 0.5rem 0.7rem;
    font-size: 0.88rem;
    gap: 0.5rem;
}
.route-drawer-handle .unified-mini-stats { font-size: 0.7rem; }
.route-drawer-chevron { flex-shrink: 0; width: 16px; height: 16px; color: var(--ink-muted); transition: transform 300ms var(--ease-out); }
.route-drawer-handle[aria-expanded="true"] .route-drawer-chevron { transform: rotate(180deg); }

/* El body se expande/colapsa animando max-height + opacity (300ms ease-out) —
   por eso ya no usa el atributo hidden (display:none no se puede animar). */
.route-drawer-body {
    padding: 0 1.1rem;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height 300ms var(--ease-out), opacity 300ms var(--ease-out), padding 300ms var(--ease-out);
}
.route-drawer-body.is-expanded {
    max-height: 65vh;
    overflow-y: auto;
    opacity: 1;
    padding: 0.8rem 1.1rem 0.85rem;
    border-top: 1px solid var(--grid-line);
}

.route-field-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--grid-line);
}
.route-field-row:last-of-type { border-bottom: none; }
.route-field-label {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
    flex-shrink: 0;
}
.route-field-row .modo-transporte { flex-shrink: 0; width: auto; gap: 0.4rem; margin-bottom: 0; }
.route-field-row .modo-btn { flex: 0 0 auto; padding: 0.4rem 0.65rem; }
.route-field-row .departure-time-group { flex-shrink: 0; width: auto; }
.route-field-row .departure-time-group input { margin-bottom: 0; }

.route-drawer .route-output { margin-top: 0.75rem; }
.route-drawer .route-card { padding: 0.75rem 0.85rem; }
.route-drawer .route-ia-body { margin-top: 0.65rem; padding-top: 0.6rem; }
.route-drawer-actions { display: flex; gap: 0.6rem; margin-top: 0.85rem; }
.route-drawer-actions .btn-nueva-busqueda.is-visible { display: block; flex: 1; width: auto; margin-top: 0; }
.btn-ver-eventos {
    flex: 1;
    padding: 0.65rem;
    background: transparent;
    color: var(--ink-soft);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-sm);
    font-weight: 600;
    font-size: 0.8rem;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.btn-ver-eventos:hover { color: var(--ink); border-color: var(--signal-cyan); }

/* ==========================================================================
   ALERTAS — tablero de alertas vigentes
   Reutiliza .kpi-strip, .chart-card, .modelo-salud-item y .report-card tal
   como están; lo único propio es el contenedor de la página y la tarjeta de
   cantón en alerta.
   ========================================================================== */
.alertas-shell {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}
/* .kpi-strip declara 5 columnas (1fr 1fr 1fr 1.6fr 1fr) porque nació para el
   Explorador, que tiene 5 KPI y donde el 4º —nivel de riesgo provincial— es
   más ancho a propósito. Alertas solo tiene 4 KPI, así que "Últimos datos"
   heredaba ese 1.6fr y la 5ª columna quedaba vacía mostrando el fondo de la
   franja. Se corrige solo acá, sin tocar la regla compartida. */
.alertas-shell .kpi-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.alertas-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.2rem;
    flex-wrap: wrap;
}
.alertas-header h1 {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--ink);
    margin: 0 0 0.4rem;
}
.alertas-header p {
    max-width: 68ch;
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--ink-soft);
    margin: 0;
}
/* Aviso de alcance: la plataforma no tiene cuentas ni envía notificaciones,
   así que la página lo dice en vez de dejar que se asuma lo contrario. */
.alertas-aviso {
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    border-left: 3px solid var(--signal-cyan);
    border-radius: var(--radius-md);
    padding: 0.75rem 0.95rem;
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--ink-soft);
    margin: 0;
}
.alertas-aviso a { color: var(--signal-cyan); }

.alertas-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1.5rem;
    align-items: start;
}
.alertas-cantones {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 0.9rem;
}
.alerta-card {
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    border-left: 3px solid var(--alerta-color, var(--grid-line-strong));
    border-radius: var(--radius-md);
    padding: 0.85rem 0.95rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.alerta-card-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.alerta-card-top h4 { font-family: var(--font-display); font-size: 0.95rem; color: var(--ink); margin: 0; }
.alerta-nivel {
    flex-shrink: 0;
    font-family: var(--font-mono);
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    border: 1px solid;
    border-radius: var(--radius-pill);
    padding: 0.2rem 0.55rem;
    white-space: nowrap;
}
.alerta-detalle { margin: 0; font-size: 0.78rem; line-height: 1.5; color: var(--ink-muted); }
.alerta-franja {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    font-size: 0.75rem;
    color: var(--ink-soft);
}
.alerta-franja svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--ink-muted); }
.alerta-franja strong { color: var(--ink); }
.alertas-resto { margin: 0.9rem 0 0; font-size: 0.78rem; color: var(--ink-muted); }
.alertas-resto:empty { display: none; }

.alerta-referencia {
    margin: 0 0 0.8rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--grid-line);
    font-size: 0.76rem;
    color: var(--ink-muted);
}
.alerta-referencia strong { color: var(--ink-soft); }
.alerta-pronostico-nivel {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}
.alertas-reportes { max-height: 520px; overflow-y: auto; }

@media (max-width: 1080px) {
    .alertas-grid { grid-template-columns: 1fr; }
    .alertas-grid .chart-card--full,
    .alertas-grid .chart-card--half { grid-column: 1 / -1; }
}

/* ==========================================================================
   ACERCA DEL SISTEMA — página institucional y de transparencia
   Reutiliza .chart-card, .landing-badge y los tokens de color/espaciado tal
   como están. Lo propio de esta página es la ficha técnica, la grilla de
   tecnologías, el flujo de pasos y el pie de créditos.
   ========================================================================== */
.acerca-shell {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}
/* .ops-shell fija el alto al viewport, así que sin esto los hijos de un
   contenedor flex en columna se encogen para caber (flex-shrink:1 por
   defecto) en vez de desbordar y activar el scroll: las secciones largas
   quedaban aplastadas a la altura de su título. */
.acerca-shell > * { flex-shrink: 0; }
.acerca-hero { max-width: 78ch; }
.acerca-hero h1 {
    font-family: var(--font-display);
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--ink);
    margin: 0.5rem 0 0.7rem;
}
.acerca-hero p { font-size: 0.92rem; line-height: 1.65; color: var(--ink-soft); margin: 0; }

.acerca-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.5rem;
    align-items: start;
}
/* Esta página no dibuja gráficos: el min-height pensado para canvas dejaría
   tarjetas con aire muerto, así que cada una toma el alto de su contenido. */
.acerca-card { min-height: 0; }
/* .chart-card--half vale "span 3" porque nació para la grilla de 6 columnas
   del Explorador; en esta grilla de 2 columnas ese span desborda y empuja
   cada tarjeta a su propia fila. Se reutiliza la clase por coherencia visual
   y solo se corrige el tramo de columnas. */
.acerca-grid > .chart-card--half { grid-column: auto; }

/* ---------- Ficha técnica ----------
   Usa el patrón de fila "label mono a la izquierda / valor a la derecha" que
   el sistema ya emplea en .map-events-detail-row, en vez de introducir una
   tabla nueva. */
.ficha-tecnica { margin: 0; }
.ficha-fila {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--grid-line);
}
.ficha-fila:last-child { border-bottom: none; }
.ficha-fila dt {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
    flex-shrink: 0;
}
.ficha-fila dd { margin: 0; font-size: 0.85rem; color: var(--ink); text-align: right; }

/* ---------- Listas simples ---------- */
.acerca-lista { list-style: none; display: flex; flex-direction: column; gap: 0.55rem; margin: 0; }
.acerca-lista li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.83rem; color: var(--ink-soft); }
.acerca-punto { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.acerca-nota {
    margin: 1rem 0 0;
    padding-top: 0.85rem;
    border-top: 1px solid var(--grid-line);
    font-size: 0.78rem;
    line-height: 1.55;
    color: var(--ink-muted);
}

/* ---------- Tecnologías ---------- */
/* 3 columnas fijas y no auto-fill: son 9 tecnologías, así quedan tres filas
   parejas de 3 sin tarjetas sueltas al final. Las filas del grid se estiran
   por defecto, de modo que todas las tarjetas de una misma fila comparten
   altura aunque su descripción sea más corta. */
.tec-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.9rem;
}
.tec-card {
    background: var(--surface-2);
    border: 1px solid var(--grid-line-strong);
    border-radius: var(--radius-md);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.tec-icono {
    width: 34px;
    height: 34px;
    border-radius: var(--radius-sm);
    background: rgba(34, 184, 224, 0.1);
    color: var(--signal-cyan);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.4rem;
}
.tec-icono svg { width: 18px; height: 18px; }
.tec-card h4 {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin: 0;
}
.tec-card strong { font-size: 0.92rem; color: var(--ink); font-weight: 700; }
.tec-card p { margin: 0.15rem 0 0; font-size: 0.78rem; line-height: 1.5; color: var(--ink-soft); }

/* ---------- Flujo de proceso ----------
   Numeración con línea conectora: comunica la secuencia sin recurrir a
   flechas decorativas ni a un diagrama que habría que mantener aparte. */
/* 3 columnas fijas: los 6 pasos quedan en dos filas de 3, sin que el último
   quede solo al final de una fila. */
.flujo {
    list-style: none;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.1rem 1.4rem;
}
.flujo-paso { display: flex; align-items: flex-start; gap: 0.75rem; position: relative; }
.flujo-num {
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(34, 184, 224, 0.12);
    border: 1px solid rgba(34, 184, 224, 0.35);
    color: var(--signal-cyan);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}
.flujo-paso h4 { font-family: var(--font-display); font-size: 0.88rem; color: var(--ink); margin: 0 0 0.2rem; }
.flujo-paso p { margin: 0; font-size: 0.78rem; line-height: 1.5; color: var(--ink-soft); }

/* ---------- Alcance ---------- */
.alcance-lista { list-style: none; display: flex; flex-direction: column; gap: 0.6rem; margin: 0 0 0.9rem; }
.alcance-lista:last-of-type { margin-bottom: 0; }
.alcance-lista li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.82rem; line-height: 1.5; color: var(--ink-soft); }
.alcance-icono { flex-shrink: 0; width: 17px; height: 17px; margin-top: 0.1rem; }
.alcance-icono svg { width: 100%; height: 100%; }
.alcance-lista--si .alcance-icono { color: var(--signal-green); }
.alcance-lista--no .alcance-icono { color: var(--signal-red); }

/* ---------- Privacidad ---------- */
.privacidad-lista { list-style: none; display: flex; flex-direction: column; gap: 0.85rem; margin: 0; }
.privacidad-lista li { display: flex; align-items: flex-start; gap: 0.7rem; }
.privacidad-icono {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-sm);
    background: var(--surface-3);
    color: var(--ink-soft);
    display: flex;
    align-items: center;
    justify-content: center;
}
.privacidad-icono svg { width: 16px; height: 16px; display: block; }
.privacidad-lista strong { display: block; font-size: 0.83rem; color: var(--ink); font-weight: 600; }
/* "div span" y no solo "span": el contenedor del ícono también es un <span>
   dentro de esta lista, así que un selector abierto lo alcanzaba y le
   imponía display:block — con eso el centrado flex dejaba de aplicarse y el
   SVG quedaba pegado a la esquina superior izquierda. */
.privacidad-lista div span { display: block; margin-top: 0.15rem; font-size: 0.76rem; line-height: 1.5; color: var(--ink-muted); }

/* ---------- Créditos ---------- */
.acerca-creditos {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    padding: 1.1rem 1.3rem;
    background: var(--surface);
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-md);
}
.acerca-creditos-label {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ink-muted);
}
.acerca-autores { margin: 0.35rem 0 0; font-size: 0.88rem; color: var(--ink); }
.acerca-creditos-meta { margin: 0; font-size: 0.74rem; line-height: 1.6; color: var(--ink-muted); text-align: right; }

@media (max-width: 1080px) {
    .acerca-grid { grid-template-columns: 1fr; }
    .tec-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .flujo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .acerca-creditos { flex-direction: column; align-items: flex-start; }
    .acerca-creditos-meta { text-align: left; }
}

@media (max-width: 680px) {
    .tec-grid, .flujo { grid-template-columns: 1fr; }
}

/* Página placeholder (Alertas / Configuración) */
.placeholder-view {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    text-align: center;
    color: var(--ink-muted);
}
.placeholder-view h2 { font-family: var(--font-display); font-size: 1.6rem; color: var(--ink); }
.placeholder-view p { max-width: 420px; font-size: 0.9rem; line-height: 1.6; }

/* ==========================================================================
   MEJORAS DE VISUALIZACIÓN (PUNTOS 3 AL 5)
   ========================================================================== */

/* Skeleton Loading Animation */
@keyframes skeleton-shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

.skeleton {
    background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%) !important;
    background-size: 200% 100% !important;
    animation: skeleton-shimmer 1.5s infinite linear !important;
    color: transparent !important;
    border-radius: var(--radius-sm);
    display: inline-block;
    pointer-events: none;
    user-select: none;
}

.skeleton * {
    visibility: hidden !important;
}

/* Contenedor del Mapa en el Explorador */
.explorador-map-wrap {
    width: 100%;
    height: 380px;
    border: 1px solid var(--grid-line);
    border-radius: var(--radius-md);
    overflow: hidden;
    position: relative;
    background: var(--void);
}

.chart-card--map {
    margin-bottom: 1rem;
}

/* Efectos Premium en Tarjetas Analíticas */
.chart-card {
    box-shadow: var(--shadow-glow-brand);
    transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.chart-card:hover {
    border-color: var(--grid-line-strong);
    box-shadow: 0 0 22px rgba(34, 184, 224, 0.14);
}
