/* ============================================================
   MeteoRanking — el tiempo, verificado.
   Lenguaje visual «1c · Cielo protagonista» (claude.ai/design,
   proyecto «Interfaz web meteorológica avanzada», 13-jul-2026):
   papel cálido + tintas azul-gris, cielo degradado con arco solar,
   sol ámbar, tarjetas blancas 16px, píldoras de fuente ○/●,
   Instrument Serif / Instrument Sans / IBM Plex Mono.
   ============================================================ */

/* ---------- fuentes autoalojadas ---------- */
@font-face {
  font-family: "Instrument Serif";
  src: url("../fonts/instrument-serif.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("../fonts/instrument-serif-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("../fonts/instrument-sans-var.woff2") format("woff2");
  font-weight: 400 700; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/plex-mono-500.woff2") format("woff2");
  font-weight: 500; font-display: swap;
}

/* ---------- tokens ---------- */
:root {
  color-scheme: light dark;

  /* tintas y superficies — paleta «RELIEVE» (handoff «cabecera viva», §3).
     Cambia respecto a «Cielo protagonista»: el papel cálido (#fbf9f6) pasa a un
     gris frío (#f3f4f7), que es lo que hace legible el relieve de las sombras
     nuevas (sobre papel cálido, una sombra gris ensucia). Las TINTAS no cambian
     ni un dígito: su contraste ya estaba calibrado y se conserva entero. */
  --fondo: light-dark(#f3f4f7, #11141b);
  --superficie: light-dark(#ffffff, #1b212d);
  --superficie-alta: light-dark(#f8f9fb, #212836);
  --tinta: light-dark(#26303f, #e3e8f0);
  --tinta-2: light-dark(#3a4658, #c3ccd9);
  /* --tinta-suave es EL GRIS MÁS CLARO QUE PUEDE LLEVAR TEXTO, y tiene que
     pasar AA sobre los TRES fondos del sitio, no solo sobre el blanco. Era
     #6b7688: 4,53:1 sobre blanco (en el filo), 4,30 sobre --superficie-alta y
     4,43 sobre --fondo, que es donde vive medio texto secundario de la página
     (la pista de «pulsa cualquier día», los rótulos de la tira horaria, las
     notas de método). Con #626d7d: 5,24 sobre blanco, 4,97 sobre la superficie
     alta y 4,72 sobre el fondo. El fondo gris frío de «Relieve» es justo lo que
     estrechaba el margen — sobre el papel cálido anterior no se notaba. */
  --tinta-suave: light-dark(#626d7d, #93a0b3);
  /* --tinta-tenue NO LLEVA TEXTO NUNCA. Sobre blanco da 2,54:1 y AA pide 4,5
     (3 en texto grande, que tampoco alcanza), así que cualquier rótulo escrito
     con este gris es ilegible por definición, no por gusto: Lighthouse lo
     cantaba en las celdas de instrumento y en la tira horaria. El 26-jul-2026
     se pasaron a --tinta-suave los 25 sitios donde pintaba texto. Aquí se queda
     para lo que no se lee: filos, carriles, rejillas y el fondo de reserva de
     las insignias de categoría. Si vuelve a aparecer en un `color:`, es un
     fallo de accesibilidad. */
  --tinta-tenue: light-dark(#9aa3b2, #6a7689);
  --borde: light-dark(#edf0f4, #232b39);
  --borde-suave: light-dark(#f2f4f8, #1e2530);
  --borde-pill: light-dark(#dde2ea, #39445a);
  --borde-cielo: light-dark(#d3dded, #39445a);

  /* SOMBRA (nueva). El diseño anterior daba profundidad solo con bordes;
     «Relieve» levanta las tarjetas del papel: un filo de 1 px que asienta el
     borde inferior y una difusa larga que da la altura. NO cabe en light-dark()
     —esa función solo admite COLORES— y las dos variantes no se diferencian
     solo en color (la oscura es más larga y profunda), así que se resuelve por
     tema unas líneas más abajo. */
  --sombra: 0 1px 2px rgb(30 41 59 / .05), 0 12px 30px -6px rgb(30 41 59 / .13);

  /* acentos.
     AJUSTE DE CONTRASTE (26-jul-2026). Los tres acentos de texto bajaron un
     escalón de luminosidad para pasar AA sobre el gris frío de «Relieve»
     (--fondo #f3f4f7), que es más oscuro que el papel cálido con el que se
     eligieron: el azul de marca daba 4,38:1 sobre blanco y 3,98 sobre el fondo
     —en los enlaces del pie y de las entradillas— y el rojo de la máxima, 4,05
     en las tarjetas de día. AA pide 4,5. Ahora: azul 5,10 sobre blanco y 4,60
     sobre el fondo; rojo 5,01 y 4,51. El salto de tono es de un 3 % de
     luminancia — puestos uno al lado del otro no se distinguen— pero es la
     diferencia entre que la máxima de cada día se lea o no con sol en la calle.
     Si alguna vez se revierte, hay que revertir los cuatro tokens juntos:
     --marca, --sinapsis, --azul-min y --rojo-max. */
  --marca: light-dark(#3970bb, #7fa9dd);       /* enlaces, línea del combinado */
  /* acento del combinado Sinapsis (fila del ranking, chip, barra). Alias de
     --marca: antes se usaba var(--isobara), que NUNCA estuvo definida, así
     que el chip de esa fila salía sin color. */
  --sinapsis: light-dark(#3970bb, #7fa9dd);
  --marca-tinta: light-dark(#2c5da3, #a9c6ea);
  --ambar: #f4b23f;                             /* el sol */
  --ambar-tinta: light-dark(#c99a3a, #e8c877);
  --rojo-max: light-dark(#bd4a33, #e07a63);
  --azul-min: light-dark(#3970bb, #7fa9dd);
  --verde: light-dark(#3f9d6a, #58b381);
  --verde-tinta: light-dark(#2f7d53, #7ecfa0);
  /* Opacidades de la tabla §3 del handoff (.10 claro / .14 oscuro). Eran .13 y
     .16, heredadas de «Cielo protagonista»: sobre el gris frío de «Relieve» ese
     verde extra ensuciaba el recuadro de honestidad, que es un aviso sereno y
     no un banner de éxito. */
  --verde-fondo: light-dark(rgb(63 157 106 / .10), rgb(88 179 129 / .14));

  /* severidad (escala del propio degradado UV de la propuesta) */
  --sev-buena: light-dark(#3f9d6a, #58b381);
  --sev-media: light-dark(#c9a92c, #e0c23a);
  --sev-alta: light-dark(#e0872f, #eb9c4d);
  --sev-muy-alta: light-dark(#d1583f, #e07a63);
  --sev-extrema: light-dark(#9b3ac0, #b568d3);
  /* --sev-sin-datos se retiró el 23-jul-2026: solo lo usaba el cuadradito sin
     dato de la tira de verificación día a día, que ya no existe. */
  --grad-uv: linear-gradient(90deg, #3f9d6a, #e0c23a, #e0872f, #d1583f, #9b3ac0);

  /* gráficas */
  --gr-contexto: light-dark(rgb(107 118 136 / .30), rgb(147 160 179 / .30));
  --gr-combinado: var(--marca);
  --gr-rejilla: light-dark(rgb(38 48 63 / .06), rgb(227 232 240 / .07));
  --gr-area: light-dark(rgb(63 121 201 / .10), rgb(127 169 221 / .13));
  --gr-prec: var(--marca);

  /* tipografía */
  --f-display: "Instrument Serif", Georgia, serif;
  --f-ui: "Instrument Sans", system-ui, sans-serif;
  --f-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* SUELO TIPOGRÁFICO DEL SITIO: 11 px. Por debajo no baja nada.
     Antes había rótulos a 9 y 9,5 px (etiquetas de instrumento, mín/máx,
     procedencia, píldora de fuente) y varios a 0,62rem = 9,9. En un portátil de
     1366×768 —el caso real, no el monitor grande del que lo diseña— eso se
     queda en el límite de lo descifrable, y el 82 % de las visitas del sitio
     son de móvil. 11 px con interletraje es lo mínimo que se lee de un vistazo
     en un rótulo en versalitas.
     Va en rem y no en px A PROPÓSITO: quien tenga el tamaño de letra subido en
     el navegador arrastra también estos rótulos. Los 9 px escritos en px se lo
     impedían. */
  --t-mini: 0.6875rem;   /* 11 px */
  --t-xs: 0.75rem;       /* 12 px */
  --t-sm: 0.855rem;
  --t-base: clamp(0.95rem, 0.9rem + 0.2vw, 1.03rem);
  --t-lg: clamp(1.15rem, 1.05rem + 0.45vw, 1.4rem);
  --t-xl: clamp(1.7rem, 1.4rem + 1.2vw, 2.5rem);
  --t-display: clamp(4.6rem, 3rem + 7.5vw, 9rem);

  /* espaciado y geometría */
  --e-1: 4px; --e-2: 8px; --e-3: 12px; --e-4: 16px; --e-5: 24px;
  --e-6: 32px; --e-7: 48px; --e-8: 64px; --e-9: 96px;
  /* Radios de «Relieve» (§3): 24 cabecera · 18 bandas y tarjetas grandes ·
     12 tarjetas de día y avisos · 999 pastillas. Se reasignan sobre los MISMOS
     tokens para que toda la página herede la geometría nueva sin tocar ni una
     de sus reglas, que es justo lo que el handoff pide para el resto del sitio. */
  --radio-s: 12px; --radio-m: 18px; --radio-l: 24px; --radio-pastilla: 999px;
  --radio-cabecera: 24px;
  --ancho-contenido: 1160px;
  --ancho-amplio: 1400px;
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* La sombra, por tema (no cabe en light-dark(): ver el token). El @media cubre
   el tema del sistema y los [data-theme] lo pisan cuando el visitante elige. */
@media (prefers-color-scheme: dark) {
  :root { --sombra: 0 1px 2px rgb(0 0 0 / .4), 0 16px 36px -8px rgb(0 0 0 / .55); }
}
:root[data-theme="light"] { --sombra: 0 1px 2px rgb(30 41 59 / .05), 0 12px 30px -6px rgb(30 41 59 / .13); }
:root[data-theme="dark"] { --sombra: 0 1px 2px rgb(0 0 0 / .4), 0 16px 36px -8px rgb(0 0 0 / .55); }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 76px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--f-ui);
  font-size: var(--t-base);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--f-display); font-weight: 400; line-height: 1.08; text-wrap: balance; }
h2 { font-size: var(--t-xl); margin: 0 0 var(--e-2); }
h3 { font-size: var(--t-lg); margin: 0 0 var(--e-2); }
h4 { margin: 0 0 var(--e-2); }
a { color: var(--marca); }
a:hover { color: var(--marca-tinta); }
.mono { font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.05em; }
button { font-family: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; border-radius: 3px; }

/* Aviso de ranking conservado dentro del panel de clasificación (gemelo del
   .ssr-conservado del SSR: mismo mensaje, misma razón). */
.rk-conservado {
  margin: var(--e-2) 0 var(--e-3);
  padding: var(--e-2) var(--e-3);
  border-left: 3px solid var(--ambar);
  background: var(--superficie-alta);
  border-radius: 0 var(--radio-s) var(--radio-s) 0;
  font-size: var(--t-xs); color: var(--tinta-suave);
}

/* Las reglas del bloque de observación de estación (.observacion-real, .obs-*)
   se ELIMINARON el 23-jul-2026: quedaron huérfanas al retirar esa banda el
   22-jul. Lo medido ya no vive en un bloque aparte, sino en la píldora de la
   cabecera y —desde el 23-jul— dentro de cada celda de la banda de datos, que
   rotula su procedencia (.bd-fuente). */

/* píldora de fuente del dato bajo la temperatura grande: «Medido en…» o
   «Previsión de…» (renderAhora decide cuál, no hay variante de clase). */
.pill-fuente {
  font-family: var(--f-mono); font-size: var(--t-mini); font-weight: 500;
  /* Interlínea apretada: la píldora es la pieza que más crece al subir el
     cuerpo de 9,9 a 11 px, y en la cabecera crece HACIA ARRIBA, contra el
     mín/máx. Con la interlínea del cuerpo (1,64) el peor caso real —San Roque,
     con nombre de estación largo y distancia— pasaba a tres líneas de 59 px y
     se comía 14 px del mín/máx. A 1,3 el mismo texto ocupa 47. */
  line-height: 1.3;
  letter-spacing: 0.05em; border-radius: var(--radio-pastilla);
  padding: 3px 9px; white-space: nowrap;
  color: var(--tinta-suave); border: 1px solid var(--borde-pill);
  background: transparent;
}

/* insignia de categoría (UV, aire): MUY ALTO, BUENA… */
.badge-cat {
  font-family: var(--f-mono); font-size: var(--t-mini); font-weight: 500;
  letter-spacing: 0.04em; color: #fff; border-radius: 6px; padding: 3px 8px;
  background: var(--cat, var(--tinta-tenue)); white-space: nowrap;
}

/* ---------- cabecera ---------- */
.cabecera {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in oklab, var(--fondo) 88%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--borde-suave);
}
.cabecera-int {
  max-width: var(--ancho-amplio);
  margin-inline: auto;
  padding: var(--e-2) clamp(var(--e-4), 3vw, var(--e-7));
  display: flex; align-items: center; gap: var(--e-5);
  /* Una sola fila SIEMPRE: lo que no cabe se recorta (ver .btn-ubicacion), no
     envuelve. Envolver cambiaba el alto de la cabecera —que es sticky y está en
     flujo— y con él la posición de toda la página. */
  flex-wrap: nowrap;
}
/* La marca no encoge y los iconos tampoco: quien cede sitio es el nombre de la
   ciudad, que para eso lleva su recorte. */
.logo { display: flex; align-items: center; gap: var(--e-2); text-decoration: none; color: var(--tinta); flex: 0 0 auto; }
.logo-marca { width: 30px; height: 30px; color: var(--marca); }
.logo-nombre { font-family: var(--f-display); font-size: 1.45rem; letter-spacing: 0.01em; }

.nav-secciones { display: flex; gap: var(--e-2); margin-inline: auto; }
.nav-secciones a {
  text-decoration: none; color: var(--tinta-suave);
  font-size: var(--t-sm); font-weight: 600; letter-spacing: 0.01em;
  padding: 6px 12px; border-radius: var(--radio-s);
  border-bottom: 2px solid transparent;
}
.nav-secciones a:hover { color: var(--tinta); background: var(--superficie-alta); }
.nav-secciones a.activa { color: var(--tinta); border-bottom-color: var(--tinta); border-radius: var(--radio-s) var(--radio-s) 0 0; }
/* Enlace que SALE de la página (Artículos): separado del grupo de anclas para
   que se lea como «otro sitio» y no como una sección más de esta página.
   Nunca lleva .activa — el scroll-spy lo ignora a propósito (app.js). */
.nav-secciones a.nav-externa {
  margin-left: var(--e-2);
  padding-left: calc(var(--e-2) + var(--e-1));
  border-left: 1px solid var(--borde-suave);
}
.nav-fiabilidad::after { content: "●"; font-size: 0.55em; vertical-align: super; color: var(--ambar); margin-left: 3px; }

.cabecera-acciones { display: flex; align-items: center; gap: var(--e-2); min-width: 0; }
.btn-ubicacion {
  display: flex; align-items: center; gap: var(--e-1);
  background: var(--superficie); border: 1px solid var(--borde-cielo);
  border-radius: var(--radio-s); padding: 7px 13px 7px 10px;
  font-family: var(--f-mono); font-size: var(--t-xs); font-weight: 500;
  cursor: pointer; color: var(--tinta-2);
  min-width: 0; /* sin esto el nombre largo no deja encoger el botón */
}
/* El nombre de la ciudad se RECORTA antes que partir la cabecera en dos filas.
   Medido a 412 px: con «—» el botón mide 50 px y la cabecera 53; al escribir
   «Mairena del Aljarafe» pasaba a 113 px, la fila envolvía y la cabecera crecía
   a 78 px — 25 px que empujaban la página entera hacia abajo y valían un CLS de
   0,12 al hidratar. Y, salto aparte, una cabecera de dos pisos en un móvil se
   come la pantalla. Nombres como «Sant Cugat del Vallès» harán lo mismo aunque
   el SSR ya escriba el nombre desde el servidor, así que la regla se queda como
   red de seguridad. */
.btn-ubicacion > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.btn-ubicacion:hover { border-color: var(--marca); }
.btn-ubicacion svg { width: 14px; height: 14px; color: var(--marca); }
.btn-icono {
  width: 36px; height: 36px; flex: 0 0 auto; display: grid; place-items: center;
  background: none; border: 1px solid var(--borde-cielo); border-radius: var(--radio-s);
  cursor: pointer; color: var(--tinta-suave);
}
.btn-icono:hover { background: var(--superficie-alta); color: var(--tinta); }
.btn-icono svg { width: 18px; height: 18px; }

/* hamburguesa: solo existe bajo 980px, donde la nav de secciones desaparece */
.btn-menu { display: none; }

/* menú móvil: hoja editorial bajo la cabecera (dialog modal nativo) */
.dialogo-nav {
  width: min(420px, 92vw);
  margin: 68px auto auto;
}
.nav-movil { display: grid; }
.nav-movil a {
  font-family: var(--f-display);
  font-size: 1.5rem;
  line-height: 1.2;
  text-decoration: none;
  color: var(--tinta);
  padding: 12px 6px;
  border-bottom: 1px solid var(--borde-suave);
}
.nav-movil a:hover { color: var(--marca-tinta); background: var(--superficie-alta); }
.nav-movil a.activa { color: var(--marca-tinta); box-shadow: inset 3px 0 0 var(--marca); padding-left: 12px; }

/* barra de progreso del primer arranque / refresco */
.barra-progreso {
  display: flex; align-items: center; gap: var(--e-3);
  max-width: var(--ancho-amplio); margin-inline: auto;
  padding: 0 clamp(var(--e-4), 3vw, var(--e-7)) var(--e-2);
}
/* El atributo [hidden] la esconde. Sin esta regla NO se cumplía: una regla de
   autor (.barra-progreso{display:flex}) gana al [hidden]{display:none} del
   navegador (origen autor > user-agent), así que la barra se quedaba FIJA
   enseñando «Preparando…» aunque el HTML y el JS la marcaran hidden. En
   producción (datos precomputados) el estado nunca está «ocupado», de modo que
   con esto la barra no llega a verse: ni fija ni parpadeando. La especificidad
   (clase+atributo) gana a la regla de arriba, y al quitar [hidden] en el modo
   laboratorio vuelve a mostrarse. */
.barra-progreso[hidden] { display: none; }
.bp-pista { flex: 0 0 220px; height: 4px; border-radius: 2px; background: var(--superficie-alta); overflow: hidden; }
.bp-relleno { height: 100%; width: 5%; border-radius: 2px; background: var(--ambar); transition: width 0.6s ease; }
.bp-texto { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--tinta-suave); }

/* ---------- bandas / layout ---------- */
/* Aire entre secciones. Estaba en 48-96 px; baja a 40-64. El criterio no es el
   gusto: para que una sección se lea como un bloque aparte basta con que el
   hueco ENTRE secciones sea mayor que el mayor hueco DENTRO de ella (aquí,
   32 px entre bloque y bloque). Con 40-64 px esa proporción se mantiene —el
   corte se sigue viendo— y la página deja de tener andenes vacíos en pantallas
   grandes. Por debajo de ~40 px las secciones empezarían a fundirse. */
.banda {
  max-width: var(--ancho-amplio);
  margin-inline: auto;
  padding: clamp(var(--e-6), 4vw, var(--e-8)) clamp(var(--e-4), 3vw, var(--e-7));
}
/* Rótulo de sub-bloque dentro de una sección («Previsión por horas»): jerarquía
   por debajo del h2 de la sección, sin competir con él. */
.sub-bloque {
  font-family: var(--f-ui); font-size: var(--t-base); font-weight: 600;
  color: var(--tinta-2); margin: var(--e-6) 0 var(--e-3);
  display: flex; align-items: center; gap: var(--e-3);
}
.sub-bloque::after {
  content: ""; flex: 1; height: 1px; background: var(--borde);
}
.banda-cabecera + .sub-bloque { margin-top: 0; }
/* Sin tope de ancho: la entradilla de cada sección llega hasta donde llega el
   bloque que presenta. Con el tope de 1160 quedaba una franja muerta a la
   derecha en cuanto la pantalla pasaba de ese ancho. */
.banda-cabecera { max-width: none; margin-bottom: var(--e-5); }
/* ==========================================================
   SELECTOR DE LAS CUATRO VISTAS DEL PRONÓSTICO (4-ago-2026)
   ----------------------------------------------------------
   Cuatro tarjetas-botón, no cuatro pastillas: son la puerta a
   los cuatro bloques que antes eran tres secciones distintas,
   y de ellos depende que alguien llegue al multimodelo — que
   es lo que NADIE encontraba cuando había que bajar hasta él.
   Por eso cada uno lleva, además del nombre, una línea que
   dice qué información va a dar: «Multimodelo» o «Por
   variables» no significan nada para quien llega de fuera.
   El color es realce, nunca la señal: en blanco y negro se
   leen enteros.
   Las columnas las reparte el mismo cálculo que la botonera
   de variables (--var-cols, equilibrarRejilla), para que no
   salga nunca una fila de tres y otra de una.
   ========================================================== */
.pron-selector {
  display: grid;
  grid-template-columns: repeat(var(--var-cols, 1), minmax(0, 1fr));
  gap: var(--e-3);
  margin: calc(var(--e-5) * -1) 0 var(--e-5);
}
.pron-selector button {
  display: flex; align-items: flex-start; gap: var(--e-3);
  min-width: 0;                       /* red de seguridad, como .var-btn */
  text-align: left; cursor: pointer;
  padding: var(--e-3) var(--e-4);
  border-radius: var(--radio-s);
  border: 1px solid var(--borde-pill);
  background: var(--superficie);
  transition: border-color .12s, background .12s, transform .12s, box-shadow .12s;
}
.pron-selector button:hover {
  border-color: var(--marca); transform: translateY(-1px); box-shadow: var(--sombra);
}
.pron-selector button[aria-selected="true"] {
  background: color-mix(in oklab, var(--marca) 12%, var(--superficie));
  border-color: var(--marca);
  box-shadow: var(--sombra);
}
.pron-btn-icono { font-size: 1.45rem; line-height: 1.1; flex: 0 0 auto; }
.pron-btn-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pron-btn-nombre {
  font-size: var(--t-lg); font-weight: 700; line-height: 1.15;
  color: var(--tinta-2);
}
.pron-selector button[aria-selected="true"] .pron-btn-nombre { color: var(--marca-tinta); }
/* La descripción es la mitad del botón, no un adorno: es lo que convierte
   «Multimodelo» en algo que alguien decide pulsar. Envuelve en vez de
   recortarse — perder el final de la frase la deja sin sentido. */
.pron-btn-desc {
  font-size: var(--t-xs); line-height: 1.4; color: var(--tinta-suave);
}
/* Sin esto el [hidden] NO esconde la vista que toca ocultar en cuanto una regla
   de autor le dé display (el mismo caso que .aviso-red y .barra-progreso). */
.pron-vista[hidden] { display: none; }
/* Entradilla de la vista (multimodelo, variables): la que antes era la nota de
   su sección. Va dentro del panel, así que solo se lee cuando toca. */
.vista-entradilla { margin: 0 0 var(--e-4); }
/* Los textos de entradilla llegaban a 68 caracteres y dejaban media sección
   vacía a la derecha en pantallas anchas. Se sueltan hasta el ancho del bloque
   que presentan (el mismo que la banda de contenido), que es lo que hace que se
   lean como parte de él y no como una columna suelta. */
.banda-nota { color: var(--tinta-suave); max-width: none; margin: 0; }
.banda-realzada {
  background: linear-gradient(color-mix(in oklab, var(--superficie-alta) 70%, var(--fondo)), var(--fondo));
  border-block: 1px solid var(--borde-suave);
  max-width: none;
}
.banda-realzada > * { max-width: var(--ancho-amplio); margin-inline: auto; }

/* ==========================================================
   CABECERA VIVA (handoff «cabecera viva», §5 y §6)
   ----------------------------------------------------------
   El cielo ya no es un fondo a sangre con tres clases (día /
   crepúsculo / noche): es un degradado CONTINUO calculado por
   hora en JS (motor/cielo_vivo.js) sobre el que se superponen
   capas de atmósfera reales. Aquí solo viven la caja, el orden
   de las capas y la tipografía; TODO el color lo inyecta el JS
   en variables inline, porque depende de la hora y del tiempo.
   ========================================================== */
.hero { padding: 0 clamp(var(--e-3), 2.2vw, 22px); max-width: var(--ancho-amplio); margin-inline: auto; }

/* ⚠️ CUERPOS +50 % (4-ago-2026, petición de Álvaro: «hay gente a quien le
   cuesta ver la información»). Los rótulos de esta cabecera venían del handoff
   de diseño con cuerpos pequeños —11, 13, 14 y 21 px— y son justo los que
   dicen de DÓNDE sale el número y de CUÁNDO es, que es el producto.
   Se subieron todos ~50 %: 11→16, 13→19, 14→21, 21→31. La temperatura grande
   NO sube (96 px ya es el elemento más legible de la página y +50 % la
   sacaría de la caja).
   EL ALTO SUBE CON ELLOS, y no es negociable: la caja recorta lo que sobra
   (overflow:hidden), así que agrandar el texto sin agrandar la caja se come el
   pie por abajo. 302→400 en escritorio, 306→404 a 720 px y 330→444 a 460 px.
   Los altos NO están estimados: se midieron con el PEOR CASO REAL de las 702
   ciudades —la píldora con el nombre de estación más largo del maestro de
   AEMET, «SAGUNTO (MONTIVER PONTAZGO - SEMIAUTOMATICA)», que da un rótulo de
   123 caracteres— y el punto más apretado de todo el rango, que son los 760 px
   justo por encima de la media query de 720. El velo baja en proporción para
   seguir tapando lo que tapaba. */
.cabecera-viva {
  position: relative;
  height: 400px;                      /* 302 del diseño + el alto de los cuerpos nuevos */
  margin-top: 18px;
  border: 1px solid var(--borde-cielo);
  border-radius: var(--radio-cabecera);
  box-shadow: var(--sombra);
  overflow: hidden;
  /* --cv-cielo lo escribe el JS con skyGradient(); este es solo el valor de
     arranque para el HTML que sirve el SSR, antes de que hidrate. */
  background: var(--cv-cielo, linear-gradient(180deg, #6d9ccf 0%, #a6c6e5 46%, #e6dcc9 82%, #eef0f4 100%));
  transition: background 1.2s ease;
}

/* Capa 1 · el arco que describe el astro. Va al FONDO, detrás de todo, y se
   estira con la caja a propósito (preserveAspectRatio="none"): es una guía
   visual, no una circunferencia. El astro se coloca aparte, en píxeles, para
   que no se deforme con ella. */
.cv-arco { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cv-arco path {
  fill: none; stroke: var(--cv-arco, rgb(38 55 80 / .26));
  stroke-width: 1.2; stroke-dasharray: 2 7;
}

/* Capa 2 · atmósfera (nubes, lluvia, rachas, estrellas). */
.cv-atmosfera { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }

/* Capa 3 · el astro. NO es un SVG estirado: es una caja de tamaño fijo que el
   JS centra en el punto del arco (en %), de modo que el sol es un círculo
   perfecto sea cual sea el ancho de la pantalla. Ese era el motivo por el que
   la versión anterior reescribía el viewBox en píxeles. */
.cv-astro {
  position: absolute; width: 62px; height: 62px;
  transform: translate(-50%, -50%); pointer-events: none;
  transition: opacity .8s ease;
}
.cv-astro svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* Capa 4 · el VELO. Es lo que garantiza que la temperatura se lea sobre
   cualquier cielo (§5: «súbelo o bájalo de opacidad, pero no lo quites»). */
.cv-velo {
  position: absolute; left: 50%; top: 152px; transform: translateX(-50%);
  width: 470px; height: 150px; max-width: 92%;
  background: var(--cv-velo, transparent);
  filter: blur(34px); border-radius: 50%; pointer-events: none;
}

/* Capa 5 · el texto. */
.cv-int {
  position: relative; height: 100%;
  display: flex; flex-direction: column; text-align: center;
  padding: 18px 22px 0;
}
.cv-superior, .cv-pie {
  display: flex; justify-content: space-between; align-items: center;
  font-family: var(--f-mono); font-size: 16px; letter-spacing: .4px;
  text-transform: uppercase; gap: var(--e-3);
}
.cv-superior { color: var(--cv-tinta-sup, rgb(30 42 62 / .7)); }
.cv-pie { color: var(--cv-tinta-pie, rgb(30 42 62 / .7)); padding-bottom: 14px; letter-spacing: .6px; }
.cv-pie-astro { color: var(--cv-tinta-pie-dest, rgb(24 34 50 / .88)); }
.cv-superior span, .cv-pie span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cv-lectura {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  margin-top: -6px; color: var(--cv-tinta, rgb(24 34 50 / .94));
}
.cv-lugar { font-family: var(--f-display); font-size: 31px; letter-spacing: .2px; line-height: 1.1; margin: 0; }
.cv-temp {
  font-family: var(--f-display); font-size: 96px; line-height: .94;
  font-feature-settings: 'tnum'; font-variant-numeric: tabular-nums; margin-top: 2px;
}
.cv-cond { font-size: 21px; color: var(--cv-tinta-2, rgb(34 46 66 / .8)); margin-top: 4px; }
.cv-maxmin {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 22px; margin-top: 12px;
  font-family: var(--f-mono); font-size: 19px; font-variant-numeric: tabular-nums;
}
/* Guarda su línea aunque aún no tenga datos, en vez de desaparecer. Estaba en
   `display:none` y era el último salto de maquetación que quedaba: al hidratar
   aparecían «Mín. 21° · Máx. 36°», el bloque centrado crecía 21 px y la
   temperatura grande —que es el elemento de LCP— se movía media línea hacia
   arriba. Medido: CLS 0,023, todo él de aquí. */
.cv-maxmin:empty::before { content: "\00a0"; }
/* «Máx. 35°» / «Mín. 22°»: el diseño sustituye las flechas ↑/↓ por la palabra,
   que se lee sin tener que descifrar un símbolo. */
.cv-max { color: var(--cv-max, #d1583f); }
.cv-min { color: var(--cv-min, #3f79c9); }
.cv-sens { color: var(--cv-tinta-2, rgb(34 46 66 / .8)); }

/* LA PÍLDORA VUELVE AL FLUJO (4-ago-2026), y es la pieza que hizo falta tocar
   para poder agrandar los textos.
   Estuvo ABSOLUTA desde el rediseño porque, ocupando altura, le quitaba sitio
   al bloque centrado y este subía hasta chocar con el sol al mediodía (medido
   entonces: 11 px de solape). Pero absoluta crece HACIA ARRIBA, contra el
   mín/máx, y al subir el cuerpo de 11 a 16 px el texto largo de verdad —«Medido
   en SAN ROQUE SOTOGRANDE (AEMET), la estación oficial más cercana · a 11 km ·
   hace 2 h 49 min»— pasaba a dos líneas ya en escritorio y a cinco en un móvil
   de 375: medido, tapaba el mín/máx por 15 px a 1.100 y por 103 a 375.
   En flujo no puede solapar NADA, por definición: empuja. Y el choque con el
   astro que motivó el absoluto ya no aplica, porque la caja ha crecido 70 px
   con este mismo cambio y el bloque centrado tiene de sobra. */
.cabecera-viva .pill-fuente {
  align-self: center;
  margin: var(--e-2) 0 var(--e-3);
  /* +50 % como el resto de la cabecera (11 → 16 px). Es EL renglón que
     distingue una medida de una estimación: si algo tenía que crecer aquí,
     era este. */
  font-size: 16px; padding: 4px 12px;
  max-width: 100%; white-space: normal;
  background: var(--cv-pill-fondo, rgb(255 255 255 / .55));
  border-color: transparent; color: var(--cv-tinta-2, rgb(34 46 66 / .8));
  backdrop-filter: blur(3px);
}
/* El aviso de red YA NO vive aquí dentro: era el otro absoluto de esta misma
   franja y se pisaba con la píldora. Está al final del fichero, junto a
   .aviso-red, porque ahora es un bloque en flujo del hero. */

@media (max-width: 720px) {
  /* 296 y no 272: por debajo de 900 px la píldora con lectura de estación pasa
     a DOS líneas («Medido en SAN ROQUE SOTOGRANDE (AEMET), la estación oficial
     más cercana · a 11 km · hace 2 h 49 min») y crece hacia arriba, tapando el
     mín/máx. Medido a 700 px: se comía 11,1 px. La píldora también baja un punto
     de cuerpo aquí, que ahorra una línea en muchos casos. */
  .cabecera-viva { height: 404px; }
  .cv-temp { font-size: 74px; }
  .cv-lugar { font-size: 29px; }
  .cv-maxmin { gap: 16px; font-size: 18px; }
  .cv-superior, .cv-pie { font-size: 15px; }
  .cabecera-viva .pill-fuente { font-size: 15px; }
  .cv-int { padding: 14px 14px 0; }
  .cv-velo { top: 132px; }
  /* La píldora ya NO baja de cuerpo aquí: bajaba a 0,58rem (9,3 px) para
     ahorrar una línea, y el precio era que el renglón que dice de DÓNDE sale el
     número —lo que distingue una medida de una estimación, que es el producto—
     quedaba en el tamaño más pequeño de toda la página justo en la pantalla
     donde peor se lee. La línea que se ahorraba se recupera con el alto extra
     que ya tiene la cabecera en este tramo. */
}
@media (max-width: 460px) {
  /* 306 y no 258: en un móvil estrecho la píldora con nombre de estación largo
     llega a TRES líneas (medido a 375 px: 54 px de alto) y crece hacia arriba
     sobre el mín/máx. Es el peor caso de toda la web. */
  .cabecera-viva { height: 444px; }
  .cv-temp { font-size: 62px; }
  .cv-lugar { font-size: 27px; }
  .cv-cond { font-size: 19px; }
  .cv-maxmin { font-size: 17px; }
  .cv-superior, .cv-pie { font-size: 14px; }
  .cabecera-viva .pill-fuente { font-size: 14px; }
  /* Se conserva el cuerpo (11 px) y lo que cede es el INTERLETRAJE. Aun así, la
     franja superior no cabe en una línea: medido a 412 px, «Sinapsis 3 ·
     actualizado hace 3 h 1 min» + «dom, 26 jul · 09:16» piden 400 px y hay 343.
     A 9 px cabía justo, y por eso estaba en 9 px. Antes que recortar con
     puntos suspensivos —que se comería los minutos por un lado y la HORA por el
     otro— la franja pasa a dos líneas: no se pierde ni un dato y el hueco sale
     del centro de la cabecera, que va sobrado. El pie (orto · luna · ocaso) sí
     cabe en una línea y se queda como está. */
  .cv-superior, .cv-pie { letter-spacing: .1px; }
  .cv-superior { flex-direction: column; align-items: center; gap: 1px; }
  .cv-velo { top: 118px; }
}

/* ==========================================================
   INSTRUMENTOS (§7 fila de 6 · §8 fila de 4)
   Variante «banda»: columnas iguales separadas por líneas de
   1px conseguidas con gap sobre el fondo --borde (nunca con
   bordes por celda: se doblarían en los cruces).
   ========================================================== */
.ins-banda {
  display: grid; gap: 1px;
  background: var(--borde);
  border: 1px solid var(--borde);
  border-radius: var(--radio-m);
  overflow: hidden;
  box-shadow: var(--sombra);
  margin-top: 12px;
}
/* Contenedor de las dos bandas dentro del hero. Antes el marcado le daba la
   clase .banda —que no tenía pareja en el CSS nuevo—, y el relleno de sección
   de .banda (clamp(48px,6vw,96px) clamp(16px,3vw,48px)) sobraba por los dos
   ejes: dejaba las bandas 86 px más estrechas que la cabecera y a 98 px de
   ella, cuando el diseño (§3) las quiere al MISMO ancho y a 12 px. El canalón
   lateral lo pone .hero (padding: 0 clamp(12px,2.2vw,22px)), que es el
   contenedor común de la cabecera y de las bandas, así que aquí el relleno
   lateral es CERO: es lo único que garantiza que compartan caja. Los 12 px de
   separación los aporta el margin-top de .ins-banda. Abajo sí queda aire
   (32-48 px) antes de la sección «Pronóstico». */
.hero-datos {
  padding: 0 0 clamp(var(--e-6), 3vw, var(--e-7));
}

/* Las bandas ajustan sus columnas al número de celdas que SOBREVIVEN: una
   variable sin dato se oculta (§9) y un repeat() fijo dejaría una columna vacía
   pintada del color del borde, que se lee como un hueco roto. */
.ins-banda-6 { grid-template-columns: repeat(6, 1fr); }
.ins-banda-5 { grid-template-columns: repeat(5, 1fr); }
.ins-banda-4 { grid-template-columns: repeat(4, 1fr); }
.ins-banda-3 { grid-template-columns: repeat(3, 1fr); }
/* CUATRO CELDAS DEL ANCHO DE CINCO, CENTRADAS (27-jul-2026). La fila 2 perdió
   «Visibilidad» al recortar las variables del forecast y quedó en cuatro. Las
   dos alternativas obvias fallan: con .ins-banda-4 (cuatro columnas a todo lo
   ancho) las celdas de abajo salen 1,25 veces más anchas que las de arriba —el
   defecto exacto que Álvaro mandó corregir el 25-jul, cuando eran 1,5— y con
   .ins-banda-5 y solo cuatro celdas queda una columna vacía pintada del color
   del borde, que se lee como un hueco roto.
   La cuenta, con box-sizing:border-box, borde de 1px y gap de 1px:
     columna de la fila de 5 = (W − 2·borde − 4·gap) / 5 = (W − 6) / 5
     ancho que necesitan 4 de esas   = 4·col + 3·gap + 2·borde = (4W + 1) / 5
   Por eso el 400 % y el +1px. Si cambian el borde o el gap de .ins-banda, esta
   fórmula cambia con ellos (el test de navegador mide las dos filas). */
.ins-banda-4c {
  grid-template-columns: repeat(4, 1fr);
  width: calc((400% + 1px) / 5);
  margin-inline: auto;
}
/* DISPOSICIÓN DE LA CELDA (26-jul-2026, a petición de Álvaro).
   Antes iba todo centrado y apilado, y la celda desperdiciaba su anchura: el
   icono y el valor ocupaban dos renglones enteros cada uno para no llenar ni
   medio. Ahora:
       ┌──────────────────────────────┐
       │ NUBOSIDAD                    │   ← rótulo, a todo el ancho
       │ [icono]                40 %  │   ← icono a la izquierda, dato a la derecha
       │ poco nuboso                  │
       │ ▬▬▬▬▬▬▬●▬▬▬▬▬▬               │   ← el resto, a todo el ancho
       │ mín 12 · máx 68 %            │
       │ previsión · Sinapsis 3       │
       └──────────────────────────────┘
   Dos columnas: la primera se ajusta al icono, la segunda se queda el resto.
   Todo lo que no es el par icono/valor cruza las dos. Y alineado a la
   izquierda, no centrado: una columna de textos centrados de longitudes
   distintas no tiene por dónde leerse. */
.ins-celda {
  background: var(--superficie); padding: 12px 12px 11px; min-width: 0;
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: center; column-gap: 8px;
  text-align: left;
}
.ins-celda > *:not(.ins-svg):not(.ins-lectura) { grid-column: 1 / -1; }
/* Celda SEMILLA: la que viaja en el HTML con su rótulo y un «—» hasta que
   renderAhora() la sustituye. Tiene la MISMA estructura que la celda real, así
   que mide lo mismo y la hidratación no mueve la página (el porqué, en el
   index.html). Solo se apaga el «—» grande: es un hueco, no una lectura. */
.ins-semilla .ins-lectura { color: var(--tinta-suave); }
/* Los cuatro rótulos pequeños de la celda suben al suelo de 11 px y pasan de
   --tinta-tenue a --tinta-suave. El color no es gusto: --tinta-tenue (#9aa3b2)
   sobre blanco da 2,5:1 y el mínimo AA para texto normal es 4,5:1; en oscuro
   daba 3,6:1. Lighthouse lo cantaba como fallo de accesibilidad señalando
   exactamente estas tres reglas (.ins-desc, .ins-minmax, .ins-uni). Con
   --tinta-suave son 4,5:1 en claro y 6,1:1 en oscuro. La jerarquía no se pierde
   —siguen siendo más claros que la lectura— pero ahora se pueden leer. */
.ins-etq {
  display: block; font-size: var(--t-mini); text-transform: uppercase;
  letter-spacing: .6px; color: var(--tinta-suave);
}
/* Icono a la izquierda y dato a la derecha, en el mismo renglón. El SVG no
   encoge (los diez están dibujados a un tamaño fijo) y el dato se alinea al
   borde derecho, que es donde el ojo compara cifras entre celdas. */
.ins-svg {
  grid-column: 1; height: 44px; display: flex; align-items: center;
  justify-content: flex-start; margin-top: 6px; flex: 0 0 auto;
}
.ins-lectura {
  grid-column: 2; justify-self: end; text-align: right;
  font-family: var(--f-mono); font-size: 18px; color: var(--tinta);
  margin-top: 6px; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.ins-uni { font-size: var(--t-mini); color: var(--tinta-suave); }
.ins-desc {
  font-size: var(--t-mini); color: var(--tinta-suave); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* La barra de rango es idéntica en las diez celdas: carril, tramo de la ventana
   en el color del instrumento al 28 % y punto en el valor de ahora. */
.ins-rango {
  height: 3px; border-radius: var(--radio-pastilla);
  background: var(--superficie-alta); position: relative; margin-top: 9px;
}
/* Luna y mareas no tienen mín/máx: conservan el HUECO para que las cuatro
   celdas queden a la misma altura (§8), pero sin carril ni punto. */
.ins-rango-vacio { background: transparent; }
.ins-tramo { position: absolute; top: 0; bottom: 0; opacity: .28; border-radius: var(--radio-pastilla); }
.ins-punto { position: absolute; top: -2px; width: 7px; height: 7px; border-radius: 50%; transform: translateX(-50%); }
.ins-minmax {
  font-family: var(--f-mono); font-size: var(--t-mini); color: var(--tinta-suave);
  margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Procedencia de la celda: no estaba en el diseño (el handoff no la conocía),
   pero es lo que impide mezclar en silencio lo que mide un aparato con lo que
   estima un modelo. --tinta-suave y no --tinta-tenue: este rótulo hay que poder
   LEERLO, y el tenue sobre blanco se queda por debajo del mínimo AA. */
.ins-fuente {
  /* Sin interletraje: «previsión · Sinapsis 3» es el renglón más largo de la
     celda y con .02em se pasaba 4 px del ancho disponible en un móvil de
     360, cortando justo el nombre del modelo. */
  font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0;
  color: var(--tinta-suave); margin-top: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Lo medido se distingue por PALABRA y color, nunca por color solo. */
.ins-fuente.medida { color: var(--verde-tinta); }
/* Los tres renglones de texto de la celda CONSERVAN su línea aunque no tengan
   nada que decir. Un <div> vacío no genera caja de línea y mide 0: sin esto,
   una celda sin descriptor, sin mín/máx o sin procedencia queda una o dos
   líneas más baja que sus vecinas, y como en una rejilla mandan las filas, toda
   la fila encoge. Consecuencias medidas: la banda cambiaba de alto entre una
   ciudad costera y una de interior (32 px), y al hidratar daba un salto de
   maquetación de CLS 0,12. El espacio duro va en el CSS y no en el HTML para
   que no se cuele en el texto que leen los lectores de pantalla. */
.ins-desc:empty::before, .ins-minmax:empty::before, .ins-fuente:empty::before {
  content: "\00a0";
}

/* ==========================================================
   CUERPOS DE LA CELDA SEGÚN EL ANCHO QUE DE VERDAD TIENE
   (26-ago-2026, petición de Álvaro: «que el texto de las tarjetas sea más
   grande»; mismo criterio que el +50 % de la cabecera viva del 4-ago).
   ----------------------------------------------------------
   VA CON @container Y NO CON @media, y el motivo no es elegancia: lo que
   decide si un renglón cabe es el ancho de la CELDA, no el de la ventana, y
   las dos bandas cambian de columnas por su cuenta (5 → 3 → 2). Las cuentas,
   con --ancho-amplio 1400, borde 1 px y gap 1 px:
     ventana 1400+ · 5 columnas → celda 270 px
     ventana  980  · 3 columnas → celda 311 px   ← MÁS ancha que a 1400
     ventana  560  · 2 columnas → celda 266 px
     ventana  360  · 2 columnas → celda 166 px
   O sea que la ventana más ancha da la celda más estrecha. Con @media habría
   que perseguir esa inversión a mano y se rompería al tocar un breakpoint.

   DÓNDE ESTÁN LOS ESCALONES. El renglón más largo de las nueve celdas es el
   descriptor de mareas, «subiendo · sobre nivel medio» (28 caracteres de la
   tipografía de interfaz, ~0,5 em de avance): pide 14 px de ancho por cada px
   de cuerpo. El segundo es «previsión · Sinapsis 3» (22 de IBM Plex Mono, 0,6
   em exactos): 13,2 px por px de cuerpo. A 240 px de celda el primero admite
   hasta 17 px y el segundo hasta 18: 15 entra con holgura. A 200 px admiten
   14,2 y 15,1: 13 entra. Por debajo de 200 NO se toca nada, y eso es
   deliberado — en un móvil de 360 la celda ofrece 154 px y «previsión ·
   Sinapsis 3» ya pide 145 a 11 px de cuerpo. Ahí no hay sitio, y subir el
   cuerpo solo serviría para cortar justo el nombre del modelo.

   EL NÚMERO SUBE GRATIS, y es el «aire» que vio Álvaro. La fila del medio la
   manda el icono, que mide 44 px de alto; el número iba a 18. Todo lo que
   crezca por debajo de 44 no le cuesta un píxel de alto a la tarjeta. El
   valor más largo de las nueve celdas es la presión, «1.013» + «hPa»: a 36 px
   son 144 px de los 188 que deja la columna. Cabe.
   LO QUE SÍ HAY QUE FIJAR ES EL INTERLINEADO: con el 1,55 que hereda del
   cuerpo, 36 px de número dan una caja de 55,8 y la fila crecería 12 px. Con
   1,05 son 37,8 y sigue por debajo del icono. Por eso el line-height es
   explícito aquí y no en la regla base.

   LO QUE SÍ CRECE. Los cuatro rótulos pequeños suman ~4 px cada uno en el
   escalón grande: ~16 px sobre una tarjeta de ~150. Es el precio de que se
   lean, y es el mismo trato que se le dio a la cabecera.
========================================================== */
.ins-celda { container-type: inline-size; }

@container (min-width: 200px) {
  .ins-lectura { font-size: 27px; line-height: 1.05; }
  .ins-etq, .ins-desc, .ins-minmax, .ins-fuente, .ins-uni { font-size: 13px; }
}
@container (min-width: 240px) {
  .ins-lectura { font-size: 36px; line-height: 1.05; }
  .ins-etq, .ins-desc, .ins-minmax, .ins-fuente, .ins-uni { font-size: 15px; }
}

/* ==========================================================
   ATMÓSFERA — reglas comunes y animaciones (§6)
   ----------------------------------------------------------
   js/ui/atmosfera.js emite SOLO lo que varía de un elemento a
   otro (posición, tamaño, duración, retardo, color) en estilos
   inline; lo común vive aquí. El contrato está escrito al final
   de ese módulo: si se cambia un nombre de animación, hay que
   cambiarlo en los dos sitios.
   ========================================================== */
.atm-estrella { position: absolute; border-radius: 50%; background: #fff; }
.atm-nube { position: absolute; left: 0; }
.atm-nube-vaiven { position: absolute; inset: 0; }
.atm-nube-bulto { position: absolute; border-radius: 50%; }
.atm-gota { position: absolute; top: -16px; border-radius: 2px; }
.atm-racha {
  position: absolute; left: 0; height: 30px;
  /* La máscara difumina los extremos del trazo; sin ella la racha entra y sale
     de golpe, y se nota que es un elemento y no una ráfaga. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 22%, #000 72%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 22%, #000 72%, transparent);
}
.atm-racha svg { width: 100%; height: 100%; display: block; }

@keyframes atm-deriva { from { transform: translateX(-60%); } to { transform: translateX(160%); } }
@keyframes atm-vaiven { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes atm-caida {
  from { transform: translate3d(0, -34px, 0) rotate(7deg); }
  to { transform: translate3d(-24px, 250px, 0) rotate(7deg); }
}
@keyframes atm-caida-viento {
  from { transform: translate3d(0, -34px, 0) rotate(17deg); }
  to { transform: translate3d(-78px, 250px, 0) rotate(17deg); }
}
@keyframes atm-racha {
  0% { transform: translateX(-30%) scaleX(.85); opacity: 0; }
  12% { opacity: .9; }
  70% { opacity: .75; }
  100% { transform: translateX(170%) scaleX(1.15); opacity: 0; }
}
/* El calc() conserva la atenuación del crepúsculo: con opacidad fija, todas las
   estrellas parpadearían igual de fuertes en cuanto anochece. */
@keyframes atm-parpadeo {
  0%, 100% { opacity: calc(var(--atmBrillo, 1) * .2); }
  50% { opacity: var(--atmBrillo, 1); }
}

/* Atmósfera pausada cuando la cabecera sale del viewport (§6): el cielo no
   tiene por qué seguir animándose bajo el scroll. */
.atm-pausada * { animation-play-state: paused !important; }

/* JERARQUÍA. Las diez variables van en DOS FILAS DE CINCO, así que todas las
   celdas miden exactamente lo mismo y ninguna pesa más que otra por tamaño: el
   orden de lectura es el que dice qué es principal. (Con 6 arriba y 4 abajo,
   las de abajo eran 1,5 veces más anchas y se comían a las principales.) */

/* Celda declarada sin dato (mareas en una ciudad de interior): ocupa su sitio
   para que la rejilla no cambie de tamaño al navegar entre costa e interior,
   pero se lee como apagada y DICE por qué no hay dato. */
.ins-apagada { background: var(--superficie-alta); }
.ins-apagada .ins-lectura, .ins-apagada .ins-etq { color: var(--tinta-suave); }

/* Las dos filas bajan a la vez para que sigan cuadrando entre sí: 5 → 3 → 2.
   .ins-banda-4c baja a DOS columnas donde la de arriba baja a tres, con el
   mismo ajuste de ancho: dos celdas del tamaño de las de arriba, centradas.
   Con tres columnas también cuadraría de tamaño, pero cuatro celdas en tres
   columnas dejan DOS huecos seguidos en el segundo renglón (dos tercios de fila
   pintados del color del borde); con dos columnas cae redonda en 2 + 2 y no
   queda ninguno. La cuenta es la de arriba con 3 en vez de 5:
     columna de la fila de 3 = (W − 2·borde − 2·gap) / 3 = (W − 4) / 3
     ancho que necesitan 2    = 2·col + gap + 2·borde   = (2W + 1) / 3          */
@media (max-width: 980px) {
  .ins-banda-6, .ins-banda-5 { grid-template-columns: repeat(3, 1fr); }
  .ins-banda-4c {
    grid-template-columns: repeat(2, 1fr);
    width: calc((200% + 1px) / 3);
  }
}
@media (max-width: 560px) {
  .ins-banda-6, .ins-banda-5, .ins-banda-4, .ins-banda-4c,
  .ins-banda-3 { grid-template-columns: repeat(2, 1fr); }
  /* Aquí las dos filas ya tienen las mismas columnas: la de cuatro suelta su
     ancho calculado y ocupa todo, igual que la de arriba (y cae en 2 + 2). */
  .ins-banda-4c { width: auto; margin-inline: 0; }
  /* 6 px de canalón y no 8: con 8, «previsión · Sinapsis 3» pedía 145 px en una
     columna de 143 y el renglón de procedencia se cortaba en «Sinapsis…» en un
     móvil de 360. Cuatro píxeles bastan, y ese renglón es de los que no se
     pueden dejar a medias: es el que distingue una medida de una estimación. */
  .ins-celda { padding: 11px 6px 10px; column-gap: 6px; }
}

/* El hero anterior («Cielo protagonista»): .cielo/.escena/.banda-datos/
   .tarjetas-extra vivían aquí. Los sustituyen la CABECERA VIVA y las dos bandas
   de instrumentos de arriba. Se borran en vez de dejarse muertos para que nadie
   los reutilice por error: la versión anterior sigue intacta en ../sitio_web/. */

/* Ya no es una leyenda de símbolos (los ○/● se quitaron: obligaban a buscar
   una clave para entender un dato). Es una frase, y se compone como tal. */
.leyenda-fuentes {
  max-width: var(--ancho-contenido);
  margin: var(--e-4) auto 0; color: var(--tinta-suave);
  font-size: var(--t-xs); line-height: 1.5;
}

/* ---------- tira horaria ---------- */
.tira-horaria {
  display: flex; gap: var(--e-4); overflow-x: auto;
  padding: var(--e-3) var(--e-1) var(--e-4);
  scrollbar-width: thin;
  border-bottom: 1px solid var(--borde);
  margin-bottom: var(--e-5);
}
.th-col {
  min-width: 52px; text-align: center; display: flex;
  flex-direction: column; gap: 3px; align-items: center;
}
.th-hora { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--tinta-suave); }
.th-emoji { font-size: 1.25rem; }
.th-temp { font-weight: 600; font-variant-numeric: tabular-nums; }
.th-lluvia { font-family: var(--f-mono); font-size: var(--t-mini); color: var(--gr-prec); }
/* El renglón conserva su línea aunque no llueva. Con `min-height: 1em` no
   bastaba: 1em son 11 px y la caja de línea CON texto mide 17, así que la tira
   medía 6 px más en una ciudad lluviosa que en una seca y daba un salto al
   cambiar de ciudad. Es el mismo arreglo que llevan los renglones de las
   celdas de instrumento. */
.th-lluvia:empty::before { content: "\00a0"; }

/* BARRAS DE LA TIRA HORARIA (26-jul-2026). Dos carriles pegados: la nubosidad
   (0-100 %, gris) y la lluvia (a escala de la ventana, azul). Los datos ya
   viajaban en el documento; lo único que faltaba era enseñarlos.
   La nubosidad va aquí y no en una sección aparte porque el 12 de agosto hay un
   eclipse total y lo que decide si se ve es el cielo cubierto, no la lluvia:
   tenerla hora a hora, junto al resto del pronóstico, es lo que le da el peso
   que pedía sin montar una pantalla nueva.
   Las dos van en carriles de ALTO FIJO para que la tira no cambie de altura
   entre una ciudad seca y una lluviosa. */
.th-barras { display: flex; align-items: flex-end; gap: 3px; height: 34px; margin-top: 2px; }
.th-pista {
  position: relative; width: 7px; height: 100%;
  display: flex; align-items: flex-end;
  background: var(--superficie-alta); border-radius: var(--radio-pastilla);
  overflow: hidden;
}
/* CARRIL ÚNICO (2-ago-2026): cuando no se espera lluvia en toda la ventana, su
   carril no se dibuja (renderTiraHoraria) y el de nubosidad se queda solo. Se
   ensancha para que siga leyéndose como un medidor y no como una raya
   olvidada — una pista de 7 px suelta parecía un resto de algo. */
.th-barras-sola .th-pista { width: 11px; }
.th-b-nub, .th-b-prec { width: 100%; border-radius: var(--radio-pastilla); }
.th-b-nub { background: var(--tinta-tenue); }
.th-b-prec { background: var(--gr-prec); }
.tira-escala {
  margin: calc(var(--e-4) * -1) 0 var(--e-5);
  font-size: var(--t-xs); color: var(--tinta-suave); line-height: 1.5;
}
.tira-escala b { color: var(--tinta-2); font-weight: 600; }
/* Muestras de color de la leyenda: la misma tinta que la barra de la columna,
   para poder atar el nombre a lo que se ve arriba sin adivinar. Son
   decorativas (aria-hidden): el nombre va escrito al lado, nunca solo color. */
.th-muestra {
  display: inline-block; width: 7px; height: 12px; border-radius: var(--radio-pastilla);
  margin-right: 5px; vertical-align: -1px;
}
.th-muestra-nub { background: var(--tinta-tenue); }
.th-muestra-prec { background: var(--gr-prec); }
/* Enlace al eclipse: se desactiva solo el 13 de agosto (lo decide el JS). */
.av-eclipse { color: var(--marca-tinta); font-weight: 600; text-decoration: none; }
.av-eclipse:hover, .av-eclipse:focus-visible { text-decoration: underline; }
.th-dia {
  align-self: stretch; writing-mode: vertical-rl; text-orientation: mixed;
  font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0.1em;
  color: var(--tinta-suave); border-left: 1px solid var(--borde);
  padding-left: 6px; min-width: 20px;
}

/* ---------- tarjetas de días ---------- */
.dias-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: var(--e-4);
  margin-bottom: var(--e-7);
}
/* Aviso de que las tarjetas se despliegan. Va VISIBLE y no como tooltip: la
   función existía en la app y en la web nadie la encontraba. */
.pista-desplegar {
  margin: 0 0 var(--e-3); font-size: var(--t-xs); color: var(--tinta-suave);
}

/* Tarjeta de día = <details>. El marcador nativo (▸) fuera: la pista de que se
   abre la da el cursor, el hover y el aviso de arriba. */
.dia-card {
  background: var(--superficie);
  border: 1px solid var(--borde);
  /* «Relieve» (§3): las tarjetas de día llevan el radio pequeño (12) y la
     sombra, como el resto de la página. Es lo único que cambia en esta
     sección: su contenido no se toca. */
  border-radius: var(--radio-s);
  box-shadow: var(--sombra);
  padding: var(--e-3) var(--e-4);
}
.dia-card > summary {
  display: grid; gap: 4px; justify-items: start;
  cursor: pointer; list-style: none;
}
.dia-card > summary::-webkit-details-marker { display: none; }
.dia-card:hover { border-color: var(--marca); }
.dia-card > summary:focus-visible {
  outline: 2px solid var(--marca); outline-offset: 3px; border-radius: var(--radio-s);
}
/* Abierta ocupa TODA la fila: con 7 columnas de 128 px, una tabla de 9 modelos
   × 6 variables dentro de una columna sería ilegible. */
.dia-card[open] { grid-column: 1 / -1; border-color: var(--marca); }
.dc-detalle { margin-top: var(--e-3); overflow-x: auto; }
.dc-tabla { width: 100%; border-collapse: collapse; font-size: var(--t-xs); }
.dc-tabla th, .dc-tabla td {
  padding: 5px var(--e-2); border-bottom: 1px solid var(--borde-suave);
  text-align: center; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.dc-tabla thead th { color: var(--tinta-suave); font-weight: 600; }
/* la primera columna (el modelo) SÍ va a la izquierda: es texto, no cifra */
.dc-tabla tbody th[scope="row"] { text-align: left; font-weight: 500; }
.dc-tabla tbody th .chip { margin-right: 6px; }
.dc-fila-sinapsis { background: var(--superficie-alta); font-weight: 600; }
.dc-fila-sinapsis th, .dc-fila-sinapsis td { border-bottom: none; }
.dc-sin-detalle { margin: 0; font-size: var(--t-xs); color: var(--tinta-suave); }
.dc-dia { font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0.07em; text-transform: uppercase; color: var(--tinta-suave); }
.dc-emoji { font-size: 1.7rem; }
.dc-temps { font-variant-numeric: tabular-nums; font-weight: 600; }
.dc-temps .max { color: var(--rojo-max); }
.dc-temps .min { color: var(--azul-min); font-weight: 500; }
.dc-lluvia { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--gr-prec); }

/* ---------- gráficas ---------- */
.segmentos { display: flex; gap: 2px; flex-wrap: wrap; }
.segmentos {
  background: var(--superficie-alta); border-radius: var(--radio-s);
  padding: 2px; width: fit-content;
}
.segmentos button {
  border: none; background: none; cursor: pointer;
  font-size: var(--t-sm); font-weight: 600; color: var(--tinta-suave);
  padding: 5px 12px; border-radius: 7px;
}
.segmentos button[aria-selected="true"], .segmentos button.activo {
  background: var(--superficie); color: var(--tinta);
  box-shadow: inset 0 0 0 1px var(--borde-pill);
}

/* ==========================================================
   BOTONERA DE «VARIABLE A VARIABLE» (2-ago-2026)
   ----------------------------------------------------------
   Sustituye a las cinco pestañas de texto pequeño que había
   encima de la gráfica. El defecto que corrige, en palabras
   de Álvaro: «no se nota que están ahí y que sólo hay que
   hacer clic para seleccionarlos». Ahora cada variable es un
   botón con superficie propia, icono y su insignia de origen.
   El color es un REALCE (filo izquierdo + icono), nunca la
   señal: en blanco y negro los botones siguen enteros.
   Rejilla auto-fit y no una tira con scroll: con nueve
   variables una tira obligaría a desplazarla para llegar a
   las últimas, que es como se perdía «Avanzado».
   ========================================================== */
/* LAS COLUMNAS LAS DECIDE EL JS, no `auto-fit` (2-ago-2026).
   Con `repeat(auto-fit, minmax(150px, 1fr))` las nueve variables salían 8+1 en
   una pantalla ancha: auto-fit mete todas las columnas que quepan y el sobrante
   cae donde caiga. `equilibrarRejilla` (js/ui/secciones.js) calcula cuántas
   caben, de ahí cuántas FILAS hacen falta, y reparte a partes iguales entre
   ellas — 5+4 en vez de 8+1, con el mismo alto. El fallback de 1 columna solo
   actúa el instante anterior a que corra el JS. */
.var-controles {
  display: grid;
  grid-template-columns: repeat(var(--var-cols, 1), minmax(0, 1fr));
  gap: var(--e-2);
  margin-bottom: var(--e-4);
}
.var-btn {
  display: flex; align-items: center; gap: var(--e-3);
  /* RED DE SEGURIDAD del ancho. Un elemento de rejilla no baja de su ancho
     min-content por defecto, así que si --var-cols se quedara alto (JS aún sin
     correr, o un navegador raro) los botones desbordarían la banda y la PÁGINA
     ENTERA cogería scroll horizontal — que es lo que pasó al bajar a 375 px con
     el observador mudo. Con min-width:0 el peor caso es un botón apretado, no
     una página rota. */
  min-width: 0;
  text-align: left; cursor: pointer;
  padding: var(--e-2) var(--e-3);
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-left: 3px solid color-mix(in oklab, var(--var-color) 45%, transparent);
  border-radius: var(--radio-s);
  transition: border-color .12s, background .12s, transform .12s;
}
.var-btn:hover { border-color: var(--borde-pill); transform: translateY(-1px); }
.var-btn[aria-selected="true"] {
  border-color: color-mix(in oklab, var(--var-color) 55%, var(--borde));
  border-left-color: var(--var-color);
  background: color-mix(in oklab, var(--var-color) 8%, var(--superficie));
  box-shadow: var(--sombra);
}
.var-btn-icono {
  font-size: 1.15rem; line-height: 1; flex: 0 0 auto;
  filter: saturate(.9);
}
.var-btn-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* Los dos renglones ENVUELVEN, no se cortan con puntos suspensivos. En una
   columna de 150 px «Calidad del aire» y «9 modelos · verificada» no caben en
   una línea, y recortarlos perdería justo lo que hay que leer: el nombre de la
   variable y si está verificada o no. Una línea de más es más barata. */
.var-btn-nombre {
  font-size: var(--t-sm); font-weight: 600; color: var(--tinta-2);
  line-height: 1.25;
}
.var-btn[aria-selected="true"] .var-btn-nombre { color: var(--tinta); }
/* LA INSIGNIA DE ORIGEN es la mitad del cambio, no un adorno: al entrar el UV
   y la calidad del aire (una sola fuente) la sección dejó de ser «cómo de
   acuerdo están los modelos», y sin este renglón un visitante creería que
   detrás de las nueve variables hay siempre nueve modelos verificados. */
.var-btn-origen {
  font-family: var(--f-mono); font-size: var(--t-mini);
  letter-spacing: .03em; color: var(--tinta-suave); line-height: 1.3;
}
.var-panel { margin-top: var(--e-2); }
/* La frase que dice qué se está mirando y de dónde sale, encima de la gráfica.
   Filo del color de la variable elegida: ata el panel al botón pulsado. */
.var-origen {
  margin: 0 0 var(--e-3);
  padding: var(--e-2) var(--e-3);
  background: var(--superficie-alta);
  border-radius: var(--radio-s);
  font-size: var(--t-xs); line-height: 1.55; color: var(--tinta-suave);
}
.var-origen:empty { display: none; }

.grafica-figura { position: relative; margin: 0; }
.grafica { width: 100%; height: auto; display: block; }
.gr-rejilla { stroke: var(--gr-rejilla); }
.gr-eje { fill: var(--tinta-suave); font-family: var(--f-mono); font-size: 11px; }
.gr-contexto { stroke: var(--gr-contexto); stroke-width: 1.1; }
.gr-combinado { stroke: var(--gr-combinado); stroke-width: 2.4; stroke-linecap: round; }
.gr-secundaria { stroke: var(--ambar-tinta); stroke-width: 1.6; stroke-dasharray: 5 4; }
.gr-area { fill: var(--gr-area); }
.gr-etiqueta-directa {
  fill: var(--gr-combinado); font-family: var(--f-mono);
  font-size: 11px; font-weight: 500;
}
.gr-cruz { stroke: var(--tinta-tenue); stroke-width: 1; stroke-dasharray: 3 3; }
.gr-punto { fill: var(--gr-combinado); stroke: var(--superficie); stroke-width: 1.5; }
.gr-barra-prec { fill: var(--gr-prec); }
.gr-tooltip {
  position: absolute; z-index: 5; pointer-events: none;
  background: color-mix(in oklab, var(--superficie) 96%, transparent);
  border: 1px solid var(--borde);
  border-radius: var(--radio-s);
  padding: var(--e-2) var(--e-3);
  font-family: var(--f-mono); font-size: var(--t-mini); line-height: 1.7;
  color: var(--tinta-suave);
  max-width: 190px;
  font-variant-numeric: tabular-nums;
}
.gr-tooltip .tt-comb { color: var(--gr-combinado); }
.gr-leyenda {
  display: flex; gap: var(--e-4); flex-wrap: wrap;
  margin-top: var(--e-2); font-size: var(--t-xs); color: var(--tinta-suave);
}
.gr-leyenda .muestra { display: inline-block; width: 16px; height: 0; border-top: 2.4px solid var(--gr-combinado); vertical-align: middle; margin-right: 5px; }
.gr-leyenda .muestra.ctx { border-top: 1.1px solid var(--gr-contexto); }
/* la línea de rachas del viento: discontinua y ámbar, como la pinta el SVG
   (.gr-secundaria). Sin muestra, la leyenda nombraba dos de las tres líneas. */
.gr-leyenda .muestra.sec { border-top: 1.6px dashed var(--ambar-tinta); }

/* ---------- multimodelo ---------- */
.mm-scroll { overflow-x: auto; scrollbar-width: thin; padding-bottom: var(--e-2); }
.mm-tabla {
  display: grid;
  /* COLUMNAS ELÁSTICAS (2-ago-2026): `minmax(46px, 1fr)` en vez de `46px`
     fijos. Con 24 pasos la tira medía 1.208 px dentro de una banda de ~1.300 y
     se quedaba justificada a la izquierda, con una franja muerta a la derecha
     que se leía como un fallo de maquetación. Ahora las columnas reparten el
     ancho sobrante y la tira llena la banda. Cuando NO cabe (más pasos, o
     pantalla estrecha) el `min-width: min-content` de abajo manda: las columnas
     vuelven a sus 46 px mínimos y `.mm-scroll` desplaza, como siempre. */
  grid-template-columns: 104px repeat(var(--n, 24), minmax(46px, 1fr));
  align-items: center;
  min-width: min-content;
  row-gap: 2px;
}
.mm-esquina, .mm-esquina-h {
  position: sticky; left: 0; z-index: 2; background: var(--fondo);
  grid-column: 1;
}
/* El rótulo va CENTRADO sobre su propio tramo de columnas, no pegado a su
   filo izquierdo: pegado parecía la etiqueta de la primera columna en vez del
   título del día entero. El filo separador ya no lo lleva este elemento — lo
   pone .mm-inicio-dia, que atraviesa la tabla de arriba abajo. */
.mm-dia {
  font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--tinta-suave); font-weight: 500;
  padding: 0 4px 3px; text-align: center;
}
.mm-hora {
  font-family: var(--f-mono); font-size: var(--t-mini); color: var(--tinta-suave);
  text-align: center; padding-bottom: 4px;
}
/* SEPARACIÓN ENTRE DÍAS. La lleva la PRIMERA celda de cada día en TODAS las
   filas (cabecera, horas y cada modelo), así que dibuja una línea vertical
   continua de arriba abajo. Antes solo había un filo en la fila de días y, con
   las columnas cada 3 h, dónde acababa un día había que adivinarlo. El primer
   día no lleva filo: no separa de nada (lo decide filoDia() en el JS). */
.mm-inicio-dia { box-shadow: inset 1px 0 0 var(--borde-pill); }
.mm-modelo {
  position: sticky; left: 0; z-index: 2; background: var(--fondo);
  grid-column: 1; display: flex; align-items: center; gap: 6px;
  font-size: var(--t-sm); font-weight: 600; color: var(--tinta-2);
  padding: 4px 10px 4px 2px; height: 100%;
  border-right: 1px solid var(--borde);
}
.mm-punto { width: 8px; height: 8px; border-radius: 2px; background: var(--chip, var(--borde)); flex: 0 0 auto; }
.mm-nombre-sinapsis { font-weight: 700; color: var(--tinta); }
/* zebra: filas alternas con fondo algo más oscuro para seguir cada modelo */
.mm-z { background: color-mix(in oklab, var(--tinta) 10%, transparent); }
.mm-modelo.mm-z { background: color-mix(in oklab, var(--tinta) 10%, var(--fondo)); }
.mm-regional { color: var(--tinta-suave); font-weight: 500; }
.mm-hr { color: var(--ambar-tinta); font-size: var(--t-mini); margin-left: 3px; }
.mm-celda {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 3px 0; border-radius: 7px;
}
.mm-icono { font-size: 1.15rem; line-height: 1; }
.mm-temp {
  /* --tinta-2 y no --tinta-suave: esta cifra cae sobre las filas CEBRA, que
     mezclan un 10 % de tinta en el fondo, y ahí el gris legible se quedaba en
     3,97:1. Además es un dato, no un rótulo secundario: que se lea mejor que la
     etiqueta de al lado es lo correcto, no una concesión. */
  font-family: var(--f-mono); font-size: var(--t-mini); color: var(--tinta-2);
  font-variant-numeric: tabular-nums;
}
/* franja de fondo alterna en la fila del combinado */
.mm-tabla > .mm-nombre-sinapsis,
.mm-tabla > .mm-nombre-sinapsis ~ .mm-celda:nth-child(-n+33) { }
.mm-nombre-sinapsis { background: color-mix(in oklab, var(--marca) 9%, var(--fondo)); box-shadow: inset 2px 0 0 var(--marca); }

/* ---------- fiabilidad ---------- */
/* Una sola columna desde el 23-jul-2026: al retirarse el panel «Verificación,
   día a día» aquí solo queda la clasificación, y con dos columnas se quedaba
   coja a media página. Sigue siendo rejilla (y no un div suelto) porque el
   margen inferior separa de la gráfica de evolución. */
.fiabilidad-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--e-5);
  margin-bottom: var(--e-5);
}
.panel {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio-m);
  box-shadow: var(--sombra);
  padding: var(--e-5);
}
.panel-cabecera { display: flex; justify-content: space-between; align-items: center; gap: var(--e-3); flex-wrap: wrap; }

/* SELECTOR DE VARIABLE DEL RANKING (2-ago-2026). Nueve pastillas grises
   apretadas contra el título no se leían como botones. Ahora: rótulo propio,
   fila entera para ellos, icono, filo visible y relleno de marca en el
   elegido. Mismo problema y misma cura que la botonera de «Variable a
   variable», pero más compactos: aquí no hay insignia de origen que contar y
   son nueve en un panel, no nueve en una sección. */
.rk-selector-rotulo {
  margin: var(--e-3) 0 var(--e-2);
  font-family: var(--f-mono); font-size: var(--t-mini);
  letter-spacing: .06em; text-transform: uppercase; color: var(--tinta-suave);
}
.rk-selector-rotulo[hidden] { display: none; }
.seg-variables { display: flex; flex-wrap: wrap; gap: 6px; }
.seg-var-btn {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 5px 11px; border-radius: var(--radio-pastilla);
  border: 1px solid var(--borde-pill);
  background: var(--superficie);
  font-size: var(--t-sm); font-weight: 600; color: var(--tinta-suave);
  transition: border-color .12s, background .12s, color .12s;
}
.seg-var-btn:hover { border-color: var(--marca); color: var(--tinta-2); }
.seg-var-btn[aria-selected="true"] {
  background: color-mix(in oklab, var(--marca) 14%, var(--superficie));
  border-color: var(--marca);
  color: var(--marca-tinta);
}
.definicion { color: var(--tinta-suave); margin: var(--e-1) 0 var(--e-4); }
/* LETRA PEQUEÑA EN TARJETAS ANCHAS. Llevaba un max-width de 60 caracteres —la
   medida cómoda de lectura— dentro de paneles de más de 1300 px, y dejaba dos
   tercios vacíos. Se probó repartirla en columnas, pero partir una nota de tres
   líneas en tres columnas se lee peor de lo que se ganaba. Va a UNA columna del
   ancho de su tarjeta: es letra pequeña de método, se lee de corrido y así
   ningún bloque queda a medio ocupar. */
.nota-metodo {
  font-size: var(--t-xs); color: var(--tinta-suave); margin: var(--e-4) 0 0;
}

/* ANCHO DE LA CLASIFICACIÓN (2-ago-2026). El panel ocupaba los 1400 px de la
   banda y las cuatro columnas se estiraban con él: entre el nombre del modelo y
   su cifra de error quedaban «kilómetros de página vacía» (Álvaro), y la vista
   tenía que cruzar media pantalla para emparejar cada fila con su número. Un
   listado de diez filas de tres datos no necesita 1400 px: se acota a una
   medida en la que la fila se lee de un golpe de vista, centrada en la banda.
   El tope va en el CONTENEDOR y no en la fila para que el borde del panel
   acompañe al contenido en vez de dibujar una caja medio vacía. */
#panel-ranking { max-width: 760px; margin-inline: auto; }
.rk-fila {
  display: grid;
  grid-template-columns: 26px minmax(120px, 1.25fr) minmax(70px, 1fr) 104px;
  gap: var(--e-3);
  align-items: center;
  padding: var(--e-2) var(--e-2);
  border-radius: var(--radio-s);
  font-variant-numeric: tabular-nums;
}
.rk-fila.sinapsis {
  background: color-mix(in oklab, var(--marca) 8%, transparent);
  box-shadow: inset 2px 0 0 var(--marca);
}
.rk-pos { font-family: var(--f-mono); font-size: var(--t-sm); color: var(--tinta-suave); text-align: right; }
.rk-nombre { font-size: var(--t-sm); font-weight: 600; display: flex; align-items: center; gap: 7px; }
.rk-nombre .chip { width: 8px; height: 8px; border-radius: 2px; background: var(--chip, var(--borde)); flex: 0 0 auto; }
.rk-nombre small { color: var(--tinta-suave); font-weight: 400; }
.rk-pista { height: 6px; border-radius: 3px; background: var(--superficie-alta); overflow: hidden; }
.rk-barra { height: 100%; border-radius: 3px; background: color-mix(in oklab, var(--marca) 45%, var(--superficie-alta)); }
.sinapsis .rk-barra { background: var(--marca); }
.rk-valor { font-family: var(--f-mono); font-size: var(--t-sm); text-align: right; }
.rk-valor small { color: var(--tinta-suave); font-size: var(--t-mini); }
.rk-sin-datos { opacity: 0.45; }
.rk-sin-verdad { margin: 0.6rem 0; padding: 0.8rem 1rem; border-left: 3px solid var(--borde); color: var(--tinta-suave); font-size: 0.95rem; line-height: 1.5; }

/* Las reglas de la verificación día a día (.tv-* de la tira y .lv-* de la
   lista) se ELIMINARON el 23-jul-2026 con el panel que las usaba. */

.panel-ancho { margin-top: var(--e-5); }

/* ---------- radar ---------- */
.radar-mapa {
  height: clamp(360px, 55vh, 560px);
  border-radius: var(--radio-m);
  border: 1px solid var(--borde);
  overflow: hidden;
  background: var(--superficie-alta);
}
.radar-linea-tiempo { display: flex; align-items: center; gap: var(--e-4); margin-top: var(--e-3); }
.radar-linea-tiempo input[type="range"] { flex: 1; accent-color: var(--marca); }
#radar .banda-cabecera { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: var(--e-3); max-width: none; }

/* ---------- sol, luna y mareas ---------- */
/* TOPE DE ANCHO POR TARJETA (2-ago-2026). Con `1fr` de máximo, la tarjeta se
   estiraba a todo el ancho de la banda, y como **la mayoría de los 702
   municipios son de interior y no tienen mareas**, el caso NORMAL era una sola
   tarjeta de 1.300 px con una tabla de cuatro filas dentro: una caja enorme
   medio vacía. Con el tope de 520 px, la de sol y luna mide lo que mide su
   contenido, y donde hay marea salen las dos juntas y centradas — que es como
   ya se veía bien. `justify-content: center` es lo que impide que una tarjeta
   sola se quede pegada al margen izquierdo con un desierto a la derecha. */
.avanzado-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 520px));
  justify-content: center;
  gap: var(--e-4);
}
/* Desde el 5-ago las tablas son una VARIABLE MÁS de la botonera y comparten
   hueco con la gráfica: el panel enseña una cosa o la otra. Sin estas dos
   reglas el [hidden] no esconde nada, porque `display: grid` es de autor y gana
   al `display: none` del navegador (el mismo caso que .aviso-red). */
.avanzado-grid[hidden] { display: none; }
.dg-lienzo[hidden] { display: none; }
.avz-card {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio-m);
  box-shadow: var(--sombra);
  padding: var(--e-4) var(--e-5);
}
.avz-card h3 { font-family: var(--f-ui); font-size: var(--t-base); font-weight: 600; }
.avz-tabla { width: 100%; border-collapse: collapse; font-size: var(--t-sm); font-variant-numeric: tabular-nums; }
.avz-tabla td, .avz-tabla th { padding: 5px 8px; text-align: right; border-bottom: 1px solid var(--borde-suave); }
.avz-tabla td:first-child, .avz-tabla th:first-child { text-align: left; }
/* ==========================================================
   FIABILIDAD DE LA PREVISIÓN (medidor de cinco barras)
   ----------------------------------------------------------
   En la tarjeta se lee SOLO «Fiabilidad» con su medidor: el
   texto completo («fiabilidad muy alta · discrepan») se salía
   de la tarjeta. El nivel lo dan las barras, y la frase
   entera está en el title y —para quien va con el dedo— dentro
   del propio día, que ya se despliega al pulsarlo.
   ========================================================== */
.fiab {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 7px;
  margin-top: 7px; padding-top: 7px;
  border-top: 1px solid var(--borde-suave);
  font-family: var(--f-mono); font-size: var(--t-mini);
  color: var(--tinta-suave); letter-spacing: .02em;
  cursor: help;
}
.fb-barras { display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; }
/* Escalera: cinco barras de altura creciente. Se entiende sin leyenda porque
   es la forma universal de «cobertura», y además la palabra va al lado. */
.fb-b { width: 3px; border-radius: 1px; background: var(--borde-pill); }
.fb-b:nth-child(1) { height: 4px; }
.fb-b:nth-child(2) { height: 6px; }
.fb-b:nth-child(3) { height: 8px; }
.fb-b:nth-child(4) { height: 10px; }
.fb-b:nth-child(5) { height: 12px; }
.fb-b.on { background: var(--fb-color, var(--tinta-suave)); }
/* El color acompaña, nunca informa solo: la palabra está en el desplegable y
   en el title, y el número de barras dice lo mismo sin color. */
.fiab-muy-alta { --fb-color: var(--verde-tinta); }
.fiab-alta     { --fb-color: var(--verde-tinta); }
.fiab-media    { --fb-color: var(--ambar-tinta); }
.fiab-poca     { --fb-color: var(--sev-alta); }
.fiab-baja     { --fb-color: var(--sev-muy-alta); }
/* La tarjeta reparte sus piezas en una fila; el medidor ocupa renglón propio. */
.dia-card summary { flex-wrap: wrap; }
.dc-fiab-leyenda {
  margin: 0 0 var(--e-3);
  font-size: var(--t-xs); line-height: 1.5; color: var(--tinta-suave);
}
/* Nota del límite de 7 días: discreta pero visible (filo ámbar, la misma
   gramática que el resto de avisos serenos del sitio: .ssr-conservado y
   .rk-conservado). No es una advertencia de error, es una limitación contada. */
.nota-7dias {
  margin: var(--e-4) 0 0;
  padding: var(--e-2) var(--e-4);
  border-left: 3px solid var(--ambar);
  background: var(--superficie-alta);
  border-radius: 0 var(--radio-s) var(--radio-s) 0;
  font-size: var(--t-xs); line-height: 1.6; color: var(--tinta-suave);
}
.nota-7dias[hidden] { display: none; }
.nota-7dias strong { color: var(--tinta-2); }

/* Solo la fila de cabecera va en versalitas mono. Los <th scope="row"> de la
   primera columna son cabecera SEMÁNTICA (para que un lector de pantalla diga
   «Crepúsculo civil, amanecer, 06:58» en vez de un número suelto), pero se leen
   como lo que son: el nombre de la fila, con la misma pinta que antes tenían
   sus <td>. */
.avz-tabla thead th {
  font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0.08em;
  color: var(--tinta-suave); text-transform: uppercase;
}
.avz-tabla tbody th { font-weight: 400; color: inherit; }
/* Cabecera que solo existe para el lector de pantalla (la esquina de la tabla
   de sol y luna: visualmente vacía, semánticamente «Fenómeno»). */
.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------- pie ---------- */
.pie { border-top: 1px solid var(--borde); background: var(--superficie); margin-top: var(--e-8); }
.pie-int {
  max-width: var(--ancho-amplio); margin-inline: auto;
  padding: var(--e-7) clamp(var(--e-4), 3vw, var(--e-7));
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--e-7);
}
.pie .logo-marca { width: 26px; height: 26px; }
.pie p { margin: var(--e-2) 0; }
/* Mismo criterio que .nota-metodo: una columna, al ancho de su contenedor (en
   el pie ya es una de las dos columnas de la rejilla, así que la línea no se
   dispara). */
.pie-metodo { font-size: var(--t-sm); color: var(--tinta-suave); }
.pie-datos h4 { font-family: var(--f-mono); font-size: var(--t-mini); letter-spacing: 0.1em; color: var(--tinta-suave); }
.pie-datos ul { list-style: none; margin: 0; padding: 0; font-size: var(--t-sm); color: var(--tinta-suave); }
.pie-datos li { margin-bottom: var(--e-1); }
.pie-sello { color: var(--tinta-suave); margin-top: var(--e-4); }
/* enlaces legales/informativos del pie (comunes a portada y páginas estáticas) */
.pie-enlaces { margin-top: var(--e-4); font-size: var(--t-sm); color: var(--tinta-suave); }
.pie-enlaces a { color: var(--tinta-suave); text-decoration: none; }
.pie-enlaces a:hover { color: var(--marca); text-decoration: underline; }

/* ---------- diálogos ---------- */
.dialogo {
  border: 1px solid var(--borde);
  border-radius: var(--radio-m);
  background: var(--superficie);
  color: var(--tinta);
  padding: var(--e-5);
  width: min(480px, 92vw);
}
.dialogo::backdrop { background: rgb(20 26 38 / 0.5); backdrop-filter: blur(2px); }
.buscador { display: flex; gap: var(--e-2); }
.buscador input {
  flex: 1; padding: 9px 12px; border-radius: var(--radio-s);
  border: 1px solid var(--borde-pill); background: var(--fondo); color: inherit;
  font: inherit;
}
.btn-primario {
  background: var(--tinta); color: var(--fondo);
  border: none; border-radius: var(--radio-s);
  padding: 9px 16px; font-weight: 600; cursor: pointer;
}
.btn-texto { background: none; border: none; color: var(--marca); font-weight: 600; cursor: pointer; padding: var(--e-2); }
.resultados, .lista-ubicaciones, .lista-lugares {
  list-style: none; margin: var(--e-3) 0; padding: 0;
}
.resultados li, .lista-ubicaciones li, .lista-lugares li {
  display: flex; justify-content: space-between; align-items: center; gap: var(--e-3);
  padding: var(--e-2) 0; border-bottom: 1px solid var(--borde-suave);
  font-size: var(--t-sm);
}
.resultados .zona, .lista-ubicaciones .zona, .lista-lugares .zona {
  color: var(--tinta-suave); font-size: var(--t-xs);
}

/* ---------- favoritas y recientes (4-ago-2026) ---------- */
#bloque-lugares[hidden], #bloque-favoritas[hidden], #bloque-recientes[hidden] { display: none; }
#bloque-lugares h4 { margin: var(--e-4) 0 0; color: var(--tinta-suave); }
/* La ciudad que se está mirando se marca en vez de esconderse: es desde donde
   se la añade a favoritas. */
.lista-lugares .lugar-actual { background: color-mix(in oklab, var(--marca) 7%, transparent); }
.lista-lugares .lugar-actual .zona { color: var(--marca-tinta); font-weight: 600; }
/* La estrella es un CONMUTADOR, no un enlace: tamaño de dedo (44 px de alto
   efectivo con el relleno) y estado en aria-pressed además de en el glifo,
   porque ★ y ☆ se distinguen mal de un vistazo y nada de un lector de pantalla. */
.btn-estrella {
  flex: 0 0 auto; border: none; background: none; cursor: pointer;
  font-size: 1.25rem; line-height: 1; padding: 8px 6px;
  color: var(--tinta-tenue);
  transition: color .12s, transform .12s;
}
.btn-estrella:hover { color: var(--ambar-tinta); transform: scale(1.12); }
.btn-estrella.es-fav { color: var(--ambar); }
/* resultados del buscador de ciudades (modo precomputado): enlaces reales */
.resultado-ciudad {
  display: flex; justify-content: space-between; align-items: center; gap: var(--e-3);
  flex: 1; color: inherit; text-decoration: none;
}
.resultado-ciudad:hover, .resultado-ciudad:focus-visible { color: var(--marca); }
.ajuste-fila { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--e-3); }

/* ---------- bloque SSR (worker) e hidratación ---------- */
/* El worker inyecta en <!--SSR:CONTENIDO--> un bloque semántico legible sin
   JS (h2, resumen, tabla de 7 días, resumen del ranking). La app lo oculta al
   terminar el primer render rico; sin JS se queda visible tal cual. */
.ssr-nucleo {
  max-width: var(--ancho-contenido);
  margin: 0 auto;
  padding: var(--e-6) var(--e-5);
  font-size: var(--t-sm);
}
.ssr-nucleo h2 { font-family: var(--f-display); margin: 0 0 var(--e-3); }
.ssr-nucleo table {
  width: 100%; border-collapse: collapse; margin: var(--e-4) 0;
}
.ssr-nucleo th, .ssr-nucleo td {
  text-align: left; padding: var(--e-2) var(--e-3);
  border-bottom: 1px solid var(--borde-suave);
}
.ssr-nucleo th { color: var(--tinta-suave); font-weight: 600; font-size: var(--t-xs); }
.ssr-oculto { display: none !important; }

/* MUNICIPIOS CERCANOS (17-ago-2026). OJO: esta sección NO lleva prefijo .ssr-
   y no es un descuido. El núcleo SSR se oculta con .ssr-oculto en cuanto el
   render rico termina; este bloque vive FUERA de él y se queda siempre,
   con JavaScript y sin él. Enseñar unos enlaces solo a los buscadores sería
   justo lo contrario de lo que hace esta casa. */
.cercanos {
  max-width: var(--ancho-contenido);
  margin: 0 auto;
  padding: var(--e-6) var(--e-5) var(--e-7);
  border-top: 1px solid var(--borde-suave);
}
.cercanos h2 {
  font-family: var(--f-display); font-size: var(--t-lg);
  margin: 0 0 var(--e-2);
}
.cercanos-sub {
  margin: 0 0 var(--e-4); color: var(--tinta-suave); font-size: var(--t-sm);
  max-width: 34rem;
}
.cercanos-lista {
  list-style: none; margin: 0; padding: 0;
  /* auto-fill y no un número fijo de columnas: en un móvil de 360 px sale una
     columna y en escritorio cuatro, sin media queries que mantener. */
  display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: var(--e-2) var(--e-4);
}
.cercanos-lista li {
  display: flex; align-items: baseline; gap: var(--e-2);
  padding: var(--e-1) 0;
}
.cercanos-lista a { color: var(--marca-tinta); text-decoration: none; }
.cercanos-lista a:hover { text-decoration: underline; }
.cerc-km { color: var(--tinta-suave); font-size: var(--t-xs); white-space: nowrap; }
/* Observación de estación en el núcleo SSR (lo que ve Google y quien no
   ejecuta JS). El crédito a AEMET/IPMA va en <small> pero NO se oculta: es
   una obligación de la licencia, no una nota al pie decorativa. */
.ssr-obs { margin: var(--e-2) 0 var(--e-4); }
.ssr-obs small { display: block; margin-top: 4px; color: var(--tinta-suave); }

/* Aviso de verificación ANÓMALA: la ciudad lleva más de un turno completo sin
   re-verificarse (DIAS_VERIFICACION_ANOMALA en el worker), lo que ya no lo
   explica la rotación. Ámbar, no rojo: es un dato viejo declarado, no una
   caída. El caso NORMAL —ranking de hace unos días, que es el turno— NO usa
   esta caja: lo cuenta .ssr-metodo-verif, en gris y sin alarma. */
.ssr-conservado {
  margin: var(--e-3) 0;
  padding: var(--e-2) var(--e-3);
  border-left: 3px solid var(--ambar);
  background: var(--superficie-alta);
  border-radius: 0 var(--radio-s) var(--radio-s) 0;
  font-size: var(--t-xs);
  color: var(--tinta-suave);
}
/* Pie de método de la verificación: fecha la ventana y explica el turno. Es
   letra pequeña informativa, no un aviso. */
.ssr-metodo-verif {
  margin: var(--e-2) 0 0;
  font-size: var(--t-xs);
  color: var(--tinta-suave);
}

/* ---------- esqueletos de carga ---------- */
.esqueleto {
  background: linear-gradient(100deg, var(--superficie-alta) 40%,
    color-mix(in oklab, var(--superficie-alta) 60%, var(--superficie)) 50%,
    var(--superficie-alta) 60%);
  background-size: 200% 100%;
  animation: brillo 1.4s infinite linear;
  border-radius: var(--radio-s);
  color: transparent !important;
  user-select: none;
}
@keyframes brillo { to { background-position: -200% 0; } }

/* Base del aviso: lo que vale en cualquier parte de la página. */
.aviso-red {
  font-size: var(--t-xs); font-family: var(--f-mono);
  color: var(--sev-alta); padding: var(--e-1) 0;
  display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap;
}
/* AVISO DE ERROR / RED en la portada. Ya no vive DENTRO del cielo: es un bloque
   en flujo entre la cabecera y las bandas (el porqué, en el index.html). Antes
   era absoluto en la MISMA franja que la píldora de fuente —los dos centrados,
   a 40 y 38 px del borde inferior— y se pisaban en cuanto había un error. Y su
   contraste dependía de «.cielo .aviso-red { color:#ffd9a0 }», un selector de
   CLASE que quedó MUERTO al renombrar el contenedor a .cabecera-viva (el id
   sigue siendo «cielo», pero un id no activa un selector de clase): el aviso
   salía en ámbar de --sev-alta, ilegible sobre un cielo de mediodía. Fuera del
   cielo el contraste ya no depende de la hora — fondo de superficie y tinta de
   página, con el filo ámbar como señal, que es la misma gramática de
   .rk-conservado y .ssr-conservado. El texto dice lo que pasa: nunca es solo
   color. */
.hero .aviso-red {
  margin: 12px 0 0;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--borde-cielo);
  border-left: 3px solid var(--ambar);
  border-radius: 0 var(--radio-s) var(--radio-s) 0;
  background: var(--superficie);
  box-shadow: var(--sombra);
  color: var(--tinta-2);
}
/* Sin esto el [hidden] NO esconde nada: .aviso-red{display:flex} es regla de
   autor y gana al [hidden]{display:none} del navegador (mismo caso que
   .barra-progreso), así que el aviso vacío ocupaba sitio siempre. */
.aviso-red[hidden] { display: none; }
.btn-reintentar {
  border: 1px solid currentColor; border-radius: var(--radio-pastilla);
  padding: 2px 12px; font-family: var(--f-mono); font-size: var(--t-xs);
  color: inherit; background: transparent;
}

/* ---------- responsive ---------- */
/* Aquí ya NO quedan reglas de .banda-datos / .bd-celda / .tarjetas-extra /
   .escena-extremo: eran del hero anterior y sus clases no existen en ningún
   HTML ni JS de esta versión (comprobado). Ojo, «banda-datos» y
   «tarjetas-extra» sí siguen vivos en index.html, pero como ID, no como clase:
   por eso estas reglas no pintaban nada. Las bandas de instrumentos tienen sus
   propias media queries junto a .ins-banda. */
@media (max-width: 980px) {
  .pie-int { grid-template-columns: 1fr; } /* .fiabilidad-grid ya es de 1 columna */
  .nav-secciones { display: none; }
  .btn-menu { display: grid; } /* la hamburguesa sustituye a la nav oculta */
}
@media (max-width: 560px) {
  .rk-fila { grid-template-columns: 22px minmax(90px, 1.4fr) minmax(50px, 1fr) 88px; gap: var(--e-2); }
}

/* Buscador: cuando el municipio escrito no está en la lista verificada, se
   ofrece la ciudad más cercana en vez de un «aún no estamos ahí» y punto. */
.sin-cobertura {
  color: var(--tinta-suave); font-size: var(--t-sm); line-height: 1.5;
  border-bottom: 0; padding-bottom: 0;
}

/* AVISO DE DESNIVEL (19-ago-2026). Acompaña al municipio vecino que se ofrece
   cuando el buscado no tiene lectura propia. No es decorativo: hay vecinos a
   17 km y 1.100 m de desnivel (Murtas y Adra), que son unos 7 °C y, en
   invierno, la diferencia entre lluvia y nieve. Ámbar y legible, no gris de
   nota al pie: quien lo lee tiene que enterarse de que ese dato no es el suyo. */
.aviso-desnivel {
  display: block; margin-top: .2rem;
  font-size: var(--t-xs); line-height: 1.45;
  color: light-dark(#8a5a00, #f0c060);
}
.leaflet-layer.capa-base-oscura { filter: invert(1) hue-rotate(180deg) brightness(0.9) contrast(0.9); }
