/* ============================================================
   VEXTO — SISTEMA DE APLICACIÓN
   Capa de interfaz. Para apps React interactivas en pantalla.

   Aporta lo que el núcleo no define porque no aplica a documento:
   superficies elevadas, estados de interacción y modo claro/oscuro.

   Los apps NO copian este archivo: lo consumen desde el submódulo
   identidad-grafica-vexto (01_Sistemas/aplicacion/). El bloque
   :root generado es autosuficiente para que funcione servido solo.

   Diferencia con `pantalla/`: pantalla produce piezas rasterizadas
   de tamaño fijo (infografías, reels). Esto produce interfaces
   responsivas con estado.
   ============================================================ */

/* >>> GENERADO desde 00_Nucleo_VEXTO/tokens.json · no editar a mano · python herramientas/tokens.py generar */
/* tokens v1.2.1 · 2026-09-16 */
:root {

  /* ---------- SEÑAL ---------- */
  /* El Punto. Máximo 10% de la superficie de cualquier pieza. Nunca decorativo, nunca en fondos, nunca en texto corrido. */
  --vx-signal-core:         #2E5CFF;  /* el azul VEXTO. Nunca cambia. */
  --vx-signal-press:        #1E44CC;  /* estado :active en interfaces */
  --vx-signal-hover:        #4A73FF;  /* estado :hover en interfaces */
  --vx-signal-tint:         #D9DEEF;  /* señal al 12% sobre Warm Concrete. Sólo para marcar la región que un gráfico subraya (p. ej. rango_referencia) — nunca fondo de pieza ni cuenta para el máx. 10% de superficie del Punto. Texto en tinta encima da >12:1. */
  --vx-signal-tint-oscuro:  #0C1532;  /* gemelo de --vx-signal-tint para Deep Void: señal al 18%. */

  /* ---------- SUPERFICIES ---------- */
  /* Fondos planos. Nunca blanco puro, nunca gradiente, nunca textura. */
  --vx-deep-void:           #050505;  /* superficie oscura. Es fondo, nunca texto. */
  --vx-warm-concrete:       #F0F0ED;  /* superficie clara. Nunca blanco puro. */
  --vx-surface-sunken:      #E6E6E2;  /* un escalón bajo Warm Concrete: marcos de gráfica, filas alternas */
  --vx-surface-zona:        #E2E2DC;  /* zona que debe leerse aparte sobre claro: banner lateral, bloque sólido de infografía */
  --vx-raised:              #101010;  /* panel elevado sobre Deep Void. Un solo escalón. */
  --vx-raised-2:            #1A1A19;  /* sólo inputs y celdas hundidas sobre oscuro */
  --vx-surface-zona-oscura: #151515;  /* zona que debe leerse aparte sobre oscuro */

  /* ---------- TINTA SOBRE CLARO ---------- */
  /* Texto sobre Warm Concrete. #0A0A0A es texto; #050505 es fondo — no se invierten. */
  --vx-ink:                 #0A0A0A;  /* titulares y texto principal */
  --vx-ink-body:            #44443F;  /* cuerpo, bajadas, labels de KPI */
  --vx-ink-soft:            #5E5E5B;  /* texto secundario denso */
  --vx-ink-muted:           #636361;  /* eyebrows, metadatos, unidades, fuentes. 5.3:1 WCAG AA sobre Warm Concrete (antes #7A7A78, 3.3:1) */
  --vx-ink-faint:           #A9A9A6;  /* nunca texto que deba leerse: extremos de escala y separadores */

  /* ---------- TINTA SOBRE OSCURO ---------- */
  --vx-on-dark:             #F2F2EF;  /* texto principal sobre Deep Void */
  --vx-on-dark-2:           #B8B8B5;  /* secundario sobre Deep Void */
  --vx-on-dark-3:           #80807E;  /* eyebrows y metadatos sobre Deep Void. 5.2:1 (antes #7A7A78, 4.7:1) */
  --vx-on-dark-4:           #575755;  /* extremo de escala sobre oscuro; nunca texto */

  /* ---------- NEUTROS DE USO RESTRINGIDO ---------- */
  --vx-dim:                 #9A9A97;  /* gris SÓLO de pantalla retroiluminada. En documento usar --vx-ink-muted. */
  --vx-blanco:              #FFFFFF;  /* SÓLO texto sobre azul de señal y papel en modo impresión. Nunca fondo de pieza. */
  --vx-mesa:                #2A2A2A;  /* mesa de previsualización alrededor de una hoja en catálogos. No imprime. */

  /* ---------- HAIRLINES ---------- */
  /* La estructura se hace con filetes de 1px y aire. No con tarjetas ni sombras. */
  --vx-line-dark:           rgba(255, 255, 255, 0.10);  /* filete sobre oscuro */
  --vx-line-light:          rgba(10, 10, 10, 0.10);  /* filete sobre claro */

  /* ---------- SERIE ORDINAL · TINTA ---------- */
  /* Para series con orden (barras por rango, estratos) sobre claro. Nunca en series nominales. Monótona en L*, salto mínimo 1.35, extremo claro > 2.0 contra Warm Concrete. El paso 4 conserva #7A7A78: es dato, no texto. */
  --vx-serie-1:             #0A0A0A;
  --vx-serie-2:             #44443F;
  --vx-serie-3:             #5E5E5B;
  --vx-serie-4:             #7A7A78;
  --vx-serie-5:             #A9A9A6;

  /* ---------- SERIE ORDINAL · TINTA SOBRE OSCURO ---------- */
  /* Misma serie invertida en luminancia sobre Deep Void. Salto mínimo 1.74, extremo apagado 2.12. */
  --vx-serie-oscuro-1:      #F2F2EF;
  --vx-serie-oscuro-2:      #C4C4C1;
  --vx-serie-oscuro-3:      #94948F;
  --vx-serie-oscuro-4:      #6B6B68;
  --vx-serie-oscuro-5:      #454543;

  /* ---------- RAMPA DE MAPA · ÁMBAR ---------- */
  /* Para coropletos en todos los medios. Eje cálido con croma que se detiene en umbra (el rojo insinúa alarma). Monótona en luminancia también bajo protanopia, deuteranopia y tritanopia; paso mínimo 1.26×; paso 1 contra el fondo 1.34:1. El azul queda para la selección, no para el dato. */
  --vx-mapa-1:              #EBCE86;
  --vx-mapa-2:              #DCAC42;
  --vx-mapa-3:              #C0821C;
  --vx-mapa-4:              #94571A;
  --vx-mapa-5:              #5A3111;

  /* ---------- RAMPA DE MAPA · ÁMBAR SOBRE OSCURO ---------- */
  /* Invertida: crece hacia la luz sobre Deep Void. Paso mínimo 1.47×. */
  --vx-mapa-oscuro-1:       #3A270F;
  --vx-mapa-oscuro-2:       #654015;
  --vx-mapa-oscuro-3:       #9E661E;
  --vx-mapa-oscuro-4:       #CE9836;
  --vx-mapa-oscuro-5:       #EFCB80;

  /* ---------- DIVERGENTE · SE CONTRAE ↔ CRECE ---------- */
  /* Magnitudes con signo. Polos por tono (pizarra fría / ámbar), no por luminancia: se conservan en daltonismo rojo-verde. Salvedad: en impresión a blanco y negro los polos se igualan. El polo positivo NO es el azul de señal. */
  --vx-div-neg-2:           #4F6084;  /* se contrae fuerte */
  --vx-div-neg-1:           #B9C3D3;
  --vx-div-0:               #D8D8D2;  /* plano */
  --vx-div-pos-1:           #E8C878;
  --vx-div-pos-2:           #A96C16;  /* crece fuerte */

  /* ---------- DIVERGENTE SOBRE OSCURO ---------- */
  --vx-div-oscuro-neg-2:    #A8B6CE;
  --vx-div-oscuro-neg-1:    #46556E;
  --vx-div-oscuro-0:        #33332F;
  --vx-div-oscuro-pos-1:    #6E4716;
  --vx-div-oscuro-pos-2:    #D9A445;

  /* ---------- ACENTOS DE EXCEPCIÓN ---------- */
  /* Únicos colores fuera de la paleta. SÓLO cuando una pieza compara regiones y el color identifica a una (uno por región, nunca por variedad), o --vx-accent-warn para un deterioro que el texto ya justificó. Nunca para dirección (sube/baja), nunca decorativos. Una pieza que no compara regiones no los toca. */
  --vx-accent-mx:           #1F8A4A;  /* México */
  --vx-accent-cn:           #E0392C;  /* China */
  --vx-accent-eu:           #8A6D00;  /* Unión Europea (dorado oscuro: el amarillo #FFCC00 daba 1.3:1 sobre Warm Concrete) */
  --vx-accent-us:           #4A4A4A;  /* Estados Unidos (neutro institucional) */
  --vx-accent-br:           #A8541F;  /* Brasil (naranja quemado: el verde anterior se confundía con México, 39.7 de distancia RGB) */
  --vx-accent-warn:         #E66A1F;  /* deterioro justificado por el texto */

  /* ---------- TIPOGRAFÍA ---------- */
  --vx-font-display:        'Archivo', 'Inter', system-ui, -apple-system, Arial, sans-serif;  /* documento e impresión, sólo titulares y cifras hero: Archivo variable (OFL) a ancho 104 y peso 800 a 900, de parentesco con el logotipo ancho; Inter queda para cuerpo, tablas y cifras tabulares (decisión B1, v1.3.0). Helvetica Neue Black rompe glifos en lectores PDF de Windows. */
  --vx-font-text:           'Inter', system-ui, -apple-system, Arial, sans-serif;
  --vx-weight-display:      900;
  --vx-font-screen-display: 'Inter Tight', 'Inter', system-ui, sans-serif;  /* pantalla rasterizada y apps: misma superfamilia con métricas cerradas. Nunca en un PDF. */
  --vx-font-screen-num:     'Inter Tight', 'Inter', system-ui, sans-serif;

  /* ---------- EL PUNTO · diámetros canónicos ---------- */
  --vx-pulse-inline:        1.6mm;  /* junto al wordmark */
  --vx-pulse-hero:          13mm;  /* spine de portada C */
  --vx-pulse-inline-deck:   16px;  /* NO es un cuarto tamaño: es --vx-pulse-inline expresado en px para el lienzo 16:9 de 1920. Sale de los 8–9px que el brief §1 fija para pantalla sobre su lienzo de 1080: 9 × (1920/1080) = 16 exacto. */
  --vx-pulse-hero-deck:     112px;  /* NO es un quinto tamaño: es --vx-pulse-hero en px para el mismo lienzo. 13mm sobre el ancho de carta (215.9mm) es 6.02%; 6.02% de 1920 es 115.6, y 112 es el múltiplo de la base de 8px más cercano. Una vez por deck, en la portada. */
}
/* <<< FIN GENERADO */

:root {
  /* ---------- TIPOGRAFÍA DE PANTALLA ----------
     Una sola superfamilia. Inter Tight para display, Inter para texto.
     Sobrescribe el display de documento que trae el bloque generado. */
  --vx-font-display:  var(--vx-font-screen-display);
  --vx-font-text:     'Inter', system-ui, -apple-system, sans-serif;

  /* ---------- ESCALA DE DATOS ORDINAL ----------
     El azul marca el extremo que importa; el resto es la serie de tinta. */
  --vx-scale-1:       var(--vx-signal-core);
  --vx-scale-2:       var(--vx-serie-2);
  --vx-scale-3:       var(--vx-serie-3);
  --vx-scale-4:       var(--vx-serie-4);
  --vx-scale-5:       var(--vx-serie-5);

  /* ---------- GEOMETRÍA ----------
     Radio 0 en todo el sistema. El único círculo perfecto es el Punto. */
  --vx-radius:        0;
  --vx-space:         4px;
}

/* ============================================================
   SUPERFICIE BASE
   Fondo plano. Nunca blanco puro, nunca gradiente, nunca textura.
   ============================================================ */

/* Las apps que cargan Tailwind traen su propio preflight, pero este
   sistema también se usa sin él. Sin esto, el margen de 8px del body
   mete una barra de scroll en cualquier layout de alto completo, y el
   borde de un contenedor lo desborda por fuera de su caja. */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--vx-warm-concrete);
  color: var(--vx-ink-body);
  font-family: var(--vx-font-text);
  -webkit-font-smoothing: antialiased;
}

html.dark, html.dark body {
  background: var(--vx-deep-void);
  color: var(--vx-on-dark-2);
}

/* ============================================================
   TIPOGRAFÍA
   Sentence case. Los titulares NO van en mayúsculas.
   Sólo el eyebrow estructural lleva caja alta.
   ============================================================ */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--vx-font-display);
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.02em;
  color: var(--vx-ink);
}

html.dark h1, html.dark h2, html.dark h3,
html.dark h4, html.dark h5, html.dark h6 {
  color: var(--vx-on-dark);
}

/* Dato hero. La relación contra su etiqueta debe acercarse a 8:1. */
.vx-hero-num {
  font-family: var(--vx-font-display);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
  line-height: 0.9;
  color: var(--vx-ink);
}
html.dark .vx-hero-num { color: var(--vx-on-dark); }

/* Eyebrow estructural — el único uso aprobado de caja alta. */
.vx-eyebrow {
  font-family: var(--vx-font-text);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--vx-ink-muted);
}
html.dark .vx-eyebrow { color: var(--vx-on-dark-3); }

table, .vx-num, [data-vx-num], .tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   EL PUNTO
   Único círculo perfecto del sistema. Nunca cambia de color,
   nunca se agranda, nunca se elimina.
   ============================================================ */

.vx-pulse {
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: var(--vx-signal-core);
  flex: none;
}

/* ============================================================
   SUPERFICIES DE PANEL
   `glass-panel` y `glass-card` conservan el nombre porque el
   marcado existente los usa, pero ya no son vidrio: son
   superficies planas delimitadas por un filete de 1px.
   Sin blur, sin transparencia, sin radio, sin sombra.
   ============================================================ */

.glass-panel, .vx-panel {
  background: var(--vx-warm-concrete);
  border: 1px solid var(--vx-line-light);
  border-radius: 0;
  backdrop-filter: none;
  box-shadow: none;
  color: var(--vx-ink-body);
}

html.dark .glass-panel, html.dark .vx-panel {
  background: var(--vx-raised);
  border-color: var(--vx-line-dark);
  color: var(--vx-on-dark-2);
}

.glass-card, .vx-surface {
  background: var(--vx-surface-sunken);
  border: 1px solid var(--vx-line-light);
  border-radius: 0;
  backdrop-filter: none;
  box-shadow: none;
}

html.dark .glass-card, html.dark .vx-surface {
  background: var(--vx-raised);
  border-color: var(--vx-line-dark);
}

/* El bloque que manda. Uno por pieza — el dato hero va aquí.
   Es el único elemento con fondo azul sólido permitido. */
.vx-block-signal {
  background: var(--vx-signal-core);
  color: var(--vx-blanco);
  border: none;
  border-radius: 0;
}

/* ============================================================
   CONTROLES
   ============================================================ */

.vx-btn {
  font-family: var(--vx-font-text);
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.01em;
  border-radius: 0;
  border: 1px solid transparent;
  padding: 0.625rem 1.25rem;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
  cursor: pointer;
}

.vx-btn--primary {
  background: var(--vx-signal-core);
  color: var(--vx-blanco);
}
.vx-btn--primary:hover  { background: var(--vx-signal-hover); }
.vx-btn--primary:active { background: var(--vx-signal-press); }

.vx-btn--ghost {
  background: transparent;
  color: var(--vx-ink-body);
  border-color: var(--vx-line-light);
}
.vx-btn--ghost:hover { border-color: var(--vx-ink); color: var(--vx-ink); }

html.dark .vx-btn--ghost {
  color: var(--vx-on-dark-2);
  border-color: var(--vx-line-dark);
}
html.dark .vx-btn--ghost:hover { border-color: var(--vx-on-dark); color: var(--vx-on-dark); }

.vx-input, input[type="text"], input[type="number"], textarea, select {
  border-radius: 0;
  font-family: var(--vx-font-text);
}

:focus-visible {
  outline: 2px solid var(--vx-signal-core);
  outline-offset: 2px;
}

::selection {
  background: var(--vx-signal-core);
  color: var(--vx-blanco);
}

/* ============================================================
   ALIAS CONTEXTUALES Y ESCALA DE DATOS

   Un componente no puede escribir `var(--vx-ink)` a secas: el
   mismo componente vive sobre claro y sobre oscuro. Estos alias
   apuntan al token correcto según el tema, y son lo único que
   los componentes consumen. No son colores nuevos — son punteros.

   La escala ordinal se invierte en luminancia sobre Deep Void:
   mismo orden semántico, distinta L*. Validada con los criterios
   del núcleo — monotonía en L*, salto mínimo 1.74 (se pide 1.35)
   y extremo apagado en 2.12 sobre el fondo (se pide 2.0).

   Origen: entrega de Claude Design, agosto 2026.
   ============================================================ */

:root {
  /* El banner necesita su propia superficie: reusando la hundida
     quedaba a 10 puntos del lienzo y no se leía como zona aparte. */
  --vx-flanco-sf: var(--vx-surface-zona);
  --vx-sf:      var(--vx-warm-concrete);   /* superficie base   */
  --vx-sf-2:    var(--vx-surface-sunken);  /* hundida / elevada */
  --vx-ln:      var(--vx-line-light);      /* filete            */
  --vx-tx:      var(--vx-ink);             /* titular / cifra   */
  --vx-tx-2:    var(--vx-ink-body);        /* cuerpo            */
  --vx-tx-3:    var(--vx-ink-muted);       /* eyebrow, unidad   */
  --vx-tx-4:    var(--vx-ink-faint);       /* extremo de escala */

  /* Escala ordinal de datos, extremo azul → extremo tinta.
     Sobre claro apunta a --vx-scale-*, que es el juego canónico:
     una sola fuente de verdad, no dos listas de hexes que alguien
     tenga que mantener sincronizadas. */
  --vx-esc-1:   var(--vx-scale-1);
  --vx-esc-2:   var(--vx-scale-2);
  --vx-esc-3:   var(--vx-scale-3);
  --vx-esc-4:   var(--vx-scale-4);
  --vx-esc-5:   var(--vx-scale-5);
  --vx-esc-0:   transparent;               /* sin dato          */

  /* ---------- RAMPA SECUENCIAL DEL MAPA · ÁMBAR ----------
     La escala ordinal (--vx-esc-*) no sirve aquí: su primer paso es
     el azul de señal y el resto no es monótono. Una coropleta pide
     una rampa que crezca sin saltos.

     Fue gris cálido y estaba mal: era la MISMA escala de tintas de
     la interfaz, así que el mapa se pintaba con el material del
     texto y no se leía como dato. Esta rampa se queda en el eje
     cálido —el del Warm Concrete— pero con croma, y se detiene en
     umbra en vez de seguir hasta el rojo: un quintil alto en rojo
     insinúa alarma, y el color no debe traer un juicio de contrabando.

     Medido (ver el audit en el commit):
     · monotónica en luminancia, y también bajo protanopia,
       deuteranopia y tritanopia — si se desordenara ahí, el mapa
       mentiría para el 8% de los hombres;
     · paso mínimo entre clases 1.26×, resto 1.37–1.93×;
     · paso 1 contra el fondo 1.34:1 (antes 1.19, y por eso el
       quintil bajo se confundía con la página).

     El azul sigue siendo de la selección, no del dato: ámbar contra
     azul es además el eje que SÍ se conserva en el daltonismo
     rojo-verde, así que el anillo de selección nunca se pierde. */

  /* ---------- ESCALA DIVERGENTE · CRECIMIENTO ----------
     Para magnitudes con signo (se contrae ↔ crece). No es la rampa
     del mapa: aquélla es secuencial y aquí hacen falta dos polos.

     Sustituye a un rgba(244,63,94) —rojo— que estaba prohibido por
     el brief. El segundo polo NO es el azul de señal: en un treemap
     donde la mayoría de los sectores crece, medio gráfico quedaría
     azul y el azul dejaría de significar «esto está seleccionado».
     Se usa una pizarra fría, del mismo lado del espectro pero sin
     croma de señal.

     Cinco clases, no siete: en oscuro hay una zona muerta de
     luminancia (L 0.13–0.29) donde un tono no admite ni texto negro
     ni blanco a 4.5:1, y con siete clases era inevitable pisarla.
     El treemap escribe el nombre del sector ENCIMA del tono, así
     que eso habría sido texto ilegible. Medido: cero etiquetas
     ilegibles, la peor a 4.57:1.

     Los dos polos coinciden casi en luminancia a propósito —una
     divergente es simétrica— y se separan por tono, que es lo que
     se conserva bajo daltonismo rojo-verde. Salvedad: en impresión
     a blanco y negro los dos polos se igualan. */

  --vx-celda-alto: 18px;                   /* fila de MapaCalor */
}

html.dark {
  --vx-flanco-sf: var(--vx-surface-zona-oscura);
  --vx-sf:      var(--vx-deep-void);
  --vx-sf-2:    var(--vx-raised);
  --vx-ln:      var(--vx-line-dark);
  --vx-tx:      var(--vx-on-dark);
  --vx-tx-2:    var(--vx-on-dark-2);
  --vx-tx-3:    var(--vx-on-dark-3);
  --vx-tx-4:    var(--vx-on-dark-4);

  /* En oscuro la rampa se invierte: sobre Deep Void crece hacia la
     luz, del umbra apagado al ámbar encendido. Mismo orden
     semántico, distinta luminancia. Auditada igual que la clara:
     monotónica en las tres dicromatías, paso mínimo 1.47×. */
  --vx-mapa-1:  var(--vx-mapa-oscuro-1);
  --vx-mapa-2:  var(--vx-mapa-oscuro-2);
  --vx-mapa-3:  var(--vx-mapa-oscuro-3);
  --vx-mapa-4:  var(--vx-mapa-oscuro-4);
  --vx-mapa-5:  var(--vx-mapa-oscuro-5);

  /* La divergente también se invierte sobre Deep Void. */
  --vx-div-neg-2: var(--vx-div-oscuro-neg-2);
  --vx-div-neg-1: var(--vx-div-oscuro-neg-1);
  --vx-div-0:     var(--vx-div-oscuro-0);
  --vx-div-pos-1: var(--vx-div-oscuro-pos-1);
  --vx-div-pos-2: var(--vx-div-oscuro-pos-2);

  --vx-esc-2:   var(--vx-serie-oscuro-2);
  --vx-esc-3:   var(--vx-serie-oscuro-3);
  --vx-esc-4:   var(--vx-serie-oscuro-4);
  --vx-esc-5:   var(--vx-serie-oscuro-5);
}

/* ============================================================
   SHELL DE APLICACIÓN
   Lo que separa una app de un documento.

   Un documento tiene columna de lectura, titular con bajada y
   márgenes de hoja. Una app tiene cromo: barra fija arriba,
   lienzo que ocupa la pantalla y no la desborda, barra de
   estado abajo. El scroll vive dentro del lienzo, no en la
   página — la página nunca se mueve.

   Uso mínimo:
     <body>
       <div class="vx-app">
         <header class="vx-barra">…</header>
         <main   class="vx-lienzo">…</main>
         <footer class="vx-pie">…</footer>
       </div>
     </body>
   ============================================================ */

.vx-app {
  height: 100dvh;
  display: grid;
  grid-template-rows: var(--vx-barra-alto, 60px) 1fr var(--vx-pie-alto, 34px);
  overflow: hidden;
}
/* Sin barra de estado. */
.vx-app--sin-pie { grid-template-rows: var(--vx-barra-alto, 60px) 1fr; }

/* Sólo lienzo: ni barra superior ni pie.
   La retícula de `.vx-app` reserva TRES filas y el padre recorta lo
   que sobra, así que una pantalla que dibuje un solo hijo lo mete en
   la fila de 60 px y desaparece —pasó con el comparador: se veía el
   titular cortado a media letra y nada debajo—. */
.vx-app--solo-lienzo { grid-template-rows: 1fr; }

/* ---------- BARRA SUPERIOR ---------- */

.vx-barra {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--vx-line-light);
  background: var(--vx-warm-concrete);
}
html.dark .vx-barra {
  border-color: var(--vx-line-dark);
  background: var(--vx-deep-void);
}

/* El logo va en la barra y reemplaza al texto "VEXTO". */
.vx-barra__logo { height: 21px; width: auto; display: block; }

/* Filete vertical. La estructura se hace con líneas, no con cajas. */
.vx-div {
  width: 1px;
  height: 20px;
  background: var(--vx-line-light);
  flex: none;
}
html.dark .vx-div { background: var(--vx-line-dark); }

/* Nombre de la sección activa. Sentence case, nunca caja alta. */
.vx-barra__seccion {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: -.01em;
  color: var(--vx-ink);
  white-space: nowrap;
}
html.dark .vx-barra__seccion { color: var(--vx-on-dark); }

/* Aviso de que lo que se ve todavía es del área anterior. Va en azul
   de señal porque advierte, y en el peso del cuerpo porque no compite
   con el nombre de la sección. */
.vx-barra__nota {
  font-size: .72rem;
  letter-spacing: .01em;
  color: var(--vx-signal-core);
  white-space: nowrap;
}

.vx-empuje { flex: 1; }

.vx-barra__accion {
  background: none;
  border: none;
  padding: .35rem .5rem;
  font: inherit;
  font-size: .8125rem;
  color: var(--vx-ink-muted);
  cursor: pointer;
  white-space: nowrap;
}
.vx-barra__accion:hover { color: var(--vx-ink); }
html.dark .vx-barra__accion { color: var(--vx-on-dark-3); }
html.dark .vx-barra__accion:hover { color: var(--vx-on-dark); }

/* ---------- LIENZO ---------- */

.vx-lienzo { overflow: auto; padding: 1.25rem; }
.vx-lienzo--sin-aire { padding: 0; }

/* ---------- BARRA DE ESTADO ---------- */

.vx-pie {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 1.25rem;
  border-top: 1px solid var(--vx-line-light);
  background: var(--vx-warm-concrete);
  font-size: .8125rem;
  color: var(--vx-ink-muted);
}
html.dark .vx-pie {
  border-color: var(--vx-line-dark);
  background: var(--vx-deep-void);
  color: var(--vx-on-dark-3);
}
.vx-pie__dato { font-variant-numeric: tabular-nums; }

/* ---------- MATRIZ ----------
   La alternativa VEXTO a la retícula de tarjetas, que el brief
   prohíbe. El fondo de la matriz ES la línea y cada celda la
   tapa: las juntas quedan como filetes continuos de 1px, sin
   bordes dobles y sin tarjetas flotando.
   ------------------------------------------------------------ */

.vx-matriz {
  display: grid;
  gap: 1px;
  background: var(--vx-line-light);
  border: 1px solid var(--vx-line-light);
  align-content: start;
}
html.dark .vx-matriz {
  background: var(--vx-line-dark);
  border-color: var(--vx-line-dark);
}
.vx-matriz--alto { min-height: 100%; }

.vx-celda {
  background: var(--vx-warm-concrete);
  padding: 1.4rem 1.5rem;
}
html.dark .vx-celda { background: var(--vx-deep-void); }

/* Celda navegable: hover, foco y filete de acento al entrar. */
.vx-celda--accion {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1.5rem;
  text-decoration: none;
  color: inherit;
  transition: background-color .12s ease;
}
.vx-celda--accion:hover { background: var(--vx-surface-sunken); }
html.dark .vx-celda--accion:hover { background: var(--vx-raised); }

.vx-celda--accion::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--vx-signal-core);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform .14s ease;
}
.vx-celda--accion:hover::before,
.vx-celda--accion:focus-visible::before { transform: scaleY(1); }

/* ---------- CELDA DE NAVEGACIÓN ----------
   Contenido de una celda que lleva a otra pantalla. Lo usan el hub
   (herramientas) y el selector de módulos del dashboard: dos
   superficies con el mismo trabajo, así que el patrón vive aquí y
   no duplicado en cada una.

   La jerarquía la carga la escala, nunca el color: sin contraste de
   tamaño entre el nombre y su etiqueta, la rejilla se lee como
   plantilla.
   ------------------------------------------------------------ */

.vx-celda__alto { display: flex; align-items: center; gap: .6rem; }

.vx-celda__etiqueta {
  font-size: .75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--vx-tx-3);
}

.vx-celda__nombre {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 1.45rem;
  line-height: 1.05;
  letter-spacing: -.025em;
  color: var(--vx-tx);
  margin: 0;
}

.vx-celda__desc {
  margin: .6rem 0 0;
  font-size: .875rem;
  line-height: 1.45;
  color: var(--vx-tx-2);
  max-width: 48ch;
}

.vx-celda__pie {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  flex-wrap: wrap;
  font-size: .8125rem;
  color: var(--vx-tx-3);
}

/* "Abrir" aparece al enfocar o pasar el cursor: en reposo sería una
   instrucción repetida en cada celda. */
.vx-celda__abrir {
  margin-left: auto;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--vx-signal-core);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity .12s ease, transform .12s ease;
}
.vx-celda--accion:hover .vx-celda__abrir,
.vx-celda--accion:focus-visible .vx-celda__abrir { opacity: 1; transform: none; }
.vx-celda--accion:hover .vx-tecla {
  border-color: var(--vx-signal-core);
  color: var(--vx-signal-core);
}

/* Celda inerte: existe pero no lleva a ningún lado. */
.vx-celda[data-viva="no"] .vx-celda__nombre,
.vx-celda[data-viva="no"] .vx-celda__desc { color: var(--vx-tx-3); }

/* ---------- MATRIZ DE NAVEGACIÓN ----------
   Dos columnas y la primera celda al alto completo: el elemento que
   manda se gana la escala, en vez de que todos midan igual.
   ------------------------------------------------------------ */

.vx-matriz--nav { grid-template-columns: 1fr; }

@media (min-width: 900px) {
  .vx-matriz--nav {
    grid-template-columns: 1.35fr 1fr;
    grid-auto-rows: minmax(150px, 1fr);
  }
  .vx-matriz--nav > :first-child { grid-row: span 2; }
  .vx-matriz--nav > :first-child .vx-celda__nombre { font-size: clamp(2rem, 3.2vw, 2.9rem); }
  .vx-matriz--nav > :first-child .vx-celda__desc { font-size: .95rem; max-width: 42ch; }
}

/* ---------- TECLA ----------
   Atajo de teclado dibujado en la interfaz. Si se muestra, funciona.
   ------------------------------------------------------------ */

.vx-tecla {
  min-width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  border: 1px solid var(--vx-line-light);
  font-size: .75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--vx-ink-muted);
}
html.dark .vx-tecla { border-color: var(--vx-line-dark); color: var(--vx-on-dark-3); }

/* ---------- PUNTO APAGADO ----------
   El Punto azul nunca cambia de color. Lo que no está vivo se
   marca con un anillo hueco, no con un punto de otro color.
   ------------------------------------------------------------ */

.vx-pulse-off {
  display: inline-block;
  width: .5em;
  height: .5em;
  border-radius: 50%;
  border: 1px solid var(--vx-ink-faint);
  flex: none;
}
html.dark .vx-pulse-off { border-color: var(--vx-on-dark-3); }

/* ============================================================
   NEUTRALIZACIÓN DE PATRONES PROHIBIDOS
   El marcado heredado trae radios, blur y gradientes de las
   plantillas originales. Se anulan aquí en lugar de tocar
   cientos de líneas de componente.

   Excepción: `.rounded-full` sobrevive — es el Punto.
   ============================================================ */

[class*="rounded-"]:not(.rounded-full):not(.vx-keep-radius) {
  border-radius: 0 !important;
}

[class*="backdrop-blur"] {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

[class*="bg-gradient-"] {
  background-image: none !important;
}

/* ============================================================
   SCROLLBAR
   ============================================================ */

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--vx-ink-faint); border-radius: 0; }
::-webkit-scrollbar-thumb:hover { background: var(--vx-ink-muted); }
html.dark ::-webkit-scrollbar-thumb { background: var(--vx-on-dark-4); }
html.dark ::-webkit-scrollbar-thumb:hover { background: var(--vx-on-dark-3); }

/* ============================================================
   MOVIMIENTO
   Corto y funcional. Nada celebratorio.
   ============================================================ */

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

.animate-celebratory-pop-in,
.vx-fade-in {
  animation: vx-fade-in .18s ease-out both;
}

@keyframes rebound {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(-3px); }
}
.animate-rebound { animation: rebound .3s ease-in-out; }

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

/* ============================================================
   CONCHA CON BANNER LATERAL
   Los temas viven a la izquierda, siempre visibles; el resto de
   la pantalla es del tema seleccionado. No hay portada: entrar a
   la herramienta es ya estar en un tema.

     <div class="vx-concha">
       <nav class="vx-flanco">…</nav>
       <div class="vx-concha__cuerpo"><!-- .vx-app --></div>
     </div>
   ============================================================ */

.vx-concha {
  height: 100dvh;
  display: grid;
  grid-template-columns: var(--vx-flanco-ancho, 232px) 1fr;
  overflow: hidden;
}
/* El lienzo del tema hereda la altura de la celda, no de la ventana:
   dentro de la concha, 100dvh se desbordaría por el borde. */
.vx-concha__cuerpo { min-width: 0; overflow: hidden; }
.vx-concha__cuerpo > .vx-app { height: 100%; }

.vx-flanco {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--vx-line-light);
  /* Superficie propia. Antes compartía fondo con el tablero y no se
     leía como una zona aparte; la hundida del sistema quedaba a diez
     puntos del lienzo, que sigue siendo demasiado poco. */
  background: var(--vx-flanco-sf);
  /* Deliberadamente NO se recorta. El desplegable de municipios mide
     300 px y el banner 232: con `overflow: hidden` se le cortaban 59 px
     y los nombres quedaban partidos. La lista de temas trae su propio
     scroll, así que recortar aquí no hacía falta para nada más. */
  overflow: visible;
}
html.dark .vx-flanco { border-color: var(--vx-line-dark); }

.vx-flanco__marca {
  height: var(--vx-barra-alto, 60px);
  display: flex;
  align-items: center;
  padding: 0 1rem;
  border-bottom: 1px solid var(--vx-line-light);
  flex: none;
}
html.dark .vx-flanco__marca { border-color: var(--vx-line-dark); }

/* ---------- ÁREA DE ANÁLISIS ----------
   Va arriba de los temas: lo que está por encima de la lista
   gobierna todo lo que está por debajo. Esa posición es el
   argumento, y por eso no hay que explicarla. */

.vx-area {
  flex: none;
  /* Por encima del lienzo: de aquí cuelga el panel del desplegable. */
  position: relative;
  z-index: 20;
  padding: .875rem 1rem 1rem;
  border-bottom: 1px solid var(--vx-line-light);
}
html.dark .vx-area { border-color: var(--vx-line-dark); }

.vx-area__rotulo {
  font-size: .625rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  margin-bottom: .3rem;
}

.vx-area__actual {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.2;
  color: var(--vx-tx);
  margin-bottom: .625rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* El Punto: la selección dejó de ser el estado completo. */
.vx-area__punto {
  width: 6px; height: 6px; flex: none;
  background: var(--vx-signal-core);
}

.vx-area__alcance {
  margin-top: .5rem;
  font-size: .6875rem;
  line-height: 1.35;
  color: var(--vx-tx-3);
}

/* Los dos desplegables, uno debajo del otro y a todo el ancho. */
.vx-desps--apilado { display: flex; flex-direction: column; gap: .375rem; }
.vx-desps--apilado .vx-desp { display: flex; width: 100%; }
.vx-desps--apilado .vx-desp > .vx-filtro__et { display: none; }
/* En escritorio el desplegable de región dice solo lo que es: su texto
   cabe entero. El rótulo es para el teléfono. */
.vx-region > .vx-filtro__et { display: none; }
/* …salvo cuando se piden de vuelta. En el comparador el rótulo es lo
   que revela que cada lugar tiene SU estado. */
.vx-desps--rotulado .vx-desp { flex-direction: column; align-items: stretch; gap: .2rem; }
.vx-desps--rotulado .vx-desp > .vx-filtro__et { display: block; }
.vx-desps--rotulado { gap: .6rem; }
.vx-desps--apilado .vx-desp__disparador { width: 100%; min-width: 0; max-width: none; }
/* El panel se abre hacia el lienzo, que es hacia donde hay sitio. */
.vx-desps--apilado .vx-desp__panel { left: 0; right: auto; }

/* Desplegables de región / zona */
.vx-region {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.vx-region__select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  display: block;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 0.8125rem;
  line-height: 1.2;
  color: var(--vx-tx);
  background-color: var(--vx-flanco-sf, var(--vx-sf));
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  border: 1px solid var(--vx-ln);
  border-radius: 0;
  padding: 6px 24px 6px 10px;
  cursor: pointer;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

.vx-region__select:hover {
  border-color: var(--vx-tx-3);
}

.vx-region__select:focus {
  outline: none;
  border-color: var(--vx-tx);
}

.vx-region__select option {
  background: var(--vx-sf-2, var(--vx-sf));
  color: var(--vx-tx);
}

html.dark .vx-region__select option {
  background: var(--vx-flanco-sf);
  color: var(--vx-on-dark);
}

.vx-region__aviso {
  margin-top: 4px;
  font-size: 0.6875rem;
  color: var(--vx-signal-core);
}


/* ---------- TEMAS ---------- */

.vx-flanco__temas { flex: 1; overflow-y: auto; padding: .75rem .625rem 1rem; }

.vx-flanco__rotulo {
  padding: .5rem .375rem .375rem;
  font-size: .625rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
}
.vx-flanco__rotulo--tenue { margin-top: .5rem; opacity: .7; }

/* Botón con superficie: sobre el fondo hundido del banner, el tema
   se levanta. Es lo que lo separa de una lista de enlaces. */
.vx-tema {
  position: relative;
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  padding: .5rem .625rem;
  margin-bottom: 2px;
  font: inherit;
  font-size: .875rem;
  line-height: 1.25;
  color: var(--vx-tx-2);
  cursor: pointer;
}
.vx-tema:hover {
  background: var(--vx-sf);
  border-color: var(--vx-ln);
  color: var(--vx-tx);
}
.vx-tema__nombre { flex: 1; min-width: 0; }

/* El tema activo toma la superficie del lienzo: el botón y el
   tablero quedan del mismo color, y se lee como una pestaña. */
.vx-tema[aria-current="true"] {
  background: var(--vx-sf);
  border-color: var(--vx-ln);
  color: var(--vx-tx);
  font-weight: 600;
}
.vx-tema[aria-current="true"]::before {
  content: "";
  position: absolute;
  left: -1px; top: -1px; bottom: -1px;
  width: 2px;
  background: var(--vx-signal-core);
}

.vx-tema[disabled] { cursor: default; opacity: .4; }
.vx-tema[disabled]:hover { background: transparent; border-color: transparent; color: var(--vx-tx-2); }

.vx-tema__tecla {
  flex: none;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--vx-tx-3);
  border: 1px solid var(--vx-ln);
  padding: 0 4px;
  line-height: 1.4;
}

.vx-flanco__pie {
  flex: none;
  padding: .75rem 1rem;
  border-top: 1px solid var(--vx-line-light);
  font-size: .6875rem;
}

/* El sello del paquete en ejecución. Al 55% de opacidad: tiene que
   poder leerse cuando se busca y desaparecer cuando no. */
.vx-flanco__sello {
  display: inline-block;
  margin-top: .25rem;
  font-size: .625rem;
  opacity: .55;
  letter-spacing: .02em;
}

.vx-concha__panel {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.vx-flanco__tema-movil { display: none; }

/* En pantalla angosta el banner se vuelve una barra superior compacta */
@media (max-width: 860px) {
  .vx-concha {
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .vx-concha__cuerpo {
    flex: 1 1 auto;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  .vx-concha__panel {
    flex: 1 1 auto;
    min-height: 0;
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .vx-concha .vx-app {
    height: 100% !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    grid-template-rows: none !important;
  }

  .vx-flanco {
    display: flex;
    flex-direction: column;
    border-right: none;
    border-bottom: 1px solid var(--vx-line-light);
    background: var(--vx-flanco-sf);
    flex: none;
    z-index: 30;
  }
  html.dark .vx-flanco { border-color: var(--vx-line-dark); }

  /* Fila 1: Logo + Selector */
  .vx-flanco__fila-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.375rem 0.75rem;
    gap: 0.75rem;
    min-width: 0;
  }

  .vx-flanco__marca {
    height: 38px;
    padding: 0;
    border-bottom: none;
    flex: none;
  }
  .vx-flanco__marca img {
    height: 18px !important;
    width: auto;
  }

  .vx-area {
    border-bottom: none;
    padding: 0;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-end;
  }

  .vx-area__rotulo, .vx-area__alcance, .vx-area__actual { display: none; }
  /* El reparto de los cuatro controles del banner vive más abajo, en
     su propio bloque: hacía falta más especificidad de la que se puede
     tener aquí. */

  /* Fila 2 (Móvil): Botones de temas */
  .vx-flanco__temas {
    flex: none;
    display: flex;
    align-items: center;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding: 0.25rem 0.5rem;
    gap: 4px;
    border-top: 1px solid var(--vx-line-light);
    scrollbar-width: none;
  }
  .vx-flanco__temas::-webkit-scrollbar { display: none; }
  html.dark .vx-flanco__temas { border-color: var(--vx-line-dark); }

  .vx-flanco__rotulo, .vx-flanco__pie { display: none; }
  .vx-tema {
    width: auto;
    white-space: nowrap;
    margin: 0;
    flex: none;
    padding: 4px 8px;
    font-size: 0.75rem;
    height: 28px;
  }
  .vx-tema__tecla { display: none; }

  /* Ocultar barra redundante del módulo sólo dentro del dashboard */
  .vx-concha .vx-barra {
    display: none !important;
  }

  .vx-barra {
    height: 48px;
    padding: 0 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  /* Sub-navegación compacta */
  .vx-modulos {
    flex: none;
    display: flex;
    overflow-x: auto;
    padding: 0.25rem 0.5rem;
    gap: 4px;
    border-bottom: 1px solid var(--vx-line-light);
    scrollbar-width: none;
  }
  .vx-modulos::-webkit-scrollbar { display: none; }
  html.dark .vx-modulos { border-color: var(--vx-line-dark); }
  .vx-modulos__op {
    padding: 4px 8px;
    font-size: 0.75rem;
    white-space: nowrap;
  }

  /* Lienzo con scroll limpio para todos los tableros y pantallas */
  .vx-lienzo,
  .vx-concha .vx-lienzo {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: auto !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    padding: 0.75rem !important;
    width: 100% !important;
    box-sizing: border-box !important;
    -webkit-overflow-scrolling: touch;
  }

  .vx-pie { display: none; }
}

/* El mapa del banner: filete arriba para separarlo de los controles. */
.vx-area__mapa {
  margin-top: .625rem;
  padding-top: .625rem;
  border-top: 1px solid var(--vx-line-light);
}
html.dark .vx-area__mapa { border-color: var(--vx-line-dark); }


/* ============================================================
   EL BANNER EN UN TELÉFONO

   Con 375 px de ancho, los cuatro controles del área —región de
   estados, estado, zona de municipios, municipio— compartían renglón
   con el logotipo. Cada uno quedaba en 64 px y el tablero abría con
   «Si…», «Ver…», «Si…», «Tod…»: cuatro botones que no dicen nada y en
   los que no se sabe qué se va a elegir.

   Se resuelve dándoles su propio espacio: el logotipo sube a un
   renglón suyo y los controles bajan a una rejilla de dos columnas,
   emparejados como se usan —la región con su estado, la zona con su
   municipio—. Cuesta unos 80 px de alto y es la diferencia entre
   poder elegir y no.

   POR QUÉ TODO VA PREFIJADO CON `.vx-flanco`. Las reglas del bloque
   móvil de arriba las pisaba `vexto-charts.css`, que carga después con
   la misma especificidad: `.vx-desp__sub-varios { display: none }`
   perdía contra un `display: inline-flex` posterior y la casilla
   seguía apareciendo. Un ancestro más en el selector gana sin depender
   del orden de carga.
   ============================================================ */
@media (max-width: 860px) {
  .vx-flanco .vx-flanco__fila-top {
    display: block;
    padding: 0.5rem 0.75rem 0.625rem;
  }

  .vx-flanco .vx-flanco__marca {
    height: auto;
    margin-bottom: 0.5rem;
  }

  .vx-flanco .vx-area { display: block; }

  .vx-flanco .vx-desps--apilado {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.375rem 0.5rem;
  }

  .vx-flanco .vx-desps--apilado > * {
    min-width: 0;
    max-width: none;
    width: 100%;
    flex: none;
  }

  .vx-flanco .vx-desps--apilado .vx-desp__disparador,
  .vx-flanco .vx-desps--apilado .vx-region__select {
    width: 100%;
    min-width: 0;
    max-width: none;
    height: 36px;
    padding: 4px 8px;
    font-size: 0.8125rem;
  }

  /* Los rótulos vuelven. Cuatro controles idénticos y truncados no
     dicen cuál es el estado y cuál el municipio; con dos palabras
     encima, sí. */
  .vx-flanco .vx-desps--apilado .vx-desp > .vx-filtro__et,
  .vx-flanco .vx-desps--apilado .vx-region > .vx-filtro__et {
    display: block;
    font-size: 9px;
    line-height: 1.2;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--vx-tx-3);
    margin-bottom: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* El panel se abre a lo ancho de la pantalla y no del disparador:
     con 170 px, «Coatzacoalcos · ZM · 3 municipios» no cabe. Se ancla
     al filo que le queda cerca para no salirse por el otro lado. */
  .vx-flanco .vx-desps--apilado .vx-desp__panel {
    width: calc(100vw - 1.5rem);
    max-width: calc(100vw - 1.5rem);
  }
  .vx-flanco .vx-desps--apilado > *:nth-child(odd) .vx-desp__panel {
    left: 0;
    right: auto;
  }
  .vx-flanco .vx-desps--apilado > *:nth-child(even) .vx-desp__panel {
    left: auto;
    right: 0;
  }

  /* La casilla de «seleccionar varios» ya vive DENTRO del panel; aquí
     fuera sólo roba un renglón y parte la rejilla. */
  .vx-flanco .vx-desp__sub-varios { display: none; }

  /* La lista, más alta: en un teléfono el panel es lo único en
     pantalla y 232 px obligan a raspar entre 212 municipios. */
  .vx-flanco .vx-desp__lista { max-height: 50vh; }
}

/* Un grupo de botones pegados —el control segmentado— no puede
   envolver: al pasar a la segunda línea, el primero de abajo pierde su
   filete izquierdo porque `first:border-l` sólo alcanza al primero de
   todos, y el grupo se lee partido. En pantalla angosta se desplaza en
   horizontal, como las pestañas de tema. */
.vx-tira { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.vx-tira::-webkit-scrollbar { display: none; }
.vx-tira > * { flex: none; }
