/* ==========================================================================
   TIPOGRAFÍAS
   Self-hosteadas, subset latin (cubre todos los acentos del español, ¿ y ¡).
   Se bajaban de Google: eso era una hoja de estilos de terceros bloqueando el
   render, dos dominios más en la CSP, y tipografías que no cargaban del todo
   sin conexión.
   Sólo las seis caras que el CSS realmente usa. Antes se pedían ocho: sobraba
   Barlow 500 y faltaba Inter 700, así que TODA negrita del cuerpo era un bold
   sintético —el navegador engordando la 400— justo en las frases que la app
   marca como importantes.
   ========================================================================== */
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/vendor/fonts/barlow-600.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/vendor/fonts/barlow-700.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/fonts/inter-400.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/vendor/fonts/inter-700.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/vendor/fonts/jetbrains-400.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/vendor/fonts/jetbrains-700.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   TEMAS
   El claro no es preferencia estética: esta app se usa parada en la vereda,
   de día, mirando el agua, y un tema oscuro a pleno sol se lee mucho peor.
   La paleta clara es propia, no el oscuro invertido: los ocho colores del
   oscuro fallan AA sobre blanco (el ámbar de alerta da 2,16). Los de acá
   están medidos; el más bajo da 5,19 sobre el fondo.
   Los fondos con alfa también son tokens: si no, quedarían calibrados para
   un solo tema y en el otro se verían mal.
   ========================================================================== */
:root {
  --fondo: #0b1418;
  --panel: #101e24;
  --panel-2: #16292f;
  --linea: #223a42;
  --texto: #e6edef;
  --tenue: #7e959d;
  --agua: #2e9bc4;
  --agua-claro: #5fc8e8;
  --tierra: #c9a227;
  --alerta: #e8a33d;
  --peligro: #d94f3d;
  --ok: #4fa88b;

  --btn-texto: #03181f;
  --ok-fondo: rgba(79, 168, 139, 0.11);
  --ok-borde: rgba(79, 168, 139, 0.45);
  --ok-suave: rgba(79, 168, 139, 0.09);
  --alerta-fondo: rgba(232, 163, 61, 0.11);
  --alerta-borde: rgba(232, 163, 61, 0.45);
  --alerta-suave: rgba(232, 163, 61, 0.08);
  --alerta-barra: rgba(232, 163, 61, 0.14);
  --peligro-fondo: rgba(217, 79, 61, 0.13);
  --peligro-borde: rgba(217, 79, 61, 0.5);
  --peligro-suave: rgba(217, 79, 61, 0.09);
  --hueco: rgba(126, 149, 157, 0.14);
  --nav-fondo: rgba(11, 20, 24, 0.96);
  --attrib-fondo: rgba(16, 41, 47, 0.82);
  --sombra: rgba(0, 0, 0, 0.5);
  /* En oscuro la profundidad la da la diferencia de luminosidad entre
     superficies; una sombra negra sobre fondo casi negro no se ve. En
     claro pasa lo contrario: sin sombra las tarjetas flotan sin apoyo. */
  --elevacion: none;
  --agua-alta: rgba(95, 200, 232, 0.55);
  --agua-baja: rgba(46, 155, 196, 0.22);
  /* El basemap del IGN es claro de origen. En tema oscuro lo invertimos, con
     saturate() bajo para que el beige urbano no quede rojizo: en una app que
     usa rojo para peligro, un mapa rojizo confunde. En tema claro va tal
     cual lo publica el organismo. */
  --filtro-mapa: invert(1) hue-rotate(180deg) saturate(0.5) brightness(0.95)
    contrast(0.9);
  /* Los íconos de MapLibre son SVG oscuros embebidos: en tema oscuro se
     invierten, en claro van como vienen. */
  --filtro-iconos-mapa: invert(1) brightness(0.92);

  /* ---- escalas ----
     Antes había 20 tamaños de texto, 23 espaciados y 8 radios: valores
     acumulados uno por uno, no un sistema. Estas escalas son la razón por la
     que las cosas se ven alineadas sin que uno sepa por qué. */
  --t-xxl: 30px; /* el número grande, la marca */
  --t-xl: 24px; /* títulos de veredicto */
  --t-l: 20px; /* h2 */
  --t-m: 17px; /* h3, nombres, teléfonos */
  --t-base: 15px; /* cuerpo */
  --t-s: 13px; /* texto chico */
  --t-xs: 12px; /* etiquetas monoespaciadas — piso de legibilidad */
  --t-tick: 10px; /* sólo los números de la regla, que es decorativa */

  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;
  --e-6: 24px;
  --e-7: 32px;

  --r-s: 6px;
  --r-m: 10px;
  --r-l: 14px;
  --r-full: 999px;

  /* Una sola curva para todo lo que responde al toque. */
  --mov: 160ms cubic-bezier(0.2, 0, 0.2, 1);

  --display: "Barlow Condensed", system-ui, sans-serif;
  --data: "JetBrains Mono", ui-monospace, monospace;
  --body: "Inter", system-ui, -apple-system, sans-serif;
}

/* Los valores del tema claro viven UNA sola vez acá. Los dos selectores de
   abajo sólo los remapean: si estuvieran duplicados, tarde o temprano uno se
   actualiza y el otro no. */
:root {
  --c-fondo: #f2f6f7;
  --c-panel: #ffffff;
  --c-panel-2: #e6edf0;
  --c-linea: #ccd9de;
  --c-texto: #0d1b21;
  --c-tenue: #4a5f67;
  --c-agua: #17607f;
  --c-agua-claro: #0f6f93;
  --c-tierra: #7a5f0d;
  --c-alerta: #8a5200;
  --c-peligro: #a5271a;
  --c-ok: #1f6b53;
  --c-btn-texto: #ffffff;
  --c-ok-fondo: rgba(31, 107, 83, 0.1);
  --c-ok-borde: rgba(31, 107, 83, 0.4);
  --c-ok-suave: rgba(31, 107, 83, 0.08);
  --c-alerta-fondo: rgba(138, 82, 0, 0.1);
  --c-alerta-borde: rgba(138, 82, 0, 0.4);
  --c-alerta-suave: rgba(138, 82, 0, 0.07);
  --c-alerta-barra: rgba(138, 82, 0, 0.12);
  --c-peligro-fondo: rgba(165, 39, 26, 0.09);
  --c-peligro-borde: rgba(165, 39, 26, 0.4);
  --c-peligro-suave: rgba(165, 39, 26, 0.07);
  --c-hueco: rgba(74, 95, 103, 0.12);
  --c-nav-fondo: rgba(255, 255, 255, 0.97);
  --c-attrib-fondo: rgba(255, 255, 255, 0.85);
  --c-sombra: rgba(13, 27, 33, 0.22);
  --c-elevacion:
    0 1px 2px rgba(13, 27, 33, 0.05), 0 2px 8px rgba(13, 27, 33, 0.04);
  --c-agua-alta: rgba(23, 96, 127, 0.42);
  --c-agua-baja: rgba(23, 96, 127, 0.14);
  --c-filtro-mapa: saturate(0.92);
  --c-filtro-iconos-mapa: none;
}

/* Por defecto seguimos al sistema, y desde CSS: con `script-src 'self'` no
   podemos usar un script inline para aplicarlo antes del primer pintado, así
   que si esto dependiera de JS habría un destello oscuro en cada carga. */
@media (prefers-color-scheme: light) {
  html:not([data-tema="oscuro"]) {
    --fondo: var(--c-fondo);
    --panel: var(--c-panel);
    --panel-2: var(--c-panel-2);
    --linea: var(--c-linea);
    --texto: var(--c-texto);
    --tenue: var(--c-tenue);
    --agua: var(--c-agua);
    --agua-claro: var(--c-agua-claro);
    --tierra: var(--c-tierra);
    --alerta: var(--c-alerta);
    --peligro: var(--c-peligro);
    --ok: var(--c-ok);
    --btn-texto: var(--c-btn-texto);
    --ok-fondo: var(--c-ok-fondo);
    --ok-borde: var(--c-ok-borde);
    --ok-suave: var(--c-ok-suave);
    --alerta-fondo: var(--c-alerta-fondo);
    --alerta-borde: var(--c-alerta-borde);
    --alerta-suave: var(--c-alerta-suave);
    --alerta-barra: var(--c-alerta-barra);
    --peligro-fondo: var(--c-peligro-fondo);
    --peligro-borde: var(--c-peligro-borde);
    --peligro-suave: var(--c-peligro-suave);
    --hueco: var(--c-hueco);
    --nav-fondo: var(--c-nav-fondo);
    --attrib-fondo: var(--c-attrib-fondo);
    --sombra: var(--c-sombra);
    --elevacion: var(--c-elevacion);
    --agua-alta: var(--c-agua-alta);
    --agua-baja: var(--c-agua-baja);
    --filtro-mapa: var(--c-filtro-mapa);
    --filtro-iconos-mapa: var(--c-filtro-iconos-mapa);
  }
}

/* La elección manual gana siempre: alguien puede querer el claro justo para
   salir a la calle, tenga el teléfono como lo tenga. */
html[data-tema="claro"] {
  --fondo: var(--c-fondo);
  --panel: var(--c-panel);
  --panel-2: var(--c-panel-2);
  --linea: var(--c-linea);
  --texto: var(--c-texto);
  --tenue: var(--c-tenue);
  --agua: var(--c-agua);
  --agua-claro: var(--c-agua-claro);
  --tierra: var(--c-tierra);
  --alerta: var(--c-alerta);
  --peligro: var(--c-peligro);
  --ok: var(--c-ok);
  --btn-texto: var(--c-btn-texto);
  --ok-fondo: var(--c-ok-fondo);
  --ok-borde: var(--c-ok-borde);
  --ok-suave: var(--c-ok-suave);
  --alerta-fondo: var(--c-alerta-fondo);
  --alerta-borde: var(--c-alerta-borde);
  --alerta-suave: var(--c-alerta-suave);
  --alerta-barra: var(--c-alerta-barra);
  --peligro-fondo: var(--c-peligro-fondo);
  --peligro-borde: var(--c-peligro-borde);
  --peligro-suave: var(--c-peligro-suave);
  --hueco: var(--c-hueco);
  --nav-fondo: var(--c-nav-fondo);
  --attrib-fondo: var(--c-attrib-fondo);
  --sombra: var(--c-sombra);
  --elevacion: var(--c-elevacion);
  --agua-alta: var(--c-agua-alta);
  --agua-baja: var(--c-agua-baja);
  --filtro-mapa: var(--c-filtro-mapa);
  --filtro-iconos-mapa: var(--c-filtro-iconos-mapa);
}
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html,
body {
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--body);
  -webkit-text-size-adjust: 100%;
}
body {
  padding-bottom: calc(72px + env(safe-area-inset-bottom));
}
/* La barra de instalar es fixed: sin esto flotaba encima del último bloque
   de cada pestaña, que además suele ser un aviso importante. */
body.con-instalar {
  padding-bottom: calc(72px + 58px + env(safe-area-inset-bottom));
  line-height: 1.5;
  font-size: var(--t-base);
}
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}
:focus-visible {
  outline: 2px solid var(--agua-claro);
  outline-offset: 2px;
  border-radius: var(--r-s);
}
@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------- cabecera ---------- */
.top {
  /* viewport-fit=cover hace que el contenido vaya por debajo de la muesca y
     la barra de estado. El safe-area estaba contemplado abajo (la nav) pero
     no arriba, así que el logo quedaba pisado. */
  padding: calc(18px + env(safe-area-inset-top)) 18px 12px;
  /* El botón de tema va en el flujo, no absoluto: estaba posicionado y el
     subtítulo le pasaba por debajo. Con flex no se solapan nunca, cualquiera
     sea el largo del texto. */
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e-4);
  border-bottom: 1px solid var(--linea);
  position: relative;
  overflow: hidden;
}
.top::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--agua), transparent);
  opacity: 0.5;
}
/* El botón de tema va en el encabezado, arriba a la derecha, donde no
   compite con nada. */
.tema {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--r-m);
  border: 1px solid var(--linea);
  background: var(--panel);
  color: var(--tenue);
  font-size: var(--t-m);
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.tema:hover {
  color: var(--texto);
}

.marca {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-xxl);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 0.95;
}
.marca span {
  color: var(--agua-claro);
}
.sub {
  font-family: var(--data);
  font-size: var(--t-xs);
  color: var(--tenue);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  /* Es un <p> por semántica; el margen inferior de los párrafos no va acá. */
  margin: var(--e-1) 0 0;
}

/* ---------- estructura ---------- */
.vista {
  display: none;
  padding: var(--e-5);
  max-width: 640px;
  margin: 0 auto;
}
.vista.on {
  display: block;
}
h2 {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-l);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin: var(--e-6) 0 var(--e-3);
}
h2:first-child {
  margin-top: var(--e-1);
}
.cuenta {
  font-family: var(--data);
  font-size: var(--t-s);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--tenue);
  text-transform: none;
}
.cuenta.completa {
  color: var(--ok);
}
h3 {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-m);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tenue);
  margin: var(--e-5) 0 var(--e-2);
}
p {
  margin: 0 0 var(--e-3);
}
.chico {
  font-size: var(--t-s);
  color: var(--tenue);
}
.tarjeta {
  background: var(--panel);
  border: 1px solid var(--linea);
  box-shadow: var(--elevacion);
  border-radius: var(--r-l);
  padding: var(--e-4);
  margin-bottom: var(--e-4);
}
.eti {
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tenue);
  display: block;
  margin-bottom: var(--e-2);
}
.dato {
  font-family: var(--data);
  font-weight: 700;
  font-size: var(--t-xxl);
  line-height: 1.1;
}
.unidad {
  font-size: var(--t-base);
  color: var(--tenue);
  font-weight: 400;
}

/* ---------- regla / hidrómetro (elemento firma) ---------- */
.regla-caja {
  display: flex;
  gap: var(--e-4);
  align-items: stretch;
  margin: var(--e-2) 0 var(--e-1);
}
.regla {
  position: relative;
  /* 74px eran pocos: entre marcas y números ya se iban 31, y las etiquetas de
     umbral se montaban encima de la numeración. */
  width: 96px;
  flex: none;
  background: var(--panel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-m);
  overflow: hidden;
  min-height: 320px;
}
.agua {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(180deg, var(--agua-alta), var(--agua-baja));
  transition: height 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
/* La superficie del agua es la línea que más se mira: va nítida y de un solo
   grosor, sin el resplandor de antes (que en tema claro quedaba raro). */
.agua::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--agua-claro);
}
.marca-linea {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dashed currentColor;
  transition: bottom 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
.marca-linea b {
  position: absolute;
  right: var(--e-1);
  top: -15px;
  font-family: var(--data);
  font-size: var(--t-tick);
  font-weight: 700;
  letter-spacing: 0.02em;
  /* El chip usaba --fondo, pero se apoya sobre la regla, que es --panel-2. */
  background: var(--panel-2);
  border: 1px solid currentColor;
  padding: 1px var(--e-1);
  border-radius: var(--r-s);
  line-height: 1.35;
}
/* 5,30 y 5,70 están siempre a 40 cm: sobre esta escala son 15px, y las
   etiquetas miden 14. Se montaban una sobre otra. Bajamos la de alerta al
   otro lado de su línea y el problema desaparece para siempre. */
.marca-linea.debajo b {
  top: 3px;
}
/* "vos" va con chip lleno: es tuyo, no un umbral oficial. */
.marca-linea.propia b {
  background: var(--tierra);
  color: var(--fondo) !important;
  border-color: var(--tierra);
}
.tic {
  position: absolute;
  left: 0;
  width: 8px;
  height: 1px;
  background: var(--linea);
}
.tic.mayor {
  width: 15px;
  background: var(--tenue);
}
.tic-num {
  position: absolute;
  left: var(--e-5);
  font-family: var(--data);
  font-size: var(--t-tick);
  font-weight: 700;
  color: var(--tenue);
  transform: translateY(-50%);
}
.leyenda {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--e-3);
}
.leyenda-item {
  border-left: 3px solid;
  padding-left: var(--e-3);
}
.leyenda-item .v {
  font-family: var(--data);
  font-weight: 700;
  font-size: var(--t-m);
  line-height: 1.15;
}
.leyenda-item .k {
  font-size: var(--t-s);
  color: var(--tenue);
  line-height: 1.35;
  margin-top: 2px;
}

/* ---------- veredicto ---------- */
.veredicto {
  border-radius: var(--r-l);
  box-shadow: var(--elevacion);
  padding: var(--e-4);
  margin-bottom: var(--e-4);
  border: 1px solid;
}
.veredicto .titu {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-xl);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1.05;
  margin-bottom: var(--e-2);
}
.v-ok {
  background: var(--ok-fondo);
  border-color: var(--ok-borde);
}
.v-ok .titu {
  color: var(--ok);
}
.v-alerta {
  background: var(--alerta-fondo);
  border-color: var(--alerta-borde);
}
.v-alerta .titu {
  color: var(--alerta);
}
.v-peligro {
  background: var(--peligro-fondo);
  border-color: var(--peligro-borde);
}
.v-peligro .titu {
  color: var(--peligro);
}
/* Mientras busca el dato, la tarjeta late suave. Es la diferencia entre
   "esperá" y "falló". */
.veredicto.cargando {
  animation: latido 1.6s ease-in-out infinite;
}
@keyframes latido {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.55;
  }
}
.v-neutro {
  background: var(--panel);
  border-color: var(--linea);
}

/* ---------- controles ---------- */
label.campo {
  display: block;
  margin-bottom: var(--e-3);
}
label.campo > span {
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--tenue);
  display: block;
  margin-bottom: var(--e-1);
}
input[type="text"],
input[type="number"],
select,
textarea {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-m);
  padding: var(--e-3) var(--e-3);
  font-family: var(--data);
}
textarea {
  font-family: var(--body);
  resize: vertical;
  min-height: 64px;
}
input[type="range"] {
  width: 100%;
  accent-color: var(--agua);
}
.btn {
  background: var(--agua);
  color: var(--btn-texto);
  border: none;
  border-radius: var(--r-m);
  /* La altura mínima se declara, no se deduce del padding: así el objetivo
     táctil no depende de que nadie toque la escala de espaciados. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 13px de alto deja el botón en 45px: el mínimo recomendado para un
     objetivo táctil son 44. Con 12px quedaba en 43. */
  padding: var(--e-3) var(--e-4);
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--t-base);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  width: 100%;
  margin-bottom: var(--e-2);
}
.btn:disabled {
  opacity: 0.55;
  cursor: default;
}
.btn:active {
  transform: translateY(1px);
}
.btn.sec {
  background: transparent;
  color: var(--texto);
  border: 1px solid var(--linea);
}
.btn.mini {
  width: auto;
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-s);
}
.fila {
  display: flex;
  gap: var(--e-2);
}
.fila > * {
  flex: 1;
  margin-bottom: var(--e-2);
}

/* ---------- pronóstico ---------- */
.dias {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: var(--e-1);
  margin-top: var(--e-1);
}
.dia {
  background: var(--panel-2);
  border-radius: var(--r-s);
  padding: var(--e-2) 3px;
  text-align: center;
  border: 1px solid transparent;
}
.dia.fuerte {
  border-color: var(--alerta);
}
.dia .d {
  font-family: var(--data);
  font-size: var(--t-xs);
  color: var(--tenue);
  text-transform: uppercase;
}
.dia .mm {
  font-family: var(--data);
  font-weight: 700;
  font-size: var(--t-base);
  margin-top: 3px;
}
.dia .mm.hay {
  color: var(--agua-claro);
}
.dia .mm.fuerte {
  color: var(--alerta);
}
/* Un número suelto no dice si 12 mm es mucho o poco. La barra da la escala y
   la línea punteada marca el umbral de 40 mm. */
.dia .barra {
  position: relative;
  height: 34px;
  margin-top: var(--e-1);
  background: var(--hueco);
  border-radius: var(--r-s);
  overflow: hidden;
}
.dia .barra i {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  background: var(--agua);
}
.dia.fuerte .barra i {
  background: var(--alerta);
}
.dia .barra u {
  position: absolute;
  left: 0;
  right: 0;
  height: 0;
  border-top: 1px dashed var(--alerta);
  opacity: 0.55;
}

/* ---------- listas ---------- */
.chk {
  display: flex;
  gap: var(--e-3);
  align-items: flex-start;
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--linea);
  cursor: pointer;
}
.chk:last-child {
  border-bottom: none;
}
.chk input {
  margin-top: 2px;
  width: 19px;
  height: 19px;
  flex: none;
  accent-color: var(--ok);
}
.chk span {
  flex: 1;
  font-size: var(--t-base);
}
.chk input:checked + span {
  color: var(--tenue);
  text-decoration: line-through;
}
/* Las listas vienen como <ul> en el HTML para que sean indexables. */
.lista-plana {
  list-style: none;
  margin: 0;
  padding: 0;
}
.punto {
  display: block;
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--linea);
  color: inherit;
  text-decoration: none;
}
.punto:last-child {
  border-bottom: none;
}
.punto .n {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-m);
  letter-spacing: 0.02em;
}
.punto .d {
  font-size: var(--t-s);
  color: var(--tenue);
  margin-top: 1px;
}
.punto .ir {
  font-family: var(--data);
  font-size: var(--t-xs);
  color: var(--agua-claro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-top: 3px;
  display: inline-block;
}

/* ---------- avisos ---------- */
.aviso {
  border-left: 3px solid var(--alerta);
  background: var(--alerta-suave);
  padding: var(--e-3) var(--e-3);
  border-radius: 0 var(--r-m) var(--r-m) 0;
  font-size: var(--t-s);
  margin-bottom: var(--e-3);
}
.aviso.grave {
  border-color: var(--peligro);
  background: var(--peligro-suave);
}
/* Una lista de acciones se lee; el mismo contenido en prosa, no. */
.pasos {
  margin: var(--e-1) 0 0;
  padding-left: var(--e-5);
  font-size: var(--t-s);
  color: var(--tenue);
}
.pasos li {
  margin-bottom: var(--e-2);
  line-height: 1.45;
}
.pasos.grave li b {
  color: var(--peligro);
  font-family: var(--data);
}
.pasos a {
  color: var(--agua-claro);
  font-weight: 700;
}
.aviso details summary {
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tenue);
}
.aviso b {
  color: var(--alerta);
}
.aviso.grave b {
  color: var(--peligro);
}
.tel {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--linea);
  color: inherit;
  text-decoration: none;
}
.tel:last-child {
  border-bottom: none;
}
.tel .q {
  font-size: var(--t-base);
}
.tel .n {
  font-family: var(--data);
  font-weight: 700;
  font-size: var(--t-m);
  color: var(--agua-claro);
}

/* ---------- mapa ---------- */
/* El basemap del IGN es claro y la app es oscura. invert + hue-rotate(180)
   invierte la luminosidad conservando los tonos: el agua sigue siendo azul y
   los espacios verdes verdes, pero sobre fondo oscuro. Va sólo sobre el
   canvas de los tiles; los pines y los controles son DOM aparte y no se
   tocan. */
#mapa .maplibregl-canvas {
  /* saturate() baja el rojizo que deja la inversión sobre el beige urbano
     del IGN: en una app que usa rojo para peligro, un mapa rojizo
     confunde. El agua queda igual de reconocible. */
  filter: var(--filtro-mapa);
}
@media (prefers-contrast: more) {
  #mapa .maplibregl-canvas {
    filter: none;
  }
}
#mapa {
  width: 100%;
  height: 340px;
  border-radius: var(--r-l);
  border: 1px solid var(--linea);
  margin-bottom: var(--e-4);
  background: var(--panel-2);
}
/* MapLibre trae sus controles en blanco. Sobre un mapa que oscurecimos a
   propósito quedaban como dos parches brillantes. */
#mapa .maplibregl-ctrl-group {
  background: var(--panel);
  border: 1px solid var(--linea);
  box-shadow: none;
}
#mapa .maplibregl-ctrl-group button + button {
  border-top-color: var(--linea);
}
#mapa .maplibregl-ctrl-group button:hover {
  background: var(--panel-2);
}
/* Los íconos son SVG oscuros embebidos: no se recolorean, se invierten. */
#mapa .maplibregl-ctrl-icon {
  filter: var(--filtro-iconos-mapa);
}
#mapa .maplibregl-ctrl-attrib {
  background: var(--attrib-fondo);
  color: var(--tenue);
  font-size: var(--t-xs);
}
#mapa .maplibregl-ctrl-attrib a {
  color: var(--agua-claro);
}
#mapa .maplibregl-ctrl-attrib-button {
  filter: var(--filtro-iconos-mapa);
}

.maplibregl-popup-content {
  background: var(--panel);
  color: var(--texto);
  border: 1px solid var(--linea);
  border-radius: var(--r-m);
  padding: var(--e-3) var(--e-3);
  font-family: var(--body);
}
.maplibregl-popup-content strong {
  font-family: var(--display);
  font-size: var(--t-m);
  letter-spacing: 0.02em;
}
.maplibregl-popup-tip {
  border-top-color: var(--panel) !important;
  border-bottom-color: var(--panel) !important;
}
.maplibregl-popup-close-button {
  color: var(--tenue);
  font-size: var(--t-m);
}
.pin {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--agua);
  border: 2px solid var(--fondo);
  box-shadow: 0 0 0 1px var(--agua);
  cursor: pointer;
}
.pin.cerca {
  background: var(--ok);
  width: 21px;
  height: 21px;
  box-shadow:
    0 0 0 1px var(--ok),
    0 0 14px var(--ok);
}
.pin.yo {
  background: var(--tierra);
  box-shadow: 0 0 0 1px var(--tierra);
}
.punto.destacado {
  background: var(--ok-suave);
  border-radius: var(--r-m);
  padding-left: var(--e-3);
  padding-right: var(--e-3);
  border-bottom-color: transparent;
}

/* ---------- tendencia ---------- */
.tend {
  display: flex;
  align-items: center;
  gap: var(--e-3);
}
.tend .flecha {
  font-size: var(--t-xl);
  line-height: 1;
  font-family: var(--data);
  font-weight: 700;
}
.sparkline {
  width: 100%;
  height: 46px;
  margin-top: var(--e-2);
  display: block;
}

/* ---------- navegación ---------- */
nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  background: var(--nav-fondo);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--linea);
  padding-bottom: env(safe-area-inset-bottom);
  z-index: 50;
}
nav button {
  flex: 1;
  background: none;
  border: none;
  padding: var(--e-3) 2px var(--e-3);
  cursor: pointer;
  color: var(--tenue);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-1);
}
nav button.on {
  color: var(--agua-claro);
}
nav button svg {
  width: 21px;
  height: 21px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
nav button span {
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
#sin-conexion {
  background: var(--alerta-barra);
  border-bottom: 1px solid var(--alerta-borde);
  color: var(--alerta);
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.04em;
  padding: var(--e-2) var(--e-5);
  text-align: center;
}
#sin-conexion[hidden] {
  display: none;
}

/* Barra de instalar: se queda hasta que la persona la cierre. Antes se
   borraba sola a los 20 s y no volvía en toda la sesión. */
.instalar {
  position: fixed;
  left: 14px;
  right: 14px;
  bottom: calc(78px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  gap: var(--e-2);
  align-items: stretch;
  box-shadow: 0 6px 24px var(--sombra);
  border-radius: var(--r-m);
}
.instalar .btn {
  margin: 0;
  flex: 1;
}
.instalar .cerrar {
  flex: none;
  width: 46px;
  border: none;
  border-radius: var(--r-m);
  background: var(--panel-2);
  color: var(--texto);
  font-size: var(--t-l);
  cursor: pointer;
}

/* ---------- impresión ---------- */
#plan-impreso {
  display: none;
}
@media print {
  /* Lo único que tiene sentido en papel es el plan, y en texto plano: los
     campos de formulario se imprimen mal y los textarea se recortan. */
  body > *:not(#plan-impreso) {
    display: none !important;
  }
  html,
  body {
    background: #fff;
    color: #000;
    padding: 0;
  }
  #plan-impreso {
    display: block;
    white-space: pre-wrap;
    font-family: ui-monospace, monospace;
    font-size: 11.5pt;
    line-height: 1.45;
    color: #000;
    padding: 0;
  }
}

/* ---------- sugerencias ---------- */
.sugerir {
  max-width: 640px;
  margin: var(--e-6) auto 0;
  padding: 0 var(--e-5);
}
.sugerir > summary {
  cursor: pointer;
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-m);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tenue);
  padding: var(--e-3) 0;
  border-top: 1px solid var(--linea);
}
.sugerir > summary:hover {
  color: var(--texto);
}
.sugerir[open] > summary {
  color: var(--texto);
}

.pie {
  padding: var(--e-6) var(--e-5) var(--e-7);
  text-align: center;
  font-size: var(--t-s);
  color: var(--tenue);
  border-top: 1px solid var(--linea);
  margin-top: var(--e-6);
  line-height: 1.6;
}
/* Una herramienta que dice "no tiene vínculo con organismos oficiales"
   gana en que se vea quién responde por ella. */
.firma {
  margin-top: var(--e-4);
  padding-top: var(--e-3);
  border-top: 1px solid var(--linea);
  font-size: var(--t-s);
}
.firma b {
  color: var(--texto);
  font-weight: 600;
}
.firma .redes {
  display: inline-flex;
  gap: var(--e-2);
  margin-left: var(--e-2);
}
.firma .redes a {
  font-family: var(--data);
  font-size: var(--t-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  padding: var(--e-1) var(--e-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-full);
  color: var(--agua-claro);
}
.firma .redes a:hover {
  border-color: var(--agua-claro);
}

.pie a {
  color: var(--agua-claro);
}

/* ==========================================================================
   ESTADOS E INTERACCIÓN
   Había 4 hover y 1 active en toda la app: nada respondía al toque. La
   diferencia entre "funciona" y "está hecho" suele ser esto.
   Todo va bajo (hover: hover) para que en el teléfono no queden estados
   pegados después de tocar.
   ========================================================================== */
.btn,
.tema,
.punto,
.tel,
.chk,
nav button,
summary,
input,
select,
textarea {
  transition:
    background-color var(--mov),
    border-color var(--mov),
    color var(--mov),
    transform var(--mov);
}

.btn:active,
.tema:active {
  transform: translateY(1px);
}

/* Las filas de lista son links: tienen que sentirse como tales. */
.punto,
.tel {
  margin: 0 calc(var(--e-2) * -1);
  padding-left: var(--e-2);
  padding-right: var(--e-2);
  border-radius: var(--r-m);
}
.punto .ir {
  transition: transform var(--mov);
}

@media (hover: hover) {
  .btn:hover:not(:disabled) {
    filter: brightness(1.08);
  }
  .btn.sec:hover:not(:disabled) {
    filter: none;
    border-color: var(--agua);
    color: var(--agua-claro);
  }
  .punto:hover,
  .tel:hover {
    background: var(--panel-2);
  }
  .punto:hover .ir {
    transform: translateX(3px);
  }
  .chk:hover span {
    color: var(--texto);
  }
  nav button:hover {
    color: var(--texto);
  }
  summary:hover {
    color: var(--texto);
  }
}

/* El foco visible tiene que verse igual en todos lados, no heredar el que
   trae cada control. */
:focus-visible {
  outline: 2px solid var(--agua-claro);
  outline-offset: 2px;
}
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  border-color: var(--agua);
  outline-offset: 0;
}

/* ---- el número grande ----
   Es el centro de la app: una app de datos se juzga por cómo trata sus
   números. A 30px una monoespaciada queda suelta; el tracking negativo la
   compacta y la hace leer como un instrumento. */
.dato {
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}
.dato .unidad {
  letter-spacing: 0;
  margin-left: 2px;
}
.leyenda-item .v,
.tel .n {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

/* ==========================================================================
   PANTALLAS ANCHAS
   La app es mobile-first y está bien que lo sea: se usa en el teléfono. Pero
   en 1440px quedaba una columna de 640px con 400px vacíos de cada lado, y la
   barra de navegación —un idioma de teléfono— estirada de punta a punta con
   los ítems a media pantalla uno de otro.
   ========================================================================== */
@media (min-width: 900px) {
  /* Reordenamos con flex para subir la nav sin tocar el orden del HTML: en el
     marcado sigue después del contenido, que es lo correcto. */
  body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding-bottom: 0;
  }
  body.con-instalar {
    padding-bottom: 0;
  }
  .top {
    order: 0;
  }
  #sin-conexion {
    order: 1;
  }
  nav {
    order: 2;
  }
  .vista {
    order: 3;
  }
  .sugerir {
    order: 4;
  }
  .pie {
    order: 5;
    margin-top: auto;
  }

  /* La nav deja de ser una barra fija abajo y pasa a acompañar al contenido. */
  nav {
    position: sticky;
    top: 0;
    z-index: 50;
    justify-content: center;
    gap: var(--e-2);
    padding: 0 var(--e-5);
    border-top: none;
    border-bottom: 1px solid var(--linea);
  }
  nav button {
    flex: none;
    flex-direction: row;
    gap: var(--e-2);
    padding: var(--e-4) var(--e-5);
    border-bottom: 2px solid transparent;
  }
  nav button.on {
    border-bottom-color: var(--agua-claro);
  }
  nav button span {
    font-size: var(--t-s);
  }

  /* El encabezado se alinea con la columna de contenido en vez de quedar
     pegado al borde de la ventana. */
  .top {
    padding-left: max(18px, calc((100vw - 1040px) / 2));
    padding-right: max(18px, calc((100vw - 1040px) / 2));
  }
  .vista,
  .sugerir {
    max-width: 1040px;
  }

  /* Mapa y lista lado a lado: el mapa queda fijo mientras se recorre la
     lista, que es como se usa un buscador de lugares en una pantalla grande. */
  .col-mapa {
    position: sticky;
    top: 76px;
  }
  #v-donde .col-mapa,
  #v-donde .col-lista {
    grid-column: auto;
  }
  /* .on: si no, este display gana sobre el `display:none` de .vista y se
     muestran todas las secciones a la vez. */
  #v-donde.on {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--e-5);
    align-items: start;
  }
  #v-donde > h2,
  #v-donde > p,
  #v-donde > .tarjeta {
    grid-column: 1 / -1;
  }
  #mapa {
    height: 460px;
  }

  /* En "Río" el hidrómetro y el pronóstico caben uno al lado del otro. */
  #v-rio.on {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--e-5);
    align-items: start;
  }
  #v-rio > .veredicto,
  #v-rio > #cta-cota,
  #v-rio > details,
  #v-rio > .aviso {
    grid-column: 1 / -1;
  }

  /* El plan es un formulario largo: dos columnas de tarjetas. */
  #v-plan.on {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--e-5);
    align-items: start;
  }
  #v-plan > h2,
  #v-plan > p,
  #v-plan > .btn {
    grid-column: 1 / -1;
  }
}

/* El foco programático de las secciones es para que un lector de pantalla
   anuncie el cambio, no para dibujar un recuadro alrededor de media página.
   Sólo se puede enfocar por script (tabindex="-1"), así que sacar el contorno
   no le quita nada a quien navega con teclado. */
.vista:focus {
  outline: none;
}
