/* ============================================================
   VEXTO — CAPA DE VISUALIZACIÓN Y PATRONES DE APLICACIÓN
   Extensión de `vexto-app.css`. No redefine nada del núcleo:
   sólo añade lo que una gráfica y un patrón de app necesitan
   y el shell no cubre.

   Requisito: cargar `vexto-app.css` ANTES que este archivo.
   El modo oscuro se activa con la clase `dark` en <html>,
   igual que en el shell.

   Versión 1.0 · 2026-08-13
   ============================================================ */

/* ------------------------------------------------------------
   1. ALIAS CONTEXTUALES
   Movidos a `vexto-app.css`: son tokens, y los tokens viven en
   el núcleo para que también los use el shell y el hub, que no
   cargan esta capa. Aquí sólo quedan componentes.
   ------------------------------------------------------------ */

/* ------------------------------------------------------------
   2. MARCO DE GRÁFICA
   Toda gráfica del sistema vive en el mismo marco: eyebrow con
   la unidad, título, cifra de contexto opcional, lienzo y pie.
   El marco no dibuja caja: separa con filetes y aire.
   ------------------------------------------------------------ */

.vx-g {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--vx-sf);
  color: var(--vx-tx-2);
}

.vx-g__cab {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 0 0 10px;
  border-bottom: 1px solid var(--vx-ln);
}

.vx-g__titulo {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -.01em;
  color: var(--vx-tx);
  margin: 0;
}

/* La unidad viaja siempre con la gráfica. Un medidor sin unidad
   no se publica. */
.vx-g__unidad {
  font-size: 12px;
  color: var(--vx-tx-3);
  font-variant-numeric: tabular-nums;
  margin-left: auto;
  white-space: nowrap;
}

.vx-g__lienzo { padding: 14px 0 0; min-width: 0; }

.vx-g__pie {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  padding-top: 10px;
  margin-top: auto;
  font-size: 12px;
  color: var(--vx-tx-3);
}

/* Leyenda: cuadro de 8px + etiqueta. Sin pills, sin redondeo. */
.vx-leyenda { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.vx-leyenda__it { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--vx-tx-2); }
.vx-leyenda__sw { width: 8px; height: 8px; flex: none; }

/* Ejes y rejilla. Trazo de 1px, nunca más de un tono. */
.vx-eje { font-size: 11px; fill: var(--vx-tx-3); font-variant-numeric: tabular-nums; }
.vx-rejilla { stroke: var(--vx-ln); stroke-width: 1; shape-rendering: crispEdges; }

/* ------------------------------------------------------------
   3. MAPA DE CALOR
   Matriz municipio × periodo. La fila es la unidad de lectura:
   el nombre se congela a la izquierda y el cuerpo hace scroll.
   ------------------------------------------------------------ */

.vx-mapa {
  display: grid;
  grid-template-columns: 170px 1fr;
  border-top: 1px solid var(--vx-ln);
  font-variant-numeric: tabular-nums;
}

.vx-mapa__cols {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 1px;
  font-size: 11px;
  color: var(--vx-tx-3);
  text-align: center;
  padding-bottom: 6px;
}

.vx-mapa__cuerpo {
  display: contents;
}

.vx-mapa__scroll {
  max-height: 340px;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

.vx-mapa__fila {
  display: grid;
  grid-template-columns: 170px 1fr;
  align-items: stretch;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-mapa__fila:hover { background: var(--vx-sf-2); }

.vx-mapa__etq {
  font-size: 12px;
  color: var(--vx-tx-2);
  padding: 0 10px 0 0;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: var(--vx-celda-alto);
}
.vx-mapa__fila--sel .vx-mapa__etq { color: var(--vx-tx); font-weight: 600; }

.vx-mapa__celdas {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 1px;
  padding: 2px 0;
}

.vx-mapa__c {
  min-height: var(--vx-celda-alto);
  background: var(--vx-esc-5);
  cursor: pointer;
  position: relative;
}
/* La matriz usa la RAMPA SECUENCIAL, no la escala ordinal. La
   ordinal empieza en el azul de señal y no es monótona: servía para
   distinguir series, no para representar magnitud. Aquí la celda
   codifica cuánto hay, así que necesita crecer sin saltos —y de paso
   deja de verse como gris de texto, que era el material equivocado—.
   `--vx-mapa-*` ya se invierte sola entre temas. */
.vx-mapa__c[data-n="0"] { background: var(--vx-esc-0); box-shadow: inset 0 0 0 1px var(--vx-ln); }
.vx-mapa__c[data-n="1"] { background: var(--vx-mapa-1); }
.vx-mapa__c[data-n="2"] { background: var(--vx-mapa-2); }
.vx-mapa__c[data-n="3"] { background: var(--vx-mapa-3); }
.vx-mapa__c[data-n="4"] { background: var(--vx-mapa-4); }
.vx-mapa__c[data-n="5"] { background: var(--vx-mapa-5); }

/* Brote: el valor se sale de su propia historia. No cambia de
   color — el sistema tiene un solo azul — se marca con corte. */
.vx-mapa__c[data-brote="1"]::after {
  content: '';
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px var(--vx-sf), inset 0 0 0 2px var(--vx-signal-core);
}

.vx-mapa__c:hover { outline: 1px solid var(--vx-tx); outline-offset: -1px; z-index: 1; }

/* ------------------------------------------------------------
   4. TABLA COMPARATIVA
   Densa, ordenable, cifras a la derecha, etiquetas a la izquierda.
   ------------------------------------------------------------ */

.vx-tabla {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}
.vx-tabla th, .vx-tabla td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--vx-ln);
  text-align: right;
  white-space: nowrap;
}
.vx-tabla th:first-child, .vx-tabla td:first-child { text-align: left; padding-left: 0; }
.vx-tabla td:last-child, .vx-tabla th:last-child { padding-right: 0; }

.vx-tabla thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--vx-sf);
  font-family: var(--vx-font-text);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--vx-tx-3);
  cursor: pointer;
  user-select: none;
  border-bottom-color: var(--vx-tx-4);
}
.vx-tabla thead th:hover { color: var(--vx-tx); }
.vx-tabla thead th[aria-sort]:not([aria-sort="none"]) { color: var(--vx-tx); }

/* El indicador de orden es un carácter, no un ícono. */
.vx-tabla__ord { margin-left: 6px; color: var(--vx-signal-core); }

.vx-tabla tbody tr:hover { background: var(--vx-sf-2); }
.vx-tabla tbody td:first-child { color: var(--vx-tx); }
.vx-tabla__num { color: var(--vx-tx-2); }
.vx-tabla__num--fuerte { color: var(--vx-tx); font-weight: 600; }

/* La dirección la carga el signo, nunca el color. */
.vx-var { color: var(--vx-tx-2); font-variant-numeric: tabular-nums; }
.vx-var--acento { color: var(--vx-tx); font-weight: 600; }

/* Contenedor de scroll horizontal. Debajo de 900px la tabla no se
   apila ni encoge la letra: rueda, con la etiqueta anclada. */
.vx-tabla-scroll { overflow-x: auto; overscroll-behavior-x: contain; }
.vx-tabla-scroll .vx-tabla th:first-child,
.vx-tabla-scroll .vx-tabla td:first-child {
  position: sticky; left: 0; z-index: 1;
  background: var(--vx-sf);
  padding-right: 14px;
}
.vx-tabla-scroll .vx-tabla thead th:first-child { z-index: 3; }

/* ------------------------------------------------------------
   5. PANEL DE INDICADORES
   Rejilla de celdas sin tarjeta: la matriz aporta los filetes.
   ------------------------------------------------------------ */

.vx-ind {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--vx-sf);
  padding: 14px 16px;
  min-width: 0;
}
.vx-ind__etq {
  font-size: 12px;
  color: var(--vx-tx-3);
  line-height: 1.3;
}
.vx-ind__cifra {
  font-family: var(--vx-font-display);
  font-weight: 900;
  font-size: 34px;
  line-height: .9;
  letter-spacing: -.03em;
  color: var(--vx-tx);
  font-variant-numeric: tabular-nums;
}
.vx-ind__pie { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.vx-ind__spark { width: 84px; height: 22px; flex: none; }
.vx-ind__spark path { fill: none; stroke: var(--vx-tx-4); stroke-width: 1.25; }
.vx-ind--destacado .vx-ind__spark path { stroke: var(--vx-signal-core); }

/* ------------------------------------------------------------
   6. TOGGLE DE VISTA
   Dos o tres opciones excluyentes. El estado activo se lee sin
   pasar el cursor: fondo de tinta, no borde de acento.
   ------------------------------------------------------------ */

.vx-toggle {
  display: inline-flex;
  border: 1px solid var(--vx-ln);
  background: var(--vx-sf);
}
.vx-toggle__op {
  appearance: none;
  border: 0;
  border-right: 1px solid var(--vx-ln);
  background: transparent;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  padding: 6px 12px;
  color: var(--vx-tx-3);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .12s ease, color .12s ease;
}
.vx-toggle__op:last-child { border-right: 0; }
.vx-toggle__op:hover { color: var(--vx-tx); background: var(--vx-sf-2); }
.vx-toggle__op[aria-pressed="true"] {
  background: var(--vx-tx);
  color: var(--vx-sf);
  font-weight: 600;
}
.vx-toggle__op:disabled { opacity: .4; cursor: not-allowed; }

/* ------------------------------------------------------------
   7. DISPERSIÓN — ETIQUETAS DE CUADRANTE
   ------------------------------------------------------------ */

.vx-cuad { font-size: 11px; fill: var(--vx-tx-3); }
.vx-cuad--vivo { fill: var(--vx-tx); }
.vx-punto { fill: var(--vx-esc-4); }
.vx-punto--señal { fill: var(--vx-signal-core); }
.vx-punto:hover { fill: var(--vx-tx); }

/* ------------------------------------------------------------
   8. ESTADOS DE PANEL (vacío, cargando, error, sin permisos)
   Los cuatro comparten anatomía: Punto o anillo, línea de
   estado, causa, acción. Cambia el contenido, no la forma.
   ------------------------------------------------------------ */

.vx-estado {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 10px;
  min-height: 180px;
  padding: 28px 0;
  border-top: 1px solid var(--vx-ln);
}
.vx-estado__linea {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--vx-tx);
  display: flex;
  align-items: center;
  gap: 8px;
}
.vx-estado__causa { font-size: 13px; color: var(--vx-tx-3); max-width: 46ch; line-height: 1.5; }

@keyframes vx-latido { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.vx-cargando .vx-pulse { animation: vx-latido 1.1s ease-in-out infinite; }

/* ------------------------------------------------------------
   7bis. BARRAS APILADAS
   Composición por categoría. Horizontal: las etiquetas de
   municipio son largas y en vertical se voltearían.
   ------------------------------------------------------------ */

.vx-apil { display: grid; gap: 1px; font-variant-numeric: tabular-nums; }
.vx-apil__fila {
  display: grid;
  grid-template-columns: 150px 1fr 92px;
  align-items: center;
  gap: 12px;
  padding: 3px 0;
}
.vx-apil__fila:hover .vx-apil__etq { color: var(--vx-tx); }
.vx-apil__etq {
  font-size: 12.5px; color: var(--vx-tx-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vx-apil__pista { display: flex; height: 16px; background: var(--vx-sf-2); min-width: 0; }
.vx-apil__seg { height: 100%; transition: width .18s cubic-bezier(.2,.8,.2,1); }
.vx-apil__seg[data-c="1"] { background: var(--vx-esc-1); }
.vx-apil__seg[data-c="2"] { background: var(--vx-esc-2); }
.vx-apil__seg[data-c="3"] { background: var(--vx-esc-3); }
.vx-apil__seg[data-c="4"] { background: var(--vx-esc-4); }
.vx-apil__seg[data-c="5"] { background: var(--vx-esc-5); }
.vx-apil__total { font-size: 12.5px; color: var(--vx-tx); text-align: right; }

/* ------------------------------------------------------------
   7ter. ÁREA APILADA Y CURVA
   ------------------------------------------------------------ */

.vx-area path[data-c="1"] { fill: var(--vx-esc-1); }
.vx-area path[data-c="2"] { fill: var(--vx-esc-2); }
.vx-area path[data-c="3"] { fill: var(--vx-esc-3); }
.vx-area path[data-c="4"] { fill: var(--vx-esc-4); }
.vx-area path[data-c="5"] { fill: var(--vx-esc-5); }

.vx-curva__real { fill: none; stroke: var(--vx-signal-core); stroke-width: 2; }
.vx-curva__igual { fill: none; stroke: var(--vx-tx-4); stroke-width: 1; stroke-dasharray: 4 4; }
.vx-curva__hueco { fill: var(--vx-sf-2); }

/* ------------------------------------------------------------
   10. CAMPOS Y DESPLEGABLE
   Radio 0, filete de 1px, sin sombra. El foco es el anillo del
   sistema; el estado abierto se marca invirtiendo el filete a
   tinta plena, no con color.
   ------------------------------------------------------------ */

.vx-campo {
  appearance: none;
  font: inherit;
  font-size: 13px;
  color: var(--vx-tx);
  background: var(--vx-sf);
  border: 1px solid var(--vx-ln);
  border-radius: 0;
  padding: 6px 10px;
  min-width: 0;
}
.vx-campo::placeholder { color: var(--vx-tx-4); }
.vx-campo:hover { border-color: var(--vx-tx-3); }
.vx-campo:disabled { opacity: .4; cursor: not-allowed; }

.vx-desp { position: relative; }

.vx-desp__disparador {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font: inherit;
  font-size: 13px;
  color: var(--vx-tx);
  background: var(--vx-sf);
  border: 1px solid var(--vx-ln);
  padding: 6px 10px;
  cursor: pointer;
  min-width: 220px;
  text-align: left;
}
.vx-desp__disparador:hover { border-color: var(--vx-tx-3); }
.vx-desp__disparador[aria-expanded="true"] { border-color: var(--vx-tx); }
.vx-desp__conteo {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  color: var(--vx-tx-3);
  font-size: 12px;
}
/* Cuando hay selección, el conteo se marca con el Punto. */
.vx-desp__conteo--vivo { color: var(--vx-tx); }

.vx-desp__panel {
  position: absolute;
  top: calc(100% + 1px);
  left: 0;
  z-index: 40;
  width: 300px;
  max-width: 88vw;
  background: var(--vx-sf);
  border: 1px solid var(--vx-tx);
  display: flex;
  flex-direction: column;
}
.vx-desp__buscar { border-bottom: 1px solid var(--vx-ln); padding: 8px; }
.vx-desp__buscar .vx-campo { width: 100%; }

.vx-desp__lista { max-height: 232px; overflow-y: auto; overscroll-behavior: contain; }

.vx-desp__op {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--vx-tx-2);
  padding: 6px 10px;
  cursor: pointer;
  text-align: left;
}
.vx-desp__op:hover { background: var(--vx-sf-2); color: var(--vx-tx); }
.vx-desp__op[aria-selected="true"] { color: var(--vx-tx); }

/* La opción de vuelta —"Todos los municipios", "Todos los estados"—
   encabeza la lista y se separa con un filete. No es una opción más
   entre 212: es la salida, y tiene que leerse como tal. Va en versal
   fina, como los rótulos del sistema, para que no compita con los
   nombres propios que vienen debajo. */
.vx-desp__op--todo {
  color: var(--vx-tx);
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--vx-ln);
  padding-bottom: 8px;
  margin-bottom: 4px;
  position: sticky;
  top: 0;
  background: var(--vx-sf);
  z-index: 1;
}
.vx-desp__op--todo:hover { background: var(--vx-sf-2); }

/* Separa el grupo del comparador de la lista de temas: no es un tema
   más, y el filete lo dice sin necesidad de explicarlo. */
/* Con el comparador al frente cada tema lleva casilla: la lista deja
   de ser navegación y pasa a ser qué se compara. Se reutiliza la
   `.vx-casilla` del kit —el sistema ya tiene un signo para "esto
   está marcado" y no hace falta inventar otro—. */
.vx-tema--casilla { gap: .55rem; }
.vx-tema--casilla .vx-tema__nombre { flex: 1; text-align: left; }

.vx-flanco__pista {
  padding: .3rem 1rem .15rem;
  font-size: 11px;
  line-height: 1.35;
  color: var(--vx-tx-3);
}

.vx-flanco__rotulo--sep {
  margin-top: 1rem;
  padding-top: .75rem;
  border-top: 1px solid var(--vx-ln);
}

/* Casilla cuadrada dibujada con filete. La marca es el Punto:
   el sistema ya tiene un signo para "esto importa". */
.vx-casilla {
  width: 13px; height: 13px; flex: none;
  border: 1px solid var(--vx-tx-3);
  display: grid; place-items: center;
}
.vx-desp__op[aria-selected="true"] .vx-casilla { border-color: var(--vx-tx); }
.vx-casilla__marca { width: 7px; height: 7px; background: var(--vx-signal-core); }

.vx-desp__pie {
  display: flex; align-items: center; gap: 12px;
  border-top: 1px solid var(--vx-ln);
  padding: 8px 10px;
  font-size: 12px;
  color: var(--vx-tx-3);
}
.vx-desp__vacio { padding: 18px 10px; font-size: 13px; color: var(--vx-tx-3); }

.vx-enlace {
  border: 0; background: none; font: inherit; font-size: 12px;
  color: var(--vx-tx-3); cursor: pointer; padding: 0;
  text-decoration: underline; text-underline-offset: 2px;
}
.vx-enlace:hover { color: var(--vx-tx); }

/* ------------------------------------------------------------
   11. BARRA DE FILTROS
   Una sola franja. El estado activo se lee sin abrir nada.
   ------------------------------------------------------------ */

.vx-filtros {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 10px 0;
  border-top: 1px solid var(--vx-ln);
  border-bottom: 1px solid var(--vx-ln);
}
.vx-filtros__grupo { display: flex; align-items: center; gap: 8px; min-width: 0; }
.vx-filtros__etq { font-size: 12px; color: var(--vx-tx-3); white-space: nowrap; }
.vx-filtros__resumen {
  margin-left: auto;
  display: flex; align-items: center; gap: 10px;
  font-size: 12px; color: var(--vx-tx-3);
  font-variant-numeric: tabular-nums;
}

/* Ficha de filtro aplicado. Contraste real: texto en tinta,
   filete en tinta, fondo de la superficie hundida. Nunca texto
   azul sobre azul translúcido. */
.vx-ficha-filtro {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--vx-tx);
  background: var(--vx-sf-2);
  border: 1px solid var(--vx-ln);
  padding: 3px 6px 3px 8px;
  white-space: nowrap;
}
.vx-ficha-filtro button {
  border: 0; background: none; font: inherit; line-height: 1;
  color: var(--vx-tx-3); cursor: pointer; padding: 0 2px;
}
.vx-ficha-filtro button:hover { color: var(--vx-tx); }

/* ------------------------------------------------------------
   12. PANEL LATERAL
   Sin sombra y sin radio: la separación la hace el filete y el
   escalón de superficie. El velo es color plano, no blur.
   ------------------------------------------------------------ */

.vx-velo {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 10, 0.28);
  z-index: 50;
}
html.dark .vx-velo { background: rgba(0, 0, 0, 0.55); }

.vx-lateral {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(420px, 92%);
  z-index: 60;
  background: var(--vx-sf);
  border-left: 1px solid var(--vx-tx);
  display: flex;
  flex-direction: column;
  animation: vx-entrar-lateral .18s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes vx-entrar-lateral { from { transform: translateX(12px); opacity: .6; } to { transform: none; opacity: 1; } }

.vx-lateral__cab {
  display: flex; align-items: flex-start; gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-lateral__cuerpo { padding: 18px 20px; overflow-y: auto; flex: 1; }
.vx-lateral__pie {
  display: flex; gap: 10px; justify-content: flex-end;
  padding: 12px 20px;
  border-top: 1px solid var(--vx-ln);
}
.vx-cerrar {
  border: 0; background: none; font: inherit; font-size: 13px;
  color: var(--vx-tx-3); cursor: pointer; padding: 2px 4px;
  margin-left: auto;
}
.vx-cerrar:hover { color: var(--vx-tx); }

/* ------------------------------------------------------------
   13. NAVEGACIÓN ENTRE SECCIONES
   Dos formas, un solo lenguaje: módulos paralelos (pestañas de
   filete) y pasos secuenciales (progreso numerado).
   ------------------------------------------------------------ */

/* El relleno lateral iguala al de `.vx-barra` y `.vx-lienzo`: esta
   barra es una fila propia de la retícula de `.vx-app`, no vive dentro
   del lienzo, así que no heredaba su aire. Sin esto la primera pestaña
   arrancaba pegada al banner lateral y la R de "Resumen" parecía
   quedarse detrás de él. */
.vx-modulos {
  display: flex;
  gap: 0;
  padding: 0 20px;
  border-bottom: 1px solid var(--vx-ln);
  overflow-x: auto;
}
.vx-modulos__op {
  border: 0; background: none; font: inherit;
  font-family: var(--vx-font-display); font-weight: 700; font-size: 14px;
  letter-spacing: -.01em;
  color: var(--vx-tx-3); cursor: pointer;
  padding: 10px 16px;
  position: relative;
  white-space: nowrap;
}
.vx-modulos__op:first-child { padding-left: 0; }
.vx-modulos__op:hover { color: var(--vx-tx); }
.vx-modulos__op[aria-current="true"] { color: var(--vx-tx); }
/* El filete activo es de 2px en Signal Core: superficie mínima,
   posición inequívoca. */
.vx-modulos__op[aria-current="true"]::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--vx-signal-core);
}
.vx-modulos__op:first-child[aria-current="true"]::after { left: 0; }

.vx-pasos { display: flex; align-items: stretch; border-top: 1px solid var(--vx-ln); border-bottom: 1px solid var(--vx-ln); }
.vx-pasos__op {
  flex: 1;
  border: 0; border-right: 1px solid var(--vx-ln);
  background: none; font: inherit; text-align: left;
  padding: 9px 12px; cursor: pointer;
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0;
}
.vx-pasos__op:last-child { border-right: 0; }
.vx-pasos__op:hover { background: var(--vx-sf-2); }
.vx-pasos__n {
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  color: var(--vx-tx-4); font-variant-numeric: tabular-nums;
  display: flex; align-items: center; gap: 6px;
}
.vx-pasos__t {
  font-size: 12.5px; color: var(--vx-tx-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vx-pasos__op[data-estado="hecho"] .vx-pasos__n,
.vx-pasos__op[data-estado="hecho"] .vx-pasos__t { color: var(--vx-tx-2); }
.vx-pasos__op[aria-current="true"] { background: var(--vx-sf-2); }
.vx-pasos__op[aria-current="true"] .vx-pasos__n { color: var(--vx-tx); }
.vx-pasos__op[aria-current="true"] .vx-pasos__t { color: var(--vx-tx); font-weight: 600; }
.vx-pasos__op[data-estado="bloqueado"] { cursor: not-allowed; }
.vx-pasos__op[data-estado="bloqueado"] .vx-pasos__t { color: var(--vx-tx-4); }

/* Barra de progreso con unidad declarada: "3 de 8". Nunca un
   medidor sin número. */
.vx-progreso { display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--vx-tx-3); }
.vx-progreso__pista { flex: 1; height: 2px; background: var(--vx-sf-2); min-width: 80px; }
.vx-progreso__valor { height: 100%; background: var(--vx-signal-core); }

/* ------------------------------------------------------------
   14. ESQUELETO DE CARGA
   Bloques del alto real del contenido, en superficie hundida.
   Sin barrido, sin brillo: el movimiento lo lleva el Punto.
   ------------------------------------------------------------ */

.vx-esq { background: var(--vx-sf-2); }
.vx-esq--linea { height: 10px; }
.vx-esq--fila { height: 30px; border-bottom: 1px solid var(--vx-ln); background: none; display: flex; align-items: center; gap: 12px; }
.vx-esq--fila > span { background: var(--vx-sf-2); height: 10px; }

/* ------------------------------------------------------------
   9. RESPONSIVO
   Por debajo de 900px el lienzo pasa a una columna y el
   MapaCalor recorta la etiqueta. Por debajo de 600px el mapa
   cambia a trimestres y la tabla deja de mostrar columnas
   secundarias — se recorta el dato, nunca el tamaño de letra.
   ------------------------------------------------------------ */

@media (max-width: 900px) {
  .vx-mapa, .vx-mapa__fila { grid-template-columns: 120px 1fr; }
  .vx-ind__cifra { font-size: 28px; }
  .vx-apil__fila { grid-template-columns: 110px 1fr 78px; }
  .vx-pasos { flex-wrap: wrap; }
  .vx-pasos__op { flex: 1 1 25%; border-bottom: 1px solid var(--vx-ln); }
  .vx-modulos { overflow-x: auto; }
}
@media (max-width: 600px) {
  .vx-mapa, .vx-mapa__fila { grid-template-columns: 96px 1fr; }
  .vx-mapa__scroll { max-height: 260px; }
  .vx-g__unidad { margin-left: 0; }
  .vx-g__cab { flex-wrap: wrap; gap: 4px 12px; }
  .vx-apil__fila { grid-template-columns: 1fr 64px; }
  .vx-apil__etq { grid-column: 1 / -1; }
  .vx-filtros { flex-direction: column; align-items: stretch; gap: 10px; }
  .vx-filtros__resumen { margin-left: 0; }
  .vx-desp__disparador { width: 100%; min-width: 0; }
  .vx-desp__panel { width: 100%; }
  .vx-pasos { display: block; }
  .vx-pasos__op { width: 100%; border-right: 0; flex-direction: row; align-items: center; gap: 10px; }
  .vx-lateral { width: 100%; border-left: 0; }
  [data-vx-secundaria] { display: none; }
}

/* ------------------------------------------------------------
   FILTRO CON RÓTULO
   Un control con su etiqueta al lado, para la barra superior.
   La etiqueta va afuera del control: dentro sería un placeholder,
   y un placeholder desaparece justo cuando hay dato que explicar.
   ------------------------------------------------------------ */

.vx-filtro {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.vx-filtro__et {
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  white-space: nowrap;
}
.vx-filtro .vx-campo { max-width: 190px; }

@media (max-width: 900px) {
  .vx-filtro__et { display: none; }
  .vx-filtro .vx-campo { max-width: 130px; }
}

/* ------------------------------------------------------------
   FRANJA DE ENFOQUE
   Cuando se elige un municipio, sus cifras se leen de corrido
   arriba del panorama. No sustituye a la vista estatal: la
   pregunta es dónde cae este municipio frente a los demás, y eso
   exige seguir viendo a los demás.
   ------------------------------------------------------------ */

.vx-foco {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 1.25rem;
  padding: .625rem .875rem;
  border: 1px solid var(--vx-signal-core);
}
.vx-foco__nombre {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: .9375rem;
  color: var(--vx-tx);
  white-space: nowrap;
}
.vx-foco__dato { display: inline-flex; flex-direction: column; gap: 1px; }
.vx-foco__et {
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  white-space: nowrap;
}
.vx-foco__val { font-size: .875rem; color: var(--vx-tx); }

/* ------------------------------------------------------------
   QUIEBRE
   Lo que se muestra cuando un tema no pudo pintarse. Dice qué
   pasó y deja salida; no finge que no ocurrió nada.
   ------------------------------------------------------------ */

.vx-quiebre { max-width: 44rem; padding: 2rem 0; }
.vx-quiebre__titulo {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 1.0625rem;
  color: var(--vx-tx);
  margin-bottom: .5rem;
}
.vx-quiebre__cuerpo { font-size: .875rem; color: var(--vx-tx-2); margin-bottom: 1rem; }
.vx-quiebre__detalle {
  font-family: var(--vx-font-mono, ui-monospace, monospace);
  font-size: .75rem;
  color: var(--vx-tx-3);
  background: var(--vx-sf);
  border: 1px solid var(--vx-ln);
  padding: .75rem;
  margin-bottom: 1rem;
  white-space: pre-wrap;
  overflow-x: auto;
}

/* ------------------------------------------------------------
   SELECTOR DE TERRITORIO — piezas que faltaban
   El desplegable ya existía en el sistema; esto completa el modo
   de selección múltiple y el rótulo en línea de la barra.
   ------------------------------------------------------------ */

/* El rótulo va pegado al disparador, dentro del mismo bloque. */
.vx-desp {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  position: relative;
}
.vx-desp > .vx-filtro__et { white-space: nowrap; }
.vx-desp__disparador { width: 100%; min-width: 150px; }
.vx-desp__sub-varios {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 2px;
  font-size: 11px;
  color: var(--vx-tx-3);
  cursor: pointer;
  user-select: none;
  font-family: var(--vx-font-display);
  letter-spacing: .01em;
  transition: color .12s ease;
}
.vx-desp__sub-varios input[type="checkbox"] {
  width: 12px;
  height: 12px;
  accent-color: var(--vx-signal-core);
  cursor: pointer;
  margin: 0;
}
.vx-desp__sub-varios:hover {
  color: var(--vx-tx-2);
}
.vx-desp__texto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* El panel cuelga del disparador, no del rótulo. */
.vx-desp__panel { top: calc(100% + 4px); left: auto; right: 0; }

.vx-desp__modo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-desp__multi {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--vx-tx-2);
  cursor: pointer;
  user-select: none;
}
.vx-desp__multi input {
  width: 13px; height: 13px;
  accent-color: var(--vx-signal-core);
  cursor: pointer;
}
.vx-desp__limpiar {
  border: 0; background: none; font: inherit; font-size: 12px;
  color: var(--vx-tx-3); cursor: pointer; white-space: nowrap;
  text-decoration: underline; text-underline-offset: 2px;
}
.vx-desp__limpiar:hover { color: var(--vx-tx); }

/* La marca del sistema es el Punto: cuadro lleno, sin palomita. */
.vx-casilla--viva { border-color: var(--vx-tx); }
.vx-casilla--viva::after {
  content: "";
  width: 7px; height: 7px;
  background: var(--vx-signal-core);
}

.vx-desp__nada { padding: 18px 10px; font-size: 13px; color: var(--vx-tx-3); }

@media (max-width: 1100px) {
  .vx-desp > .vx-filtro__et { display: none; }
  .vx-desp__disparador { min-width: 118px; }
}

/* ------------------------------------------------------------
   PERFIL DE POSICIÓN
   Sólo aparece con un municipio elegido: sitúa su cifra dentro
   del recorrido completo del estado.
   ------------------------------------------------------------ */

.vx-perfil { display: flex; flex-direction: column; gap: .875rem; }
.vx-perfil__fila {
  display: grid;
  grid-template-columns: 12rem 1fr 9.5rem;
  align-items: center;
  gap: 1rem;
}
.vx-perfil__et {
  font-size: .8125rem;
  color: var(--vx-tx-2);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.vx-perfil__nota { font-size: 10px; color: var(--vx-tx-3); }
.vx-perfil__pista { min-width: 0; }
.vx-perfil__escala {
  display: flex;
  justify-content: space-between;
  gap: .5rem;
  font-size: 10px;
  color: var(--vx-tx-3);
  margin-top: -2px;
}
.vx-perfil__mediana { color: var(--vx-tx-3); }
.vx-perfil__valor {
  text-align: right;
  font-size: .875rem;
  color: var(--vx-tx);
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.vx-perfil__pct { font-size: 10px; color: var(--vx-tx-3); }
.vx-perfil__sin { font-size: .8125rem; color: var(--vx-tx-3); }
.vx-perfil__pie {
  font-size: 11px;
  color: var(--vx-tx-3);
  margin-top: .25rem;
  padding-top: .5rem;
  border-top: 1px solid var(--vx-ln);
}

@media (max-width: 760px) {
  .vx-perfil__fila { grid-template-columns: 1fr; gap: .25rem; }
  .vx-perfil__valor { text-align: left; flex-direction: row; gap: .5rem; align-items: baseline; }
}

/* ------------------------------------------------------------
   ESPECIALIZACIÓN — cociente de localización
   ------------------------------------------------------------ */

.vx-espec { display: flex; flex-direction: column; gap: .625rem; }
.vx-espec__fila {
  display: grid;
  grid-template-columns: 13rem 1fr 3.5rem;
  grid-template-areas: "et pista cifra" "det det det";
  align-items: center;
  gap: .25rem .875rem;
}
.vx-espec__et {
  grid-area: et;
  font-size: .8125rem;
  color: var(--vx-tx-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vx-espec__pista {
  grid-area: pista;
  position: relative;
  height: 18px;
  background: var(--vx-sf-2);
  min-width: 0;
}
.vx-espec__barra { position: absolute; left: 0; top: 0; bottom: 0; display: block; }
/* La paridad se dibuja encima de la barra: es la referencia, no el fondo. */
.vx-espec__paridad {
  position: absolute;
  top: -3px; bottom: -3px;
  width: 1px;
  background: var(--vx-tx);
  z-index: 1;
}
.vx-espec__cifra { grid-area: cifra; text-align: right; font-size: .8125rem; color: var(--vx-tx); }
.vx-espec__detalle {
  grid-area: det;
  font-size: 10px;
  color: var(--vx-tx-3);
  padding-bottom: .25rem;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-espec__pie {
  font-size: 11px;
  color: var(--vx-tx-3);
  margin-top: .25rem;
}

@media (max-width: 760px) {
  .vx-espec__fila { grid-template-columns: 1fr 3.5rem; grid-template-areas: "et cifra" "pista pista" "det det"; }
}

/* ------------------------------------------------------------
   FILA DE FILTROS
   Lo que no es territorio: periodo y alcance. El territorio vive
   en la barra, con el mismo control en todos los temas.
   ------------------------------------------------------------ */

.vx-filtros {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  padding-bottom: .875rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-filtros__grupo { display: flex; align-items: center; gap: .625rem; }

.vx-anios { display: flex; flex-wrap: wrap; gap: 0; }
.vx-anio {
  font: inherit;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--vx-tx-2);
  background: var(--vx-sf);
  border: 1px solid var(--vx-ln);
  margin-left: -1px;
  padding: 5px 10px;
  cursor: pointer;
}
.vx-anio:first-child { margin-left: 0; }
.vx-anio:hover { color: var(--vx-tx); border-color: var(--vx-tx-3); z-index: 1; position: relative; }
/* Activo con tinta plena, no con borde de acento: el azul se
   reserva para el dato, no para el control. */
.vx-anio[aria-pressed="true"] {
  color: var(--vx-sf);
  background: var(--vx-tx);
  border-color: var(--vx-tx);
  z-index: 2;
  position: relative;
}
/* Año incompleto: filete punteado. Se puede elegir; compararlo
   contra un año cerrado es cosa de quien lo lee. */
.vx-anio[data-parcial="si"] { border-style: dashed; color: var(--vx-tx-3); }
.vx-anio[data-parcial="si"][aria-pressed="true"] { color: var(--vx-sf); }

/* ------------------------------------------------------------
   10. NOTAS DEL TABLERO
   Ubicado al final de todo el lienzo, en la esquina inferior
   derecha, para no competir ni tapar ninguna gráfica o cifra.
   ------------------------------------------------------------ */

.vx-notas {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-end;
  margin-top: 2.5rem;
  margin-bottom: 1.5rem;
  padding-right: 0.5rem;
  box-sizing: border-box;
  z-index: 30;
}

.vx-notas__boton {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font: inherit;
  font-size: 12px;
  color: var(--vx-tx-3);
  background: var(--vx-sf);
  border: 1px solid var(--vx-ln);
  padding: 6px 12px;
  cursor: pointer;
}
.vx-notas__boton:hover { color: var(--vx-tx); border-color: var(--vx-tx-3); }
.vx-notas__boton[aria-expanded="true"] { color: var(--vx-tx); border-color: var(--vx-tx); }

.vx-notas__signo {
  width: 14px; height: 14px;
  display: grid; place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 9px;
  font-style: italic;
  line-height: 1;
}

.vx-notas__panel {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0.5rem;
  width: 27rem;
  max-width: calc(100vw - 3rem);
  max-height: 60vh;
  display: flex;
  flex-direction: column;
  background: var(--vx-sf);
  border: 1px solid var(--vx-tx);
}
.vx-notas__alto {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .625rem .875rem;
  border-bottom: 1px solid var(--vx-ln);
}
.vx-notas__titulo {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: .8125rem;
  color: var(--vx-tx);
}
.vx-notas__cerrar {
  border: 0; background: none; font: inherit; font-size: 18px; line-height: 1;
  color: var(--vx-tx-3); cursor: pointer; padding: 0 2px;
}
.vx-notas__cerrar:hover { color: var(--vx-tx); }

.vx-notas__cuerpo {
  overflow-y: auto;
  padding: .875rem;
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--vx-tx-2);
}
.vx-notas__cuerpo p + p { margin-top: .75rem; }
.vx-notas__cuerpo strong { color: var(--vx-tx); font-weight: 600; }

/* El lienzo es el ancla del botón: sin esto se pegaría a la
   ventana y taparía el pie de la app. */
.vx-lienzo { position: relative; }

@media (max-width: 760px) {
  .vx-notas { padding-right: 0; margin-top: 1.5rem; margin-bottom: 1rem; }
  .vx-notas__panel { width: calc(100vw - 1.5rem); right: 0; }
}

/* El enfoque ya no se quita desde el tablero: se cambia el área en
   el banner, que es donde vive la selección. */
.vx-foco__vía { font-size: 11px; color: var(--vx-tx-3); white-space: nowrap; }

/* ------------------------------------------------------------
   REPARTO ORDENADO
   Barra segmentada más lista. La barra contesta cómo se reparte
   el total; la lista, cuánto pesa cada tramo. Se necesitan las
   dos: una tabla sola no deja ver la forma del reparto.
   ------------------------------------------------------------ */

.vx-reparto { display: flex; flex-direction: column; gap: .75rem; }
.vx-reparto .vx-apil__pista { height: 22px; }

.vx-reparto__lista { display: flex; flex-direction: column; gap: 1px; }
.vx-reparto__fila {
  display: grid;
  grid-template-columns: 9px 1fr auto auto;
  align-items: center;
  gap: .625rem;
  padding: .3rem .25rem;
  font-size: .8125rem;
}
.vx-reparto__fila:hover { background: var(--vx-sf-2); }
.vx-reparto__marca { width: 9px; height: 9px; display: block; }
.vx-reparto__etq {
  color: var(--vx-tx-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vx-reparto__pct { color: var(--vx-tx); min-width: 3.5rem; text-align: right; }
.vx-reparto__abs { color: var(--vx-tx-3); min-width: 4rem; text-align: right; font-size: .75rem; }
.vx-reparto__pie { font-size: 11px; color: var(--vx-tx-3); }

/* ------------------------------------------------------------
   MAPA DE LA REPÚBLICA
   El territorio se dibuja con tinta, no con color: la entidad o
   el municipio marcado toma el azul de señal y el resto queda en
   el extremo tenue de la escala. Sin degradados ni relieve —el
   mapa localiza, no compite con las gráficas.
   ------------------------------------------------------------ */

.vx-mapa-geo { display: flex; flex-direction: column; gap: .5rem; }

/* Envuelve el <svg> del mapa.

   `width: 100%` NO es decorativo: `.vx-ubi__mapa .vx-mapa-geo` es un
   flex en columna con `align-items: center`, así que un hijo de
   bloque sin ancho declarado se encoge a su contenido. Al meter este
   envoltorio para el zoom, el mapa pasó de ocupar los 603 px de su
   celda a 300 —la mitad—, sin que nada lo dijera. */
.vx-mapa-geo__lienzo {
  position: relative;
  width: 100%;
}

.vx-mapa-geo__svg {
  width: 100%;
  height: auto;
  display: block;
  /* Explícito y no heredado del user-agent: con contenido escalado
     por el zoom, dejar `overflow: visible` derramaría piezas fuera
     de la tarjeta en vez de recortarlas en el borde del mapa. */
  overflow: hidden;
  touch-action: none;
}

/* La tarjeta de KPI se declara contenedor de consulta para que la
   cifra pueda dimensionarse contra el ancho de SU celda —con `cqw`—
   y no contra la ventana. Sin esto, la cifra más larga se salía del
   borde en cuanto la retícula estrechaba las columnas. */
.vx-kpi { container-type: inline-size; min-width: 0; }

.vx-mapa-geo__pieza {
  stroke-width: .5;
  vector-effect: non-scaling-stroke;
  transition: fill .15s linear, stroke-width .15s linear;
  outline: none;
}
.vx-mapa-geo__pieza[data-activo] { fill: var(--vx-tx-3); }
.vx-mapa-geo__pieza[data-marcado][data-activo] { fill: var(--vx-signal-core); }
.vx-mapa-geo__pieza:focus,
.vx-mapa-geo__pieza:focus-visible,
.vx-mapa-geo__pieza:active {
  outline: none !important;
}

.vx-mapa-geo__etq {
  font-family: var(--vx-font-display);
  font-size: 18px;
  font-weight: 800;
  fill: var(--vx-on-dark);
  paint-order: stroke fill;
  stroke: var(--vx-deep-void);
  stroke-width: 4.5px;
  stroke-linejoin: round;
  letter-spacing: -.01em;
}

html:not(.dark) .vx-mapa-geo__etq {
  fill: var(--vx-ink);
  stroke: var(--vx-warm-concrete);
  stroke-width: 4.5px;
}

.vx-mapa-geo__etq[data-hover] {
  fill: var(--vx-signal-core);
}

.vx-mapa-geo__chips {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .65rem;
  margin-bottom: .35rem;
}

.vx-mapa-geo__chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .65rem;
  background: var(--vx-signal-tint, rgba(46, 92, 255, 0.12));
  border: 1px solid var(--vx-signal-core);
  color: var(--vx-tx);
  font-family: var(--vx-font-display);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: -.01em;
  border-radius: 0;
  line-height: 1.2;
}
/* --vx-signal-tint es el 12% de señal sobre Warm Concrete (fondo claro):
   sobre Deep Void resulta casi blanco y el texto --vx-tx (claro en oscuro)
   deja de leerse. El twin oscuro (18% de señal) es el que corresponde. */
html.dark .vx-mapa-geo__chip { background: var(--vx-signal-tint-oscuro, rgba(46, 92, 255, 0.18)); }

.vx-mapa-geo__chip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--vx-signal-core);
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
  padding: 2px 4px;
  margin-left: 2px;
  border-radius: 0;
  transition: opacity .12s ease;
}

.vx-mapa-geo__chip-btn:hover {
  opacity: 0.7;
}

.vx-mapa-geo__pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  font-size: 12px;
  color: var(--vx-tx-3);
  margin-top: .35rem;
  min-height: 26px;
  overflow: hidden;
}
.vx-mapa-geo__pie > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vx-mapa-geo__encima {
  margin-left: auto;
  color: var(--vx-signal-core);
  font-weight: 800;
  font-size: 1rem;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ------------------------------------------------------------
   UBICACIÓN
   Abre cada tablero: mapa interactivo a la izquierda, lo que hay que saber
   del área a la derecha.
   ------------------------------------------------------------ */

.vx-ubi {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  border: 1px solid var(--vx-ln);
  padding: 0.875rem;
  margin-bottom: 1rem;
  background: var(--vx-sf);
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.vx-ubi__mapa {
  min-width: 0;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
}

.vx-ubi__mapa .vx-mapa-geo {
  width: 100%;
  max-width: 100%;
  height: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.vx-ubi__mapa .vx-mapa-geo__svg {
  width: 100%;
  max-width: 100%;
  height: auto;
  /* El mapa es la pieza que abre el tablero: se le da altura de
     verdad. Con 230 px quedaba muy por debajo de su tarjeta y
     parecía una miniatura en un marco vacío. */
  max-height: 340px;
  margin: 0 auto;
  display: block;
}

.vx-ubi__panel {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  border-top: 1px solid var(--vx-ln);
  padding-top: 0.875rem;
  box-sizing: border-box;
}

.vx-ubi__titulo {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--vx-tx);
}
.vx-ubi__contexto {
  font-size: .6875rem;
  color: var(--vx-tx-3);
  margin-top: .15rem;
}

.vx-ubi__datos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 0.5rem;
  width: 100%;
  box-sizing: border-box;
}
.vx-ubi__dato { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.vx-ubi__et {
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
}
.vx-ubi__val {
  font-family: var(--vx-font-display);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.1;
  color: var(--vx-tx);
}
/* Uno por tarjeta toma el azul: el que responde la pregunta del tema. */
.vx-ubi__dato[data-destacado] .vx-ubi__val { color: var(--vx-signal-core); font-size: 1.25rem; }
.vx-ubi__nota { font-size: 10px; color: var(--vx-tx-3); line-height: 1.35; }

.vx-ubi__lectura {
  margin-top: auto;
  padding-top: .625rem;
  border-top: 1px solid var(--vx-ln);
  font-size: .75rem;
  line-height: 1.45;
  color: var(--vx-tx-2);
}

@media (min-width: 960px) {
  .vx-ubi {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 1.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1.5rem;
    align-items: center;
  }
  .vx-ubi__mapa {
    max-height: 560px;
    min-height: 320px;
  }
  .vx-ubi__mapa .vx-mapa-geo__svg {
    max-height: 500px;
  }
  .vx-ubi__panel {
    border-left: 1px solid var(--vx-ln);
    border-top: none;
    padding-left: 1.5rem;
    padding-top: 0;
    gap: 1.25rem;
  }
  .vx-ubi__titulo {
    font-size: 1.375rem;
  }
  .vx-ubi__contexto {
    font-size: .75rem;
  }
  .vx-ubi__datos {
    gap: 1.25rem 1rem;
  }
  .vx-ubi__et {
    font-size: 10px;
  }
  .vx-ubi__val {
    font-size: 1.125rem;
  }
  .vx-ubi__dato[data-destacado] .vx-ubi__val {
    font-size: 1.5rem;
  }
  .vx-ubi__lectura {
    font-size: .8125rem;
    line-height: 1.5;
  }
}

/* ------------------------------------------------------------
   LEYENDA DE LA COROPLETA
   Con los cortes en cifras reales. Un degradado sin números no
   dice nada: la pregunta que contesta una coropleta es "¿cuánto
   es oscuro?", y sin cotas no hay respuesta.
   ------------------------------------------------------------ */

.vx-mapa-geo__leyenda {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem .875rem;
  padding-top: .5rem;
  border-top: 1px solid var(--vx-ln);
}
.vx-mapa-geo__leyenda-tit {
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  white-space: nowrap;
}
.vx-mapa-geo__tramos {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem .75rem;
  min-width: 0;
}
.vx-mapa-geo__tramo {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: 11px;
  color: var(--vx-tx-2);
  white-space: nowrap;
}
.vx-mapa-geo__sw {
  width: 11px;
  height: 11px;
  flex: none;
  border: 1px solid var(--vx-ln);
}
/* La misma trama que el mapa, para que la leyenda no mienta. */
.vx-mapa-geo__sw--sin {
  background:
    repeating-linear-gradient(45deg,
      var(--vx-ln) 0 1.5px,
      transparent 1.5px 4px),
    var(--vx-esc-5);
}
.vx-mapa-geo__leyenda-pie {
  margin-left: auto;
  font-size: 10px;
  color: var(--vx-tx-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* El control de métrica va sobre el mapa: cambia lo que el mapa
   dibuja, no lo que dice el tablero. */
.vx-ubi__mapa { flex-direction: column; align-items: stretch; gap: .5rem; }
.vx-ubi__metrica { display: flex; justify-content: flex-end; }

/* ============================================================
   COMPARADOR

   Una tabla, no tarjetas. La comparación vive en la alineación de
   las filas: el mismo dato tiene que quedar a la misma altura en
   las tres columnas, y cualquier envoltorio que rompa eso rompe la
   pantalla entera.
   ============================================================ */

.vx-comp__cab { margin-bottom: 1.5rem; }

.vx-comp__titulo {
  font-size: clamp(20px, 2.4vw, 30px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--vx-tx);
  margin: .25rem 0 .35rem;
}

.vx-comp__sub {
  font-size: 13px;
  color: var(--vx-tx-3);
  max-width: 62ch;
}

/* ---------- Elección de lugares ---------- */

.vx-comp__ranuras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  align-items: start;
  padding-bottom: 1.25rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--vx-ln);
}

.vx-comp__ranura-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: .4rem;
}

.vx-comp__ranura-num {
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
}

.vx-comp__quitar,
.vx-comp__agregar {
  border: 0;
  background: none;
  font: inherit;
  font-size: 11px;
  color: var(--vx-tx-3);
  cursor: pointer;
  padding: 0;
}
.vx-comp__quitar:hover { color: var(--vx-tx); }

.vx-comp__agregar {
  align-self: center;
  border: 1px dashed var(--vx-ln);
  padding: .75rem 1rem;
  font-size: 12px;
  color: var(--vx-tx-2);
  width: 100%;
}
.vx-comp__agregar:hover { border-color: var(--vx-tx-3); color: var(--vx-tx); }

/* ---------- La tabla ---------- */

.vx-comp__tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.vx-comp__th-etq,
.vx-comp__th {
  text-align: left;
  padding: 0 .75rem .6rem 0;
  border-bottom: 1px solid var(--vx-ln);
  vertical-align: bottom;
  font-weight: 400;
}

.vx-comp__th { text-align: right; }

.vx-comp__th-etq {
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  width: 34%;
}

.vx-comp__th-nombre {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--vx-tx);
  line-height: 1.2;
}

.vx-comp__th-ent {
  display: block;
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
  margin-top: 2px;
}

.vx-comp__td-etq {
  text-align: left;
  font-weight: 400;
  color: var(--vx-tx-2);
  padding: .7rem .75rem .7rem 0;
  border-bottom: 1px solid var(--vx-ln);
  vertical-align: top;
}

.vx-comp__nota {
  display: block;
  font-size: 11px;
  color: var(--vx-tx-3);
  margin-top: 2px;
  max-width: 34ch;
}

.vx-comp__td {
  text-align: right;
  padding: .7rem 0;
  border-bottom: 1px solid var(--vx-ln);
  color: var(--vx-tx-2);
  white-space: nowrap;
}

/* La ventaja se dice con el Punto y con peso, nunca con color de
   semáforo: en varios de estos indicadores "mejor" es discutible, y
   pintar de verde una opinión la disfraza de dato. */
.vx-comp__td--lider { color: var(--vx-tx); font-weight: 600; }

.vx-comp__punto {
  display: inline-block;
  width: 5px;
  height: 5px;
  background: var(--vx-signal-core);
  margin-right: .45rem;
  vertical-align: middle;
}

/* ---------- Rejilla de perfiles ---------- */

.vx-comp__rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

@media (max-width: 700px) {
  /* En pantalla angosta la tabla se sale antes que nada: se le deja
     rodar sola en vez de encoger la letra hasta lo ilegible. */
  .vx-comp__tabla { min-width: 460px; }
  .vx-g__lienzo { overflow-x: auto; }
}

/* Interruptor de referencia de la especialización. Va encima de la
   rejilla y no dentro de cada tarjeta: la elección es una sola para
   todas las columnas —si cada una se midiera contra algo distinto,
   volveríamos al problema que este control resuelve—. */
.vx-comp__ref {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: .75rem;
}

.vx-comp__ref-et {
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--vx-tx-3);
}

/* Sin área elegida. No es un error ni una carga: es un estado de
   espera, y por eso se ve como una página en blanco con instrucción,
   no como una alerta. */
.vx-sin-area {
  align-items: center;
  justify-content: center;
  padding: 2rem;
  text-align: left;
}

.vx-sin-area__titulo {
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--vx-tx);
  margin: .3rem 0 .5rem;
}

.vx-sin-area__texto {
  font-size: 13px;
  line-height: 1.5;
  color: var(--vx-tx-3);
  max-width: 46ch;
}

/* Fila de acción del comparador. El botón es el único primario de la
   pantalla: es la acción que cuesta —dispara las consultas— y por eso
   se distingue de todo lo demás, que sólo prepara. */
.vx-comp__accion {
  display: flex;
  align-items: center;
  gap: .85rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}

.vx-comp__accion-nota {
  font-size: 12px;
  color: var(--vx-tx-3);
}
