﻿/* ===========================================================================
   REDISEÑO CON EL LENGUAJE GRÁFICO DE VOX

   La paleta y las proporciones NO están estimadas a ojo: se muestrearon de cinco
   creatividades reales del partido (guardadas en pipeline/datos/estilo_vox/) midiendo la
   moda de color por zonas. De ahí salen el rojo #c80d22, el verde #00583a, el amarillo
   #ffd600, el gris papel #d8dad7 y la tinta #1c1c1c.

   Sobre el VERDE: se probó a sacarlo del cuadrado del logotipo oficial (#2c7b48) y el usuario
   lo descartó por ser demasiado claro. El que va es el #00583a de la barra de cierre de las
   creatividades. Del logotipo se aprovecha SOLO la palabra en blanco, recortada sin fondo por
   pipeline/logo_web.py.

   Los seis recursos que definen ese lenguaje y que aquí se reproducen:
     1. Titular ULTRANEGRO CONDENSADO en caja alta, con el interlineado muy apretado.
     2. Bloque de color macizo detrás de una línea o de una palabra (rojo o negro), a modo
        de rotulador. Es el gesto más reconocible.
     3. Contraste de peso dentro del mismo titular: una línea fina y la siguiente ultranegra.
     4. Pegatinas blancas con sombra, a veces giradas un grado.
     5. Filete rojo vertical a la izquierda de las listas, y pestañas de color que sangran.
     6. Barra verde de cierre, esquinas duras y acentos amarillos para señalar.

   LO QUE NO SE TOCA:
     · Los colores del dato (la escala naranja→rojo→negro de los cinco mapas, pipeline/escala.py).
       Están en datos.json y los pinta el JavaScript; aquí solo se respetan.
     · Todo el trabajo del mapa físico: relieve, inclinación, perspectiva, sombras, el mar
       y las dos capas. Esos bloques van más abajo marcados y solo han cambiado de
       tipografía los rótulos.
   =========================================================================== */
:root {
  /* --- paleta muestreada de las creatividades del partido --- */
  --vox-rojo: #c80d22;          /* bloque de énfasis; el rojo de «LA PAGA SEMANAL» */
  --vox-rojo-hondo: #a30a1b;    /* el mismo, para estados pulsados */
  --vox-granate: #b80101;       /* variante de prensa, más apagada */
  --vox-verde: #00583a;         /* la barra de cierre y el «GRACIAS A VOX» */
  --vox-verde-claro: #0d6b48;
  --vox-amarillo: #ffd600;      /* solo para señalar: flechas, arcos, avisos */

  /* Los dos de la bandera de España. NO son los del partido: van juntos y solo se usan juntos,
     en el filete del botón de afiliación. */
  --esp-rojo: #aa151b;
  --esp-oro: #f1bf00;

  --tinta: #1c1c1c;
  --tinta-2: #4c4c4a;
  /* #7d7d79 hasta el 11-oct-2026: daba 2,8:1 sobre el fondo, por debajo del mínimo legible
     (4,5:1) y peor aún al sol en el móvil. Este da 4,6:1 y sigue más claro que --tinta-2. */
  --tinta-3: #5b5b57;
  --linea: #c0c6bd;
  --linea-2: #dae0d6;
  /* El gris papel, con un verde tenue. Es EL MISMO color que el mar del mapa: el punto medio
     exacto del degradado que hornea pipeline/relieve_web.py (#cbd2c8 → #d5dcd2). Las tres
     páginas comparten fondo con el agua, y por eso el sitio se lee como una pieza. Si se
     cambia aquí, hay que cambiar MAR_N y MAR_S allí y regenerar el relieve. */
  --fondo: #d0d7cd;
  --fondo-2: #e3e8e0;
  /* Un peldaño más claro que los dos fondos, para lo que tiene que despegarse de la banda sin
     llegar a ser papel: las cifras destacadas y el recuadro del destacado. Sigue teniendo el
     verde tenue de la familia, así que no se lee como un blanco distinto. */
  --realce: #f0f3ee;
  --papel: #ffffff;

  /* Esquinas duras: el sistema es rectangular. 3 px es lo justo para que no se vea tosco
     en pantalla sin llegar a leerse como «redondeado». */
  --r: 3px;
  --r-chico: 2px;

  --sombra: 0 1px 0 rgba(28, 28, 28, .05), 0 8px 22px rgba(28, 28, 28, .16);
  --sombra-alta: 0 2px 0 rgba(28, 28, 28, .06), 0 20px 46px rgba(28, 28, 28, .26);

  /* Grano de papel. Va en el propio CSS como SVG para no pedir otro fichero. */
  --grano: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)' opacity='.06'/%3E%3C/svg%3E");

  --display: 'Anton', 'Barlow Condensed', Impact, system-ui, sans-serif;
  --titular: 'Barlow Condensed', 'Arial Narrow', system-ui, sans-serif;
  --texto: 'Barlow', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --cab: 62px;

  /* El mar: verde oscuro con un degradado muy leve que aclara hacia abajo. Estos dos
     valores son de reserva: los de verdad los escribe js/app.js leyéndolos de geo.json,
     que a su vez los saca del pipeline que hornea el agua en el ráster. Puestos a mano
     aquí, el fondo de la página y el agua de la imagen acabarían separándose. */
  --mar-n: #37473f;
  --mar-s: #4d6056;

  /* La provincia se pinta con transparencia normal sobre la montaña. Ese algo es lo que
     deja ver el relieve incluso en las provincias negras, que a plena opacidad taparían la
     montaña del todo. */
  --prov-alfa: .76;
}

* { box-sizing: border-box; }
/* SIN BARRAS DE SCROLL EN TODO EL SITIO (petición del usuario, 12-oct-2026): ni en la página,
   ni en la ficha, ni en los buscadores, ni en las listas. Todo sigue desplazándose igual con la
   rueda, el panel táctil o el dedo; solo deja de verse la barra. */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; width: 0; height: 0; }

html, body { height: 100%; margin: 0; }

body {
  font: 400 15px/1.5 var(--texto);
  color: var(--tinta);
  background: var(--fondo);
  display: grid;
  grid-template-rows: auto 1fr;
  /* sin esto la columna implícita se dimensiona al max-content del texto más largo y
     la página se hace más ancha que la pantalla en el móvil */
  grid-template-columns: minmax(0, 1fr);
  overflow: hidden;
  -webkit-text-size-adjust: 100%;
  /* arrastrar el mapa no debe seleccionar los rótulos de las provincias */
  user-select: none;
  -webkit-user-select: none;
}
/* el texto que sí se lee y se copia vuelve a ser seleccionable */
.ficha-contenido, .notas-cuerpo, .med-main { user-select: text; -webkit-user-select: text; }

h1, h2, h3, h4 { margin: 0; line-height: 1.02; font-weight: 400; }
button { font: inherit; color: inherit; }

/* --------------------------------------------------------- recursos de marca */
/* 1. El bloque macizo detrás del texto. Dos cosas obligatorias:
      · `box-decoration-break: clone`, o al partirse en dos líneas el bloque pierde el
        relleno lateral justo en el corte.
      · un interlineado holgado en el titular que lo contiene. Con el interlineado
        apretadísimo que pide Anton, el bloque de una línea se monta encima de la anterior
        y tapa el texto. En las creatividades del partido cada bloque va en su propia línea
        y con aire: es parte del recurso, no un defecto. */
.marca {
  background: var(--vox-rojo); color: #fff;
  padding: .11em .2em .16em; margin: 0 -.05em;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
h1:has(.marca), h2:has(.marca) { line-height: 1.18; }
.marca-negra { background: var(--tinta); color: #fff; }
/* 2. Palabra suelta en rojo dentro de una línea negra */
.rojo { color: var(--vox-rojo); }
.verde { color: var(--vox-verde); }
/* 3. Pegatina girada, como los rótulos superpuestos de las creatividades */
.pegatina { background: var(--papel); box-shadow: var(--sombra); transform: rotate(-.7deg); }

/* ------------------------------------------------------------------ cabecera */
/* La cabecera va en el verde institucional, el mismo de la barra de cierre de las
   creatividades. Todo lo que era negro pasa a blanco; lo que va dentro del bloque rojo se
   queda igual, que para eso es un bloque macizo y no un color de texto. */
.cabecera {
  display: flex; align-items: center; gap: 16px;
  padding: 0 14px; height: var(--cab);
  background: var(--vox-verde) var(--grano);
  color: #fff;
  z-index: 30;
}
/* El título es el enlace a la portada, y lo es en las tres páginas */
.cab-marca {
  min-width: 0; flex: 1; text-decoration: none; color: inherit;
  border-radius: var(--r-chico);
  display: flex; align-items: center; gap: 10px;
}
/* El icono del mapa 1 haciendo de logotipo. `flex: none` es obligatorio: dentro de un flex
   una imagen se encoge antes que el texto, y en pantalla estrecha se quedaba en una raya.
   El titular ya se ajusta solo con su `clamp`, así que quien cede es él. */
.cab-icono { flex: none; width: 34px; height: 34px; display: block; }
.cab-marca:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
/* El titular va SIEMPRE en una línea, también en el móvil más estrecho. El `clamp` lo
   escala con el ancho de la ventana y los botones se encogen a solo icono antes de que el
   título tenga que partirse: es él quien manda en la cabecera, no ellos. */
/* El tamaño NO es un porcentaje del ancho, es una resta: el hueco que le queda al titular
   es la ventana MENOS lo que ocupan los botones y los márgenes, que son píxeles fijos. Con
   un `vw` a secas, o sobraba sitio en las pantallas grandes o se cortaba en las pequeñas.
   Los 212 px son los CUATRO botones, el logotipo y los márgenes, y el 13,9 el ancho medio
   del titular en Anton por cada píxel de cuerpo (medido: 241 px de texto con 17,4 px de
   cuerpo).
   OJO: esa reserva hay que revisarla cada vez que se añade o se quita algo a los lados. Eran
   128 con tres botones; al entrar «Qué es la Ley de Nietos» el titular pasó a cortarse con
   puntos suspensivos por debajo de 375 px, porque la resta seguía descontando tres; y subió
   de 168 a 212 el 7-ago-2026, al ponerle el logotipo delante (34 px de icono + 10 de hueco).
   Medido con los cuatro: la barra de acciones ocupa 144 px en modo compacto y los márgenes
   y el hueco entre bloques suman 24. */
.cabecera h1 {
  font-family: var(--display);
  font-size: clamp(12px, calc((100vw - 212px) / 13.9), 26px);
  letter-spacing: -.005em;
  text-transform: uppercase; color: #fff; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; line-height: 1.24;
}
/* Al pasar por encima solo se atenúa lo que NO va en el bloque rojo: el bloque es una
   mancha maciza y bajarle la opacidad lo ensuciaría. */
.cab-marca:hover h1 { color: rgba(255, 255, 255, .82); }
.cab-resumen {
  margin: 3px 0 0; font-family: var(--titular); font-weight: 500;
  font-size: 13px; letter-spacing: .01em; color: rgba(255, 255, 255, .8);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cab-resumen strong { font-weight: 700; color: #fff; }
/* `position: relative` para que el desplegable del botón unificado cuelgue de AQUÍ. Se ancla
   a las acciones y no a `.cabecera` porque en el mapa la cabecera es una fila de la rejilla y
   no está posicionada, así que el menú se habría ido a buscar el viewport. */
.cab-acciones { display: flex; gap: 7px; flex: none; position: relative; }

/* Botones de la cabecera: rectángulo con filete, en blanco sobre el verde. Al pasar por
   encima se invierten, que es el gesto de las creatividades. */
.btn-icono {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 12px; border: 2px solid rgba(255, 255, 255, .85); border-radius: var(--r-chico);
  background: transparent; color: #fff; cursor: pointer; text-decoration: none;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; line-height: 1;
  transition: background .14s, color .14s, border-color .14s;
}
.btn-icono:hover { background: #fff; color: var(--vox-verde); border-color: #fff; }
.btn-icono.activo { background: #fff; color: var(--vox-verde); border-color: #fff; }

/* «Cómo lo paramos» va al revés que los demás: macizo y en ROJO SIEMPRE —también en la página
   a la que lleva—, para que se identifique de un vistazo como la llamada a la acción (petición
   del usuario, 12-oct-2026; antes iba en blanco y pasaba a rojo al pulsarlo). Al pulsarlo, y
   en el ordenador al pasar el ratón, se pone en blanco. */
.btn-destacado,
.btn-destacado.activo {
  background: var(--vox-rojo); color: #fff; border-color: var(--vox-rojo);
}
.btn-destacado:hover,
.btn-destacado:active {
  background: #fff; color: var(--vox-rojo); border-color: #fff;
}
.btn-icono svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.btn-texto {
  border: 0; background: none; cursor: pointer; padding: 8px 10px;
  font-family: var(--titular); font-size: 15px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; color: var(--tinta-2);
  border-radius: var(--r-chico);
}
.btn-texto:hover { background: var(--vox-rojo); color: #fff; }

/* --------------------------------------------------- barra flotante de mapas */
/* Un contenedor sin fondo: la pastilla de los iconos y, colgando de ella, la pestaña con
   la frase del mapa elegido. El alto TOTAL de este bloque es lo que js/mapa.js descuenta
   para encuadrar España (lo mide del DOM), así que la frase puede ocupar las líneas que
   haga falta sin acabar tapando el mapa. */
.barra-mapas {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 15; max-width: calc(100% - 24px);
  display: flex; flex-direction: column; align-items: center;
  pointer-events: none;                 /* solo la pastilla y la pestaña reciben el ratón */
}
.pastilla {
  pointer-events: auto; max-width: 100%;
  display: flex; align-items: center;
  border-radius: var(--r); padding: 5px;
  background: var(--papel);
  box-shadow: var(--sombra);
}
#pestanas { display: flex; gap: 3px; overflow-x: auto; scrollbar-width: none; }
#pestanas::-webkit-scrollbar { display: none; }
#pestanas button {
  display: inline-grid; place-items: center; flex: none;
  width: 46px; height: 40px; padding: 0;
  border: 0; border-radius: var(--r-chico); background: none;
  cursor: pointer; transition: background .14s, box-shadow .14s;
}
#pestanas button:hover { background: var(--fondo-2); }
/* El seleccionado lleva un aro rojo, no un fondo negro: los cinco iconos están dibujados
   con trazo oscuro y sobre negro se perdían los contornos. */
#pestanas button.activa {
  background: var(--papel);
  box-shadow: inset 0 0 0 2px var(--vox-rojo);
}
/* Sin seleccionar, el icono va desaturado pero CASI OPACO: la urna del mapa 5 es casi toda
   blanca y apagada desaparecía sobre la pastilla, que también es blanca. La diferencia la
   marcan el aro y el color, no el desvanecerse. */
.pest-icono {
  width: 26px; height: 26px; display: block;
  filter: grayscale(.75); opacity: .82;
  transition: filter .14s, opacity .14s, transform .14s;
}
#pestanas button:hover .pest-icono { filter: grayscale(.2); opacity: 1; }
#pestanas button.activa .pest-icono { filter: none; opacity: 1; transform: scale(1.06); }

/* NIVEL MUNICIPAL (petición del usuario, 12-oct-2026). La barra se queda con los dos mapas que
   hay por municipio, el 3 y el 4, y se VE cambiar para que se sepa dónde se está: los iconos
   1, 2 y 5 se pliegan uno tras otro, entra la etiqueta «Municipios» y la pastilla da un
   latido (js/app.js, animarBarra). Al volver a las provincias, lo mismo al revés. */
#pestanas button {
  overflow: hidden;
  transition: background .14s, box-shadow .14s, width .36s cubic-bezier(.2, .8, .3, 1),
    margin .36s cubic-bezier(.2, .8, .3, 1), opacity .24s, transform .36s cubic-bezier(.2, .8, .3, 1);
}
.barra-mapas.municipal #pestanas button:is([data-mapa="1"], [data-mapa="2"], [data-mapa="5"]) {
  width: 0; margin-left: -3px; opacity: 0; transform: scale(.35); pointer-events: none;
}
.barra-mapas.municipal #pestanas button[data-mapa="2"] { transition-delay: .05s; }
.barra-mapas.municipal #pestanas button[data-mapa="5"] { transition-delay: .1s; }
.nivel-lupa {
  flex: none; display: grid; place-items: center; overflow: hidden;
  width: 0; height: 40px; padding: 0; margin-right: 0; border: 0;
  border-radius: var(--r-chico); background: var(--vox-rojo); color: #fff; cursor: pointer;
  opacity: 0; transform: scale(.4); pointer-events: none;
  transition: width .38s cubic-bezier(.2, .8, .3, 1), margin .38s cubic-bezier(.2, .8, .3, 1),
    opacity .24s, transform .38s cubic-bezier(.2, .8, .3, 1), background .14s;
}
.nivel-lupa svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor;
  stroke-width: 2.7; stroke-linecap: round;
}
.barra-mapas.municipal .nivel-lupa {
  width: 46px; margin-right: 5px; opacity: 1; transform: none; pointer-events: auto;
  transition-delay: .14s;
}
.nivel-lupa:hover { background: #a50b1c; }
.nivel-lupa:focus-visible { outline: 2px solid var(--tinta); outline-offset: 2px; }
/* abierta: la lupa pasa a negro, como un botón pulsado */
.barra-mapas.buscando .nivel-lupa { background: var(--tinta); }

/* EL BUSCADOR DE LA LUPA: va en el sitio de la pregunta, superpuesto, y la pregunta se queda
   ocupando su hueco sin verse (así la barra mide lo mismo y el mapa no se recoloca). */
.barra-mapas.buscando .frase-mapa { visibility: hidden; }
.buscador-mun {
  position: absolute; left: 50%; transform: translateX(-50%);
  width: min(340px, calc(100vw - 24px)); padding: 8px; pointer-events: auto;
  border-radius: var(--r-chico); background: var(--papel); box-shadow: var(--sombra);
}
.buscador-mun[hidden] { display: none; }
.buscador-mun.abierta { animation: desplegar-buscador .3s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes desplegar-buscador {
  from { opacity: 0; clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}
/* 16 px: con menos, el iPhone amplía la página entera al tocar el campo */
.buscador-mun input {
  width: 100%; padding: 10px 12px; border: 0; border-radius: var(--r-chico);
  background: var(--fondo-2); color: var(--tinta);
  font-family: var(--titular); font-size: 16px; font-weight: 700; letter-spacing: .02em;
}
.buscador-mun input::placeholder { color: var(--tinta-3); text-transform: uppercase; }
.buscador-mun input:focus { outline: 2px solid var(--vox-rojo); outline-offset: 0; }
.bm-aviso { margin: 8px 4px 2px; font-size: 14px; color: var(--tinta-3); }
.bm-aviso[hidden] { display: none; }
.buscador-mun ul {
  list-style: none; margin: 6px 0 0; padding: 0;
  max-height: min(48vh, 360px); overflow-y: auto; overscroll-behavior: contain;
}
.buscador-mun li button {
  width: 100%; display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 9px 10px; border: 0; border-radius: var(--r-chico); background: none;
  text-align: left; cursor: pointer; color: var(--tinta);
  font-family: var(--titular); font-size: 15.5px; font-weight: 700;
}
.buscador-mun li button:hover, .buscador-mun li button:focus-visible { background: var(--fondo-2); outline: none; }
.bm-nombre small { font-weight: 500; color: var(--tinta-3); font-size: 13px; }
.bm-prov { flex: none; font-weight: 500; font-size: 13.5px; color: var(--tinta-3); }
.bm-mas { padding: 8px 10px 4px; font-size: 13px; color: var(--tinta-3); }
.pastilla.latido { animation: latido .56s cubic-bezier(.2, .8, .3, 1); }
@keyframes latido {
  0% { transform: scale(1); }
  38% { transform: scale(1.07); }
  100% { transform: scale(1); }
}

/* La pestaña de la frase: pegatina blanca ligeramente girada. Se despliega hacia abajo con
   un recorte, no con un escalado: escalar deformaría el texto mientras dura la animación. */
.frase-mapa {
  pointer-events: auto;
  margin: 7px 0 0; padding: 8px 15px 9px;
  max-width: min(600px, 100%);
  border-radius: var(--r-chico);
  background: var(--papel); box-shadow: var(--sombra);
  font-family: var(--titular); font-size: 15px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .015em; line-height: 1.14;
  text-align: center; color: var(--tinta); text-wrap: balance;
  transform: rotate(-.55deg);
}
.frase-mapa:empty { display: none; }
.frase-mapa.abierta { animation: desplegar .34s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes desplegar {
  from { opacity: 0; transform: rotate(-.55deg) translateY(-8px); clip-path: inset(0 0 100% 0); }
  to   { opacity: 1; transform: rotate(-.55deg);                  clip-path: inset(0 0 0 0); }
}

/* ===========================================================================
   MAPA FÍSICO — ZONA INTOCABLE
   De aquí hasta el final del bloque de rótulos, lo único que ha cambiado en el rediseño
   es la tipografía de los rótulos. La geometría, la inclinación, la perspectiva, el orden
   de capas y el mar están como estaban y romperlos cuesta días.
   =========================================================================== */
/* El mapa se ve como un TABLERO INCLINADO: el norte se hunde hacia el fondo y el sur se
   levanta hacia el espectador, de modo que el relieve se mira más de frente y no en planta.
   --inclinacion  grados de rotateX
   --perspectiva  distancia del punto de vista, en múltiplos del alto del contenedor
   --sobreancho / --sobrealto  cuánto mayor que el contenedor es el SVG. Hacen falta: al
       inclinar, los bordes del tablero se meten hacia dentro, y si midiera lo mismo que el
       contenedor se verían las esquinas vacías por arriba.
   js/mapa.js LEE estos valores para deshacer la proyección, así que aquí está el original
   y no hay que duplicarlos en el JavaScript. */
.lienzo {
  /* «clip» y no solo «hidden»: con «hidden» el lienzo sigue siendo un contenedor con scroll y
     el navegador lo desplaza al enfocar con el teclado una provincia que asoma por el borde
     (14-oct-2026: el mapa entero y la leyenda quedaban corridos 45 px hasta recargar). */
  position: relative; overflow: hidden; overflow: clip;
  --inclinacion: 38;
  --perspectiva: 2.4;
  --sobreancho: 1.34;
  --sobrealto: 1.72;
  /* El mismo degradado que lleva horneado el ráster, para que el borde del relieve se
     funda con el fondo. Aquí va en píxeles de pantalla y allí por latitud, así que solo
     coinciden del todo en el encuadre de casa; con un recorrido de 22 niveles de 255 la
     diferencia no se ve. */
  background: linear-gradient(180deg, var(--mar-n), var(--mar-s));
  perspective: var(--perspectiva-px, 1200px);
  perspective-origin: 50% 50%;
}

/* El tablero se inclina y SOLO contiene el relieve, que es una imagen: rasterizarlo no le
   quita nada. Los vectores van en #mapa, encima y sin transformar (ver js/mapa.js). */
.tablero {
  position: absolute; left: 50%; top: 50%;
  width: calc(100% * var(--sobreancho));
  height: calc(100% * var(--sobrealto));
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotateX(calc(var(--inclinacion) * 1deg));
  pointer-events: none;
}
#relieve { position: absolute; inset: 0; transform-origin: 0 0; }
.relieve-img { position: absolute; display: block; }
/* El agua del recuadro, al tono que le toca por su latitud (lo calcula js/app.js) */
.canarias-fondo { position: absolute; background: var(--mar-caja, var(--mar-s)); }
/* Discontinua OSCURA: sobre el mar hueso, la blanca de antes no se veía */
.canarias-borde {
  position: absolute; border: 1.5px dashed rgba(28, 28, 28, .34);
  border-radius: 2px;
}

/* Los vectores: plano, en píxeles de pantalla, ENCIMA del relieve.
   Las tres líneas de abajo son obligatorias juntas y ninguna sobra. `.tablero` lleva una
   transformación 3D, así que el navegador lo saca a una capa compuesta aparte; una capa así
   se puede pintar por encima de un hermano posterior que NO esté compuesto, y el z-index a
   secas no lo evita. El `translateZ(0)` saca también a #mapa a su propia capa, y entonces
   sí manda el z-index. Sin esto, al pulsar provincias de la periferia (Gerona era el caso
   claro) el relieve tapaba las provincias y el mapa se quedaba en gris sin nada de color.
   El SVG sigue SIN transformación 3D propia, así que no se congela en una textura y los
   rótulos y los bordes siguen nítidos a cualquier zoom: está comprobado. */
#mapa {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  z-index: 1;
  transform: translateZ(0);
  touch-action: none; cursor: grab;
}
.tablero { z-index: 0; }
#mapa:active { cursor: grabbing; }

/* DISOLUCIÓN DEL BORDE INFERIOR, SOLO EN EL TELÉFONO.
   Abajo, el mapa muere contra la barra del navegador con un corte recto que se ve duro. Esto
   lo funde.

   Es un degradado hacia `--fondo` ENCIMA del mapa, no una máscara sobre el mapa, y la
   diferencia importa: enmascarar `#mapa` o `.tablero` los saca a otra capa compuesta y ahí
   es donde este mapa ha dado siempre problemas de repintado. Un degradado en un elemento
   aparte no toca el pintado del mapa.

   Funciona porque el agua y el papel son EXACTAMENTE el mismo color (`--fondo` es el punto
   medio del mar): el mapa no se desvanece hacia «otro color», se desvanece hacia el suyo. Si
   algún día se separan esos dos colores, aquí se verá una banda.

   z-index 2: por encima del mapa (1) y por debajo de toda la interfaz (10-15), así que la
   leyenda y los botones quedan nítidos encima. */
@media (max-width: 899px) {
  .lienzo::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 76px;
    /* Ancho ajustado a mano: 132 px se comían demasiado mapa y el desvanecido se notaba muy
       arriba. A 76 px la disolución queda ceñida al borde —más marcada, pero sin volver al
       corte seco de antes—.
       Siguen siendo tres paradas y no dos: con un degradado lineal a secas, el ojo ve dónde
       empieza. La de en medio se saca de `--fondo` con `color-mix` y NO se escribe su rgb a
       mano: ese color tiene que seguir siendo el punto medio del mar (lo comprueba
       valida_web.py) y una copia literal aquí se separaría en cuanto se recalculara el
       relieve. La primera declaración es el respaldo para navegadores sin `color-mix`. */
    background: linear-gradient(to top, var(--fondo) 0%, var(--fondo) 30%, transparent 100%);
    background: linear-gradient(to top, var(--fondo) 0%, var(--fondo) 30%,
      color-mix(in srgb, var(--fondo) 48%, transparent) 62%, transparent 100%);
    pointer-events: none; z-index: 2;
  }
}

/* Las provincias van con transparencia normal, sin `mix-blend-mode`: mezclar obliga al
   navegador a releer el fondo (que es la capa 3D del relieve) y ahí es donde aparecían
   cercos a medio pintar. La transparencia deja ver la montaña igual y no cuesta nada. */
.prov {
  fill-opacity: var(--prov-alfa);
  stroke: #fff; stroke-width: .9; stroke-linejoin: round;
  cursor: pointer;
  transition: fill .45s ease;
}
/* Probado y descartado: poner `shape-rendering: optimizeSpeed` mientras el mapa se mueve
   sale MÁS caro, porque cambiar la clase obliga a recalcular el estilo de las 53 formas. */
/* Ni recuadro de foco ni ningún adorno al pulsar: el usuario no quiere marcas que indiquen
   que ha hecho clic. La respuesta al clic es el vuelo a la provincia y su ficha. */
.prov:focus, .prov:focus-visible, .prov:active { outline: none; }
/* id 54: Gibraltar. No es provincia y no tiene ficha, pero se pinta con el color de Cádiz,
   que es quien lo rodea (js/mapa.js lo lee de geo.color_prestado). En gris se leía como un
   agujero. El `fill` de aquí es solo el respaldo por si algún día no hay color prestado. */
.prov.sin-datos {
  fill: #b9c0c6;
  pointer-events: none; cursor: default;
}

.marcador {
  fill-opacity: var(--prov-alfa);
  stroke: #fff; stroke-width: 1.4; cursor: pointer;
  transition: fill .45s ease;
}
.marcador:focus, .marcador:focus-visible, .marcador:active { outline: none; }
#mapa:focus, #mapa *:focus { outline: none; }

/* Solo un realce MUY leve al pasar el ratón, para saber qué se va a pulsar. Al pulsar no
   queda ninguna marca: la provincia seleccionada no se subraya de ninguna manera. */
.capa-realce { pointer-events: none; }
.realce {
  fill: none; stroke: #fff; stroke-width: 2.2;
  stroke-linejoin: round; opacity: 0; transition: opacity .2s ease;
}
.realce-fondo { stroke: rgba(20, 24, 29, .4); stroke-width: 4; }
.capa-realce.sobre .realce { opacity: .75; }
.capa-realce.sobre .realce-fondo { opacity: .22; }

/* ------------------------------------------------- el segundo nivel: los municipios
   El canvas municipal (js/municipios.js) va plano, ENTRE el relieve (.tablero) y el SVG de
   provincias, que va después en el DOM y por eso queda encima. Lo coloca y lo transforma el
   JavaScript. Aparece y desaparece con un fundido corto al cruzar el umbral de zoom. */
.capa-municipios {
  position: absolute; left: 0; top: 0; z-index: 1;
  pointer-events: none; transform-origin: 0 0;
  opacity: 0; transition: opacity .25s ease;
}
.capa-municipios.visible { opacity: 1; }
/* La provincia que ya tiene sus municipios pintados se queda solo con su borde blanco, más
   grueso que el de los municipios para que la provincia se siga leyendo. */
.prov { transition: fill .45s ease, fill-opacity .25s ease; }
.prov.con-mun { fill-opacity: 0; pointer-events: none; stroke-width: 1.6; }
/* El municipio elegido SÍ se marca (la provincia no): sin la marca no se sabe cuál de las
   371 manchas de Burgos es el de la ficha. El señalado con el ratón, más suave. */
.capa-realce.municipio .realce { stroke-width: 2.4; }
/* El municipio elegido, relleno de su color encima de todo lo gris (js/mapa.js) */
.realce-relleno { stroke: none; fill-opacity: .9; }
.capa-realce.municipio.activa .realce { opacity: .95; }
.capa-realce.municipio.activa .realce-fondo { opacity: .45; }
.capa-realce.municipio.sobre .realce { opacity: .8; }
.capa-realce.municipio.sobre .realce-fondo { opacity: .25; }
/* El nombre del municipio junto al cursor, en escritorio. Sin caja ni borde: texto con un
   halo, como los rótulos del mapa. */
.mun-etiqueta {
  position: absolute; z-index: 3; pointer-events: none;
  font-family: var(--titular); font-weight: 700; font-size: 15px; text-transform: uppercase;
  color: var(--tinta); letter-spacing: .02em; white-space: nowrap;
  text-shadow: 0 0 3px #fff, 0 0 6px #fff, 0 0 9px rgba(255, 255, 255, .9);
  transform: translate(14px, -50%);
}
.mun-etiqueta[hidden] { display: none; }

.capa-rotulos { pointer-events: none; }
/* Al trabajar el SVG en píxeles de pantalla, el tamaño del rótulo es fijo y ya está: no
   hay que compensar el zoom con ninguna variable.
   La condensada es además una mejora funcional y no solo de estilo: al ocupar menos ancho,
   caben más nombres de provincia antes de que el recorte por ancho los apague. */
.rotulo {
  font-family: var(--titular); font-size: 13.5px; font-weight: 500;
  fill: #16181a; letter-spacing: .015em;
  paint-order: stroke fill;
  /* El halo va OPACO y algo más fino. Traslúcido, el relieve se colaba entre los trazos y
     las cifras de cinco dígitos del mapa 2 se leían fatal. */
  stroke: #fff; stroke-width: 2.8px; stroke-linejoin: round;
}
.rotulo.sobre-oscuro { fill: #fff; stroke: rgba(0, 0, 0, .62); }
/* Provincia apagada por una selección: el rótulo se atenúa pero NO desaparece. Los nombres
   tienen que poder leerse siempre, también los del resto del mapa. */
.rotulo.apagado { opacity: .5; transition: opacity .45s ease; }
/* La cifra es el dato: va en negrita y algo mayor que el nombre. Se probó en Anton y se
   descartó — a este tamaño y con halo, las cifras largas se emplastaban. */
.rotulo-valor { font-weight: 700; font-size: 15px; letter-spacing: .005em; }
/* Las cifras de los municipios (mapas 3 y 4 del nivel municipal): el mismo halo que los
   rótulos, algo menores. Aparecen y se van con el nivel, con un fundido. */
.capa-cifras-mun { pointer-events: none; opacity: 0; transition: opacity .3s ease; }
.capa-cifras-mun.visible { opacity: 1; }
.cifra-mun {
  font-family: var(--titular); font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  text-anchor: middle; fill: #16181a;
  paint-order: stroke fill; stroke: #fff; stroke-width: 2.4px; stroke-linejoin: round;
}
.cifra-mun.sobre-oscuro { fill: #fff; stroke: rgba(0, 0, 0, .6); }
.cifra-mun.apagada { opacity: .55; }
/* ======================= fin de la zona intocable del mapa ================== */

/* ---------------------------------------------------------------- leyenda */
/* A la DERECHA: el recuadro de Canarias ocupa la esquina inferior izquierda del mapa,
   igual que en los PDF, y la leyenda lo tapaba. */
.leyenda {
  position: absolute; right: 12px; bottom: 12px; z-index: 10;
  width: min(268px, calc(100vw - 24px));
  padding: 11px 13px 12px; border-radius: var(--r);
  background: var(--papel); box-shadow: var(--sombra);
}
.leyenda ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.leyenda li { display: block; }
/* Cada nivel es un botón: al pulsarlo deja en color solo sus provincias */
/* Sin `width: 100%`: la leyenda se dimensiona al contenido en pantalla estrecha, y un ancho
   porcentual dentro de un contenedor que se ajusta al contenido colapsaba las etiquetas a
   dos líneas. El `nowrap` remata que «Riesgo máximo» no se parta nunca. */
.ley-item {
  display: flex; align-items: center; gap: 9px; white-space: nowrap;
  padding: 4px 6px; margin: 0 -6px; border: 0; border-radius: var(--r-chico);
  background: none; cursor: pointer; text-align: left;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .02em; line-height: 1.1; color: var(--tinta);
  transition: background .14s, color .14s;
}
.ley-item:hover { background: var(--fondo-2); }
.ley-item.activo { background: var(--tinta); color: #fff; }
.ley-item.activo .muestra { border-color: rgba(255, 255, 255, .6); }
/* Cuadrados, no pastillas: las muestras del dato conservan su color exacto */
.muestra { width: 16px; height: 16px; flex: none; border: 1px solid rgba(0, 0, 0, .3); }
/* LA BARRA DE LA LEYENDA MUNICIPAL (12-oct-2026): un deslizador cuya pista es la escala de
   colores del mapa; lo que queda por debajo del umbral elegido se apaga en la pista igual que
   se apagan esos municipios en el mapa. Sin bordes (norma del usuario). */
.leyenda.con-barra { width: min(268px, calc(100vw - 24px)); }
/* en el teléfono la leyenda comparte la esquina con «Compartir» y «Descargar» (unos 105 px a
   la derecha): se deja ese hueco y algo de aire */
@media (max-width: 899px) { .leyenda.con-barra { width: min(260px, calc(100vw - 138px)); } }
.ley-umbral[hidden], #leyenda-items[hidden] { display: none; }
.lu-titulo {
  margin: 0 0 6px; font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .02em; line-height: 1.15; color: var(--tinta);
}
.lu-titulo span {
  display: block; margin-top: 2px; font-size: 13px; letter-spacing: .01em; color: var(--tinta-2);
}
.lu-barra {
  -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 26px;
  margin: 0; padding: 0; background: transparent; cursor: pointer; touch-action: none;
}
.lu-barra::-webkit-slider-runnable-track {
  height: 12px; border-radius: 6px;
  background: linear-gradient(90deg, rgba(222, 222, 216, .92) 0 var(--corte, 0%),
    transparent var(--corte, 0%)), var(--grad);
}
.lu-barra::-moz-range-track {
  height: 12px; border-radius: 6px;
  background: linear-gradient(90deg, rgba(222, 222, 216, .92) 0 var(--corte, 0%),
    transparent var(--corte, 0%)), var(--grad);
}
.lu-barra::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin-top: -6px;
  border-radius: 50%; background: #fff; cursor: grab;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .45), inset 0 0 0 6px var(--tinta);
}
.lu-barra::-moz-range-thumb {
  width: 24px; height: 24px; border: 0; border-radius: 50%; background: #fff; cursor: grab;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .45), inset 0 0 0 6px var(--tinta);
}
.lu-barra:focus-visible { outline: 2px solid var(--vox-rojo); outline-offset: 3px; border-radius: 6px; }
.lu-marcas {
  display: flex; justify-content: space-between; margin-top: 2px;
  font-family: var(--titular); font-size: 12px; font-weight: 700; color: var(--tinta-3);
}
/* al cambiar de nivel la leyenda cambia de contenido, y se ve entrar */
.leyenda.cambia #leyenda-items, .leyenda.cambia .ley-umbral { animation: leyenda-entra .42s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes leyenda-entra {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------- descargar la imagen 9:16 */
/* Pegado a la leyenda: a su IZQUIERDA en escritorio y, en el teléfono —donde la leyenda se
   va a la esquina de abajo a la izquierda—, a su DERECHA, en la de abajo a la derecha.
   `--leyenda-ancho` lo anota js/app.js midiendo la leyenda, porque no mide lo mismo en
   escritorio (268 px) que en el teléfono (lo que ocupe su contenido). El valor de reserva es
   el de escritorio, para que el botón no salte si el JavaScript tarda. */
.btn-descarga {
  position: absolute; z-index: 10;
  right: calc(12px + var(--leyenda-ancho, 268px) + 10px); bottom: 12px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 13px; border: 0; border-radius: var(--r-chico);
  background: var(--tinta); color: #fff; box-shadow: var(--sombra); cursor: pointer;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; line-height: 1;
  transition: background .14s;
}
.btn-descarga:hover { background: var(--vox-rojo); }
.btn-descarga svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
/* Con la ficha abierta manda el botón de su cabecera, que baja la imagen de esa provincia.
   Dos botones de descarga a la vez que bajan cosas distintas no se entienden. */
body.con-ficha .btn-descarga { display: none; }
/* Sin JavaScript no hay mapa que descargar y el botón no haría nada. `.con-js` lo pone
   js/app.js en su primera línea. */
html:not(.con-js) .btn-descarga { display: none; }

/* Compartir: el mismo botón, JUSTO ENCIMA del de descarga. Hereda toda la caja y solo cambia
   el alto al que se ancla; así los dos se mueven juntos con la leyenda y no hay dos posiciones
   que puedan separarse. Los 42 px son el alto del de descarga (32) más el hueco (10). */
.btn-compartir {
  position: absolute; z-index: 10;
  right: calc(12px + var(--leyenda-ancho, 268px) + 10px); bottom: 54px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 13px; border: 0; border-radius: var(--r-chico);
  background: var(--tinta); color: #fff; box-shadow: var(--sombra); cursor: pointer;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; line-height: 1;
  transition: background .14s;
}
.btn-compartir:hover { background: var(--vox-rojo); }
/* Los tres nodos del icono van MACIZOS y las dos varillas con trazo: dibujados los dos con
   `stroke` a este tamaño, los círculos se veían como anillos sucios. */
.btn-compartir svg {
  width: 16px; height: 16px; fill: currentColor; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round;
}
.btn-compartir svg path { fill: none; }
body.con-ficha .btn-compartir { display: none; }
html:not(.con-js) .btn-compartir { display: none; }

/* ------------------------------------------- las cinco páginas de /compartir/
   Casi nadie las ve: existen para que WhatsApp y compañía encuentren la vista previa del
   mapa concreto, y al visitante lo manda a la portada un `location.replace`. Lo que se
   estiliza aquí es lo que queda si el JavaScript no corre. */
body.compartir { display: block; overflow: auto; background: var(--fondo); }
.compartir-caja {
  max-width: 620px; margin: 0 auto; padding: 18vh 24px 40px; text-align: center;
}
.compartir-caja h1 {
  font-family: var(--display); font-size: clamp(30px, 8vw, 54px); line-height: 1.06;
  text-transform: uppercase; margin: 0 0 18px;
}
.compartir-caja p { font-size: 18px; color: var(--tinta-2); margin: 0 0 28px; }
.compartir-ir {
  display: inline-block; padding: 13px 26px; border-radius: var(--r-chico);
  background: var(--vox-rojo); color: #fff; text-decoration: none;
  font-family: var(--titular); font-size: 17px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
}

/* --------------------------------------------------------------- flotantes */
/* abajo, no arriba: arriba está la barra flotante de mapas */
.pista {
  position: absolute; left: 50%; top: auto; bottom: 14px; transform: translateX(-50%);
  max-width: calc(100% - 28px); text-align: center;
  margin: 0; padding: 8px 15px; border-radius: var(--r-chico); z-index: 10;
  background: var(--tinta); color: #fff;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; line-height: 1.15;
  pointer-events: none; transition: opacity .3s;
}
.pista.oculta { opacity: 0; }

.btn-reiniciar {
  position: absolute; right: 12px; top: 12px; z-index: 10;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 13px; border: 0; border-radius: var(--r-chico);
  background: var(--tinta); color: #fff; box-shadow: var(--sombra); cursor: pointer;
  font-family: var(--titular); font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; line-height: 1;
  opacity: 0; pointer-events: none; transform: translateY(-6px);
  transition: opacity .2s, transform .2s, background .14s;
}
.btn-reiniciar.visible { opacity: 1; pointer-events: auto; transform: none; }
.btn-reiniciar:hover { background: var(--vox-rojo); }
/* Dónde va este botón está repartido entre tres reglas y conviene verlas juntas:
     · aquí arriba, arriba a la derecha, que es su sitio en escritorio;
     · con la ficha abierta en escritorio, abajo a la izquierda (media query de 900);
     · en pantalla estrecha, arriba a la izquierda o abajo a la derecha según el ancho,
       porque abajo a la derecha está la leyenda y arriba en medio está la barra de mapas.
   `top: auto` o `bottom: auto` son obligatorios en cada salto: con `top` y `bottom` a la vez
   el botón se estira a todo el alto del lienzo. */
.btn-reiniciar svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }

.error {
  position: absolute; inset: auto 16px 16px; padding: 14px; border-radius: var(--r);
  background: var(--papel); color: var(--vox-rojo);
  font-size: 14px; font-weight: 600;
}

/* ------------------------------------------------------------------ ficha */
/* En el teléfono la ficha sube hasta JUSTO DEBAJO de la cabecera y tapa el mapa entero.
   Antes se quedaba en el 88 % del alto y asomaba una franja de mapa por arriba que no servía
   para nada: ni se podía usar el mapa (la ficha se lleva los gestos) ni se leía bien la
   ficha. `--cab` es la altura de la cabecera, así que las dos piezas encajan sin números
   repetidos. */
.ficha {
  position: fixed; z-index: 60; background: var(--papel);
  display: flex; flex-direction: column;
  left: 0; right: 0; bottom: 0; top: var(--cab);
  border-radius: 0; box-shadow: var(--sombra-alta);
  transform: translateY(101%);
  /* Algo más rápida y con una curva más decidida que antes: la tarjeta ya entra llena, así
     que lo único que se ve es el deslizamiento y conviene que sea corto.

     `visibility` VA EN LA TRANSICIÓN, y sin eso la ficha no se veía bajar: al quitar la
     clase, `visibility: hidden` se aplicaba de golpe en el mismo fotograma y la tarjeta
     desaparecía en el sitio en vez de deslizarse. Retrasándola lo que dura el movimiento, se
     ve el recorrido entero y solo entonces se oculta. Al ABRIR no se retrasa, o la ficha
     entraría invisible. */
  transition: transform .3s cubic-bezier(.3, .9, .3, 1), visibility 0s linear .3s;
  visibility: hidden;
}
.ficha.abierta {
  transform: none; visibility: visible;
  transition: transform .3s cubic-bezier(.3, .9, .3, 1), visibility 0s;
}
/* Mientras el dedo la lleva, la ficha tiene que seguir al dedo SIN transición: con ella
   puesta, cada movimiento se interpolaba durante 300 ms y la tarjeta iba por detrás. */
.ficha.arrastrando { transition: none; }

/* LA HOJA POR PASOS DEL TELÉFONO (petición del usuario, 12-oct-2026). Al tocar una provincia
   o un municipio la ficha sube solo hasta enseñar el nombre, tres cifras y «Ver ficha
   completa» (`.media`); por encima se sigue viendo el mapa con lo elegido en color. Hacia
   arriba, ficha completa; hacia abajo, se cierra (js/hoja.js). Lo que asoma lo mide js/app.js
   (`--alto-media`). Solo en la hoja de abajo: en el escritorio y en el teléfono en
   horizontal la ficha es un panel lateral y no tiene paso intermedio. */
.hoja-resumen, .ver-completa { display: none; }
@media (max-width: 899px) and (orientation: portrait), (max-width: 899px) and (min-height: 501px) {
  .ficha.abierta.media {
    transform: translateY(calc(100% - var(--alto-media, 40vh) - env(safe-area-inset-bottom, 0px)));
  }
  /* A media altura el contenido NO hace scroll, pero sin tocar su `overflow`: en el iPhone,
     pasar de `overflow: hidden` a `auto` al abrir la ficha completa dejaba la caja sin su
     scroll nativo y había que empujar fuerte para que bajase (lo vio el usuario el
     12-oct-2026). Solo se bloquea el gesto, y js/app.js la deja arriba del todo. */
  .ficha.media .ficha-contenido { touch-action: none; }
  .ficha:not(.media) .ficha-contenido { touch-action: pan-y; }
  /* a media altura no puede asomar NADA por debajo del botón (asomaba media línea de lo
     siguiente, cortada por el borde de la pantalla) */
  .ficha.media .ver-completa ~ * { visibility: hidden; }
  .ficha.media .hoja-resumen, .ficha.midiendo .hoja-resumen { display: grid; }
  .ficha.media .ver-completa, .ficha.midiendo .ver-completa { display: flex; }
}
/* El resumen y el botón van SEPARADOS, con aire de sobra: las cifras se tienen que leer
   enteras, sin que el botón se les eche encima (petición del usuario, 12-oct-2026). */
.hoja-resumen {
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 14px 0 20px;
  align-items: start;
}
.fr-dato { margin: 0; display: flex; flex-direction: column; gap: 3px; }
.fr-cifra {
  font-family: var(--titular); font-size: 23px; font-weight: 700; line-height: 1;
  color: var(--tinta); white-space: nowrap;
}
.fr-txt { font-size: 12.5px; line-height: 1.25; color: var(--tinta-2); }
.ver-completa {
  width: 100%; min-height: 44px; justify-content: center; align-items: center;
  border: 0; border-radius: var(--r-chico); background: var(--tinta); color: #fff;
  font-family: var(--titular); font-size: 15px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; cursor: pointer;
}
.ver-completa:active { background: var(--vox-rojo); }

/* El tirador se agarra con el dedo, así que necesita área táctil de verdad: los 4 px de la
   línea son lo que se VE, no lo que se puede tocar. El padding le da 30 px de alto real y
   `touch-action: none` evita que Safari se quede pensando si el gesto es un scroll. */
.ficha-tirador {
  flex: none; padding: 13px 0 13px; margin: 0 auto;
  width: 120px; display: flex; justify-content: center;
  cursor: grab; touch-action: none;
}
.ficha-tirador::before {
  content: ''; display: block; width: 44px; height: 4px; border-radius: 2px;
  background: var(--linea); transition: background .15s, width .15s;
}
.ficha-tirador:active { cursor: grabbing; }
.ficha-tirador:active::before, .ficha.arrastrando .ficha-tirador::before {
  background: var(--tinta-3); width: 56px;
}
/* EL MISMO BOTÓN DE CERRAR EN LAS DOS HOJAS: la ficha de provincia y el buscador. Antes el
   buscador cerraba con la palabra «Cerrar» y la ficha con una aspa en un recuadro; eran dos
   cosas distintas para lo mismo. La regla vive aquí una vez y las dos la usan. */
.btn-cerrar {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border: 2px solid var(--tinta); border-radius: var(--r-chico);
  background: var(--papel); color: var(--tinta);
  cursor: pointer; transition: background .14s, color .14s;
}
.btn-cerrar:hover { background: var(--tinta); color: #fff; }
.btn-cerrar svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round;
}

.ficha-cerrar {
  position: absolute; right: 10px; top: 12px; z-index: 2;
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 2px solid var(--tinta); border-radius: var(--r-chico); background: var(--papel);
  cursor: pointer; transition: background .14s, color .14s;
}
.ficha-cerrar:hover { background: var(--tinta); color: #fff; }
.ficha-cerrar svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.ficha-contenido { overflow-y: auto; overscroll-behavior: contain; padding: 6px 18px 34px; -webkit-overflow-scrolling: touch; }

/* La caja del riesgo va CENTRADA con el nombre y con aire por debajo: pegada a la primera
   pastilla se leía como parte de ella y no como lo que es, el dato de cabecera. */
.ficha-cab {
  /* EL NIVEL VA A LA DERECHA DEL NOMBRE, en una etiqueta de dos renglones —«RIESGO» pequeño
     arriba y el nivel debajo— (decisión del usuario, 11-oct-2026). Para que quepa SIEMPRE en
     una línea, todo el bloque escala con --k: js/app.js (ajustarCabeceraFicha) lo baja desde 1
     hasta que nada se sale, así que un nombre largo encoge a la vez el nombre, los botones y
     la etiqueta, y ninguno tapa a otro. Los 44 px de la derecha son el hueco de la ✕. */
  --k: 1;
  display: flex; align-items: center; gap: calc(12px * var(--k));
  padding: 12px 44px 0 0; margin-bottom: 22px;
}
.ficha-cab > div:first-child { flex: 0 0 auto; min-width: 0; }
/* La línea de arriba en rojo y caja alta condensada: la «pestaña» de las creatividades */
.ficha-sobre {
  margin: 0 0 4px; font-family: var(--titular); font-size: 13px; font-weight: 700;
  color: var(--vox-rojo); text-transform: uppercase; letter-spacing: .05em;
}
.ficha-cab h2 {
  font-family: var(--display); font-size: calc(40px * var(--k)); line-height: .92;
  text-transform: uppercase; letter-spacing: -.01em; white-space: nowrap;
}
/* El nombre y su botón de descarga, en la misma línea. `align-items: center` y no `baseline`:
   el titular es Anton a 40 px y el botón un cuadrado de 34, y alineados por la base el botón
   se colgaba por debajo del nombre. */
.ficha-nombre { display: flex; align-items: center; gap: calc(12px * var(--k)); }
.btn-descarga-ficha {
  flex: none; width: calc(34px * var(--k)); height: calc(34px * var(--k)); padding: 0; border: 0; border-radius: var(--r-chico);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--tinta); color: #fff; cursor: pointer; transition: background .14s;
}
.btn-descarga-ficha:hover, .btn-compartir-ficha:hover { background: var(--vox-rojo); }
.btn-descarga-ficha svg {
  width: calc(17px * var(--k)); height: calc(17px * var(--k)); fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
}
/* El de compartir, a la derecha del de descargar y con la misma caja. */
.btn-compartir-ficha {
  flex: none; width: calc(34px * var(--k)); height: calc(34px * var(--k)); padding: 0; border: 0; border-radius: var(--r-chico);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--tinta); color: #fff; cursor: pointer; transition: background .14s;
}
.btn-compartir-ficha svg {
  width: calc(17px * var(--k)); height: calc(17px * var(--k)); fill: currentColor; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round;
}
.btn-compartir-ficha svg path { fill: none; }

/* La caja conserva el color del NIVEL DE RIESGO, que es dato y no estilo. Ya NO lleva
   cifra: la puntuación del índice es una métrica interna y lo que el lector necesita es el
   nivel, que es justo lo que el color del mapa está diciendo. */
/* Dos renglones centrados: «RIESGO» pequeño arriba y el nivel debajo. A la derecha del todo. */
.nota-caja {
  margin-left: auto; flex: none; display: grid; justify-items: center; text-align: center;
  padding: calc(7px * var(--k)) calc(12px * var(--k)) calc(8px * var(--k)); color: #fff;
}
.nota-txt {
  font-family: var(--titular); font-size: calc(11px * var(--k)); line-height: 1;
  font-weight: 700; text-transform: uppercase; letter-spacing: .08em; opacity: .85;
}
.nota-nivel {
  margin-top: calc(4px * var(--k)); font-family: var(--display); font-size: calc(24px * var(--k));
  line-height: 1; text-transform: uppercase; letter-spacing: -.005em; white-space: nowrap;
}
.nota-prov { border: 0; cursor: pointer; font: inherit; }
.nota-prov:hover { filter: brightness(1.15); }
.ficha-oficial { margin: 6px 0 0; font-size: 13px; color: var(--tinta-3); }
.nivel-negro { background: #17110f; }
.nivel-rojo { background: #b1221a; }
.nivel-naranja { background: #c9620c; }

/* Los bloques se separan con un filete rojo grueso arriba, como las secciones del partido */
.bloque { margin-top: 26px; padding-top: 18px; border-top: 3px solid var(--tinta); }
.bloque h3 {
  font-family: var(--display); font-size: 21px; text-transform: uppercase;
  letter-spacing: -.005em; margin-bottom: 8px;
}
.bloque-intro { margin: 0 0 14px; font-size: 13.5px; color: var(--tinta-2); }

/* --------------------------------------------------------- ingredientes */
.ingredientes { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.ingrediente { padding: 13px 14px; background: var(--fondo-2); border-radius: var(--r-chico); }
.ing-cab { display: flex; align-items: flex-start; gap: 9px; }
.ing-num {
  flex: none; display: grid; place-items: center; width: 22px; height: 22px; margin-top: 1px;
  background: var(--tinta); color: #fff;
  font-family: var(--display); font-size: 14px; line-height: 1;
}
.ing-cab h4 {
  font-family: var(--titular); font-size: 16px; font-weight: 700; line-height: 1.1;
  text-transform: uppercase; letter-spacing: .01em;
}
/* La fila centra el icono con el bloque de cifras; dentro, las cifras y sus unidades se
   alinean por la base entre ellas, que es lo que pide leer un número con su unidad. */
.ing-dato { display: flex; align-items: center; gap: 10px; margin: 10px 0 0; }
.ing-valores { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; min-width: 0; }
.ing-cifra {
  font-family: var(--display); font-size: 34px; line-height: .9;
  letter-spacing: -.01em; font-variant-numeric: tabular-nums;
}
/* La segunda cifra grande (el número de votantes junto al porcentaje) va algo menor y
   separada, para que se lea como el complemento del dato principal y no como otro dato. */
.ing-cifra-2 { font-size: 27px; margin-left: 8px; color: var(--tinta-2); }
/* El porcentaje que acompaña en PEQUEÑO a la cifra de personas (tarjeta 3 de la provincia,
   14-oct-2026): a su derecha, a la altura de la unidad, en negro para que se lea como dato. */
.ing-cifra-chica { font-size: 21px; margin-left: 6px; color: var(--tinta); }
/* Unidad en dos renglones («VOTANTES / EXTRANJEROS»): el ÚLTIMO renglón se alinea con la base
   de la cifra, así el primero sube a su lado en vez de colgar por debajo. */
.ing-unidad-2r { line-height: 1; align-self: last baseline; }
.ing-unidad { font-family: var(--titular); font-size: 15px; font-weight: 700; text-transform: uppercase; color: var(--tinta-2); }
/* El acceso al mapa del ingrediente es su propio icono, el mismo de la barra flotante: se
   reconoce sin leer nada. Va alineado a la derecha y con área de pulsación de sobra. */
.ir-mapa {
  margin-left: auto; flex: none;
  display: grid; place-items: center; width: 46px; height: 46px; padding: 0;
  border: 0; background: var(--papel); border-radius: var(--r-chico);
  box-shadow: 0 1px 4px rgba(28, 28, 28, .16);
  cursor: pointer; transition: background .14s, box-shadow .14s;
}
.ir-mapa img { width: 30px; height: 30px; display: block; transition: transform .14s; }
.ir-mapa:hover { background: var(--fondo-2); box-shadow: 0 1px 3px rgba(28, 28, 28, .2); }
.ir-mapa:hover img { transform: scale(1.08); }
/* El mapa que se está viendo (ver marcarMapaEnFicha en app.js): fondo rojo claro, sin aro ni
   borde (cajas y pastillas van sin bordes: norma del usuario, 11-oct-2026). */
.ir-mapa.activa { background: #f8d3cf; box-shadow: none; }

/* La barra conserva EXACTAMENTE el degradado del dato: es la escala de los mapas */
.ing-barra {
  position: relative; height: 22px; margin: 10px 0 0;
  background: var(--linea-2); border-radius: var(--r-chico); overflow: hidden;
}
.ing-barra-relleno {
  height: 100%;
  background: linear-gradient(90deg, #f7d842, #ee8000 42%, #c81e1e 78%, #6e0b0b);
}
.ing-barra-txt {
  position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
  font-family: var(--titular); font-size: 12px; font-weight: 700;
  color: var(--tinta); font-variant-numeric: tabular-nums;
}
.ing-pie { margin: 9px 0 0; font-size: 13.5px; color: var(--tinta); }
/* la explicación de cómo puntúa cada ingrediente ya no va en la ficha: está en
   metodologia.html, que es donde se audita el método */

/* ------------------------------------------------------------------ gráfica */
.grafica { margin: 0; position: relative; }
/* `touch-action: pan-y`: en el móvil, deslizar en horizontal recorre la gráfica y deslizar en
   vertical sigue moviendo la hoja de la ficha (ver activarGrafica en ficha.js). */
.grafica svg {
  width: 100%; height: auto; display: block; touch-action: pan-y; cursor: crosshair;
  -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent;
}
.grafica svg:focus { outline: none; }
.grafica svg:focus-visible { outline: 2px solid var(--vox-rojo); outline-offset: 3px; }
.g-cursor { opacity: 0; pointer-events: none; transition: opacity .12s; }
.g-cursor.visible { opacity: 1; }
.g-cursor line { stroke: var(--tinta); stroke-width: 1; stroke-dasharray: 2 3; }
.g-cursor circle { fill: #fff; stroke: var(--vox-rojo); stroke-width: 2.6; }
.g-globo {
  position: absolute; z-index: 2; left: 0; top: 0; pointer-events: none;
  padding: 6px 10px 7px; border-radius: var(--r-chico); white-space: nowrap;
  background: var(--tinta); color: #fff; box-shadow: 0 4px 14px rgba(0, 0, 0, .2);
  font-family: var(--titular); line-height: 1.15;
}
.g-globo[hidden] { display: none; }
.g-globo-fecha { display: block; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; opacity: .78; }
.g-globo-valor { display: block; font-size: 18px; font-weight: 700; }
.g-globo-ley { display: block; font-size: 12.5px; font-weight: 700; color: #ff9d9d; }
.g-globo-ley:empty { display: none; }
.g-pista { margin: 6px 0 0; font-size: 12px; color: var(--tinta-3); }
/* «ratón» o «dedo» según el dispositivo tenga puntero fino o no */
.g-pista-dedo { display: none; }
@media (hover: none) { .g-pista-raton { display: none; } .g-pista-dedo { display: inline; } }
.g-rejilla { stroke: var(--linea-2); stroke-width: 1; }
.g-eje { font-family: var(--titular); font-size: 11px; font-weight: 500; fill: var(--tinta-3); }
.g-area { fill: rgba(200, 13, 34, .13); }
.g-linea { fill: none; stroke: var(--vox-rojo); stroke-width: 2.4; stroke-linejoin: round; }
.g-punto { fill: var(--vox-rojo); }
.g-ley { stroke: var(--tinta); stroke-width: 1.4; stroke-dasharray: 3 3; }
.g-ley-txt { font-family: var(--titular); font-size: 11.5px; font-weight: 700; fill: var(--tinta); text-transform: uppercase; }
.grafica figcaption { margin-top: 8px; font-size: 12.5px; color: var(--tinta-2); }
.fuente-min { display: block; margin-top: 3px; font-size: 11px; color: var(--tinta-3); }
/* `p.cargando` y no `.cargando` a secas: el `<body>` lleva la clase `cargando` durante el
   arranque, recogía estos 22 px de relleno y al quitársela toda la página saltaba hacia arriba
   (CLS medido de 0,14-0,17 en la auditoría del 11-oct-2026). */
p.cargando { font-family: var(--titular); font-size: 14px; font-weight: 700; text-transform: uppercase; color: var(--tinta-3); padding: 22px 0; text-align: center; }
/* La gráfica va la PRIMERA de la ficha (11-oct-2026). Mientras llega la serie, el hueco ya
   tiene el alto de la gráfica —la misma proporción 640×250 de su viewBox— para que al
   pintarse no empuje hacia abajo los ingredientes que el lector ya está mirando. */
.grafica-hueco:has(> p.cargando) { aspect-ratio: 640 / 250; display: grid; place-items: center; }
.bloque-grafica + .ingredientes { margin-top: 24px; }

/* -------------------------------------------- elecciones de la ficha (11-oct-2026)
   Antes una tabla de tres columnas; ahora una tarjeta por elección con su bandera, y las dos
   cifras —votos al PSOE y % del voto exterior— grandes y en el rojo del partido, con una
   barra que dibuja el porcentaje. Pensado primero para el móvil: una sola columna. */
.elecciones { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.elec {
  display: grid; grid-template-columns: 46px 1fr; column-gap: 12px; row-gap: 10px;
  align-items: center; padding: 13px 14px 14px;
  background: var(--fondo-2); border-radius: var(--r-chico);
}
.elec-bandera {
  width: 46px; height: 31px; object-fit: contain; background: #fff;
  border: 1px solid rgba(0, 0, 0, .14); border-radius: 2px; -webkit-touch-callout: none;
}
.elec-cab { min-width: 0; display: grid; gap: 2px; }
.elec-titulo {
  font-family: var(--titular); font-size: 16px; font-weight: 700; line-height: 1.12;
  text-transform: uppercase; letter-spacing: .02em; color: var(--tinta);
}
.elec-fecha { font-size: 13px; color: var(--tinta-2); }
.elec-cifras { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.elec-cifra b {
  display: block; font-family: var(--display); font-weight: 400; font-size: 34px; line-height: 1;
  color: var(--vox-rojo); letter-spacing: -.005em;
}
.elec-cifra b small { font-size: 20px; }
.elec-cifra b sup { font-size: 18px; vertical-align: super; line-height: 0; }
.elec-cifra span {
  display: block; margin-top: 4px; font-family: var(--titular); font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; color: var(--tinta-2);
}
.elec-barra {
  grid-column: 1 / -1; height: 10px; border-radius: 5px; overflow: hidden;
  background: rgba(0, 0, 0, .09);
}
.elec-barra i { display: block; height: 100%; background: var(--vox-rojo); border-radius: 5px; }
.elec-aviso { grid-column: 1 / -1; margin: 0; font-size: 12.5px; color: var(--tinta-2); }

/* ------------------------------------------------------------------ tablas */
.tabla-elecciones { width: 100%; border-collapse: collapse; font-family: var(--titular); font-size: 14px; }
.tabla-elecciones caption { text-align: left; font-size: 12.5px; color: var(--tinta-3); padding-bottom: 8px; font-family: var(--texto); }
.tabla-elecciones th, .tabla-elecciones td { padding: 7px 6px; text-align: right; border-bottom: 1px solid var(--linea-2); }
.tabla-elecciones thead th {
  font-size: 11.5px; color: #fff; background: var(--tinta); font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; border-bottom: 0; vertical-align: bottom;
}
/* la columna de la elección, a la izquierda también en la cabecera */
.tabla-elecciones .col-izq, .tabla-elecciones tbody th { text-align: left; }
.tabla-elecciones tbody th { font-weight: 500; }
.tabla-elecciones td { font-variant-numeric: tabular-nums; font-weight: 700; }
.num-fuerte { font-weight: 700; }

/* Los avisos van en amarillo: en las creatividades el amarillo es siempre el «ojo a esto» */
.avisos {
  margin-top: 12px; padding: 11px 13px; background: #fff8d6; border-radius: var(--r-chico);
}
.avisos p { margin: 0; font-size: 12.5px; color: #5c4a05; }
.avisos p + p { margin-top: 7px; }
.ast { font-weight: 700; }

/* El bloque del 23-J (rejilla de datos y recordatorio) se quitó de la ficha; sus estilos se
   fueron con él. Las notas de lectura siguen enteras en metodologia.html. */

/* EL PIE DE LA FICHA: fijo, siempre a la vista.
   El enlace a las medidas estaba al final del contenido, así que solo lo veía quien bajaba
   hasta abajo del todo, y la ficha es larga. Aquí va fuera de lo que hace scroll —hermano
   de `.ficha-contenido` dentro del flex de `.ficha`, con `flex: none`—, así que se queda
   anclado mientras la ficha esté abierta.
   El `env(safe-area-inset-bottom)` es para el iPhone: sin él, el botón queda debajo de la
   barra de gestos y se pulsa a medias. */
.ficha-pie {
  flex: none; padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--papel); border-top: 1px solid var(--linea-2);
  box-shadow: 0 -6px 18px rgba(0, 0, 0, .07);
}

/* El enlace a las medidas: bloque verde de cierre, que es el remate de todas las piezas */
.enlace-medidas {
  display: flex; align-items: center; gap: 13px; padding: 16px;
  border-radius: var(--r); background: var(--vox-verde); color: #fff; text-decoration: none;
  transition: background .16s;
}
.enlace-medidas:hover { background: var(--vox-verde-claro); }
/* Una sola línea, en caja alta y con el espaciado abierto: en Anton, apretada y a este
   tamaño, la frase se leía como un bloque compacto y costaba distinguir las palabras. */
.em-txt {
  flex: 1; font-family: var(--display); font-size: 19px; line-height: 1.1;
  text-transform: uppercase; letter-spacing: .055em;
}
.em-flecha {
  flex: none; width: 26px; height: 26px;
  fill: none; stroke: #fff; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .16s;
}
.enlace-medidas:hover .em-flecha { transform: translateX(3px); }

/* ----------------------------------------------------------- panel lista */
/* Fuera la barra verde que llevaba encima: solo decoraba y no se podía tocar. En su sitio
   va el mismo tirador de la ficha de provincia, con el mismo gesto (js/hoja.js). */
.panel-lista {
  position: fixed; z-index: 70; background: var(--papel);
  left: 0; right: 0; bottom: 0;
  /* `svh` y NO `dvh`. Esta era la causa del listado achatado: `dvh` es la altura del
     viewport DINÁMICA, y en iOS se recalcula cuando aparece el teclado, así que el panel
     pasaba de 78 % de la pantalla a 78 % de lo poco que deja el teclado y se aplastaba solo.
     `svh` es la altura con las barras del navegador desplegadas y no se mueve. La primera
     línea es el respaldo para navegadores sin esas unidades. */
  height: 78vh; height: 78svh;
  border-radius: 0; box-shadow: var(--sombra-alta);
  display: flex; flex-direction: column;
  transform: translateY(101%); visibility: hidden;
  /* misma razón que en la ficha: sin retrasar `visibility` no se ve bajar, desaparece */
  transition: transform .34s cubic-bezier(.22, .8, .28, 1), visibility 0s linear .34s;
}
.panel-lista.abierto {
  transform: none; visibility: visible;
  transition: transform .34s cubic-bezier(.22, .8, .28, 1), visibility 0s;
}
.panel-lista.arrastrando { transition: none; }
.pl-tirador {
  flex: none; padding: 11px 0 7px; margin: 0 auto;
  width: 120px; display: flex; justify-content: center;
  cursor: grab; touch-action: none;
}
.pl-tirador::before {
  content: ''; display: block; width: 44px; height: 4px; border-radius: 2px;
  background: var(--linea); transition: background .15s, width .15s;
}
.pl-tirador:active { cursor: grabbing; }
.pl-tirador:active::before, .panel-lista.arrastrando .pl-tirador::before {
  background: var(--tinta-3); width: 56px;
}
/* «Provincias y municipios» (11-oct-2026): un campo de búsqueda común y dos desplegables.
   El campo vuelve porque 8.132 municipios no se encuentran desplazando. Va arriba del todo
   de la hoja: en el móvil el teclado tapa la parte de abajo, no lo que se escribe. */
.pl-cab { display: flex; gap: 8px; align-items: center; padding: 6px 14px 8px; }
.pl-titulo {
  flex: 1; margin: 0; font-family: var(--display); font-size: 26px; line-height: 1;
  text-transform: uppercase; letter-spacing: -.005em;
}
.pl-pie { margin: 0; padding: 0 16px 8px; font-size: 12px; color: var(--tinta-3); }
.pl-busca {
  flex: none; position: relative; margin: 0 14px 8px;
}
.pl-busca svg {
  position: absolute; left: 12px; top: 50%; width: 19px; height: 19px; transform: translateY(-50%);
  fill: none; stroke: var(--tinta-3); stroke-width: 2.2; stroke-linecap: round; pointer-events: none;
}
/* Sin borde (norma del usuario): el campo se distingue por su fondo gris. 16 px de letra,
   que es lo mínimo para que el iPhone no amplíe la página al enfocarlo. */
#pl-campo {
  width: 100%; padding: 11px 12px 11px 40px; border: 0; border-radius: var(--r-chico);
  background: var(--fondo-2); color: var(--tinta);
  font-family: var(--titular); font-size: 16px; font-weight: 500;
}
#pl-campo:focus { outline: 2px solid var(--tinta); outline-offset: 0; }
#pl-campo::placeholder { color: var(--tinta-3); }
.pl-cuerpo { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 0 28px; }
.pl-grupo { margin: 0 8px 4px; }
.pl-grupo summary {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px; cursor: pointer;
  list-style: none; border-radius: var(--r-chico);
  font-family: var(--display); font-size: 19px; line-height: 1; text-transform: uppercase;
  letter-spacing: -.005em; color: var(--tinta);
}
.pl-grupo summary::-webkit-details-marker { display: none; }
/* La flecha del desplegable va dibujada (SVG), no con bordes: la norma del usuario es que no
   haya filetes ni bordes, y el validador los busca. */
.pl-grupo summary::after {
  content: ''; margin-left: auto; width: 14px; height: 14px; flex: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M2.5 5l4.5 4.5L11.5 5' fill='none' stroke='%234c4c4a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform .15s;
}
.pl-grupo[open] summary::after { transform: rotate(180deg); }
.pl-grupo summary:hover { background: var(--fondo-2); }
.pl-cuenta {
  font-family: var(--titular); font-size: 13px; font-weight: 700; color: var(--tinta-3);
  letter-spacing: .03em;
}
.pl-aviso { margin: 2px 10px 8px; font-size: 13px; color: var(--tinta-3); }
.pl-aviso[hidden] { display: none; }
.pl-mas { padding: 6px 10px 2px; font-size: 12.5px; color: var(--tinta-3); }
#lista-provincias, #lista-municipios { list-style: none; margin: 0; padding: 0; }
#lista-municipios small {
  font-family: var(--texto); font-size: 12px; font-weight: 400; text-transform: none;
  letter-spacing: 0; color: var(--tinta-3);
}
#lista-provincias button, #lista-municipios button {
  width: 100%; display: flex; align-items: center; gap: 11px;
  padding: 9px 10px; border: 0; background: none; border-radius: var(--r-chico);
  cursor: pointer; text-align: left;
  font-family: var(--titular); font-size: 16px; font-weight: 500;
}
#lista-provincias button:hover, #lista-municipios button:hover { background: var(--fondo-2); }
.lp-punto { width: 13px; height: 13px; flex: none; border: 1px solid rgba(0, 0, 0, .28); }
.lp-nombre { flex: 1; text-transform: uppercase; letter-spacing: .01em; }
.lp-nivel {
  font-family: var(--titular); font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--tinta-3);
}

/* -------------------------------------------------- notas de lectura */
/* Ya no van en un diálogo del mapa: viven en metodologia.html. Los estilos se quedan aquí
   porque esa página los reutiliza con el mismo marcado (section > h3 + p). */
.notas-cuerpo section { padding: 14px 0; border-bottom: 1px solid var(--linea-2); }
.notas-cuerpo section:last-child { border-bottom: 0; }
.notas-cuerpo h3 {
  font-family: var(--titular); font-size: 17px; font-weight: 700; margin-bottom: 5px;
  text-transform: uppercase; letter-spacing: .01em;
}
.notas-cuerpo p { margin: 0; font-size: 13.5px; color: var(--tinta-2); }
.notas-cuerpo p + p { margin-top: 8px; }
.notas-fuente p { font-size: 12px; color: var(--tinta-3); }

/* ------------------------------------------------- bloque indexable de provincia
   Lo escribe pipeline/paginas_provincia.py en las 52 páginas `/provincia/<slug>/`. Es el
   contenido que lee un buscador y lo único que ve quien llegue sin JavaScript, que en este
   sitio es quien no puede ver nada más: el mapa entero es JavaScript.

   En cuanto arranca la aplicación se oculta (`.con-js`, que pone js/app.js en su primera
   instrucción), porque entonces el visitante ve la ficha de verdad sobre el mapa con esta
   misma información y repetirla debajo sobraría. No es contenido escondido al buscador: es
   el mismo dato que la ficha enseña, y Google, que ejecuta el JavaScript, ve la ficha. */
.prov-seo { max-width: 720px; margin: 0 auto; padding: 26px 20px 40px; }
.con-js .prov-seo { display: none; }
.prov-seo h1 { font-family: var(--titular); font-size: clamp(28px, 7vw, 44px); line-height: 1.06; text-transform: uppercase; margin: 0 0 10px; }
.prov-seo-nivel { font-family: var(--titular); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; font-size: 14px; color: #fff; background: var(--vox-rojo); display: inline-block; padding: .18em .45em; margin: 0 0 18px; }
.prov-seo-datos { margin: 0 0 20px; padding-left: 18px; }
.prov-seo-datos li { margin-bottom: 10px; line-height: 1.5; }
.prov-seo-aviso { font-size: 13.5px; color: var(--tinta-2); margin: 0 0 26px; }
.prov-seo-otras h2 { font-family: var(--titular); font-size: 16px; text-transform: uppercase; margin: 0 0 10px; }
.prov-seo-otras ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 14px; }

/* ---------------------------------------------------------- pie legal
   Los enlaces obligatorios, en todas las páginas. En las de lectura va como un pie normal;
   en el mapa, que ocupa la pantalla entera, va fijo y pequeño abajo a la izquierda, y se
   esconde cuando hay una ficha abierta porque esa esquina es la única que le queda libre
   al botón «Ver España». */
.pie-legal { display: flex; flex-wrap: wrap; gap: 6px 16px; justify-content: center; padding: 18px 20px 26px; font-size: 12px; }
.pie-legal a { color: var(--tinta-3); text-decoration: none; }
.pie-legal a:hover { color: var(--tinta); text-decoration: underline; }
body:not(.pagina-medidas) .pie-legal {
  position: fixed; left: 10px; bottom: 6px; z-index: 4;
  padding: 0; justify-content: flex-start; gap: 10px; font-size: 11px;
  transition: opacity .2s;
}
body:not(.pagina-medidas) .pie-legal a { color: var(--tinta-3); }
body.con-ficha .pie-legal { opacity: 0; pointer-events: none; }
/* En el teléfono va CENTRADO abajo del todo, discreto, en el hueco que queda entre la
   leyenda y «Ver España». Antes se ocultaba en móvil, y el aviso legal y la política de
   privacidad tienen que estar a mano desde cualquier página, también desde el mapa. */
@media (max-width: 899px) {
  body:not(.pagina-medidas) .pie-legal {
    left: 0; right: 0; bottom: 4px;
    justify-content: center; gap: 12px; font-size: 10.5px;
  }
}

/* ------------------------------------------------------- aviso de cookies
   Solo aparece si hay analítica configurada (js/config.js). Lo pinta
   js/consentimiento.js.

   Los dos botones tienen EL MISMO tamaño, el mismo peso y el mismo relieve a propósito: la
   AEPD persigue expresamente los diseños en los que rechazar cuesta más que aceptar, así
   que «Rechazar» no puede ser un enlace pequeño ni ir en gris claro. Si alguien retoca esto
   más adelante, esa simetría es lo único que no se puede tocar. */
/* Va CENTRADO y bloqueando la página: si no, mucha gente no decide nunca y no se puede
   medir a nadie. No es un «muro de cookies» —lo que la norma prohíbe— porque las dos
   salidas son reales: se puede rechazar y seguir usando la web igual. */
.cookies {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center; padding: 20px;
  background: rgba(20, 20, 20, .72);
  animation: cookies-entra .18s ease-out;
}
@keyframes cookies-entra { from { opacity: 0; } to { opacity: 1; } }
/* En las páginas de lectura hay que bloquear el scroll de fondo mientras el modal está
   abierto. Va en las DOS, html y body: en `body` a secas la regla de maquetación de las
   páginas de lectura ganaba y se seguía pudiendo desplazar la página por detrás. */
/* ============================================================ la barra de zoom del mapa */
/* Pegada al borde derecho de la pantalla y solo en escritorio: en el móvil están el pellizco
   y el doble toque, y una barra de doce píxeles se pulsa mal con el dedo.
   Rectangular y sin curvas, como todo lo demás del sistema. */
/* VA CENTRADA EN LA PÁGINA, CABECERA INCLUIDA, y por eso es `fixed` y no `absolute`. Estando
   dentro del lienzo, un `top: 50%` es el centro del MAPA, que empieza debajo de la cabecera:
   la barra quedaba medio alto de cabecera más abajo del centro real. Con `fixed` el 50 % es el
   de la ventana. Se puede porque en esta página el mapa ocupa la ventana entera y no hay
   scroll, así que no hay diferencia entre estar fija a la ventana y estarlo al documento; y
   ningún antecesor crea bloque contenedor —el `rotateX` está en `.tablero`, que es hermano y
   no padre—, así que el `right: 0` sigue siendo el borde de la pantalla. */
.zoom-barra {
  position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 25;
  display: grid; justify-items: center; gap: 4px;
  padding: 6px 3px;
  /* MUY TRANSPARENTE a propósito: la herramienta no puede tapar el mapa, que es el contenido.
     Lo único que hace el velo es separar los signos del relieve lo justo para que se lean. */
  background: rgba(255, 255, 255, .28);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.zoom-signo {
  width: 18px; height: 18px; padding: 0; border: 0; cursor: pointer;
  background: transparent; color: var(--tinta-2);
  font-family: var(--titular); font-size: 14px; font-weight: 700; line-height: 1;
  transition: color .14s;
}
.zoom-signo:hover { color: var(--vox-rojo); }
.zoom-signo:focus-visible { outline: 2px solid var(--vox-rojo); outline-offset: 1px; }

/* EL CONTROL ES UN `range` GIRADO. `writing-mode: vertical-rl` es lo que hoy pone un `range`
   en vertical de verdad —`appearance: slider-vertical` está obsoleto y `orient` solo lo
   entiende Firefox—, y se deja el atributo `orient` en el HTML como red para Firefox viejo.
   `direction: rtl` sube el valor hacia ARRIBA: sin él, el máximo queda abajo y el `+` de
   arriba no correspondería con nada. */
/* EL RAÍL LO PINTA EL PROPIO CONTROL, en su fondo, y no el pseudoelemento del carril. Es la
   única forma de que el cuadrado quede centrado SIN adivinar nada: dónde coloca cada navegador
   el tirador respecto al carril no está definido —Chrome y Firefox no coinciden— y ajustarlo
   con un margen a ojo dejaba el cuadrado a un lado del raíl. Así:
     · el raíl se dibuja al 50 % del ancho ±1,5 px, o sea centrado por construcción;
     · el control mide exactamente lo que el tirador, así que el tirador ocupa todo el ancho y
       su centro ES el centro del control.
   Los dos centros coinciden porque son el mismo, no porque cuadren las cuentas. */
.zoom-rango {
  writing-mode: vertical-rl; direction: rtl;
  width: 11px; height: 104px; margin: 0; padding: 0;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  background: linear-gradient(to right,
    transparent calc(50% - 1.5px), rgba(28, 28, 28, .3) calc(50% - 1.5px),
    rgba(28, 28, 28, .3) calc(50% + 1.5px), transparent calc(50% + 1.5px));
}
.zoom-rango::-webkit-slider-runnable-track { width: 100%; background: transparent; }
.zoom-rango::-moz-range-track { width: 100%; background: transparent; }
/* El tirador es un CUADRADO, que es lo que se pidió y además lo que toca en este sistema. */
.zoom-rango::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 11px; height: 11px; margin-left: 0;
  background: var(--vox-rojo); border: 0; border-radius: 0;
}
.zoom-rango::-moz-range-thumb {
  width: 11px; height: 11px;
  background: var(--vox-rojo); border: 0; border-radius: 0;
}
.zoom-rango:focus-visible { outline: 2px solid var(--vox-rojo); outline-offset: 2px; }
@media (max-width: 860px), (hover: none) {
  .zoom-barra { display: none; }
}
/* Con la ficha abierta el panel entra por la derecha y taparía la barra justo cuando el mapa
   sigue a la vista a su izquierda. Se corre hasta el canto del panel, que es la misma solución
   que ya usa «Ver España» al abrirse la ficha.
   EL ANCHO NO SE ESCRIBE AQUÍ: lo mide js/app.js del propio panel y lo deja en
   `--ficha-ancho`. Escrito a mano ya se descuadró una vez —el panel no mide lo mismo en todos
   los anchos de ventana— y el resultado es una barra medio tapada, que es peor que ninguna. */
body.con-ficha .zoom-barra { right: var(--ficha-ancho, 460px); }

html.con-cookies, body.con-cookies { overflow: hidden; }

.cookies-caja {
  width: min(520px, 100%); max-height: 90vh; overflow-y: auto;
  background: #fff; color: var(--tinta);
  padding: 30px 28px 24px; border-radius: var(--r);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .45);
}
.cookies-caja h2 {
  font-family: var(--titular); font-size: clamp(21px, 5.4vw, 27px); line-height: 1.1;
  text-transform: uppercase; margin: 0 0 14px;
}
.cookies-txt { font-size: 14.5px; line-height: 1.55; color: var(--tinta-2); }
.cookies-txt strong { color: var(--tinta); }
.cookies-txt p { margin: 0 0 10px; }
.cookies-pie { margin: 16px 0 0; font-size: 12.5px; color: var(--tinta-3); text-align: center; }
.cookies-pie a { color: var(--tinta-3); text-decoration: underline; }
.cookies-btns { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
/* LOS DOS BOTONES TIENEN QUE MEDIR LO MISMO. El color puede distinguirlos —«Aceptar todas»
   va en el verde institucional para que sea la opción evidente— pero el tamaño, la
   tipografía, el peso, el relleno y el número de clics son idénticos, y los dos van al mismo
   nivel. Ahí está la diferencia entre destacar una opción, que es legítimo, y esconder la
   otra, que invalida el consentimiento de TODOS, también el de quien aceptó. */
.cookies-btns button {
  font-family: var(--titular); font-size: 15px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; padding: 15px 22px; width: 100%;
  border: 2px solid transparent; border-radius: var(--r); cursor: pointer;
}
/* Sobre fondo blanco los dos tienen que verse igual de botón. «Aceptar todas» va en verde
   macizo y «Rechazar» en blanco con el mismo borde de 2 px en tinta: distinto
   color, idéntica presencia. Un secundario sin borde se lee como un simple enlace, y ese es
   el patrón que invalida el consentimiento.
   OJO CON LA ESPECIFICIDAD: van con `.cookies-btns` delante a propósito. Como `.cookies-no`
   a secas (0,1,0) pierde contra `.cookies-btns button` (0,1,1), el `border-color` de la
   regla común ganaba y dejaba el botón de rechazar SIN borde visible. */
.cookies-btns .cookies-si { background: var(--vox-verde); color: #fff; border-color: var(--vox-verde); }
.cookies-btns .cookies-no { background: #fff; color: var(--tinta); border-color: var(--tinta); }
.cookies-btns button:hover { filter: brightness(1.08); }
.cookies-btns button:focus-visible { outline: 3px solid var(--vox-amarillo); outline-offset: 2px; }

/* ---------------------------------------------------------------- cargador */
.cargador { position: fixed; inset: 0; display: none; place-items: center; background: var(--fondo) var(--grano); z-index: 100; }
body.cargando .cargador { display: grid; }
.cargador span {
  width: 28px; height: 28px;
  border: 3px solid var(--linea); border-top-color: var(--vox-rojo);
  animation: giro .8s linear infinite;
}
@keyframes giro { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------ escritorio */
@media (min-width: 900px) {
  :root { --cab: 66px; }
  .cabecera { padding: 0 20px; }
  .cabecera h1 { font-size: 26px; }
  .cab-resumen { font-size: 14px; }

  /* La ficha es un panel lateral que se pone ENCIMA del mapa. El lienzo ya NO se encoge:
     encogerlo abría un hueco que la tarjeta tardaba media segundo en tapar, y obligaba a
     rehacer la proyección en mitad del vuelo. Lo que el panel tapa se descuenta en
     #margenesInterfaz de js/mapa.js, así que la provincia se encuadra en la parte que
     queda a la vista y el mapa no cambia de tamaño ni una vez. */
  .ficha {
    left: auto; top: 0; right: 0; bottom: 0;
    width: 460px; height: 100dvh;
    transform: translateX(101%);
    border-top: 0;
  }
  .ficha-tirador { display: none; }
  .ficha-contenido { padding: 18px 24px 40px; }
  .ficha-cab { padding-top: 6px; }
  body.con-ficha .leyenda { display: none; }

  /* En escritorio el panel entra desde la derecha, no desde abajo: el tirador no pinta nada
     y el gesto de bajarlo tampoco. */
  .pl-tirador { display: none; }
  .panel-lista {
    left: auto; top: calc(var(--cab) + 10px); right: 12px; bottom: auto;
    /* `svh` por lo mismo que en el teléfono: este panel lleva un campo de texto, y en una
       tableta con teclado en pantalla `dvh` lo encogería al escribir. */
    width: 350px; height: min(70vh, 620px); height: min(70svh, 620px);
    transform: translateX(calc(100% + 16px));
    border-top: 5px solid var(--vox-verde);
  }
  .leyenda { right: 16px; bottom: 16px; }
  .btn-descarga { right: calc(16px + var(--leyenda-ancho, 268px) + 12px); bottom: 16px; }
  .btn-compartir { right: calc(16px + var(--leyenda-ancho, 268px) + 12px); bottom: 60px; }
  .btn-reiniciar { right: 16px; top: 16px; }
  /* con la ficha abierta, la esquina de abajo a la izquierda es la única que el panel no
     tapa (y la leyenda se oculta sola con la ficha abierta) */
  body.con-ficha .btn-reiniciar { left: 16px; bottom: 16px; top: auto; right: auto; }
  /* `top` va explícito a auto: si se fijan `top` y `bottom` a la vez, la píldora se
     estira a toda la altura del lienzo y se ve como un pegote oscuro sobre el mapa */
  .pista { top: auto; bottom: 18px; }
}

/* Entre móvil y escritorio la cabecera se queda sin sitio: el resumen sobra antes
   que los botones, y el rótulo de los botones antes que su icono. */
@media (max-width: 899px) {
  .cab-resumen { display: none; }
  /* en pantalla estrecha la inclinación se come más alto útil, pero se mantiene marcada */
  .lienzo { --inclinacion: 30; --sobreancho: 1.26; --sobrealto: 1.50; }
  .barra-mapas { top: 10px; }
  .pastilla { padding: 4px; }
  #pestanas button { width: 42px; height: 36px; }
  .pest-icono { width: 24px; height: 24px; }
  .frase-mapa { font-size: 14px; padding: 7px 12px 8px 11px; margin-top: 5px; }
  /* «VER ESPAÑA» SE QUEDA EN SU ICONO —el recuadro de las cuatro esquinas— y vuelve arriba a
     la derecha, igual que en escritorio. Antes bajaba a la esquina de abajo porque con el
     rótulo no cabía al lado de la barra de mapas; sin él sí cabe: la barra va centrada y su
     pastilla mide unos 218 px, así que a la derecha quedan libres más de 60.
     `bottom: auto` es obligatorio: con `top` y `bottom` a la vez el botón se estira a todo el
     alto del lienzo. */
  .btn-reiniciar { top: 10px; bottom: auto; right: 10px; left: auto; padding: 10px; }
  .btn-reiniciar span { display: none; }
  /* LAS CAJAS SE SUBEN Y PIERDEN LA SOMBRA DURA.
     Con el degradado del borde inferior, dejarlas pegadas abajo tenía dos efectos malos: sus
     sombras caían sobre la parte ya desvanecida y dibujaban un cerco oscuro, y al quedar
     nítidas justo donde el mapa se disuelve, hacían que el corte de los laterales se notara
     MÁS que sin degradado. Subidas por encima de la banda y con una sombra suave, la
     disolución se lee igual de limpia en el centro que en los lados. */
  .btn-reiniciar { box-shadow: 0 2px 10px rgba(0, 0, 0, .12); }
  .leyenda { bottom: 30px; width: auto; padding: 9px 12px; box-shadow: 0 2px 10px rgba(0, 0, 0, .12); }
  .btn-descarga {
    right: calc(10px + var(--leyenda-ancho, 200px) + 8px); bottom: 30px;
    padding: 8px 11px; font-size: 13px; box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
  }
  .btn-compartir {
    right: calc(10px + var(--leyenda-ancho, 200px) + 8px); bottom: 71px;
    padding: 8px 11px; font-size: 13px; box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
  }
  .leyenda li { font-size: 13px; gap: 8px; }
  .muestra { width: 14px; height: 14px; }
  .ficha-cab h2 { font-size: calc(36px * var(--k)); }
  /* Por encima de la leyenda, que en el teléfono mide unos 118 px de alto y arranca a 30 px
     del borde. Medido: a menos de 148 px la pista se le monta encima y tapa «Riesgo máximo». */
  .pista { bottom: 160px; }
}
/* La leyenda solo se va a la izquierda en el teléfono. Entre 560 y 900 px la pantalla es
   ancha y baja, el recuadro de Canarias baja a esa misma esquina y la leyenda lo tapaba.
   Ahí la leyenda ocupa el abajo-derecha, y el botón de descarga se le pone a la izquierda.
   «Ver España» ya no entra en el reparto: por debajo de 900 px vive arriba a la derecha, solo
   con su icono. */
@media (min-width: 560px) and (max-width: 899px) {
  .leyenda { right: 10px; left: auto; }
}
/* Entre 900 y 1100 px la pista «Pulsa una provincia…», centrada abajo, chocaba con los botones
   de compartir y descargar, que van pegados a la izquierda de la leyenda: medido a 1024 px,
   la pista llegaba a x=643 y el botón empezaba en 615. Ahí se sube por encima de los botones.
   (Por encima de 1100 px ya no se tocan; por debajo de 900 px la sube la regla de arriba,
   que la pone sobre la leyenda.) */
@media (min-width: 900px) and (max-width: 1100px) {
  .pista { bottom: 100px; }
}
/* Los botones sueltan su rótulo bastante antes de que el título tenga que apretarse: por
   debajo de 1160 px quedan en iconos cuadrados, que es lo que deja el ancho al titular.
   ERAN 860 px CON TRES BOTONES. Con el cuarto —«Qué es la Ley de Nietos»— pasó a 1060.
   El 11-oct-2026 «Provincias» pasó a llamarse «Provincias y municipios» y la barra de
   acciones creció de 640 a 718 px: a 1083 px de ventana el titular salía cortado.
   La cuenta, medida y no estimada: 718 de botones + 301 de titular + 34 de logotipo + 66 de
   márgenes y huecos = 1119 px, así que el corte se pone en 1160 para no ir al límite. Si algún
   día cambia un rótulo o se añade o se quita un acceso, este número hay que volver a medirlo. */
@media (max-width: 1160px) {
  .cabecera { gap: 10px; padding: 0 10px; }
  .cab-acciones { gap: 5px; }
  /* En la cabecera compacta el titular se centra EN SU HUECO, que es lo que queda antes de
     chocar con los botones (`.cab-marca` es `flex: 1`, así que ese hueco ya está calculado).
     NO se centra respecto a la pantalla: los botones están solo a un lado, y centrarlo
     contra la ventana lo metería debajo de ellos. El `clamp` deja holgura en casi todos los
     anchos, y sin esto el título queda pegado al borde izquierdo con un vacío delante de los
     botones. Va en esta media query y no en la de 899 porque es aquí donde los botones
     pasan a solo icono: por encima la cabecera se lee como la ancha y el título va alineado
     a la izquierda igual que en escritorio. */
  .cabecera h1 { text-align: center; }
  .btn-icono span { display: none; }
  .btn-icono { padding: 0; width: 38px; height: 38px; justify-content: center; }
  .btn-icono svg { width: 17px; height: 17px; }
  /* TRES BOTONES EN MÓVIL, CUATRO OPCIONES EN ESCRITORIO. «Provincias» y «Metodología y
     datos» se funden aquí en un solo botón que las despliega: con cuatro accesos en una
     pantalla de 320 px no le queda hueco al titular, y el titular es quien manda en esta
     cabecera. Los dos originales siguen en el marcado —solo se ocultan— para no duplicar
     el código que abre el listado de provincias. */
  #btn-lista, #btn-metodo { display: none; }
  /* El selector lleva `.cab-acciones` delante para GANARLE al `#btn-menu { display: none }`
     de más abajo. Con `#btn-menu` a secas los dos tienen la misma especificidad y decide el
     orden en el fichero, así que ganaba el de abajo y el botón no aparecía nunca. Es la
     misma trampa que dejó sin borde el botón de rechazar del aviso de cookies. */
  .cab-acciones #btn-menu { display: inline-flex; }
}

/* El desplegable del botón unificado. Papel blanco y esquinas duras, como el resto del
   sistema; cuelga de la cabecera, que es `position: sticky`, así que va en absoluto respecto
   a ella y con un z-index por encima del mapa. */
#btn-menu { display: none; }
.cab-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  display: grid; min-width: 190px;
  background: var(--papel); border-radius: var(--r-chico); box-shadow: var(--sombra-alta);
  overflow: hidden;
}
.cab-menu[hidden] { display: none; }
.cab-menu > * {
  padding: 13px 15px; border: 0; background: none; cursor: pointer; text-align: left;
  text-decoration: none; color: var(--tinta);
  font-family: var(--titular); font-size: 15px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em;
}
.cab-menu > * + * { border-top: 1px solid var(--linea-2); }
.cab-menu > *:hover { background: var(--vox-rojo); color: #fff; }
.cab-menu > *:focus-visible { outline: 3px solid var(--vox-rojo); outline-offset: -3px; }
@media (max-width: 420px) {
  .cabecera { padding: 0 8px; gap: 8px; }
  .cab-marca { gap: 7px; }
  .cab-icono { width: 28px; height: 28px; }
  .btn-icono { width: 33px; height: 33px; border-width: 1.6px; }
  .btn-icono svg { width: 15px; height: 15px; }
  .cab-acciones { gap: 4px; }
}

@media (max-width: 559px) {
  .leyenda { left: 10px; right: auto; }
  /* La leyenda se va a la izquierda, así que la esquina de abajo a la derecha queda entera
     para el botón de descarga, que es donde se pidió. «Ver España» no se la disputa: está
     arriba a la derecha. */
  .btn-descarga { left: auto; right: 10px; bottom: 30px; }
  .btn-compartir { left: auto; right: 10px; bottom: 71px; }
  /* La altura a la que sube la pista para no montarse sobre la leyenda ya la fija la media
     query de 899 px; aquí solo se encoge. Tenerla en un solo sitio importa: cuando la
     leyenda subió de 10 a 30 px, este valor se quedó corto y volvió el solape. */
  .pista { font-size: 13px; padding: 7px 12px; }
}

@media (min-width: 1400px) {
  .ficha { width: 530px; }
}


/* =====================================================================================
   REVISIÓN DE MÓVIL (11-oct-2026). Medido en 320, 375 y 390 px y en horizontal (812×375).
   Va al final a propósito: sobrescribe reglas de los bloques de 420, 559 y 899 px.
   ===================================================================================== */

/* 1. GESTOS. Todo el lienzo es del mapa: un pellizco que empezara sobre la leyenda o la barra
   ampliaba la PÁGINA entera, porque solo #mapa llevaba `touch-action: none` (Leaflet hace lo
   mismo con su contenedor). Los botones siguen recibiendo su toque. La ficha y el buscador
   viven fuera de .lienzo, así que su scroll no se ve afectado. Fuera también el recuadro gris
   que pinta el navegador al tocar, y el menú de «guardar imagen» al mantener un icono. */
.lienzo { touch-action: none; -webkit-tap-highlight-color: transparent; }
.cabecera, .ficha, .panel-lista { -webkit-tap-highlight-color: transparent; }
.pest-icono, .cab-icono, .ir-mapa img { -webkit-touch-callout: none; }

/* 2. TAMAÑO PARA EL DEDO en pantallas táctiles. Medido a 375 px: cabecera 33 px, compartir y
   descargar 32, cada nivel de la leyenda 23, botones de la ficha 34 y enlaces legales 16. La
   referencia es 44 px; donde el dibujo no puede crecer se agranda la zona sensible con un
   ::after invisible, sin cambiar lo que se ve. */
@media (pointer: coarse) {
  .btn-icono { width: 40px; height: 40px; }
  .ley-item { padding-block: 7px; }
  #pestanas button { height: 44px; }
  .btn-descarga, .btn-compartir { min-height: 40px; }
  .btn-descarga-ficha, .btn-compartir-ficha { position: relative; width: calc(38px * var(--k)); height: calc(38px * var(--k)); }
  .btn-descarga-ficha::after, .btn-compartir-ficha::after, .ficha-cerrar::after {
    content: ''; position: absolute; inset: -4px;
  }
  body:not(.pagina-medidas) .pie-legal { font-size: 12px; }
  body:not(.pagina-medidas) .pie-legal a { padding: 8px 6px; margin: -8px -6px; }
}
/* La leyenda crece con los niveles más altos: la pista y los botones se reacomodan. */
@media (pointer: coarse) and (max-width: 899px) {
  .pista { bottom: 176px; }
  .btn-compartir { bottom: 78px; }
}
/* En 420 px o menos la cabecera ya va justa: los botones se quedan en 38 (antes 33), que es
   lo que cabe sin que el titular baje de tamaño. */
@media (pointer: coarse) and (max-width: 420px) {
  .btn-icono { width: 38px; height: 38px; }
}

/* 3. :HOVER QUE SE QUEDA PEGADO. En el táctil, tocar deja el estado de «ratón encima» puesto
   hasta tocar otra cosa: la leyenda, los botones del mapa y las flechas de las tiras se
   quedaban marcados. En pantallas sin ratón se vuelven a su estado de reposo; el toque se
   marca con :active, que dura lo que dura el dedo. */
@media (hover: none) {
  .ley-item:hover:not(.activo) { background: none; }
  .btn-descarga:hover, .btn-compartir:hover, .btn-descarga-ficha:hover,
  .btn-compartir-ficha:hover { background: var(--tinta); }
  .btn-icono:not(.activo):not(.btn-destacado):hover { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .85); }
  .btn-destacado:hover { background: var(--vox-rojo); color: #fff; border-color: var(--vox-rojo); }
  .btn-destacado:active { background: #fff; color: var(--vox-rojo); border-color: #fff; }
  #pestanas button:hover:not(.activa) { background: transparent; }
  .ley-item:active { background: var(--fondo-2); }
  .btn-descarga:active, .btn-compartir:active, .btn-descarga-ficha:active,
  .btn-compartir-ficha:active { background: var(--vox-rojo); }
}

/* 4. ZONAS SEGURAS: con `viewport-fit=cover` (que hace falta para el botón del pie de la
   ficha, ver .ficha-pie), en horizontal la muesca del iPhone tapaba el logotipo, «Ver España»
   y la leyenda. Se apartan lo que mida la muesca, y nada donde no la hay.
   La muesca solo estorba de lado, con el teléfono en horizontal: ahí se aplica. */
@supports (padding: max(0px)) {
  @media (orientation: landscape) and (max-height: 500px) {
    .cabecera { padding-left: max(10px, env(safe-area-inset-left));
                padding-right: max(10px, env(safe-area-inset-right)); }
    .ficha-contenido, .ficha-pie { padding-right: max(18px, env(safe-area-inset-right)); }
    .leyenda { right: max(10px, env(safe-area-inset-right)); }
  }
}

/* 5. TELÉFONO EN HORIZONTAL: unos 340-375 px útiles de alto. Medido a 812×340: quedaban 24 px
   de mapa entre la barra y la leyenda, la pista se montaba en la barra y la ficha dejaba 165
   px para leer. La ficha pasa a panel lateral, como en escritorio (el encuadre del mapa ya la
   descuenta como lateral: es casi tan alta como el lienzo y más estrecha que el 75 %). */
@media (orientation: landscape) and (max-height: 500px) {
  .frase-mapa { min-height: 0 !important; white-space: nowrap; overflow: hidden;
                text-overflow: ellipsis; max-width: 62vw; }
  .pista { bottom: 14px; }
  .ficha { left: auto; top: 0; bottom: 0; right: 0; width: min(440px, 58vw); height: 100dvh;
           transform: translateX(101%); }
  .ficha-tirador { display: none; }
  .ficha-pie { padding-top: 8px; }
  .enlace-medidas { padding: 10px 14px; }
  .leyenda { padding: 6px 10px; }
  .ley-item { padding-block: 3px; }
}

/* ============================================================== EL VÍDEO (14-oct-2026)
   Recuadro flotante con la miniatura del vídeo de YouTube: enlace a una pestaña nueva
   (js/video.js lleva el plegado). Petición del usuario: «un recuadro moderno», con sombra que
   lo separe del mapa, un poco más grande en escritorio y discreto en el teléfono, y SIN
   estorbar la navegación.
   · Sin bordes ni filetes (norma del proyecto): lo separa del mapa la sombra.
   · Va por encima de TODO menos de la ficha (de provincia o de municipio) y del buscador,
     que pasan por encima de él (decisión del usuario): en escritorio el panel lo tapa al
     entrar por la derecha, y en el teléfono lo tapa la hoja cuando se abre entera. Por eso el
     z-index va justo por debajo del de la ficha (60) y del buscador (70), y no se esconde: lo
     resuelve el orden de las capas.
   · La ✕ NO lo quita: lo pliega hacia el borde derecho y deja una pestaña roja que lo vuelve
     a sacar. Al recargar sale siempre desplegado. */
.video-flotante {
  position: fixed; z-index: 58;
  top: calc(var(--cab) + 14px); right: 14px; width: var(--vf-ancho, 240px);
  opacity: 0; transform: translateX(24px); pointer-events: none;
  transition: opacity .35s ease, transform .45s cubic-bezier(.2, .9, .25, 1.15);
}
.video-flotante.visible { opacity: 1; transform: none; pointer-events: auto; }
/* ESCONDIDO: el recuadro sale entero por la derecha (su ancho más el margen hasta el borde)
   y queda a la vista solo la pestaña, que cuelga de su lado izquierdo. */
.video-flotante.visible.plegado { transform: translateX(calc(100% + var(--vf-margen, 14px))); }
.video-flotante.plegado .vf-enlace,
.video-flotante.plegado .vf-cerrar { visibility: hidden; transition: visibility 0s .45s; }
body.con-cookies .video-flotante { opacity: 0; transform: translateX(24px); pointer-events: none; }

.vf-enlace {
  display: block; padding: 6px; border-radius: 6px;
  background: var(--papel); color: var(--tinta); text-decoration: none;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .16), 0 12px 30px rgba(0, 0, 0, .34);
  transition: transform .18s ease, box-shadow .18s ease;
}
.vf-enlace:hover { transform: translateY(-2px);
  box-shadow: 0 3px 6px rgba(0, 0, 0, .18), 0 18px 38px rgba(0, 0, 0, .38); }
.vf-enlace:focus-visible { outline: 3px solid var(--vox-amarillo); outline-offset: 2px; }
.vf-pantalla {
  position: relative; display: block; overflow: hidden; border-radius: 3px;
  aspect-ratio: 16 / 9; background: var(--tinta);
}
.vf-pantalla img { display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform .3s ease; }
.vf-enlace:hover .vf-pantalla img { transform: scale(1.04); }

/* El play, en el CENTRO de la miniatura (petición del usuario). */
.vf-play {
  position: absolute; left: 50%; top: 50%; width: 48px; height: 48px;
  margin: -24px 0 0 -24px; display: grid; place-items: center;
  background: var(--vox-rojo); border-radius: 50%; color: #fff;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .45);
  animation: vf-latido 1.5s ease-in-out infinite;
}
.vf-play svg { width: 26px; height: 26px; fill: currentColor; margin-left: 3px; }
/* el aro que se expande con cada latido */
.vf-play::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(200, 13, 34, .7);
  animation: vf-aro 1.5s ease-out infinite;
}
/* Un golpe corto y el resto quieto. A 1,5 s se repite a menudo (el usuario lo pidió más
   seguido que los 2,6 s del principio) sin llegar a ser un parpadeo continuo. */
@keyframes vf-latido {
  0%, 50%, 100% { transform: scale(1) rotate(0); }
  60% { transform: scale(1.18) rotate(-9deg); }
  70% { transform: scale(1.08) rotate(7deg); }
  80% { transform: scale(1.14) rotate(-4deg); }
  90% { transform: scale(1) rotate(0); }
}
@keyframes vf-aro {
  0%, 50% { box-shadow: 0 0 0 0 rgba(200, 13, 34, .7); }
  95%, 100% { box-shadow: 0 0 0 16px rgba(200, 13, 34, 0); }
}
.vf-enlace:hover .vf-play { animation-duration: 1s; }

/* Debajo, SOLO el título del vídeo, tal cual lo escribió el usuario («LEY DE NIETOS: ¿fraude
   electoral?», con sus mayúsculas y minúsculas: por eso sin text-transform), en DOS renglones,
   uno por trozo, en cualquier pantalla. Sin etiqueta «VÍDEO»: la quitó el usuario. */
.vf-titulo {
  display: block; padding: 7px 3px 2px;
  font-family: var(--titular); font-weight: 700; font-size: 16px; line-height: 1.1;
  letter-spacing: .01em; text-align: center;
}
.vf-titulo > span { display: block; }

.vf-cerrar {
  position: absolute; top: -9px; right: -9px; width: 26px; height: 26px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--tinta); color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
}
/* área de pulsación mayor que el dibujo: 40 px alrededor de la ✕ */
.vf-cerrar::before { content: ''; position: absolute; inset: -7px; }
.vf-cerrar svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 3; stroke-linecap: round; }
.vf-cerrar:hover { background: var(--vox-rojo); }

/* la pestaña que queda en el borde con el vídeo escondido; late igual que el play */
.vf-pestana {
  position: absolute; top: 18px; left: -32px; width: 32px; height: 48px; padding: 0 0 0 2px;
  display: grid; place-items: center; border: 0; cursor: pointer;
  background: var(--vox-rojo); color: #fff; border-radius: 7px 0 0 7px;
  box-shadow: -3px 3px 10px rgba(0, 0, 0, .3);
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.vf-pestana svg { width: 20px; height: 20px; fill: currentColor;
  animation: vf-latido 1.5s ease-in-out infinite; }
.vf-pestana:hover { background: var(--vox-rojo-hondo); }
.vf-pestana:focus-visible { outline: 3px solid var(--vox-amarillo); outline-offset: 2px; }
.video-flotante.plegado .vf-pestana { opacity: 1; pointer-events: auto; transition-delay: .25s; }

/* ESCRITORIO: «Ver España» vive en la MISMA esquina (arriba a la derecha del lienzo), así
   que con el vídeo abierto se aparta a su izquierda —si no, quedaba tapado debajo— y con el
   vídeo plegado vuelve a su sitio y la pestaña baja por debajo de él (lo pidió el usuario: la
   pestaña se pintaba encima de «Ver España»). `con-video` lo pone js/video.js en <body>.
   Con la ficha abierta «Ver España» se va abajo a la izquierda y aquí no se toca. */
@media (min-width: 900px) {
  body.con-video:not(.con-ficha) .btn-reiniciar { right: calc(14px + var(--vf-ancho, 240px) + 12px); }
  .vf-pestana { top: 62px; }
}
/* Escritorio bajo: que no llegue a la barra de zoom, que va centrada a la derecha. */
@media (min-width: 900px) and (max-height: 700px) { body { --vf-ancho: 200px; } }

/* TELÉFONO Y TABLETA: pegado al borde derecho, sin esquinas por ese lado, JUSTO DEBAJO de la
   pregunta de la barra de mapas, sin tocarla: a la altura de Francia (decisión final del
   usuario, 14-oct-2026, tras probarlo a media pantalla, donde tapaba la mitad del mapa). El
   borde inferior de la barra lo mide js/video.js y lo deja en `--video-arriba`, porque la
   pregunta cambia de alto (dos o tres renglones, la lupa de los municipios). El título va más
   pequeño, en sus dos renglones. */
@media (max-width: 899px) {
  .video-flotante { top: var(--video-arriba, calc(var(--cab) + 130px)); right: 0; width: 124px;
                    --vf-margen: 0px; }
  .vf-enlace { padding: 4px 0 4px 4px; border-radius: 6px 0 0 6px; }
  .vf-pantalla { border-radius: 3px 0 0 3px; }
  .vf-titulo { font-size: 12px; padding: 4px 4px 0 0; }
  .vf-play { width: 32px; height: 32px; margin: -16px 0 0 -16px; }
  .vf-play svg { width: 18px; height: 18px; margin-left: 2px; }
  /* la ✕ va a la IZQUIERDA: por la derecha el recuadro se sale de la pantalla */
  .vf-cerrar { right: auto; left: -10px; top: -10px; width: 24px; height: 24px; }
  .vf-pestana { top: 14px; width: 28px; height: 44px; left: -28px; }
  .vf-pestana svg { width: 17px; height: 17px; }
}
