/* ==========================================================================
   TripFinder — la hoja de estilos entera.

   Es un panel de salidas, no un atlas. Lo que manda:

     · UNA SOLA PÁGINA. El feed, buscar y seguir viven juntos en la portada.
       Cuando de verdad usas una de las dos herramientas, la ventana se amplía
       a su página completa. Las secciones se enlazan con anclas.
     · TIPOGRAFÍA DE TRES VOCES. Switzer para todo lo que se lee, IBM Plex Mono
       para todo lo que es un DATO (precios, códigos, horas, rótulos), y Pinyon
       Script como acento manuscrito: aparece cinco veces contadas en toda la
       web y por eso significa algo.
     · EL NARANJA ES EL PRECIO. `--accent` no decora: marca lo que ha bajado.
       Si se usa para otra cosa deja de querer decir nada.
     · CONTRASTE 4.5:1 EN LOS DOS TEMAS. Lo audita `tools/contraste.py` en CI.

   Los colores viven todos aquí arriba. Ninguna regla de más abajo escribe un
   hex a mano: si hay que cambiar la paleta, se cambia en un sitio.
   ========================================================================== */

:root {
  /* ---- superficies -------------------------------------------------- */
  --paper: #0f0f0e;      /* el fondo de todo */
  --surface: #171715;    /* paneles y el feed */
  --surface2: #1e1e1b;   /* el panel de al lado, y la fila al pasar por encima */
  --field: #1a1a18;      /* dentro de un formulario */

  /* ---- tinta -------------------------------------------------------- */
  --ink: #f3f0e8;
  --muted: #9a968d;      /* texto secundario */
  --line: #2c2b28;       /* el borde de un contenedor */
  --hair: #232320;       /* la raya entre dos filas */

  /* ---- los dos colores que significan algo --------------------------- */
  --accent: #ff5a22;     /* el precio que ha bajado. RELLENOS */
  --accent-txt: #ff5a22; /* el mismo, cuando es TEXTO sobre papel */
  --deep: #4fd6b0;       /* lo que se queda apuntado y vigila solo */

  /* ---- la lámina invertida: el chollo del día y la cabecera del feed -- */
  --hero-bg: #f4f1e8;
  --hero-ink: #12110f;
  --hero-hair: #d9d4c7;
  --hero-muted: #6e6a5e;
  /* El verde de la lamina va al reves que el de la pagina: la lamina es clara
     cuando la pagina es oscura, y el mismo token no puede servir para las dos.
     `tools/contraste.py` lo audita contra `--hero-bg`, no contra `--paper`. */
  --hero-deep: #0f5f52;
  --btn-bg: #f4f1e8;
  --btn-ink: #12110f;
  --code-bg: #f4f1e8;
  --code-ink: #12110f;
  --sobre-acento: #12110f; /* lo que se lee ENCIMA del naranja */


  /* ---- forma -------------------------------------------------------- */
  --r: 10px;             /* paneles, el feed, las tarjetas */
  --r-s: 7px;            /* campos y filas dentro de un panel */
  --r-pill: 999px;       /* botones y chips */
  --r-tag: 4px;          /* el código IATA */
  --tap-min: 44px;       /* área táctil mínima, aunque se vea más pequeño */
  --pad-page: 20px;
  --ancho: 1120px;
  --sombra: 0 1px 0 rgb(0 0 0 / 0.04), 0 8px 24px -12px rgb(0 0 0 / 0.35);

  /* ---- tipografía ---------------------------------------------------- */
  --font-sans: "Switzer", "Switzer respaldo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "Switzer", "Switzer respaldo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-script: "Pinyon Script", "Snell Roundhand", cursive;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  --fs-display: clamp(30px, 5.2vw, 46px);
  --fs-title: clamp(28px, 4.6vw, 40px);
  --fs-heading: 20px;
  --fs-subhead: 18px;
  --fs-city: 17px;
  --fs-city-s: 15px;
  --fs-lede: 15px;
  --fs-body: 14px;
  --fs-body-s: 13px;
  --fs-ui: 13px;
  --fs-ui-s: 12px;
  --fs-input: 15px;
  --fs-amount: 42px;
  --fs-figure: 22px;
  --fs-cifra: 19px;
  --fs-data: 12.5px;
  --fs-data-s: 11.5px;
  --fs-meta: 11px;
  --fs-caps: 9.5px;
  --fs-caps-l: 10px;

  --ls-title: -0.045em;
  --ls-caps: 0.14em;
  --ls-code: 0.1em;
  --lh-body: 1.55;

  /* ---- movimiento ---------------------------------------------------- */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --t-micro: 0.12s;
  --t: 0.18s;
  --t-med: 0.26s;
  --t-panel: 0.34s;
  --velo: rgba(4, 4, 3, 0.72);
}

/* La carta de día. Antes el `--line` era tinta plena —el filo negro—; en el
   rediseño compacto pasa a una raya suave: con tanto filo, una pantalla densa
   parecía una hoja de cálculo. Lo que separa ahora es el blanco de las
   tarjetas sobre el papel, no el borde. */
:root[data-tema="claro"] {
  --paper: #f6f4ef;
  --surface: #ffffff;
  --surface2: #f1eee7;
  --field: #ffffff;

  --ink: #16150f;
  --muted: #64605a;        /* 4.6:1 sobre --surface2, el más oscuro de los tres */
  --line: #dcd6ca;
  --hair: #ebe7de;

  --accent: #e8410d;       /* relleno: #12110f encima da 4.7:1 */
  --accent-txt: #c5370b;   /* texto sobre papel: 4.5:1 */
  --deep: #0f5f52;

  --hero-bg: #16150f;
  --hero-ink: #f3f0e9;
  --hero-hair: #2e2c24;
  --hero-muted: #a9a497;
  --hero-deep: #4fd6b0;
  --btn-bg: #16150f;
  --btn-ink: #f3f0e9;
  --code-bg: #16150f;
  --code-ink: #fffdf8;
  --sobre-acento: #12110f;
  --velo: rgba(22, 21, 15, 0.5);
  --sombra: 0 1px 0 rgb(22 21 15 / 0.03), 0 8px 24px -14px rgb(22 21 15 / 0.18);
}

/* ==========================================================================
   EL RESPALDO DE SWITZER

   Switzer vive en un solo sitio —el CDN de Fontshare— y no está en Google
   Fonts. Si ese dominio va lento, se cae o se lo bloquean a alguien, la web
   entera pasa a la tipografía del sistema. Eso no se puede evitar sin
   auto-alojar la fuente; lo que SÍ se puede evitar es que además se mueva todo
   de sitio cuando llega.

   Estas cifras están medidas, no estimadas: se sacan de comparar
   `switzer-latin-400-normal.woff2` con Liberation Sans (métricamente
   compatible con Arial, que es el respaldo más probable):

     Switzer   ascendente 98,0%  descendente 25,0%  interlínea 9,0%  ancho medio 510/1000em
     Arial     ascendente 90,5%  descendente 21,2%  interlínea 3,3%  ancho medio 490/1000em

   Con los `override` y el `size-adjust` al 104,3%, el texto de respaldo ocupa
   la misma caja que Switzer: no hay salto de maquetación cuando la fuente
   entra, ni párrafos que cambian de altura a mitad de carga. */
@font-face {
  font-family: "Switzer respaldo";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans"), local("Roboto");
  ascent-override: 98%;
  descent-override: 25%;
  line-gap-override: 9%;
  size-adjust: 104.3%;
}

/* ==========================================================================
   BASE
   ========================================================================== */

* { box-sizing: border-box; }

/* Esto no es una manía: media hoja pone `display:flex` o `display:grid` en un
   selector de clase, y eso PISA el `display:none` que el navegador le da a
   `[hidden]`, que es un selector de atributo con la misma especificidad y va
   antes en la cascada. Sin esta línea, el panel de alojamiento, el calendario
   y el selector de destinos se quedan abiertos desde que carga la página. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  /* La cabecera es pegajosa: sin esto, un ancla deja el título debajo. */
  scroll-padding-top: 76px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 var(--fs-body) / var(--lh-body) var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent-txt); }

img, svg { max-width: 100%; }
input, select, button, textarea { font: inherit; color: inherit; }
::placeholder { color: var(--muted); opacity: 1; }
/* LO QUE PINTA EL NAVEGADOR TAMBIÉN TIENE TEMA, y sin decírselo lo pinta claro:
   es lo que da por hecho cuando nadie declara nada. De ahí venía el desplegable
   de las preferencias con fondo casi blanco y el texto casi blanco encima —se
   veía la caja y no se leía lo de dentro—, y también la barra de scroll clara
   en un modal oscuro, las flechitas de los campos numéricos y el amarillo del
   autorrelleno. Una línea por tema y se acaba la familia entera de fallos. */
:root { color-scheme: dark; }
:root[data-tema="claro"] { color-scheme: light; }

/* Las opciones las pinta el sistema en su propia ventana, fuera de la página,
   así que van con el tema puesto a mano: forzarlas claras dejaba una lista
   blanca colgando de un desplegable oscuro. */
select option { color: var(--ink); background: var(--surface); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
input:focus-visible, select:focus-visible {
  outline-offset: 1px;
}

/* El apretado del titular va por tamaño, no por etiqueta: -0.045em está pensado
   para los 70px de la portada, y aplicado a un h2 de 26px pega las palabras
   —"El feed" salía "Elfeed"—. Cuanto más pequeño, menos se aprieta. */
h1, h2, h3, h4 { margin: 0; font-weight: 700; }
h1 { letter-spacing: var(--ls-title); word-spacing: 0.12em; }
h2 { letter-spacing: -0.03em; word-spacing: 0.1em; }
h3, h4 { letter-spacing: -0.02em; word-spacing: 0.06em; }
/* El respiro del espacio es para el titular; la línea pequeña de debajo va con
   el espaciado normal del texto. */
h1 small, h2 small, h3 small, h4 small { letter-spacing: 0; word-spacing: normal; }

/* El acento manuscrito. No es decoración: separa lo que se dice de lo que se
   promete. Va con su propio interlineado porque Pinyon tiene ascendentes muy
   largas y sin esto empuja la línea entera. */
/* El acento manuscrito. Pinyon Script tiene una altura de x mucho menor que
   Switzer: a 1.12em, que es lo que decía el prototipo, se ve pequeño y
   flotando al lado de un titular de 70px en negrita. A 1.35em las dos voces
   pesan lo mismo, que es de lo que se trata.

   El `line-height: 0.85` no es un capricho: Pinyon tiene ascendentes larguísimas
   y con el interlineado normal empuja la línea entera y descuadra el titular. */
em, .script {
  font-family: var(--font-script);
  font-style: normal;
  font-weight: 400;
  letter-spacing: 0;
  font-size: 1.35em;
  line-height: 0.85;
  color: var(--accent-txt);
}

/* Todo lo que es un dato va en monoespaciada: precios, horas, códigos y
   rótulos. Es lo que deja comparar dos filas de un vistazo. */
.mono, .cifra, .amount, .iata, .build { font-family: var(--font-mono); }

.rotulo {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}

@keyframes tf-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
@keyframes tf-rise { from { opacity: 0; transform: translateY(8px); } }
@keyframes tf-fade { from { opacity: 0; } }
@keyframes tf-spin { to { transform: rotate(360deg); } }

/* En el atlas había tres capas de fondo. Aquí no hay ninguna: el fondo es
   plano y lo que separa es el filo. Se dejan los nodos vacíos por si algún
   HTML viejo sigue en caché. */
.grain, .glow, .registro { display: none; }

/* La región donde se anuncia lo que está pasando. Fuera de la vista, pero NO
   fuera del árbol: `display:none` o `visibility:hidden` la esconderían también
   del lector de pantalla, que es justo para quien existe. Un píxel recortado
   es la forma que sí lee todo el mundo. */
.solo-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.sin-js {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 18px var(--pad-page);
  color: var(--accent-txt);
  font-size: var(--fs-body-s);
}

/* ==========================================================================
   LA CABECERA
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.topbar-in {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 12px var(--pad-page);
  display: flex;
  align-items: center;
  gap: 18px;
}

/* La marca: un avión de papel, "Trip" manuscrito y "finder" en negrita muy
   apretada. El margen negativo es lo que las hace una sola palabra. */
.marca { display: flex; align-items: baseline; gap: 9px; flex: none; }
.marca svg { align-self: center; }
.marca-trip {
  font-family: var(--font-script);
  font-size: 26px;
  line-height: 1;
  letter-spacing: 0.01em;
}
.marca-finder {
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.035em;
  /* Con Pinyon Script de verdad la "p" de Trip lleva un rasgo largo que se
     mete debajo de "finder": el -6px del prototipo estaba medido contra una
     cursiva de sistema, que no lo tiene. Se deja en -1px, que junta las dos
     mitades sin que se pisen. */
  margin-left: -1px;
}

.zonas {
  display: flex;
  gap: 20px;
  font-size: var(--fs-ui);
  font-weight: 500;
  color: var(--muted);
}
.zona { white-space: nowrap; }
.zona:hover { color: var(--accent-txt); }
.zona.activa { color: var(--ink); }

.topbar-hueco { flex: 1; }

.tema {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  border-radius: var(--r-pill);
  font-size: var(--fs-body);
  cursor: pointer;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.tema:hover { color: var(--ink); border-color: var(--ink); }
.tema-txt {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* El botón de cuenta y el de entrar: la píldora rellena de la cabecera. */
.cuenta, #tfCuenta {
  flex: none;
  padding: 10px 18px;
  border: 1px solid var(--btn-bg);
  background: var(--btn-bg);
  color: var(--btn-ink);
  border-radius: var(--r-pill);
  font-size: var(--fs-ui);
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease),
              color var(--t) var(--ease);
}
.cuenta:hover, #tfCuenta:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--sobre-acento);
}
.cuenta b { font-weight: 700; }
.cuenta-txt { max-width: 12ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* El test de destinos. Era un cuadradito con un «?» que nadie sabia que hacia;
   ahora es un boton con su nombre: «Ayúdame a elegir» (y «¿Dónde ir?» en el
   movil, donde no cabe mas). */
.flap {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  padding: 6px 5px 5px;
  border: 1px solid var(--hair);
  background: none;
  color: var(--muted);
  border-radius: var(--r-tag);
  font: 500 var(--fs-data-s) / 1 var(--font-mono);
  letter-spacing: 0.06em;
}
.flap-boton {
  position: relative;
  margin-left: 10px;
  padding: 9px 14px;
  border-color: var(--line);
  border-radius: var(--r-pill);
  cursor: pointer;
  color: var(--muted);
  font: 500 var(--fs-ui-s, 13px) / 1 inherit;
  letter-spacing: 0;
  white-space: nowrap;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.flap-txt-corto { display: none; }
.flap-boton:hover, .flap-boton:focus-visible { color: var(--accent-txt); border-color: var(--accent); }
.flap-boton.con-memoria { color: var(--accent-txt); border-color: var(--accent); }
.flap-boton::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: max(100%, var(--tap-min));
  height: max(100%, var(--tap-min));
  transform: translate(-50%, -50%);
}

/* ==========================================================================
   EL CUERPO
   ========================================================================== */

main {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 0 var(--pad-page) 96px;
}

.masthead {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 46px var(--pad-page) 30px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 48px;
  align-items: end;
  border-bottom: 1px solid var(--line);
}

/* El panel no tiene sidebar: su cabecera va en una columna y sus cifras
   debajo, a lo ancho. Con la rejilla de dos, el texto y los números se
   repartían en diagonal —título arriba a la izquierda, lede a la derecha,
   cifras debajo del título— y no se leía en ningún orden. */
.masthead.ancha {
  display: block;
}
.masthead.ancha .lede { max-width: 52ch; }
.masthead.ancha .stats {
  grid-template-columns: repeat(4, 1fr);
  max-width: 680px;
  margin-top: 24px;
}

h1 {
  font-size: var(--fs-display);
  line-height: 0.98;
  margin: 0 0 18px;
  text-wrap: balance;
}
h1 em { font-size: 1.3em; }

/* La rejilla de estadísticas es un fondo con hilos de un píxel: vacía —el
   panel la deja así hasta que entras— se quedaba pintando un filete suelto
   debajo del titular. */
.stats:empty { display: none; }

.lede {
  margin: 0;
  max-width: 48ch;
  color: var(--muted);
  font-size: var(--fs-lede);
  line-height: var(--lh-body);
  text-wrap: pretty;
}
.trato {
  margin: 14px 0 0;
  max-width: 52ch;
  color: var(--muted);
  font-size: var(--fs-body-s);
  line-height: var(--lh-body);
}
.trato a { color: var(--accent-txt); border-bottom: 1px solid currentColor; }

/* Los cuatro números. Rejilla de un píxel: el fondo es la línea y cada celda
   se pinta encima, que es como se hace una tabla sin dibujar bordes. */
.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  margin: 0;
  background: var(--line);
  border: 1px solid var(--line);
}
.stats > div {
  background: var(--paper);
  padding: 12px 14px;
  margin: 0;
}
.stats dt {
  font: 400 var(--fs-caps-l) / 1.2 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.stats dd {
  margin: 2px 0 0;
  font: 600 var(--fs-figure) / 1.1 var(--font-mono);
  letter-spacing: -0.03em;
}
.stats dd.hot { color: var(--accent-txt); }
.stats .stats-pie {
  grid-column: 1 / -1;
  padding: 10px 14px;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.stats .stats-pie b { color: var(--ink); font-weight: 400; }

/* ==========================================================================
   EL CHOLLO DEL DÍA
   Lámina invertida: el único bloque de la página con el fondo al revés, que es
   lo que lo separa del feed sin necesidad de gritar.
   ========================================================================== */

.ticket {
  margin: 30px 0 0;
  border: 1px solid var(--line);
  background: var(--hero-bg);
  color: var(--hero-ink);
  border-radius: var(--r);
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  animation: tf-rise var(--t-med) var(--ease);
}
.ticket-izq {
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}
.ticket-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kicker {
  font-family: var(--font-script);
  font-size: 24px;
  line-height: 1;
  color: var(--accent-txt);
}
.kicker-tag {
  font: 400 var(--fs-meta) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hero-muted);
}
.dest {
  margin: 0;
  font-size: var(--fs-title);
  line-height: 1;
  letter-spacing: var(--ls-title);
}
.dest small {
  display: block;
  margin-top: 10px;
  font: 400 var(--fs-body-s) / 1.4 var(--font-sans);
  letter-spacing: 0;
  color: var(--hero-muted);
}

/* Los cuatro tramos, con la misma rejilla de un píxel que las estadísticas. */
.legs {
  /* La misma rejilla se usa en dos sitios con tintas OPUESTAS: dentro de la
     lámina invertida del chollo y dentro del detalle de una fila, que va sobre
     el papel de la página. Sin estas variables locales el detalle pintaba
     marfil sobre marfil y los horarios no se veían. */
  --legs-hilo: var(--hair);
  --legs-fondo: var(--surface2);
  --legs-ink: var(--ink);
  --legs-muted: var(--muted);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin: 0;
  background: var(--legs-hilo);
  border: 1px solid var(--legs-hilo);
  color: var(--legs-ink);
}
.ticket .legs {
  --legs-hilo: var(--hero-hair);
  --legs-fondo: var(--hero-bg);
  --legs-ink: var(--hero-ink);
  --legs-muted: var(--hero-muted);
}
.ticket-izq .legs { margin-top: auto; }
.legs > div { background: var(--legs-fondo); padding: 11px 12px; min-width: 0; }
.legs dt {
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--legs-muted);
}
.legs dd {
  margin: 3px 0 0;
  font-size: var(--fs-body-s);
  color: var(--legs-ink);
}
.legs dd i { color: var(--legs-muted); font-style: normal; }
.legs .hhmm { display: block; margin-top: 1px; font: 400 var(--fs-body-s) var(--font-mono); }
.legs .dias { font: 400 20px/1 var(--font-mono); }
.legs .useful { font: 400 var(--fs-body-s) var(--font-mono); }
.legs .useful small { display: block; font-size: var(--fs-ui-s); color: var(--legs-muted); }

.ticket-der {
  border-left: 1px solid var(--hero-hair);
  padding: 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 20px;
}
.ticket-precio { min-width: 0; }
.amount {
  font-weight: 700;
  font-size: var(--fs-amount);
  letter-spacing: -0.05em;
  line-height: 1;
  font-family: var(--font-sans);
}
/* El símbolo va más pequeño que la cifra, pero pegado se leía "60€" como una
   sola palabra. Un pelo de aire y ya. */
.amount span, .quiz-precio .cifra span { font-size: 0.6em; margin-left: 0.11em; }
.ticket-cab { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.stamp {
  font: 600 var(--fs-ui-s) / 1 var(--font-mono);
  color: var(--accent-txt);
}
.pax-nota, .per-person {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-ui-s);
  color: var(--hero-muted);
}
.ticket-notas {
  display: block;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--hero-hair);
  font-size: var(--fs-data);
  color: var(--hero-muted);
}
.ticket-notas > span {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
}
.ticket-notas b { font: 400 var(--fs-data) var(--font-mono); color: var(--hero-ink); font-weight: 400; }
.was { color: var(--hero-muted); }
.escapada { font-family: var(--font-mono); }
.escapada.real { color: var(--deep); }

/* En la lámina del chollo los botones van uno debajo de otro (la columna es
   estrecha); donde hay sitio, en fila. */
.actions { display: grid; gap: 8px; }
.acciones-fila { display: flex; flex-wrap: wrap; gap: 10px; }
.perdido { padding: 24px 0; display: grid; gap: 12px; justify-items: start; }
.perdido .vacio { max-width: 60ch; font-family: var(--font-sans); font-size: var(--fs-body-s); }
.hero-extra { font-size: var(--fs-ui-s); color: var(--hero-muted); }
.hidden-warn { color: var(--accent-txt); }
.alts summary { cursor: pointer; }

/* ==========================================================================
   BOTONES
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 24px;
  min-height: var(--tap-min);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--sobre-acento);
  font-size: var(--fs-ui);
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: filter var(--t) var(--ease), background var(--t) var(--ease),
              color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.btn:hover { filter: brightness(1.1); color: var(--sobre-acento); }
.btn.primary { background: var(--accent); color: var(--sobre-acento); }
.btn.ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink);
  font-weight: 500;
}
.btn.ghost:hover { border-color: var(--ink); color: var(--ink); filter: none; }
.btn.small { padding: 9px 16px; font-size: var(--fs-ui-s); }
.btn.deep { background: var(--deep); border-color: var(--deep); color: #0e1614; }
.btn.deep:hover { background: transparent; color: var(--deep); filter: none; }
/* Un botón apagado no se difumina: sobre el relleno naranja, bajarle la
   opacidad dejaba el rótulo casi ilegible. Se vacía y se queda con el hilo. */
.btn[disabled], .btn.apagado {
  background: transparent;
  border-color: var(--hair);
  color: var(--muted);
  cursor: default;
  filter: none;
}
.btn[disabled]:hover, .btn.apagado:hover { filter: none; color: var(--muted); }
/* Dentro de la lámina invertida los botones fantasma cambian de tinta. */
.ticket .btn.ghost { border-color: var(--hero-hair); color: var(--hero-ink); }
.ticket .btn.ghost:hover { border-color: var(--hero-ink); }

/* ==========================================================================
   EL FEED
   ========================================================================== */

.feed { margin-top: 44px; scroll-margin-top: 76px; }

.feed-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.feed-head h2 { font-size: var(--fs-heading); }
.feed-cuenta {
  font: 400 var(--fs-meta) var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* La barra de filtros: campos sin caja, solo una raya debajo. */
/* La barra de filtros de móvil y la cabecera/pie de la hoja no existen por
   encima de 760 px: allí `.controls` es la fila de siempre. */
.filtros-movil, .hoja-solo { display: none; }
.filtros-movil > input {
  flex: 1;
  min-width: 0;
  min-height: var(--tap-min);
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-size: 16px;
  font-weight: 500;
}
.filtros-movil > input:hover, .filtros-movil > input:focus { border-color: var(--muted); }
.filtros-btn {
  flex: none;
  min-height: var(--tap-min);
  padding: 12px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  font: 600 15px var(--font-sans);
  white-space: nowrap;
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.filtros-btn.on {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--sobre-acento);
}
.hoja-cab {
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font: 700 19px var(--font-sans);
  letter-spacing: -0.03em;
}
.hoja-pie {
  gap: 10px;
  align-items: center;
  border-top: 1px solid var(--hair);
  padding-top: 14px;
}
.hoja-pie > .btn { flex: none; }
.hoja-pie > #filtrosVer { flex: 1; }

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
  padding: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--r);
}
.field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 0 1 130px;
  min-width: 0;
}
/* El campo de destino crece, pero con tope: sin él se comía todo el hueco
   sobrante y quedaba un subrayado vacío de medio panel. El tope es SOLO para
   la barra del feed: en el panel hay campos anchos que tienen que serlo. */
.field.grow { flex: 1 1 190px; }
.controls .field.grow { max-width: 260px; }
/* El hueco que sobre se va entre los campos y los interruptores. */
.controls .switch:first-of-type { margin-left: auto; }
.field label, .field > span {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.field input, .field select {
  border: none;
  border-bottom: 1px solid var(--hair);
  background: transparent;
  padding: 6px 0;
  font-size: var(--fs-input);
  font-weight: 500;
  width: 100%;
  min-width: 0;
  border-radius: 0;
  transition: border-color var(--t) var(--ease);
}
.field input[type="number"], .field .cifra { font-family: var(--font-mono); font-weight: 400; }
.field input:hover, .field select:hover { border-color: var(--muted); }
/* El deslizador ocupa el mismo alto que un campo escrito para que la fila de
   controles alinee por abajo. */
.field input[type="range"] { border: none; padding: 10px 0 9px; accent-color: var(--accent); }

/* Los interruptores son chips, no casillas: se pulsan con el pulgar. */
.switch {
  display: inline-flex;
  align-items: center;
  padding: 10px 14px;
  min-height: var(--tap-min);
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.switch:hover { border-color: var(--muted); color: var(--ink); }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Los chips de la hoja de filtros son `.switch` sin casilla dentro: marcan su
   estado con `aria-pressed`, así que el encendido va por las dos vías. */
.switch:has(input:checked),
.switch[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
}
.switch:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- la tabla ------------------------------------------------------------
   Una rejilla de seis columnas compartida por la cabecera y por cada fila:
   si se cambia aquí, se cambia en las dos a la vez. La última es «compartir»,
   que se pulsa sin abrir la fila: pasar un chollo a alguien es lo que más se
   hace con él y no debería costar dos toques. */
.rows, .board-head, .saved-rows, .watch-rows {
  /* EL NOMBRE DEL SITIO ES LO ULTIMO QUE SE CEDE, y era lo primero. Las
     columnas fijas —seguir, precio, compartir— y los huecos suman 424 px que no
     se encogen; las otras tres llevaban `minmax(0, …)`, o sea permiso para
     bajar hasta CERO. Entre 761 y 1000 px de ventana el destino se quedaba en
     14 px: "Dublín" era una D y media. Justo debajo de esa franja empieza la
     maqueta apilada del móvil, así que el fallo solo se veía en ventanas de
     portátil, que es donde más se mira esto.

     `9ch` es el suelo: por debajo de eso no cabe el nombre de una ciudad. */
  --cols: 40px minmax(9ch, 1.05fr) minmax(0, 1.58fr) minmax(0, 0.83fr) 208px 96px;
}

/* Y antes de llegar al suelo se sueltan las columnas que sobran, en orden de
   lo menos importante: primero compartir —que es un atajo, y la fila se abre
   igual—, luego la compañía, que se lee dentro de la fila abierta. Lo que
   queda es lo que contesta «¿a dónde, cuándo y cuánto?». */
@media (max-width: 1080px) and (min-width: 761px) {
  .rows, .board-head, .saved-rows, .watch-rows {
    --cols: 40px minmax(11ch, 1.25fr) minmax(0, 1.4fr) 168px;
  }
  .board-head span:nth-child(4),
  .board-head span:nth-child(6) { display: none; }
  .brow > .airline,
  .brow > .compartir-cell { display: none; }
}

.tabla {
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--surface);
}

.board-head {
  display: grid;
  grid-template-columns: var(--cols);
  gap: 16px;
  /* Los 30 px de la derecha son los del chevron de las filas: la cabecera usa
     la misma rejilla, y sin el mismo hueco sus rotulos quedaban 16 px
     corridos respecto a las columnas que rotulan. */
  padding: 8px 30px 8px 14px;
  background: var(--code-bg);
  color: var(--code-ink);
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
}
.board-head span:last-child { text-align: right; }

.brow {
  display: grid;
  grid-template-columns: var(--cols);
  gap: 16px;
  padding: 11px 14px;
  border-top: 1px solid var(--hair);
  align-items: center;
  cursor: pointer;
  animation: tf-fade var(--t-med) var(--ease) backwards;
  transition: background var(--t-micro) var(--ease);
}
.rows .brow:first-child { border-top: none; }
.brow:hover, .brow:focus-visible { background: var(--surface2); }

/* LA MARCA DE QUE LA FILA SE ABRE.

   La fila tiene el cursor de mano y se ilumina al pasar por encima, pero nada
   decia que dentro hay cinco botones y los tramos de ida y vuelta: habia que
   pulsarla para enterarse. Un chevron, que es lo que se reconoce sin que nadie
   lo explique, y que gira al abrirse.

   Va SOLO en las filas que se abren de verdad (`[data-open]`): el panel de
   cuentas reusa `.brow` para sus filas y una flecha ahi seria una mentira.

   `top` es un numero fijo y no `50%` a proposito: `.brow-detail` vive DENTRO
   de la fila, asi que con el detalle desplegado la mitad de la fila cae en
   mitad del panel abierto y la flecha se iria a pasear ahi. Anclada arriba se
   queda en su renglon, que es el que se pulsa. */
.brow[data-open] { position: relative; padding-right: 30px; }
.brow[data-open]::after {
  content: "";
  position: absolute;
  right: 13px;
  top: 18px;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(-45deg);
  transition: transform var(--t) var(--ease), border-color var(--t) var(--ease);
}
.brow[data-open]:hover::after { border-color: var(--ink); }
.brow[data-open].open::after { transform: rotate(45deg); }

/* El botón de seguir un viaje. Va el primero, como en un parte de salidas.
   Antes era un cuadratín de 20 px con un glifo puesto por CSS y el `color` del
   botón en transparente: no decía qué hacía y cualquier texto de dentro salía
   invisible. Ahora es una píldora con campana; la palabra sale donde cabe. */
.fav {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 600 var(--fs-ui) / 1 var(--font-sans);
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
/* En escritorio manda el icono: la columna del parte es estrecha. */
.fav .fav-txt { display: none; }
.fav:hover, .fav:focus-visible { border-color: var(--deep); color: var(--ink); }
.fav.on {
  border-color: var(--deep);
  background: var(--deep);
  color: #0e1614;
}
.fav.on:hover { color: #0e1614; }
.fav::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: max(100%, var(--tap-min));
  height: max(100%, var(--tap-min));
  transform: translate(-50%, -50%);
}

/* Dentro de la lámina invertida todo va con SUS tintas: `--muted`, `--line` y
   `--ink` son las del fondo de fuera y ahí dentro no se ven —en tema claro son
   negro sobre negro—. Cualquier regla nueva que entre en `.ticket` va igual. */
.ticket .fav { border-color: var(--hero-hair); color: var(--hero-muted); }
.ticket .fav:hover { border-color: var(--deep); color: var(--hero-ink); }
/* Encendido manda el relleno, dentro y fuera de la lámina: si no, la regla de
   arriba le devolvía el `--hero-muted` encima del verde y no se veía. */
.ticket .fav.on, .ticket .fav.on:hover { color: #0e1614; border-color: var(--deep); }
.ticket .iata { color: var(--hero-muted); border-color: var(--hero-hair); }

.dest-cell { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.iata {
  flex: none;
  font: 500 var(--fs-meta) / 1 var(--font-mono);
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 3px 6px;
  border-radius: var(--r-tag);
  letter-spacing: var(--ls-code);
  font-variant-numeric: tabular-nums;
}
.iata.hidden { border-color: var(--accent); color: var(--accent-txt); }
.city {
  font-weight: 600;
  font-size: var(--fs-city-s);
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* EL PAIS CEDE PRIMERO. `.city` y `.country` son dos hermanos en un flex y
   encogian por igual, asi que al estrechar la ventana «Reino Unido» se llevaba
   por delante a «Manchester» aunque la celda tuviera 193 px de sobra. Con un
   `flex-shrink` enorme, el pais absorbe practicamente toda la reduccion y el
   nombre solo se corta cuando ya no cabe ni el nombre solo.

   Es la misma regla que la rejilla, dicha donde de verdad aprieta: lo que hay
   que leer es a donde vas. */
/* La bandera, pegada al nombre del país. `font-style: normal` porque va en un
   `<i>` —que aquí es «un trocito distinto», no una cursiva— y un emoji en
   cursiva se ve torcido en algunas tipografías.

   En Windows no hay glifo de bandera y salen las dos letras del código. Es un
   mal menor honesto: se sigue sabiendo de qué país habla. */
.bandera {
  font-style: normal;
  margin-right: 0.35em;
  /* Que no arrastre la línea: los emoji suelen medir más que el texto. */
  line-height: 1;
}

.country {
  flex: 0 9999 auto;
  min-width: 0;
  font-size: var(--fs-ui-s);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.when { min-width: 0; }
/* Toda la fecha en una línea: "vie 8 ene 16:10 → dom 10 19:10". Los `<b>` van
   en línea a propósito —en bloque partían la fila en tres renglones— y lo que
   sobra se corta con puntos suspensivos en vez de doblarse. */
.when {
  font: 400 var(--fs-data) var(--font-mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.when b { font-weight: 500; }
.when i { font-style: normal; color: var(--muted); }
.when small {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-data-s);
  color: var(--muted);
}
.when.weekend b { color: var(--ink); }

/* LOS VUELOS EN LOS QUE YA SE BUSCÓ CAMA.

   Buscar alojamiento son tres minutos de workflow, y lo buscado queda
   publicado para siempre: la fila tiene que decir que eso ya está hecho ANTES
   de que la abras, o se vuelve a pedir lo que ya está.

   Se marca con un filo en el margen y con la palabra donde ya se lee el resto
   del viaje. Nada de una columna nueva: el ancho es justo lo que no sobra en
   esta rejilla, y añadir una se come el nombre de la ciudad. */
.brow.con-cama { box-shadow: inset 3px 0 0 var(--deep); }
.when .cama-ok {
  font-style: normal;
  color: var(--deep);
}
.kicker-tag.cama-ok { color: var(--deep); }

.airline { min-width: 0; }
.airline small {
  display: block;
  font-size: var(--fs-data-s);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Los puntos guía eran del atlas: aquí las columnas ya alinean solas. */
.leader { display: none; }

.price { text-align: right; min-width: 0; }
/* La cifra y su descuento, en la misma línea y alineados por la base. */
.cifra-fila {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 7px;
}
.price .cifra {
  font: 600 var(--fs-cifra) / 1.1 var(--font-mono);
  letter-spacing: -0.02em;
}
.price small { display: block; font-size: var(--fs-meta); color: var(--muted); }
.price .off {
  display: inline;
  font: 600 var(--fs-ui-s) var(--font-mono);
  color: var(--accent-txt);
}
/* Todas las notas del precio caben en un solo renglón, separadas por un punto.
   Es lo que mantiene el panel a una altura de fila constante. */
.nota-fila {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  flex-wrap: nowrap;
  white-space: nowrap;
  gap: 0 6px;
  margin-top: 1px;
}
.nota-fila > * + *::before {
  content: "·";
  color: var(--muted);
  opacity: 0.55;
  margin-right: 6px;
}
.price .nota-fila small,
.price .nota-fila .escapada,
.price .nota-fila .delta { display: inline; font-size: var(--fs-meta); }
.price .escapada { display: block; font-size: var(--fs-meta); color: var(--muted); }

/* "No se ha visto nunca mas barato". Va en verde y no en naranja a proposito:
   el naranja ya es el descuento, y si las dos cosas salieran del mismo color la
   fila diria dos veces lo mismo de un vistazo. */
.minimo {
  display: inline-block;
  font: 600 var(--fs-meta) / 1 var(--font-mono);
  letter-spacing: 0.02em;
  color: var(--deep);
  text-transform: lowercase;
  white-space: nowrap;
}
.ticket-cab .minimo {
  font-size: var(--fs-ui-s);
  color: var(--hero-deep);
}
.price .nota-fila .minimo { display: inline; }

/* ==========================================================================
   LA HOJA DE COMPARTIR
   ========================================================================== */

/* Por qué una hoja y no el menú del sistema a secas: `navigator.share` no
   existe en los navegadores de escritorio, así que allí lo único que quedaba
   era copiar el enlace. Quien pasa un chollo lo manda por WhatsApp o por
   correo, y esos son enlaces normales que funcionan en todas partes. */
.hoja-compartir {
  width: min(470px, 100%);
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 24px 26px 28px;
}
/* `minmax(0, 1fr)` y no `auto`: un enlace largo es una sola palabra sin sitios
   por donde partir, y con la pista en `auto` el bloque crecía hasta los 477 px
   dentro de una hoja de 350 y se salía de la pantalla en un móvil. */
.hoja-bloque { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; min-width: 0; }
.hoja-rotulo {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.hoja-nota { margin: 0; font-size: var(--fs-meta); line-height: 1.45; color: var(--muted); }

/* La ficha del viaje va en la lámina invertida, como el chollo del día: lo que
   se comparte tiene cara, y verla antes de mandarla evita mandar la que no es. */
.hoja-ficha {
  background: var(--hero-bg);
  color: var(--hero-ink);
  border: 1px solid var(--hero-hair);
  border-radius: var(--r);
  padding: 16px 18px;
}
.hoja-ficha-cab {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.hoja-ficha-cab b,
.hoja-ficha-cab span { font: 700 var(--fs-h3) var(--font-sans); letter-spacing: -0.04em; }
.hoja-ficha-pie {
  margin-top: 6px;
  font: 400 var(--fs-meta) / 1.5 var(--font-mono);
  color: var(--hero-muted);
}

.hoja-enlace { display: flex; gap: 8px; align-items: stretch; }
.hoja-url {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--hair);
  background: var(--field);
  border-radius: var(--r);
  padding: 11px 12px;
  font: 400 var(--fs-meta) var(--font-mono);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hoja-enlace .btn { flex: none; }
.hoja-apps { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.hoja-apps .btn { justify-content: center; text-align: center; }
.hoja-guardar { border-top: 1px solid var(--hair); padding-top: 16px; }
.hoja-guardar .btn { justify-self: start; }

/* El botón de guardárselo va en verde y perfilado: no es la acción principal
   de la hoja —esa es mandarlo— pero tampoco es una más de la lista. */
.btn.deep-ghost {
  border-color: var(--deep);
  background: transparent;
  color: var(--deep);
  font-weight: 600;
}
.btn.deep-ghost:hover { background: var(--deep); color: var(--sobre); }

/* El filo que separa, al abrir una fila, lo de mirar y reservar de lo de
   llevárselo: sin él son seis botones seguidos y ninguno manda. */
.filo {
  width: 1px;
  align-self: stretch;
  min-height: 24px;
  background: var(--hair);
  margin: 0 4px;
}

/* El «compartir» de cada fila. Discreto a propósito: es una acción de paso,
   no compite con el precio ni con el botón de seguir. */
.compartir-cell { display: flex; justify-content: flex-end; }
.compartir-btn {
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 400 var(--fs-meta) var(--font-mono);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.compartir-btn:hover { color: var(--ink); border-color: var(--muted); }

/* La diferencia contra el precio al que lo apuntaste. */
.delta { display: block; font: 500 var(--fs-meta) var(--font-mono); }
.delta.baja, .price .delta.baja { color: var(--deep); }
.delta.sube, .price .delta.sube { color: var(--accent-txt); }
.delta.igual, .price .delta.igual { color: var(--muted); }

.brow-detail {
  grid-column: 1 / -1;
  border-top: 1px solid var(--hair);
  margin-top: 11px;
  padding-top: 14px;
  display: grid;
  gap: 14px;
}
/* En la lámina los botones van uno debajo de otro porque la columna es
   estrecha; aquí hay toda la fila, así que van en línea y a su ancho. */
.brow-detail .actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.brow-detail .actions > .btn { flex: 0 0 auto; }

.ver-mas { display: flex; justify-content: center; margin-top: 14px; }

.empty, .vacio {
  margin-top: 8px;
  font: 400 var(--fs-meta) var(--font-mono);
  color: var(--muted);
}

/* Lo que se enseña mientras llegan los datos. */
.cargando { padding: 8px 0; }
.cargando-fila {
  height: 44px;
  border-top: 1px solid var(--hair);
  background: linear-gradient(90deg, transparent, var(--surface2), transparent);
  background-size: 200% 100%;
  animation: tf-barrer 1.4s infinite linear;
}
@keyframes tf-barrer { to { background-position: -200% 0; } }
.cargando-nota { font: 400 var(--fs-meta) var(--font-mono); color: var(--muted); padding-top: 10px; }
.spin {
  display: inline-block;
  /* Sin el hueco, la rueda y el texto salen pegados: «⟳preguntando». */
  margin-right: 8px;
  vertical-align: -1px;
  width: 12px; height: 12px;
  border: 1.5px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: tf-spin 0.8s linear infinite;
}

.errors {
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 12px 14px;
  font-size: var(--fs-body-s);
  color: var(--muted);
}
.errors summary { cursor: pointer; color: var(--accent-txt); }

/* ==========================================================================
   LOS DOS PANELES: buscar y seguir
   ========================================================================== */

.panels {
  margin-top: 52px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.herramienta {
  scroll-margin-top: 76px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.herramienta.segunda { background: var(--surface2); }
.herramienta > .finder-body { display: contents; }

.kicker-num {
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--accent-txt);
}
.herramienta.segunda .kicker-num,
.herramienta.verde .kicker-num { color: var(--deep); }
.herramienta h3 { font-size: var(--fs-subhead); margin: 8px 0 0; }
.herramienta h3 em { font-size: 1.15em; color: inherit; }
.finder-lede, .herramienta p {
  margin: 10px 0 0;
  font-size: var(--fs-body-s);
  line-height: var(--lh-body);
  color: var(--muted);
  text-wrap: pretty;
}

/* Los campos: rejilla de un píxel, cada celda con su fondo de formulario. */
.finder-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
}
.finder-form label, .finder-form .celda {
  background: var(--field);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
/* "Destino" y "Fechas" se encienden por separado según lo que se elija arriba.
   El que se quede solo ocupa la fila entera: si no, el hueco de al lado deja
   ver el fondo de la rejilla y parece una celda rota. */
.finder-form:has(#destWrap[hidden]) #departWrap:not([hidden]),
.finder-form:has(#departWrap[hidden]) #destWrap:not([hidden]) { grid-column: 1 / -1; }
/* Y en general: la última celda que se queda sola la marca `cuadrarRejilla`. */
.finder-form > [data-sola] { grid-column: 1 / -1; }

.finder-form label > span {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.finder-form input, .finder-form select, .finder-form .date-btn {
  border: none;
  background: transparent;
  padding: 0;
  font-size: var(--fs-input);
  font-weight: 600;
  width: 100%;
  min-width: 0;
  border-radius: 0;
  text-align: left;
  cursor: pointer;
}
.finder-form input[type="number"], .finder-form .cifra { font-family: var(--font-mono); font-weight: 400; }
.finder-form .party {
  grid-column: 1 / -1;
  background: var(--field);
  padding: 10px 12px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
/* Los rótulos de esta fila no miden lo mismo ("Avísame si baja de €" se dobla)
   y sin esto las cifras quedaban a alturas distintas. Se empujan al fondo. */
.finder-form .party > label {
  background: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 4px;
}
.hint { font-size: var(--fs-ui-s); color: var(--muted); line-height: 1.45; max-width: 70ch; }
/* Un renglón de texto no se estira a lo ancho del panel: a más de setenta
   caracteres el ojo pierde el salto de línea. Estas notas llevan su propio
   filete arriba, así que se acorta el TEXTO —de ahí el `span`— y no la caja,
   que si no el filete quedaba a media anchura. */
.vacio { max-width: 74ch; }
.nota-txt { display: inline-block; max-width: 74ch; vertical-align: middle; }
.finder-form + .candado-nota { margin-top: 0; }
/* El aviso de «hace falta una cuenta», encima de la herramienta: una caja con
   su frase y sus dos botones, no una nota perdida debajo del formulario. */
.candado-nota {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 1px solid var(--hair);
  border-radius: var(--r-md, 12px);
}
.candado-nota, .cuenta-nota {
  font-size: var(--fs-ui-s);
  color: var(--muted);
  border-top: 1px solid var(--hair);
  padding-top: 12px;
}
.candado-nota a, .cuenta-nota a { color: var(--accent-txt); text-decoration: underline; text-underline-offset: 2px; }
.finder-form.candado > .btn { background: transparent; border-color: var(--hair); color: var(--muted); }

/* La página completa de una herramienta: la misma caja, sin borde ni fondo,
   porque ahí ya no compite con nada. */
.herramienta.completa {
  border: none;
  background: none;
  padding: 0;
}
.finder { border: none; background: none; }
.finder summary { display: none; }
/* En el panel van varias `.finder` seguidas —token, sin dueño, registro— y sin
   esto la primera se pegaba al borde de la fila de botones de arriba. */
#panelAdmin > .finder, #panelAdmin > details.finder { margin-top: 26px; }


/* ==========================================================================
   EN OBSERVACIÓN
   ========================================================================== */

.observacion {
  margin-top: 20px;
  scroll-margin-top: 76px;
  border: 1px dashed var(--line);
  border-radius: var(--r);
  padding: 22px;
  display: flex;
  gap: 22px;
  align-items: center;
  flex-wrap: wrap;
}
.observacion-num { min-width: 140px; }
.observacion-num b {
  display: block;
  font-weight: 700;
  font-size: 36px;
  letter-spacing: var(--ls-title);
  line-height: 1.15;
}
.observacion p { margin: 0; flex: 1; min-width: 260px; }

.favoritos, .watches, .searches { margin-top: 28px; }
/* `.herramienta h3` es más específica y le ganaba el tamaño: dentro del panel
   de seguir, «Siguiendo a diario» salía a cuerpo de subtítulo en vez de como
   el rótulo pequeño que es. Solo se veía con seguimientos de verdad, que es
   justo lo que no tiene una página recién abierta. */
.watch-head,
.herramienta .watch-head {
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
}
.favrow, .watch, .ya-hecha, .saved {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  gap: 10px 16px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  margin-bottom: 8px;
}
/* Una entrada en observación tiene lo mismo que una fila del panel de salidas
   —sitio, fechas, curva, precio— así que se lee igual: en UNA línea y con las
   columnas alineadas. Con la rejilla de tres se partía en dos renglones y el
   precio quedaba flotando en mitad de la caja. */
.favrow {
  /* Mismo suelo que el tablón, y por lo mismo: aquí el destino también llevaba
     `minmax(0, …)` y a 780 px de ventana se quedaba en 0 px de ancho. */
  grid-template-columns: 34px minmax(9ch, 1.1fr) minmax(0, 1fr) 78px 132px auto;
  gap: 8px 16px;
}

/* En la franja de portátil estrecho se suelta la curva: dice cómo va el precio,
   que es mirar, no decidir. El nombre y el precio se quedan. */
@media (max-width: 1080px) and (min-width: 761px) {
  .favrow { grid-template-columns: 34px minmax(11ch, 1.2fr) minmax(0, 1fr) 132px auto; }
  .favrow > .spark-cell { display: none; }
}
.favrow .spark-cell { display: grid; place-items: center; min-width: 0; }
.favrow .spark-cell:empty { visibility: hidden; }
.favrow .when { text-align: right; }
.watch .dest-cell { grid-column: 2; }

/* Un seguimiento y una búsqueda guardada NO empiezan por un código de tres
   letras: su primera celda es el rótulo entero. Con la rejilla que arranca en
   34 px el rótulo salía a palabra por renglón y el "quitar" se quedaba suelto
   en mitad de la caja. */
.watch, .saved, .ya-hecha {
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 4px 14px;
}
.watch > b, .saved > b, .ya-hecha > b {
  grid-column: 1;
  grid-row: 1;
  font-weight: 600;
  font-size: var(--fs-body-s);
  min-width: 0;
}
.watch > .meta, .saved > .meta, .ya-hecha > .meta { grid-column: 1; grid-row: 2; }
.saved > .best { grid-column: 2; grid-row: 1 / span 2; justify-self: end; }
.watch > .quitar, .saved > .quitar, .ya-hecha > .btn, .saved > .btn {
  grid-column: 3;
  grid-row: 1 / span 2;
  justify-self: end;
}
/* Lo que un seguimiento o una búsqueda encontró se despliega debajo, entero. */
.watch > .watch-rows, .saved > .saved-rows { grid-column: 1 / -1; grid-row: 3; }
.favrow .meta, .watch .meta, .saved .meta, .ya-hecha .meta {
  font-size: var(--fs-ui-s);
  color: var(--muted);
}
.favacc { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.best { font: 600 var(--fs-data) var(--font-mono); color: var(--deep); }

.quitar {
  position: relative;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 400 var(--fs-ui-s) var(--font-mono);
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.quitar:hover { border-color: var(--accent); color: var(--accent-txt); }
.quitar::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: max(100%, var(--tap-min));
  height: max(100%, var(--tap-min));
  transform: translate(-50%, -50%);
}

/* La puerta a la lista entera desde el contador de la portada: antes el bloque
   decía cuántos sigues y no llevaba a ninguna parte. */
.observacion-ir { margin: 14px 0 0; }

/* --- la banda de cambio de precio ----------------------------------------
   Lo primero que ves al entrar cuando algo tuyo se ha movido. El titular dice
   cuánto dinero y en qué dirección; debajo, una ficha por viaje con su curva.
   El filo de arriba se reparte como se reparten los cambios: verde lo que baja
   y naranja lo que sube, así se ve la proporción sin contar nada. */
.fav-aviso {
  /* Sin caja, sin fondo y sin sombra: la banda es un aviso, no un panel. Lo
     único que queda es el filo de arriba, que se reparte como se reparten los
     cambios —verde lo que baja, naranja lo que sube— y es la única nota de
     color de todo esto. */
  margin: 20px 0 24px;
  font-size: var(--fs-body-s);
  color: var(--ink);
}
.fav-aviso::before {
  content: "";
  display: block;
  height: 2px;
  background: linear-gradient(
    to right,
    var(--deep) 0 var(--pbaja, 100%),
    var(--accent) var(--pbaja, 100%) 100%
  );
}

.aviso-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 18px;
  flex-wrap: wrap;
  padding: 12px 0 8px;
}
/* Un rótulo, no un titular. La cifra grande y la rúbrica en script eran un
   cartel para decir que algo ha bajado catorce euros. */
.aviso-rotulo {
  margin: 0;
  font: 400 var(--fs-caps-l) / 1.2 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--ink);
}
.aviso-rotulo span { color: var(--muted); }

/* Las regiones, arriba del selector de destinos: son lo más ancho que se puede
   elegir sin irse a un continente entero, y quien abre esto sin un sitio en la
   cabeza es justo a quien le sirven. */
.pais.regiones { border-bottom: 1px solid var(--line); padding-bottom: 12px; margin-bottom: 4px; }
.regiones-rotulo {
  margin: 0 0 8px;
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.ciudad.region { font-weight: 600; }
.ciudad.region i { font-style: normal; color: var(--muted); font-family: var(--font-mono); }

/* La cola de peticiones, en el panel. */
.peticiones { margin-top: 24px; display: grid; gap: 8px; }
.peticion {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  padding: 14px 16px;
  display: grid;
  gap: 10px;
}
.peticion-quien { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 10px; }
.peticion-tag {
  font: 500 var(--fs-data-s) / 1 var(--font-mono);
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 3px 6px;
  letter-spacing: 0.1em;
}
/* Una petición de antes del buzón: llegó sin contraseña dentro y hay que
   ponerla a mano. El botón distinto era la única pista, y un botón no explica
   nada por sí solo: quien aprueba se encontraba un formulario pidiéndole una
   contraseña sin saber por qué unas veces sí y otras no. */
.peticion-vieja {
  margin: 0;
  padding: 8px 10px;
  border-left: 2px solid var(--accent);
  background: var(--surface2);
  font-size: var(--fs-body-s);
  color: var(--muted);
}
.peticion-vieja b { color: var(--ink); font-weight: 600; }

.peticion-porque {
  margin: 0;
  font-size: var(--fs-body-s);
  line-height: 1.55;
  max-width: 70ch;
  white-space: pre-wrap;
}
.peticion-acc { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* El diálogo de tu cuenta. Era una columna plana de campo-tras-campo con
   «Guardar» y «Salir de la cuenta» como dos botones del mismo ancho, uno encima
   del otro: salir pesaba lo mismo que guardar y estaba a un dedo. */
.cuenta-quien {
  margin: 0;
  font-size: var(--fs-body-s);
  line-height: 1.55;
  color: var(--muted);
  max-width: 62ch;
}
.cuenta-quien b { color: var(--ink); }
.cuenta-aviso { display: block; margin-top: 8px; color: var(--accent-txt); }
.cuenta-plan { display: block; margin-top: 8px; color: var(--deep); }

/* Cada bloque dice de qué va antes de empezar, para que no haya que deducirlo
   del primer campo. */
.bloque-head {
  margin: 0 0 4px;
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}

/* «Cada cuánto» y «hasta cuánto» son una sola decisión, así que van en una
   línea. Sueltos parecían dos ajustes sin relación. */
.par-campo { display: grid; gap: 8px; }
/* La caja es de 440 px: el desplegable y «…y solo si bajan de 150 €» no caben
   en una línea, y forzarlos dejaba el tope colgando solo en el renglón de
   abajo. Cada cosa en su línea, y la segunda sangrada para que se lea como lo
   que es: el matiz de la de arriba, no otro ajuste. */
.par-tope {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-left: 2px;
}
.par-tope #tfTope { width: 92px; text-align: right; }
.par-y, .par-unidad { font-size: var(--fs-body-s); color: var(--muted); }

/* La casilla depende del desplegable de encima: sangrada se ve que es suya. */
.modal-form .switch.sangrada { margin: 2px 0 0 2px; }

/* Salir va al final y en peso de texto: es la única acción de aquí que
   deshace algo, y no compite con «Guardar». */
.cuenta-salir {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  padding-top: 16px;
  border-top: 1px solid var(--hair);
}

/* La otra puerta, en el diálogo de entrar. Quien llega ahí a probar una
   contraseña que no tiene es justo quien necesita pedirla. */
.login-pedir {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--hair);
  font-size: var(--fs-body-s);
  color: var(--muted);
}

/* Pedir una cuenta (2d del diseño). */
.pedir-caja { max-width: 560px; }
.pedir-body { display: grid; gap: 16px; }
.pedir-lede {
  margin: 0;
  font-size: var(--fs-body-s);
  line-height: 1.55;
  color: var(--muted);
  max-width: 62ch;
}
.pedir-campos { display: grid; gap: 14px; }
.campo { display: grid; gap: 6px; }
.campo > span:first-child {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.campo input, .campo textarea {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--hair);
  border-radius: 4px;
  background: var(--field);
  color: var(--ink);
  font: 400 var(--fs-input) var(--font-sans);
}
.campo textarea { resize: vertical; line-height: 1.5; }
.campo input.mal { border-color: var(--accent); }
.campo-pie { font-size: var(--fs-meta); color: var(--muted); line-height: 1.45; }
.campo-pie-doble { display: flex; justify-content: space-between; gap: 12px; }
.pedir-sugerencias { display: flex; flex-wrap: wrap; gap: 8px; }
.pedir-acc { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.pedir-nota {
  margin: 0;
  font-size: var(--fs-meta);
  line-height: 1.5;
  color: var(--muted);
  max-width: 62ch;
}
.pedir-nota.mal { color: var(--accent-txt); }
.pedir-hecha { display: grid; gap: 12px; }
.pedir-hecha h3 { margin: 0; font-size: var(--fs-subhead); letter-spacing: -0.025em; }
.pedir-hecha p { margin: 0; font-size: var(--fs-body-s); line-height: 1.55; }
.pedir-hecha .meta { color: var(--muted); }
.pedir-hecha .meta a { color: var(--accent-txt); }
.pedir-enlace { display: block; margin-top: 6px; font-family: var(--font-mono); font-size: 12px; word-break: break-all; user-select: all; }

/* La búsqueda que acaba de terminar (2a·3 del diseño). Va donde estaba su
   barra de progreso, encima de las guardadas, porque es donde estabas mirando. */
.terminada {
  display: grid;
  /* `.saved` es una rejilla de tres columnas y esta ficha va apilada: sin
     reponer la columna, el titular, el resumen y las filas salian uno al lado
     del otro y la ficha se leia en diagonal. */
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--surface);
  padding: 16px 18px;
}
.term-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.term-head b { font-weight: 600; font-size: var(--fs-body-s); }
.term-desde {
  flex: none;
  font: 600 var(--fs-meta) var(--font-mono);
  color: var(--deep);
}
.term-meta { font-size: var(--fs-meta); color: var(--muted); }
.term-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 14px;
  align-items: center;
  padding: 10px 0;
  border-top: 1px solid var(--hair);
}
.term-que { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.term-iata {
  flex: none;
  font: 500 var(--fs-data-s) / 1 var(--font-mono);
  color: var(--muted);
  border: 1px solid var(--line);
  padding: 3px 6px;
  border-radius: 3px;
  letter-spacing: 0.1em;
}
.term-ciudad {
  font-weight: 600;
  font-size: var(--fs-city-s);
  letter-spacing: -0.02em;
  /* El nombre largo se recorta él; lo que no puede es empujar al precio fuera. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.term-cia { font: 400 var(--fs-meta) var(--font-mono); color: var(--muted); }
.term-precio { font: 600 var(--fs-city-s) var(--font-mono); }
.term-acc {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  border-top: 1px solid var(--hair);
  padding-top: 12px;
}

/* En el móvil la compañía se cae: entre el destino y el precio, es lo único
   que se puede mirar después. */
@media (max-width: 560px) {
  .term-cia { display: none; }
}

/* La hoja de alojamiento mientras busca (2c del diseño). Los huecos barriendo
   no son adorno: dicen que van a salir FILAS y cuántas caben, así que al llegar
   el resultado la hoja no salta de vacía a llena. Con una sola línea de texto
   quedaba un palmo de nada debajo y parecía que se había colgado. */
.buscando { display: grid; gap: 14px; }
.buscando-linea {
  margin: 0;
  display: flex;
  align-items: center;
  font: 400 var(--fs-meta) var(--font-mono);
  color: var(--muted);
}
.esqueleto { display: grid; gap: 8px; }
.esqueleto i {
  height: 74px;
  border: 1px solid var(--hair);
  border-radius: 4px;
  background: linear-gradient(90deg, transparent, var(--surface2), transparent);
  background-size: 200% 100%;
  animation: tf-barrer 1.4s infinite linear;
}
.buscando-nota, .party-nota {
  margin: 0;
  font-size: var(--fs-body-s);
  line-height: 1.55;
  color: var(--muted);
  max-width: 62ch;
}
.party-nota { font-size: var(--fs-meta); line-height: 1.45; }

/* Quien prefiere no ver animaciones tampoco quiere tres barras barriendo. */
@media (prefers-reduced-motion: reduce) {
  .esqueleto i { animation: none; background: var(--surface2); }
}

/* UNA LINEA POR VIAJE, con su curva pegada al lado: de eso habla la fila.
   Antes cada cambio era una ficha con caja, titular, precio a cuerpo de
   portada, sello y tres botones. Lo que se HACE con el viaje —seguirlo,
   compartirlo, buscar cama— ya está en la lista de abajo; aquí solo hace falta
   saber qué ha cambiado, cuál, cuánto y cómo viene. */
.cambios { list-style: none; margin: 0; padding: 0; display: grid; }

.cambio {
  display: grid;
  grid-template-columns: 64px minmax(8ch, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 9px 0;
  border-top: 1px solid var(--hair);
}
.cambio:first-child { border-top: 0; }
.cambio-curva { line-height: 0; }
.cambio-sitio {
  font-weight: 600;
  font-size: var(--fs-city-s);
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cambio-precio {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font: 400 var(--fs-data) var(--font-mono);
}
.cambio-precio s { color: var(--muted); }
.cambio-precio b { font-weight: 600; }
.cambio-dif {
  font: 400 var(--fs-data) var(--font-mono);
  font-variant-numeric: tabular-nums;
  min-width: 6ch;
  text-align: right;
}
.cambio.baja .cambio-dif { color: var(--deep); }
.cambio.sube .cambio-dif { color: var(--accent-txt); }
.cambio-ver {
  font: 400 var(--fs-meta) var(--font-mono);
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cambio-ver:hover { color: var(--accent-txt); }

/* En el móvil la fila se parte en dos renglones antes que comerse el nombre, y
   la curva se queda al lado de los dos: sigue siendo de lo que habla la fila. */
@media (max-width: 560px) {
  .cambio {
    grid-template-columns: 64px minmax(0, 1fr) auto;
    gap: 2px 12px;
    padding: 11px 0;
  }
  .cambio-curva { grid-area: 1 / 1 / 3 / 2; align-self: center; }
  .cambio-sitio { grid-area: 1 / 2 / 2 / 3; }
  .cambio-dif { grid-area: 1 / 3 / 2 / 4; }
  .cambio-precio { grid-area: 2 / 2 / 3 / 3; }
  .cambio-ver { grid-area: 2 / 3 / 3 / 4; text-align: right; }
}

.aviso-pie {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 20px 16px;
  font-size: var(--fs-meta);
  color: var(--muted);
}

/* La curva de precio. */
.historia { display: flex; align-items: center; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.historia b { font: 600 var(--fs-data) var(--font-mono); }
.historia span { display: block; font-size: var(--fs-ui-s); color: var(--muted); }
.historia.barato span { color: var(--deep); }
.historia.caro span { color: var(--accent-txt); }
.spark-cell svg, .historia svg { display: block; }
/* La curva se pintaba con la tinta del texto: un trazo blanco tan fuerte como
   el titular de al lado. Va con el color de lo que cuenta —verde si ha bajado,
   apagado si ha subido— y sobre una caja con su propio fondo, para que se lea
   como un gráfico y no como un garabato. */
.spark {
  color: var(--muted);
  background: var(--surface2);
  border: 1px solid var(--hair);
  border-radius: var(--r-tag);
  padding: 2px 4px;
  box-sizing: content-box;
}
.spark.baja { color: var(--deep); }
.spark.sube { color: var(--accent-txt); }
.ticket .spark { background: none; border-color: var(--hero-hair); }
/* Dentro de la ficha de cambio, la caja sobra: la ficha ya es la caja, y dos
   marcos anidados en 272 px es un marco de más. */
.cambio .spark { background: none; border-color: transparent; padding: 0; }
/* La curva va del color del CAMBIO, no del de la serie entera. `sparkline` se
   pinta según el primer punto contra el último, así que un vuelo que lleva
   semanas bajando y hoy sube salía con la curva verde al lado de un «+9 €»
   naranja: la misma fila diciendo dos cosas. Aquí manda lo que ha pasado. */
.cambio.baja .spark { color: var(--deep); }
.cambio.sube .spark { color: var(--accent-txt); }
.cambio-nota { font-size: var(--fs-ui-s); color: var(--muted); }
.sello-dif { font: 500 var(--fs-meta) var(--font-mono); color: var(--accent-txt); }

/* ==========================================================================
   EL PIE
   ========================================================================== */

.foot {
  border-top: 1px solid var(--line);
  background: var(--paper);
  color: var(--muted);
}
.foot-in {
  max-width: var(--ancho);
  margin: 0 auto;
  padding: 20px var(--pad-page);
  display: flex;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  font: 400 var(--fs-meta) var(--font-mono);
  letter-spacing: 0.04em;
}
.foot a { color: var(--accent-txt); }
.build { opacity: 0.6; }
#frescura { white-space: normal; }
@media (min-width: 460px) { #frescura { white-space: nowrap; } }
#frescura.viejo { color: var(--accent-txt); }
.aviso-pie a { color: var(--accent-txt); }

/* ==========================================================================
   DIÁLOGOS
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  padding: 20px;
  background: var(--velo);
  animation: tf-fade var(--t) var(--ease);
}
.modal-caja {
  width: min(560px, 100%);
  max-height: 86vh;
  /* Un modal más largo que la pantalla tiene que poder rodar: sin esto, lo que
     cayera por debajo del 86 % del alto quedaba fuera y no había forma de
     llegar —ni con el dedo ni con el tabulador— al último botón. */
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 24px 26px 28px;
  animation: tf-rise var(--t-med) var(--ease);
}
.modal-caja.estrecha { width: min(440px, 100%); }
.modal-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 14px;
}
/* En un modal que rueda, la cabecera se queda arriba: el «cerrar» tiene que
   estar a mano sin volver al principio. El -24px es el padding de la caja. */
.modal-caja > .modal-head {
  position: sticky;
  top: -24px;
  z-index: 2;
  margin-top: -24px;
  padding-top: 24px;
  background: var(--surface);
}
.modal-head h2 { font-size: var(--fs-subhead); }
.modal-head button, [data-cerrar] {
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 400 var(--fs-ui-s) var(--font-mono);
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.modal-head button:hover, [data-cerrar]:hover { color: var(--accent-txt); border-color: var(--accent); }

.modal-form { display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
/* Un segundo formulario dentro del mismo modal —las preferencias arriba y la
   contraseña abajo— necesita su propia frontera: si no, los dos parecen uno y
   el botón de "Guardar" del de arriba parece que también vale para el de
   abajo. */
.tf-bloque {
  margin-top: 6px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.tf-bloque h3 { font-size: var(--fs-city); letter-spacing: -0.025em; }
.modal-form label {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
/* OJO CON EL `select`. Esta regla solo decía `input`, así que los dos desplegables
   de las preferencias —cada cuánto quieres los chollos y el parte de lo que
   sigues— se quedaban con el aspecto que les da el navegador: fondo
   `rgb(239,239,239)`, casi blanco, heredando el color de texto de la página, que
   también es casi blanco. Blanco sobre blanco: se veía la caja y no se leía lo
   que ponía dentro. El resto de la web ya los pinta (`.field select`,
   `.finder-form select`); aquí faltaban. */
.modal-form input, .modal-form select, .token-box input, #destSearch {
  border: 1px solid var(--hair);
  background: var(--field);
  color: var(--ink);
  border-radius: var(--r);
  padding: 10px 12px;
  font-size: var(--fs-input);
  width: 100%;
}
.modal-form input:hover, .modal-form select:hover,
.token-box input:hover, #destSearch:hover { border-color: var(--muted); }

/* Dentro de un formulario, esto es una casilla con su frase al lado, no uno de
   los chips de la barra de filtros. Sin deshacer lo de `.switch` y lo de
   `.modal-form label`, «Solo cuando haya algo nuevo que contar» salía como una
   pastilla de mono en mayúsculas y con la casilla en `opacity: 0`: una frase
   entera gritada, dentro de una caja, sin nada que indicara que se marca. */
.modal-form .switch {
  display: flex;
  gap: 10px;
  align-items: center;
  border: none;
  border-radius: 0;
  padding: 2px 0;
  min-height: 0;
  font: 400 var(--fs-body-s) / 1.4 var(--font-sans);
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  white-space: normal;
}
.modal-form .switch input {
  position: static;
  opacity: 1;
  width: 18px;
  height: 18px;
  flex: none;
  accent-color: var(--accent);
}
.modal-form .switch:has(input:checked) { background: none; color: var(--ink); }
.modal-form .switch:hover { border: none; color: var(--ink); }
.modal-form .meta { margin: 0 0 4px; font-size: var(--fs-ui-s); color: var(--muted); }
.modal-form .btn { margin-top: 14px; }
/* La puerta del panel lleva `.finder-form` y `.estrecha-form` a la vez, y son
   dos maquetaciones distintas: la primera es la rejilla de un píxel de las
   herramientas y la segunda una columna de campos normales. Aquí manda la
   segunda, y hay que deshacer la primera entera —el fondo, el borde y las
   celdas— o los campos salen como bandas sin caja donde escribir. */
.finder-form.estrecha-form {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  background: none;
  border: none;
}
.estrecha-form { display: grid; gap: 10px; }
.estrecha-form .field,
.estrecha-form label {
  background: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.estrecha-form .field label,
.estrecha-form > label > span {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.estrecha-form input {
  border: 1px solid var(--hair);
  background: var(--field);
  border-radius: var(--r);
  padding: 10px 12px;
  font-size: var(--fs-input);
  font-weight: 400;
  width: 100%;
}
.estrecha-form input:hover { border-color: var(--muted); }
.estrecha-form .finder-lede { margin: 0 0 4px; }
.estrecha-form .btn { justify-self: start; margin-top: 4px; }
/* Una contraseña no necesita mil píxeles de campo: un renglón de lectura basta
   y así el foco cae donde tiene que caer. */
#puerta .finder-body { max-width: 460px; }
.campo-clave { position: relative; display: flex; }
.campo-clave input { padding-right: 84px; }
.ver-clave {
  position: absolute;
  right: 6px; top: 50%;
  transform: translateY(-50%);
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 400 var(--fs-ui-s) var(--font-mono);
  cursor: pointer;
}
.ver-clave:hover { color: var(--ink); border-color: var(--ink); }
/* La pildora de "ver" mide 28 px de alto y tiene que seguir midiendo eso: es un
   detalle dentro del campo, no un boton de la pagina. Lo que se agranda es el
   area de toque, con el mismo truco que `.fav` y `.flap-boton` — un `::after`
   invisible de 44 px centrado encima. */
.ver-clave::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: max(100%, var(--tap-min));
  height: max(100%, var(--tap-min));
  transform: translate(-50%, -50%);
}

.dest-list { overflow-y: auto; padding-bottom: 4px; }
.pais { border-top: 1px solid var(--hair); padding: 12px 0; }
.pais-todo {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 8px 0;
  min-height: var(--tap-min);
  border: none;
  background: none;
  color: var(--muted);
  font: 400 var(--fs-caps-l) var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}
.pais-todo:hover { color: var(--accent-txt); }
.ciudades { display: flex; flex-wrap: wrap; gap: 6px; }
.ciudad {
  padding: 8px 12px;
  min-height: var(--tap-min);
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  background: transparent;
  font-size: var(--fs-ui);
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.ciudad:hover { border-color: var(--accent); color: var(--accent-txt); }
.ciudad .codigo { font: 400 var(--fs-meta) var(--font-mono); color: var(--muted); margin-left: 6px; }

/* ==========================================================================
   EL PANEL DE ALOJAMIENTO
   ========================================================================== */

.panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: min(520px, 100%);
  z-index: 45;
  background: var(--surface);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  animation: tf-entrar var(--t-panel) var(--ease);
}
@keyframes tf-entrar { from { transform: translateX(100%); } }
.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--line);
}
.panel-head h2 { font-size: var(--fs-subhead); }
.panel-dates { margin: 4px 0 0; font: 400 var(--fs-data) var(--font-mono); color: var(--muted); }
#panelClose {
  position: relative;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: 400 var(--fs-ui-s) var(--font-mono);
  cursor: pointer;
}
#panelClose:hover { color: var(--accent-txt); border-color: var(--accent); }
#panelClose::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: max(100%, var(--tap-min));
  height: max(100%, var(--tap-min));
  transform: translate(-50%, -50%);
}
.panel-body { overflow-y: auto; padding: 20px 22px 40px; display: grid; gap: 14px; }
.backdrop { position: fixed; inset: 0; z-index: 44; background: var(--velo); }

/* Dos columnas: lo que es a la izquierda, lo que cuesta a la derecha. El
   precio total es lo que decide, así que va alineado y en cifra grande, no
   como una línea más de texto corrido. */
.stay {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 14px;
  background: var(--surface2);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px 14px;
  align-items: start;
}
.stay > div:first-child { min-width: 0; }

/* LA ZONA RECOMENDADA. Va arriba del panel, antes de la lista: es lo que se
   decide primero — en qué barrio te quedas— y después ya se elige la casa. */
.zona-rec {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-left: 2px solid var(--deep);
  background: var(--surface2);
  display: grid;
  gap: 2px;
  font-size: var(--fs-body-s);
}
.zona-rec b { color: var(--ink); font-weight: 600; }
.zona-rec span { color: var(--muted); font-family: var(--font-mono); font-size: var(--fs-meta); }
.zona-rec small { color: var(--muted); font-size: var(--fs-meta); }

/* LAS FOTOS DEL ALOJAMIENTO.

   Con foto, la ficha pasa a tres columnas: la tira de fotos, el texto y el
   precio. Sin ella se queda como estaba — una ficha con un hueco gris donde
   debería ir una casa es peor que una ficha sin foto.

   El carrusel es CSS y nada más: `scroll-snap` en una tira horizontal. Con el
   dedo en el móvil y con la rueda o la barra en el escritorio. Cero JavaScript
   y cero estado que mantener. */
.stay.con-foto {
  grid-template-columns: 132px minmax(0, 1fr) auto;
}
.stay-fotos {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  border-radius: calc(var(--r) - 4px);
  position: relative;
  /* Sin esto la tira empuja la rejilla al cargar las imágenes. */
  width: 132px;
  scrollbar-width: none;
}
.stay-fotos::-webkit-scrollbar { display: none; }
.stay-fotos img {
  flex: 0 0 100%;
  width: 132px;
  /* El hueco, reservado antes de que la foto llegue: si no, la lista salta
     entera cada vez que carga una. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  scroll-snap-align: start;
  background: var(--surface);
  display: block;
}
/* Cuántas hay, para que se sepa que se puede deslizar. */
.stay-cuantas {
  position: absolute;
  left: 6px;
  bottom: 6px;
  padding: 2px 6px;
  border-radius: var(--r-pill);
  background: var(--code-bg);
  color: var(--paper);
  font: 400 var(--fs-meta) var(--font-mono);
  pointer-events: none;
}

/* En el móvil el panel es estrecho: la foto va arriba y a todo lo ancho, que
   es donde de verdad se ve algo. */
@media (max-width: 560px) {
  .stay.con-foto { grid-template-columns: minmax(0, 1fr) auto; }
  .stay-fotos,
  .stay-fotos img { width: 100%; }
  .stay-fotos {
    grid-column: 1 / -1;
    margin-bottom: 4px;
  }
  .stay-fotos img { aspect-ratio: 16 / 9; }
}
.stay .amount-s {
  text-align: right;
  font: 600 var(--fs-cifra) var(--font-mono);
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.stay .amount-s small {
  display: block;
  font: 400 var(--fs-meta) var(--font-sans);
  color: var(--muted);
  letter-spacing: 0;
}
.stay .name { font-weight: 600; font-size: var(--fs-city-s); }
.stay .meta { font-size: var(--fs-ui-s); color: var(--muted); }
.stay .cifra { font: 600 var(--fs-cifra) var(--font-mono); }
/* En la banda de cambios, el sello va a la izquierda y los botones a la
   derecha: el motivo primero, la acción después. */

/* --- los estados de una búsqueda ------------------------------------------
   Lanzar un barrido son ocho minutos. Lo que se ve mientras tanto no puede ser
   una rueda girando: tiene que decir por dónde va, que se puede cerrar la
   pestaña, y —cuando la búsqueda ya estaba hecha— que NO se ha lanzado nada. */
.lanzada { position: relative; }
.lanzada.ya-hecha { border-left: 2px solid var(--deep); }
.lanzada-hora {
  grid-column: 2 / -1;
  justify-self: end;
  align-self: start;
  font: 400 var(--fs-meta) var(--font-mono);
  color: var(--muted);
  white-space: nowrap;
}
.lanzada-hora.deep { color: var(--deep); }
.lanzada-barra {
  grid-column: 1 / -1;
  height: 6px;
  background: var(--hair);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.lanzada-barra i {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width var(--t-med) var(--ease);
}
.lanzada-pie {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font: 400 var(--fs-meta) var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--muted);
}
.lanzada-nota {
  grid-column: 1 / -1;
  margin: 0;
  max-width: 64ch;
  font-size: var(--fs-meta);
  line-height: 1.45;
  color: var(--muted);
}
.lanzada-acc {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  border-top: 1px solid var(--hair);
  padding-top: 12px;
}
.meta.aviso { color: var(--accent-txt); }

/* El sello dice por qué esa cama está donde está: «el más barato», «el más
   céntrico», «hotel». Verde cuando es un motivo para elegirla; gris cuando solo
   la describe. */
.sello {
  display: inline-block;
  margin-top: 8px;
  font: 400 var(--fs-meta) var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--hair);
  border-radius: 3px;
  padding: 2px 6px;
}
.sello.bueno { color: var(--deep); border-color: var(--deep); }

.seguir-buscando { border-top: 1px solid var(--hair); padding-top: 14px; display: grid; gap: 8px; }
.seguir-buscando h3 {
  margin: 0;
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.seguir-pills { display: flex; flex-wrap: wrap; gap: 8px; }

.escapada-compartir {
  border-top: 1px solid var(--hair);
  padding-top: 14px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.escapada-compartir span { font-size: var(--fs-meta); color: var(--muted); max-width: 30ch; }

.stay .insignia {
  justify-self: start;
  font: 400 var(--fs-meta) var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--deep);
  border: 1px solid var(--deep);
  border-radius: var(--r-tag);
  padding: 2px 6px;
}
.total {
  border: 1px solid var(--accent);
  border-radius: var(--r);
  padding: 16px;
  display: grid;
  gap: 6px;
}
.total-head { font: 400 var(--fs-caps-l) var(--font-mono); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--muted); }
.total-figure { font: 600 var(--fs-figure) var(--font-mono); letter-spacing: -0.03em; }
/* «132 € por persona»: la cifra en mono y la coletilla en texto corrido, que
   pegada y monoespaciada salía «132 €por persona» y parecía una palabra. */
.total-figure span {
  margin-left: 8px;
  font: 400 var(--fs-ui-s) var(--font-sans);
  letter-spacing: 0;
  color: var(--muted);
}
.total-break { font-size: var(--fs-ui-s); color: var(--muted); }
/* El monoespaciado va bien para una línea corta de estado ("Buscando…"), pero
   un párrafo de tres renglones así se lee como un volcado de consola. El texto
   corrido vuelve a la de leer. */
.wait, .status {
  font: 400 var(--fs-data) var(--font-mono);
  color: var(--muted);
  display: grid;
  gap: 14px;
  justify-items: start;
  align-items: center;
}
.wait p, .status p {
  margin: 0;
  max-width: 62ch;
  font: 400 var(--fs-body-s) / 1.55 var(--font-sans);
}
.wait strong, .status strong { color: var(--ink); font-weight: 600; }
/* El "¿cuántos viajáis?" de la hoja de camas no vive dentro de un formulario
   con rejilla, así que su caja hay que ponérsela aquí. */
.panel .party {
  display: flex;
  align-items: center;
  gap: 12px;
  font: 400 var(--fs-body-s) var(--font-sans);
  color: var(--ink);
}
.panel .party input {
  width: 66px;
  padding: 9px 10px;
  border: 1px solid var(--hair);
  border-radius: var(--r);
  background: var(--field);
  color: var(--ink);
  font: 400 var(--fs-input) var(--font-mono);
  text-align: center;
}
.panel .party input:hover, .panel .party input:focus { border-color: var(--muted); }
.link-tag { font-size: var(--fs-ui-s); color: var(--accent-txt); }
.rescan { justify-self: start; }
.perdido { color: var(--muted); font-size: var(--fs-body-s); }
.perdido-ref { font-family: var(--font-mono); }

/* ==========================================================================
   EL CALENDARIO
   ========================================================================== */

/* Ojo con los selectores: `calendario.js` pinta `.meses > .mes > .semana` (las
   iniciales de los días) y `.dias` (los botones). La hoja anterior buscaba los
   botones dentro de `.semana`, no los encontraba nunca y los días salían con
   el gris de fábrica del navegador, sin rejilla y sin número legible. */
.cal {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  padding: 14px;
  max-height: 340px;
  overflow-y: auto;
}
.meses {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
  gap: 20px 24px;
}
.mes { min-width: 0; }
.mes h4 {
  font: 400 var(--fs-caps-l) var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.semana, .dias { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.semana {
  margin-bottom: 4px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--hair);
}
.semana i {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  font-style: normal;
  letter-spacing: 0;
  text-align: center;
  color: var(--muted);
}
.dia {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--ink);
  font: 400 var(--fs-ui-s) var(--font-mono);
  border-radius: var(--r-tag);
  cursor: pointer;
  transition: background var(--t) var(--ease), color var(--t) var(--ease);
}
.dia:hover:not([disabled]), .dia:focus-visible:not([disabled]) { background: var(--surface2); }
.dia.extremo { background: var(--accent); color: var(--sobre-acento); }
.dia.dentro { background: var(--hair); }
.dia[disabled] { color: var(--hair); cursor: default; }

/* ==========================================================================
   EL TEST DE DESTINOS
   ========================================================================== */

.quiz-caja { width: min(560px, 100%); }
.quiz-head h2 { font-size: var(--fs-subhead); }
/* La barra de pasos, con el capítulo delante. Diez casillas seguidas se leen
   como una cuesta; "El viaje · 2 de 4" las parte en tres tramos cortos. */
.quiz-progreso { display: grid; gap: 7px; margin-top: -8px; }
.quiz-capitulo {
  font: 400 var(--fs-caps) var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.quiz-capitulo i { font-style: normal; opacity: 0.5; margin: 0 2px; }
.quiz-casillas { display: flex; gap: 4px; }
.quiz-paso { flex: 1; height: 3px; background: var(--hair); transition: background var(--t-med) var(--ease); }
.quiz-paso.hecho { background: var(--ink); }
.quiz-paso.ahora { background: var(--accent); }

/* Lo que has contestado, devuelto con tus palabras. Va en monoespaciado y en
   una caja aparte porque es una CITA de lo que pediste, no texto nuestro. */
.quiz-tuyo {
  margin: 0 0 4px;
  padding: 10px 12px;
  border-left: 2px solid var(--accent);
  background: var(--surface2);
  font: 400 var(--fs-data) / 1.5 var(--font-mono);
  color: var(--ink);
}

.quiz-cuerpo { overflow-y: auto; min-height: 0; }
.quiz-cuenta {
  margin: 0 0 6px;
  font: 400 var(--fs-caps) var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.quiz-pregunta { margin: 0 0 6px; font-size: var(--fs-subhead); }
.quiz-pie, .quiz-aviso { margin: 0 0 16px; font-size: var(--fs-body-s); line-height: var(--lh-body); color: var(--muted); }
.quiz-aviso { color: var(--accent-txt); }

.quiz-opciones { display: grid; }
.quiz-opcion {
  display: flex;
  align-items: baseline;
  gap: 12px;
  width: 100%;
  padding: 14px 2px;
  min-height: var(--tap-min);
  text-align: left;
  background: none;
  border: 0;
  border-top: 1px solid var(--hair);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  transition: color var(--t) var(--ease);
}
.quiz-opciones .quiz-opcion:last-child { border-bottom: 1px solid var(--hair); }
.quiz-opcion:hover, .quiz-opcion:focus-visible { color: var(--accent-txt); }
.quiz-opcion:hover .quiz-tecla, .quiz-opcion:focus-visible .quiz-tecla { border-color: var(--accent); color: var(--accent-txt); }
.quiz-tecla {
  flex: none;
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  padding: 3px 5px;
  border: 1px solid var(--line);
  border-radius: var(--r-tag);
  color: var(--muted);
  font: 400 var(--fs-meta) / 1 var(--font-mono);
}
.quiz-texto { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.quiz-texto b { font-weight: 600; font-size: var(--fs-city-s); letter-spacing: -0.02em; }
.quiz-texto small { font-size: var(--fs-body-s); color: var(--muted); }
.quiz-atras {
  margin-top: 16px;
  padding: 8px 2px;
  min-height: var(--tap-min);
  background: none;
  border: 0;
  color: var(--muted);
  font: 400 var(--fs-ui-s) var(--font-mono);
  cursor: pointer;
}
.quiz-atras:hover, .quiz-atras:focus-visible { color: var(--accent-txt); }

.quiz-billetes { display: grid; }
.quiz-billete { border-top: 1px solid var(--hair); padding: 18px 0; }
.quiz-billetes .quiz-billete:last-child { border-bottom: 1px solid var(--hair); }
.quiz-billete-top { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
.quiz-billete .dest-cell { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; }
.quiz-billete .city { font-size: var(--fs-city); font-weight: 700; letter-spacing: var(--ls-title); }
.quiz-billete .country { font: 400 var(--fs-meta) var(--font-mono); text-transform: lowercase; letter-spacing: 0.06em; }
.quiz-precio { text-align: right; display: flex; flex-direction: column; gap: 2px; }
.quiz-precio .cifra, .quiz-precio .amount { font: 600 var(--fs-cifra) var(--font-mono); letter-spacing: -0.02em; }
.quiz-precio .pax-nota { color: var(--muted); }
.quiz-cuando { margin: 10px 0 0; font: 400 var(--fs-data) var(--font-mono); color: var(--muted); }
.quiz-porque { margin: 10px 0 0; font-size: var(--fs-body-s); line-height: var(--lh-body); color: var(--ink); }
.quiz-acciones { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.quiz-estado { margin: 10px 0 0; font: 400 var(--fs-data) var(--font-mono); color: var(--deep); }
.quiz-estado:empty { display: none; }
.quiz-estado a { color: var(--accent-txt); }

/* ==========================================================================
   EL PANEL DE ADMINISTRACIÓN
   ========================================================================== */

.cuenta-row { grid-template-columns: 92px 1fr auto; align-items: center; }
.cuenta-row.apagada { opacity: 0.5; }
.cuenta-row.sin-acceso { border-left: 2px solid var(--accent); }
.aviso-acceso { display: block; padding-top: 4px; font: 400 var(--fs-meta) var(--font-mono); }
.btn.urge { color: var(--accent-txt); border-color: var(--accent); }
.cuenta-row .favacc { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.cuenta-row .detalle { grid-column: 1 / -1; }
.cuenta-detalle { border-top: 1px solid var(--hair); margin-top: 12px; padding-top: 14px; }
.detalle-cols { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.detalle-cols h4 {
  margin: 0 0 8px;
  font: 400 var(--fs-caps) var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.lista-seca { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.lista-seca li { font: 400 var(--fs-data-s) / 1.6 var(--font-mono); color: var(--muted); }
.lista-seca b { color: var(--ink); font-weight: 500; }
.lista-seca .apagado { color: var(--muted); opacity: 0.6; }
.ojo { color: var(--accent-txt); }
.token-box { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.token-box a { color: var(--accent-txt); }
.token-status { margin: 12px 0 0; font: 400 var(--fs-data-s) var(--font-mono); color: var(--deep); }

/* ==========================================================================
   RESPONSIVE
   Los mismos cortes que el prototipo: 940 para las dos columnas, 760 para la
   tabla, que es donde una fila de cinco columnas deja de caber.
   ========================================================================== */

@media (max-width: 940px) {
  .masthead { grid-template-columns: 1fr; gap: 30px; }
  .ticket { grid-template-columns: 1fr; }
  .ticket-der { border-left: none; border-top: 1px solid var(--hero-hair); }
  .panels { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  :root { --pad-page: 16px; }
  .board-head { display: none; }

  /* La barra en un móvil estrecho. Se cae por este orden: primero el nav y el
     punto de "en vivo" (arriba), luego las iniciales MAD —que son decoración,
     mientras que el `?` de al lado es un botón— y por último el nombre de la
     cuenta, que deja la inicial. Lo que queda cabe en 320 px, que es el ancho
     del móvil más estrecho que sigue en la calle. */
  /* EL NAV NO SE ESCONDE. Estaba en `display: none` por debajo de 760 px, así
     que desde un móvil no había forma de llegar a «buscar» ni a «vuelos que
     sigues»: la única puerta a la herramienta completa era rellenar el
     formulario compacto y enviarlo. Baja a una segunda fila de la barra, que
     ocupa 40 px y es lo que cuesta que la web se pueda recorrer. */
  .topbar-in { gap: 8px; padding: 9px var(--pad-page) 7px; flex-wrap: wrap; }
  .zonas {
    order: 9;
    flex-basis: 100%;
    /* Cinco zonas desde que el Interrail tiene página: con 18 px, «Interrail»
       se quedaba cortado por el borde en un móvil de 390. */
    gap: 14px;
    margin: 0 -2px -2px;
    padding: 2px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .zonas::-webkit-scrollbar { display: none; }
  .zona { padding: 4px 0; }
  .flap-boton { margin-left: 0; padding: 8px 10px; font-size: 12px; }
  .flap-txt-largo { display: none; }
  .flap-txt-corto { display: inline; }
  /* LOS FILTROS EN MÓVIL. Antes se veían los nueve controles a la vez y el
     primer vuelo quedaba fuera de pantalla. Ahora arriba solo hay dos cosas
     —buscador y "Filtros · N"— y el resto vive en una hoja que sube desde
     abajo. La hoja NO es otro bloque: es este mismo `.controls`, con los
     mismos campos y los mismos oyentes, con otra maquetación. */
  .filtros-movil { display: flex; gap: 8px; align-items: center; }
  .hoja-solo { display: flex; }
  #filtrosFondo { z-index: 40; }

  /* OJO con el selector: `.controls` no es solo la barra de filtros del feed
     —el panel de administración la reusa para su fila de botones—, así que
     convertirla en hoja a secas dejaba el panel SIN «crear cuenta», sin
     «cambiar la contraseña del panel» y sin «cerrar» en cualquier móvil. La
     hoja es la que lleva `.hoja`. */
  .controls.hoja {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 41;
    display: none;
    /* Rejilla y no columna: los dos interruptores de abajo caben en un mismo
       renglón, que es como se leen (dos ajustes, no dos secciones). */
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: 18px 10px;
    max-height: 88vh;
    overflow: auto;
    padding: 16px 16px calc(20px + env(safe-area-inset-bottom));
    border: none;
    border-top: 1px solid var(--line);
    border-radius: 16px 16px 0 0;
    background: var(--surface);
    animation: tf-rise var(--t-med) var(--ease);
  }
  .controls.hoja.abierta { display: grid; }
  .controls.hoja > *:not(.switch) { grid-column: 1 / -1; }
  .controls.hoja .field { flex: none; max-width: none; }
  /* Por debajo de 16 px iOS hace zoom al enfocar un campo. */
  .controls.hoja .field input, .controls.hoja .field select { font-size: 16px; }
  /* El buscador ya está en la barra de arriba. */
  .controls.hoja .field.grow { display: none; }
  .controls.hoja .switch:first-of-type { margin-left: 0; }
  .controls.hoja .switch { justify-content: center; }
  /* Continente y ordenar se pulsan como fichas; el `select` sigue mandando. */
  .controls.hoja .field:has(.hoja-chips) select { display: none; }
  .hoja-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }

  .cuenta, #tfCuenta { padding: 10px 12px; }
  /* Con sesión el botón se queda en la inicial; sin ella la palabra "entrar"
     se queda, porque un círculo a secas no dice a dónde lleva. */
  .cuenta.dentro .cuenta-txt { display: none; }
  .cuenta:not(.dentro) > b { display: none; }

  /* DENSIDAD. A 375 px el clamp del titular deja 40 px, que es demasiado. */
  /* OJO con el 0: el handoff traía `28px 0 22px` y ese cero se lleva por
     delante `--pad-page`, así que el titular y la entradilla quedaban pegados
     al borde de la pantalla mientras el resto de la página sí tenía margen. */
  .masthead { padding: 28px var(--pad-page) 22px; }
  .masthead h1 { font-size: 36px; }
  .stats dd { font-size: 21px; }
  .ticket-izq, .ticket-der { padding: 18px; }

  /* La fila pasa de tres columnas a dos: arriba destino y precio, debajo las
     fechas a todo el ancho —ya no compiten con la compañía— y abajo la
     compañía con el botón de seguir, que es donde tiene sitio para su
     palabra y donde llega el pulgar. */
  .brow {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 7px 12px;
    padding: 14px 16px;
    align-items: start;
  }
  /* El nombre del sitio es lo que se busca con la vista: el país baja debajo
     en vez de robarle sitio y dejar "Berg…" y "It…". */
  .dest-cell { flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
  .brow > .dest-cell .country { flex-basis: 100%; }
  .brow > .dest-cell { grid-area: 1 / 1 / 2 / 2; }
  .brow > .price { grid-area: 1 / 2 / 2 / 3; }
  .brow > .when { grid-area: 2 / 1 / 3 / 3; white-space: normal; }
  .brow > .airline { grid-area: 3 / 1 / 4 / 2; align-self: center; }
  .brow > .fav {
    grid-area: 3 / 2 / 4 / 3;
    justify-self: end;
    align-self: center;
    width: auto;
    height: auto;
    padding: 9px 14px;
  }
  .brow > .fav .fav-txt { display: inline; }
  .brow > .brow-detail { grid-area: 4 / 1 / 5 / 3; }
  /* En 390 px la fila ya son tres renglones: un cuarto botón la haría crecer
     un 40 % con 120 viajes en la lista. Aquí se comparte abriendo la fila,
     que es un toque y lleva también «al calendario». */
  .brow > .compartir-cell { display: none; }

  /* La cabecera de la banda se reparte en tres —rúbrica, titular, «Enterado»—
     y a lo ancho eso funciona. Envuelta en 390 px salía la rúbrica abajo a la
     izquierda, el titular arriba a la derecha y el botón en un tercer renglón:
     se leía en zigzag. Apilada se lee en el orden en que está escrita. */
  .aviso-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  .aviso-head h3 { margin: 0; }

  /* La fila de un viaje apuntado no tenía maqueta de móvil: se quedaba con sus
     SEIS columnas de escritorio —34px + 1.1fr + 1fr + 78px + 132px + auto— que
     en 390 px no caben de ninguna manera. El resultado era la ciudad comida,
     los botones colgando fuera de la tarjeta y la página con barra horizontal.
     Se lee como la del feed: el sitio arriba, el precio a su lado, y las fechas
     y los botones en sus propios renglones. */
  .favrow {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 12px;
    align-items: start;
  }
  .favrow > .iata { grid-area: 1 / 1 / 2 / 2; justify-self: start; }
  .favrow > .dest-cell { grid-area: 2 / 1 / 3 / 2; }
  .favrow > .dest-cell .country { flex-basis: 100%; }
  .favrow > .price { grid-area: 2 / 2 / 3 / 3; text-align: right; }
  .favrow > .when { grid-area: 3 / 1 / 4 / 3; text-align: left; white-space: normal; }
  .favrow > .spark-cell { grid-area: 4 / 1 / 5 / 3; justify-items: start; }
  /* El puntito de relleno solo tiene sentido en una línea que se lee de un
     lado al otro; apilada, es una raya suelta en medio. */
  .favrow > .leader { display: none; }
  .favrow > .favacc { grid-area: 5 / 1 / 6 / 3; justify-content: flex-start; }

  /* El panel reusa `.brow` para sus filas de cuenta, pero sus celdas son otras
     —no hay precio, ni fechas, ni compañía— así que la maqueta de arriba le
     descolocaba el sello y los botones. Lleva `.brow.cuenta-row` para ganarle
     por especificidad y no por orden. */
  .brow.cuenta-row { grid-template-columns: minmax(0, 1fr) auto; }
  .cuenta-row > .dest-cell { grid-area: 1 / 1 / 2 / 2; }
  .cuenta-row > .iata { grid-area: 1 / 2 / 2 / 3; justify-self: end; }
  .cuenta-row > .favacc { grid-area: 2 / 1 / 3 / 3; justify-content: flex-start; }
  .cuenta-row > .detalle { grid-area: 3 / 1 / 4 / 3; }

  .finder-form .party { grid-template-columns: 1fr 1fr; gap: 14px; }
  /* Impar y último: ocupa la fila entera. Con tres campos —el de seguir los
     tiene— la rejilla de dos dejaba media celda vacía enseñando el fondo. */
  .finder-form .party > label:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .stats > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* Los tramos se doblan a dos columnas pero SIN abrir el hueco: la separación
     es la misma rejilla de un píxel, si no el fondo asoma como una banda gris. */
  .legs { grid-template-columns: 1fr 1fr; gap: 1px; }
  .stats { grid-template-columns: 1fr 1fr; }
  .modal-caja { padding: 18px; }
  .panel { width: 100%; border-left: none; }
}

/* LO QUE SE PULSA CON EL DEDO.

   `--tap-min: 44px` estaba desde el primer dia, con el comentario «area tactil
   minima, aunque se vea mas pequeño», y estaba puesto donde se penso para el
   pulgar: los chips, las ciudades del selector, los favoritos. Pero no en la
   barra de arriba ni en los formularios, que es por donde se entra.

   Medido a 390 px: los desplegables de buscar, 21 px de alto; el campo de la
   cifra, 23; los enlaces del nav, 28; el boton de cerrar un panel, 32; el del
   tema, 38; la cuenta, 42. Ninguno llegaba, y son justo los seis sitios que se
   pulsan primero.

   Solo en movil. En un escritorio con raton los 44 px no hacen falta y
   convertirian el formulario compacto de la portada en un formulario alto:
   los campos siguen siendo la linea fina de siempre. Lo vigila
   `tests/web/dedo.spec.js`, que recorre todo lo pulsable de cada pagina. */
@media (max-width: 760px) {
  /* La marca es un enlace a la portada. No crece la barra: la fila ya mide 44
     por la cuenta y el tema. */
  .marca { padding: 8px 0; }

  /* EL NAV. Pasa de 28 a 44 y la barra crece nueve pixeles, contando que se le
     quitan los siete de abajo que ahora pone el propio enlace. Es lo que vale
     no fallar el tiro en la unica puerta a las dos herramientas. «Feed» mide 33
     px de ancho, de ahi el `min-width`. */
  .topbar-in { padding-bottom: 0; }
  .zona {
    padding: 12px 0;
    min-width: var(--tap-min);
    text-align: center;
  }

  .tema { width: var(--tap-min); height: var(--tap-min); }
  .cuenta, #tfCuenta { min-height: var(--tap-min); }

  /* LOS CAMPOS DE BUSCAR Y SEGUIR. La celda ya medía 54 px —rotulo, hueco y
     campo— pero el campo ocupaba solo los 21 de abajo: el resto de la celda no
     hacia nada al tocarlo. Con `flex: 1` el campo se estira hasta llenar su
     celda, asi que se toca donde se ve. El texto no se mueve: un `select` y un
     `input` centran su contenido en la caja. */
  .finder-form input,
  .finder-form select,
  .finder-form .date-btn {
    flex: 1;
    min-height: var(--tap-min);
  }

  /* Cerrar. Lo primero que se busca al abrir una hoja, y era el boton mas
     pequeño de la casa. */
  .modal-head button, [data-cerrar] { min-height: var(--tap-min); }

  /* LOS FILTROS DEL TABLON. En movil los nueve controles viven en una hoja que
     sube desde abajo: es el sitio con mas cosas que tocar por centimetro de
     toda la web, y sus campos median 35 px. El deslizador del precio tambien:
     la barra se sigue dibujando fina, lo que crece es la caja que la rodea. */
  .hoja .field input, .hoja .field select { min-height: var(--tap-min); }
}

/* EL PIE DE LA PAGINA DEL INTERRAIL: lo que el precio no cuenta. */
.tren-pie {
  margin: 18px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--hair);
  font-size: var(--fs-body-s);
  line-height: var(--lh-body);
  color: var(--muted);
  text-wrap: pretty;
}
.tren-pie b { color: var(--ink); font-weight: 600; }
.tren-pie .btn { margin-left: 8px; vertical-align: middle; }

/* INTERRAIL. Una tarjeta por ruta: las cuatro cifras que deciden —dias de
   bono, noches, horas de tren y reservas— y debajo el viaje en orden, de vuelo
   a vuelo. Las paradas en tinta y los tramos en gris: lo que se lee de un
   vistazo es por donde pasas, y como llegas es el detalle. */
.ir { margin-top: 28px; }
.ir-titulo { font-size: var(--fs-subhead); margin: 8px 0 0; }
.ir-rutas { display: grid; gap: 14px; margin-top: 6px; }
.ir-ruta {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  padding: 18px;
}
.ir-ruta header h3 { font-size: var(--fs-body); margin: 0; }
.ir-ruta header p { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-body-s); }
.ir-cifras {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin: 14px 0;
  background: var(--hair);
  border: 1px solid var(--hair);
}
.ir-cifras > div { background: var(--surface); padding: 8px 10px; }
.ir-cifras dt {
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.ir-cifras dd { margin: 6px 0 0; font: 600 var(--fs-data) / 1.2 var(--font-mono); }
.ir-cifras dd small { display: block; font-weight: 400; font-size: var(--fs-meta); color: var(--deep); }
.ir-pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.ir-parada { display: flex; align-items: baseline; gap: 10px; padding: 4px 0; }
.ir-parada b { font-weight: 600; }
.ir-parada small { color: var(--muted); font: 400 var(--fs-meta) var(--font-mono); }
.ir-tramo {
  margin-left: 6px;
  padding: 2px 0 2px 14px;
  border-left: 1px dashed var(--line);
  color: var(--muted);
  font: 400 var(--fs-meta) / 1.6 var(--font-mono);
}
.ir-reserva { color: var(--accent-txt); }
/* El billete suelto va en pequeño y apagado: es el apunte, no el dato. Lo que
   se lee es el total de abajo. */
.ir-billete { display: block; opacity: 0.75; }

/* SIN BONO Y CON BONO. Dos cifras lado a lado y la que gana, marcada. Cuando
   depende, ninguna se marca: marcar una seria afirmar lo que no se sabe. */
.ir-precio {
  margin: 0 0 14px;
  padding: 12px 14px;
  border-left: 2px solid var(--deep);
  background: var(--surface2);
}
.ir-precio-titulo {
  margin: 0 0 8px;
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.ir-precio dl { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 0; }
.ir-precio dt { font-size: var(--fs-body-s); color: var(--muted); }
.ir-precio dd { margin: 2px 0 0; font: 600 var(--fs-data) / 1.2 var(--font-mono); }
.ir-precio small { display: block; color: var(--muted); font: 400 var(--fs-meta) var(--font-mono); }
.ir-precio .gana dd { color: var(--deep); }
.ir-precio .gana dt::after { content: " · mejor"; color: var(--deep); }
.ir-veredicto { margin: 10px 0 0; font-size: var(--fs-body-s); color: var(--ink); }
.ir-apunte { display: block; margin-top: 6px; font-size: var(--fs-meta); }
.ir-desglose { margin: 8px 0 0; font: 400 var(--fs-meta) / 1.5 var(--font-mono); color: var(--muted); }
.ir-desglose b { color: var(--accent-txt); font-weight: 500; }

/* EL ALOJAMIENTO DE CADA PARADA. Va colgado de su ciudad, con la foto, el
   nombre, de quien es y a cuanto del centro. La que sale es la mejor por
   precio y cercania; «Cambiar» despliega las demas y elegir una recalcula el
   total de arriba. */
.ir-pedir { display: grid; gap: 6px; margin: 0 0 14px; justify-items: start; }
.ir-pedir small, .ir-buscando { color: var(--muted); font-size: var(--fs-body-s); }
.ir-buscando { display: flex; gap: 8px; align-items: center; margin: 0 0 14px; }
.ir-cama { margin: 2px 0 6px 6px; padding-left: 14px; border-left: 1px solid var(--deep); }
.ir-cama.esperando, .ir-cama.vacia {
  display: flex; gap: 8px; align-items: center;
  color: var(--muted); font: 400 var(--fs-meta) var(--font-mono);
}
.ir-cama-sel {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
}
/* Sin foto, dos columnas: si no, el texto cae en la columna de la foto y el
   precio en la del texto, pegado al nombre en vez de a la derecha. */
.ir-cama-sel.sin-foto { grid-template-columns: minmax(0, 1fr) auto; }
.ir-cama-sel img { width: 56px; height: 56px; object-fit: cover; border-radius: calc(var(--r) - 4px); }
.ir-cama-sel a { color: var(--ink); font-weight: 500; overflow-wrap: anywhere; }
.ir-cama-sel small, .ir-elegir small {
  display: block;
  color: var(--muted);
  font: 400 var(--fs-meta) var(--font-mono);
}
.ir-cama-sel b, .ir-elegir b { font: 600 var(--fs-data) var(--font-mono); white-space: nowrap; }
.ir-otras summary {
  cursor: pointer;
  padding: 10px 0;
  min-height: var(--tap-min);
  color: var(--deep);
  font-size: var(--fs-body-s);
}
.ir-otras ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.ir-elegir {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: var(--tap-min);
  padding: 8px 10px;
  border: 1px solid var(--hair);
  border-radius: calc(var(--r) - 4px);
  background: transparent;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.ir-elegir:hover, .ir-elegir:focus-visible { border-color: var(--deep); }

/* EL PRECIO DEL VUELO, debajo de su linea: la cifra y de donde sale. */
.ir-vuelo-precio {
  display: block;
  margin-top: 2px;
  font: 400 var(--fs-meta) / 1.5 var(--font-mono);
  color: var(--muted);
}
.ir-vuelo-precio b { color: var(--ink); font-weight: 600; }
.ir-vuelo-precio.sin { color: var(--accent-txt); }
.ir-grupo { margin: 6px 0 0; font: 500 var(--fs-meta) / 1.5 var(--font-mono); color: var(--ink); }

/* PERSONALIZAR. Plegado por defecto: la ruta tal cual es un buen punto de
   partida, y el panel no puede tapar lo que se lee primero. */
.ir-ajustar { margin: 0 0 14px; border: 1px solid var(--hair); border-radius: var(--r); }
.ir-ajustar > summary {
  cursor: pointer;
  padding: 12px 14px;
  min-height: var(--tap-min);
  color: var(--deep);
  font-size: var(--fs-body-s);
}
.ir-ajustar > summary b { color: var(--accent-txt); font-weight: 500; }
.ir-ajustar-cuerpo { padding: 0 14px 14px; display: grid; gap: 10px; justify-items: start; }
.ir-ajustar ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; width: 100%; }
.ir-ajustar li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 10px;
  align-items: center;
  padding: 4px 0;
  border-top: 1px solid var(--hair);
}
.ir-ajustar li.fuera { grid-template-columns: minmax(0, 1fr) auto; color: var(--muted); }
.ir-aj-noches { display: inline-flex; align-items: center; gap: 6px; }
.ir-aj-noches b { font: 500 var(--fs-meta) var(--font-mono); min-width: 8ch; text-align: center; }
.ir-aj-noches button, .ir-aj-quitar {
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.ir-aj-quitar { padding: 0 12px; font-size: var(--fs-meta); color: var(--muted); }
.ir-aj-noches button:disabled, .ir-aj-quitar:disabled { opacity: 0.35; cursor: default; }
.ir-ruta.ajustada { border-color: var(--deep); }
.ir-libre { color: var(--deep); }
.ir-vuelo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 0;
  color: var(--muted);
  font-size: var(--fs-body-s);
}
.ir-vuelo:first-child { border-bottom: 1px solid var(--hair); margin-bottom: 4px; }
.ir-vuelo:last-child { border-top: 1px solid var(--hair); margin-top: 4px; }

/* EL FORMULARIO DEL INTERRAIL. Tres bloques numerados —el pase, el viaje, las
   ciudades— porque es el orden en que cambia la cuenta, y cada uno se lee de
   un vistazo. Los campos van en la misma rejilla que el buscador. */
.ir-form { display: grid; gap: 14px; margin: 18px 0 10px; }
.ir-bloque { border: 1px solid var(--hair); border-radius: var(--r); padding: 12px 14px 14px; margin: 0; min-width: 0; }
.ir-bloque legend { padding: 0 6px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.ir-paso {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--sobre-acento);
  font: 600 12px var(--font-mono);
}
.ir-opciones { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 6px 0 10px; }
.ir-opcion {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  cursor: pointer;
}
.ir-opcion:has(input:checked) { border-color: var(--deep); background: color-mix(in srgb, var(--deep) 8%, transparent); }
.ir-opcion input { margin-top: 3px; accent-color: var(--deep); }
.ir-opcion span { display: grid; gap: 2px; }
.ir-opcion small { color: var(--muted); font-size: var(--fs-meta); line-height: 1.4; }
.ir-fila {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
}
.ir-fila label { background: var(--field); padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ir-fila label[hidden] { display: none; }
.ir-fila label > span {
  font: 400 var(--fs-caps) / 1.2 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.ir-fila label > span i { text-transform: none; letter-spacing: 0; font-style: normal; opacity: 0.8; }
.ir-fila input, .ir-fila select {
  border: none;
  background: transparent;
  padding: 0;
  font-size: var(--fs-input);
  font-weight: 600;
  width: 100%;
  min-width: 0;
  color: var(--ink);
  min-height: 28px;
}
.ir-ayuda { margin: 4px 0 10px; color: var(--muted); font-size: var(--fs-body-s); }
.ir-ciudades { display: grid; gap: 8px; }
.ir-pais { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ir-pais > span {
  flex: 0 0 100%;
  font: 400 var(--fs-caps) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 4px;
}
.ir-chip {
  min-height: 40px;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  font-size: var(--fs-body-s);
  cursor: pointer;
}
.ir-chip:hover { border-color: var(--deep); }
.ir-chip[aria-pressed="true"] { background: var(--deep); border-color: var(--deep); color: var(--paper); font-weight: 600; }
.ir-chip[aria-pressed="true"]::before { content: "✓ "; }
.ir-elegidas { margin: 6px 0 0; font: 400 var(--fs-meta) / 1.5 var(--font-mono); color: var(--muted); }
.ir-limpiar { border: none; background: none; padding: 4px 0; color: var(--accent-txt); cursor: pointer; font: inherit; text-decoration: underline; }
.ir-etiqueta {
  margin: 0 0 2px !important;
  font: 400 var(--fs-caps) / 1 var(--font-mono) !important;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--deep) !important;
}
.ir-ruta.elegida { border-color: var(--deep); }
.ir-problema {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-size: var(--fs-body-s);
}
.ir-otras-titulo { margin: 18px 0 0; font-size: var(--fs-body); }
.ir-cortas { display: grid; gap: 8px; }
.ir-ruta.corta { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 14px; }
.ir-ruta.corta h3 { margin: 0; font-size: var(--fs-body); }
.ir-corta-paradas { margin: 2px 0; font-size: var(--fs-body-s); }
.ir-corta-idea { margin: 2px 0; font-size: var(--fs-body-s); color: var(--muted); }
/* Clásica o menos conocida: un rótulo, no un color. El naranja es del precio
   y el verde de lo que se vigila; esto es tinta y un filete. */
.ir-tipo {
  display: inline-block;
  margin-bottom: 4px;
  padding: 2px 7px;
  border: 1px solid var(--line);
  border-radius: var(--r-tag);
  font: 500 var(--fs-caps) / 1.3 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--ink);
}
.ir-tipo.alternativa { border-style: dashed; }
.ir-etiqueta .ir-tipo { margin: 0; padding: 0 5px; }
.ir-monton { margin: 14px 0 6px; font: 500 var(--fs-meta) / 1.4 var(--font-mono); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--muted); }
.ir-ruta.corta .meta { margin: 0; font: 400 var(--fs-meta) / 1.4 var(--font-mono); color: var(--muted); }
.ir-ruta.corta .btn { flex: none; }
.ir-largo { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; color: var(--accent-txt); }
.ir-lejos { color: var(--accent-txt); }
.ir-cama-aviso { margin: 0 0 4px; font-size: var(--fs-meta); color: var(--accent-txt); }
.ir-sin-sesion { margin: 0 0 14px; }
.ir-roto { color: var(--accent-txt); }

/* EL MAPA DEL INTERRAIL. Las líneas de tren en gris, la ruta elegida encima en
   verde, y las ciudades como botones: el círculo grande e invisible es la zona
   de toque, que en un móvil un punto de ocho píxeles no se acierta. */
.ir-mapa { margin: 4px 0 8px; border: 1px solid var(--hair); border-radius: var(--r); background: var(--field); }
.ir-mapa-svg { display: block; width: 100%; height: auto; max-height: 70vh; }
.ir-mapa-lineas line { stroke: var(--line); stroke-width: 1.2; opacity: 0.45; }
.ir-mapa-ruta { fill: none; stroke: var(--deep); stroke-width: 3.5; stroke-linejoin: round; stroke-linecap: round; opacity: 0.9; }
.ir-nodo { cursor: pointer; outline: none; }
.ir-nodo-toque { fill: transparent; }
.ir-nodo-punto { fill: var(--muted); stroke: var(--field); stroke-width: 1.5; transition: r 0.15s; }
.ir-nodo text { pointer-events: none; font: 500 11px var(--font-sans, system-ui); fill: var(--muted); paint-order: stroke; stroke: var(--field); stroke-width: 3px; }
.ir-nodo:hover .ir-nodo-punto, .ir-nodo:focus-visible .ir-nodo-punto { fill: var(--ink); }
.ir-nodo:focus-visible .ir-nodo-toque { stroke: var(--accent); stroke-width: 2; }
.ir-nodo text.menor { font-size: 9px; opacity: 0.85; }
.ir-nodo.parada .ir-nodo-punto { fill: var(--deep); }
.ir-nodo.parada text { fill: var(--ink); }
.ir-nodo.sel .ir-nodo-punto { fill: var(--accent); }
.ir-nodo.sel text { fill: var(--ink); font-weight: 700; }
#irElegidas { margin: 0 0 6px; font-size: var(--fs-body-s); color: var(--muted); }
#irElegidas b { color: var(--ink); }
.ir-lista > summary { cursor: pointer; color: var(--deep); font-size: var(--fs-body-s); padding: 8px 0; min-height: var(--tap-min); }

/* EL RESUMEN: lo que es el viaje a la izquierda, lo que cuesta a la derecha. */
.ir-resumen {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px 20px;
  align-items: start;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--hair);
  margin-bottom: 14px;
}
.ir-resumen h3 { margin: 2px 0 0; font-size: var(--fs-subhead); letter-spacing: -0.02em; }
.ir-res-idea { margin: 4px 0 0; color: var(--muted); font-size: var(--fs-body-s); }
.ir-res-datos {
  list-style: none; margin: 10px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font: 400 var(--fs-meta) / 1.4 var(--font-mono); color: var(--ink);
}
.ir-res-datos small { color: var(--muted); }
.ir-res-total { display: grid; justify-items: end; text-align: right; gap: 2px; }
.ir-res-total > span { font: 400 var(--fs-caps) / 1.2 var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.ir-res-total > b { font: 600 clamp(26px, 5vw, 36px) / 1.05 var(--font-mono); color: var(--ink); letter-spacing: -0.02em; }
.ir-res-total[data-completo="si"] > b { color: var(--deep); }
.ir-res-total small { color: var(--muted); font: 400 var(--fs-meta) var(--font-mono); }
.ir-res-estado { max-width: 30ch; }
.ir-res-acciones { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }

/* EL VIAJE DÍA A DÍA: la fecha a la izquierda, un icono en la raya del
   tiempo y lo que pasa ese día. */
.ir-itinerario-titulo { margin: 18px 0 8px; font-size: var(--fs-body); }
.ir-itinerario { list-style: none; margin: 0; padding: 0; display: grid; }
.ir-ev {
  display: grid;
  grid-template-columns: 76px 22px minmax(0, 1fr) auto;
  gap: 0 10px;
  align-items: start;
  padding: 10px 0;
  position: relative;
}
.ir-ev + .ir-ev { border-top: 1px dashed var(--hair); }
.ir-ev-dia { font: 400 var(--fs-meta) / 1.4 var(--font-mono); color: var(--muted); padding-top: 2px; }
.ir-ev-ico { text-align: center; line-height: 1.4; }
.ir-ev-ciudad .ir-ev-ico { color: var(--deep); }
.ir-ev-cuerpo { min-width: 0; display: grid; gap: 6px; }
.ir-ev-titulo { margin: 0; font-weight: 600; }
.ir-ev-titulo small { font: 400 var(--fs-meta) var(--font-mono); color: var(--muted); margin-left: 8px; }
.ir-ev-meta { margin: 0; font: 400 var(--fs-meta) / 1.5 var(--font-mono); color: var(--muted); }
.ir-ev-meta b { color: var(--ink); }
.ir-ev-meta.sin { color: var(--accent-txt); }
.ir-ev-accion { align-self: start; }
.ir-ev-tren.de-noche .ir-ev-titulo { color: var(--deep); }
.ir-ev .ir-cama { margin: 0; padding: 10px; border: 1px solid var(--hair); border-left: 3px solid var(--deep); border-radius: var(--r); background: var(--field); }
.ir-ev .ir-cama.esperando, .ir-ev .ir-cama.vacia { border-left-color: var(--line); }
.ir-cama-sel img { width: 88px; height: 66px; }
.ir-cama-sel b { display: grid; justify-items: end; }
.ir-cama-sel b small { font: 400 var(--fs-meta) var(--font-mono); color: var(--muted); }
.ir-otros-dias { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: var(--fs-meta); color: var(--muted); }
.ir-dia-chip {
  min-height: 36px;
  padding: 4px 12px;
  border: 1px solid var(--deep);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink);
  font: 400 var(--fs-meta) var(--font-mono);
  cursor: pointer;
}
.ir-dia-chip small { color: var(--deep); }
.ir-dia-chip:hover { background: color-mix(in srgb, var(--deep) 12%, transparent); }
.ir-nocturno {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  padding: 8px 10px; border-radius: var(--r);
  background: color-mix(in srgb, var(--deep) 8%, transparent);
  font-size: var(--fs-body-s);
}
.ir-largo { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; color: var(--accent-txt); font-size: var(--fs-body-s); }
.ir-mas { margin-top: 18px; }
.ir-mas > summary {
  cursor: pointer; padding: 12px 14px; min-height: var(--tap-min);
  border: 1px solid var(--line); border-radius: var(--r);
  font-weight: 600;
}
.ir-mas[open] > summary { margin-bottom: 10px; }

/* El Interrail en el movil. */
@media (max-width: 760px) {
  .ir-cifras { grid-template-columns: 1fr 1fr; }
  .ir-ruta { padding: 14px; }
  /* El nombre encima y los controles debajo: en fila, «Ámsterdam» se metía
     debajo del botón de quitar una noche. */
  .ir-ajustar li { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
  .ir-ajustar li:not(.fuera) .ir-aj-ciudad { grid-column: 1 / -1; font-weight: 500; }
  .ir-opciones { grid-template-columns: 1fr; }
  .ir-ruta.corta { flex-direction: column; align-items: stretch; }
  .ir-ruta.corta .btn { align-self: flex-start; }
  .ir-resumen { grid-template-columns: 1fr; }
  .ir-res-total { justify-items: start; text-align: left; }
  .ir-ev { grid-template-columns: 22px minmax(0, 1fr); }
  .ir-ev-dia { grid-column: 2; order: -1; padding: 0; }
  .ir-ev-ico { grid-row: 1 / span 3; }
  .ir-ev-accion { grid-column: 2; justify-self: start; margin-top: 6px; }
  .ir-cama-sel img { width: 64px; height: 48px; }
}

@media (max-width: 420px) {
  .finder-form { grid-template-columns: 1fr; }
  .quiz-billete-top { grid-template-columns: auto minmax(0, 1fr); }
  .quiz-precio { grid-column: 2; text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

/* Entrar y crear una cuenta (Firebase): dos pestañas en el mismo diálogo. */
.nube-pestanas {
  display: flex;
  gap: 4px;
  margin: 0 0 14px;
  padding: 4px;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
}
.nube-pestanas button {
  flex: 1;
  min-height: var(--tap-min);
  padding: 8px 14px;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--fs-ui);
  font-weight: 500;
  cursor: pointer;
  transition: all var(--t) var(--ease);
}
.nube-pestanas button:hover { color: var(--ink); }
.nube-pestanas button[aria-selected="true"] { background: var(--ink); color: var(--paper); }
.nube-pestanas button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Vincular una cuenta nueva con una de antes (panel) y avisar de que falta
   verificar el correo (tu cuenta). */
.nube-vincular { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.nube-vincular select { max-width: 100%; }
.nube-verificar { padding: 12px 14px; border: 1px solid var(--hair); border-radius: var(--r-md, 12px); margin: 0 0 14px; }
.nube-verificar .controls { margin: 8px 0 0; }

/* «Cómo funciona»: tres pasos para quien llega por primera vez. Una lista
   numerada de verdad, porque el orden es la información. */
.como { padding-block: 22px 8px; }
.como-titulo {
  margin: 0 0 12px;
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.como-pasos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: paso;
}
.como-pasos li {
  display: grid;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--hair);
  border-radius: var(--r-md, 12px);
  counter-increment: paso;
}
.como-pasos li::before {
  content: counter(paso);
  font: 500 var(--fs-data-s) / 1 var(--font-mono);
  color: var(--accent-txt);
}
.como-pasos b { font-size: var(--fs-body-s); }
.como-pasos span { font-size: var(--fs-body-s); color: var(--muted); line-height: 1.45; }
@media (max-width: 760px) {
  .como-pasos { grid-template-columns: 1fr; }
}

/* La página de privacidad: un texto para leer, a ancho de lectura. */
.privacidad { max-width: 68ch; padding-block: 12px 40px; }
.privacidad h2 {
  margin: 26px 0 6px;
  font: 400 var(--fs-caps-l) / 1 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.privacidad p { margin: 0; line-height: 1.6; }
.privacidad .acciones-fila { margin-top: 28px; }
.foot-enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.foot-enlace:hover { color: var(--accent-txt); }

/* En un móvil estrecho la marca y el botón del test no caben juntos con el tema y
   la cuenta, y la cuenta se caía a una segunda fila vacía. Con la letra manuscrita
   de verdad (Pinyon Script, que solo carga con red) el nombre es más ancho que con
   la de reserva, así que el corte está en 430 px y no justo al límite. Se queda el
   icono de la marca (el nombre sigue en el título y en el pie). */
@media (max-width: 430px) {
  .marca-trip, .marca-finder { display: none; }
  /* Solo el icono: sigue siendo un enlace y se pulsa con el dedo. */
  .marca { min-width: var(--tap-min); min-height: var(--tap-min); justify-content: center; }
}

/* Los correos de «tu cuenta»: un interruptor y, si se enciende, el resto. */
fieldset.avisos { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: 6px; }
fieldset.avisos legend { padding: 0; }
.avisos-opciones { display: grid; gap: 6px; padding-left: 12px; border-left: 2px solid var(--line); }
.avisos-cuando { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.avisos-cuando > span { display: grid; gap: 4px; }

/* «Salgo el lunes → vuelvo el jueves»: dos desplegables con una flecha. */
.dias-par { display: flex; align-items: flex-end; gap: 8px; }
.dias-par > label { flex: 1; display: grid; gap: 4px; }
.dias-flecha { padding-bottom: 10px; color: var(--muted); font-family: var(--font-mono); }

/* Entrar: Google arriba si está configurado, una raya, y el correo. */
.login { display: grid; gap: 10px; }
.login-google { display: flex; justify-content: center; min-height: 44px; }
.login-o { display: flex; align-items: center; gap: 10px; margin: 0; color: var(--muted); font: 400 var(--fs-meta) / 1 var(--font-mono); }
.login-o::before, .login-o::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.login-pista { margin: -2px 0 0; }
.login-boton { width: 100%; }
.login-hecho { margin: 0; font-weight: 600; }
#nubeOlvide.resalta { border-color: var(--accent-txt); color: var(--accent-txt); }

/* Instalar como app: abajo, pequeño, y se va con un toque. */
.instalar {
  position: fixed;
  z-index: 40;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(560px, calc(100% - 24px));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.25);
  font-size: var(--fs-body-s);
  animation: instalar-entra 0.25s var(--ease) both;
}
.instalar p { flex: 1 1 240px; margin: 0; }
.instalar-ico { font-family: var(--font-mono); }
.instalar-pie {
  border: 0;
  background: none;
  padding: 10px 0;
  min-height: 44px;
  color: var(--accent-txt);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
@keyframes instalar-entra { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (prefers-reduced-motion: reduce) { .instalar { animation: none; } }

/* ==========================================================================
   REDISEÑO COMPACTO (octubre de 2026)

   La misma voz —el naranja es el precio, el verde lo que se vigila, tres
   tipografías— con menos ruido. Lo que cambia:

     · COMPACTA. Titulares más bajos, menos aire entre bloques, una portada
       que se recorre en dos pantallas y no en seis.
     · LAS TARJETAS SEPARAN, NO LOS FILOS. Blanco (o gris) de tarjeta sobre
       papel, con una raya suave y una sombra que apenas se ve. El filo negro
       del tema claro se fue: en una pantalla densa hacía hoja de cálculo.
     · SE NAVEGA COMO UNA APP. Pestañas con icono arriba; en el móvil, la
       barra de abajo al alcance del pulgar.
     · DETALLES. Foco visible en todo, selección con el naranja muy rebajado,
       pestañas que se mueven con el teclado, botones que ceden al pulsarlos.

   Va al final a propósito: pisa lo de arriba sin tener que buscarlo.
   ========================================================================== */

::selection { background: color-mix(in srgb, var(--accent) 32%, transparent); color: var(--ink); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.btn:active, .pestanas [role="tab"]:active, .tab:active { transform: translateY(1px); }

/* ---- la cabecera ------------------------------------------------------ */
.topbar {
  background: color-mix(in srgb, var(--paper) 84%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom-color: var(--hair);
}
.topbar-in { padding: 8px var(--pad-page); gap: 14px; min-height: 56px; }
.marca-trip { font-size: 23px; }
.marca-finder { font-size: 17px; }
.zonas {
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
  background: var(--surface);
}
.zona {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 13px 6px 10px;
  border-radius: var(--r-pill);
  transition: color var(--t) var(--ease), background var(--t) var(--ease);
}
.zona:hover { color: var(--ink); background: var(--surface2); }
.zona.activa { color: var(--ink); background: var(--surface2); box-shadow: inset 0 0 0 1px var(--line); }
.zona-ico { flex: none; width: 16px; height: 16px; }
.tema { border-color: var(--hair); }
.cuenta, #tfCuenta { padding: 8px 14px; }
.flap-boton { padding: 8px 13px; border-color: var(--hair); }

/* La barra de abajo: solo en el móvil (ver más abajo). */
.tabbar { display: none; }

/* ---- el cuerpo -------------------------------------------------------- */
main { padding-bottom: 56px; }
h1 { line-height: 1.02; margin: 6px 0 10px; }
.masthead { padding: 30px var(--pad-page) 22px; gap: 32px; border-bottom: 0; }
.masthead .kicker { margin: 0; }
.masthead .lede { font-size: var(--fs-body); }
.masthead .lede .trato {
  margin-left: 4px;
  color: var(--accent-txt);
  border-bottom: 1px solid currentColor;
  white-space: nowrap;
}
.stats {
  background: var(--hair);
  border-color: var(--hair);
  border-radius: var(--r);
  overflow: hidden;
  box-shadow: var(--sombra);
}
.stats > div { background: var(--surface); padding: 10px 14px; }

/* «Cómo funciona», en una franja: los tres pasos se leen de un vistazo. */
.como { padding-block: 0; }
.como-titulo {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.como-pasos {
  gap: 0;
  border: 1px solid var(--hair);
  border-radius: var(--r);
  background: var(--surface);
}
.como-pasos li {
  grid-template-columns: auto 1fr;
  column-gap: 10px;
  row-gap: 1px;
  align-items: baseline;
  padding: 11px 14px;
  border: 0;
  border-radius: 0;
}
.como-pasos li + li { border-left: 1px solid var(--hair); }
.como-pasos li::before {
  grid-row: span 2;
  align-self: start;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface2);
  color: var(--ink);
}
.como-pasos span { font-size: var(--fs-ui-s); }

/* ---- el chollo del día y el feed -------------------------------------- */
.ticket { margin-top: 20px; box-shadow: var(--sombra); }
.feed { margin-top: 30px; }
.feed-head { margin-bottom: 10px; }
.controls { border-color: var(--hair); border-radius: var(--r); background: var(--surface); }
.brow { transition: background var(--t-micro) var(--ease); }

/* ---- buscar / seguir, en una tarjeta con pestañas ---------------------- */
.panels.con-pestanas {
  display: block;
  margin-top: 30px;
  border: 1px solid var(--hair);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sombra);
  overflow: hidden;
}
.pestanas {
  display: flex;
  gap: 4px;
  padding: 6px 6px 0;
  border-bottom: 1px solid var(--hair);
}
.pestanas [role="tab"] {
  position: relative;
  padding: 10px 14px 12px;
  min-height: var(--tap-min);
  border: 0;
  background: none;
  color: var(--muted);
  font-size: var(--fs-ui);
  font-weight: 500;
  cursor: pointer;
  transition: color var(--t) var(--ease);
}
.pestanas [role="tab"]:hover { color: var(--ink); }
.pestanas [role="tab"][aria-selected="true"] { color: var(--ink); font-weight: 600; }
.pestanas [role="tab"][aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
}
#tabSeguir[aria-selected="true"]::after { background: var(--deep); }
.con-pestanas .herramienta {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 16px 18px 18px;
  gap: 12px;
}
.con-pestanas .finder-lede { margin: 0; }
.finder-form { border-radius: var(--r-s); overflow: hidden; }
.observacion { margin-top: 20px; border-radius: var(--r); border-color: var(--hair); }

/* ---- el pie ----------------------------------------------------------- */
.foot { border-top-color: var(--hair); }
.foot-enlaces { display: inline-flex; gap: 16px; }

/* ---- los planes ------------------------------------------------------- */
.planes-main { padding-top: 4px; }
.planes-estreno {
  margin: 0 0 16px;
  padding: 10px 14px;
  border: 1px dashed var(--line);
  border-radius: var(--r);
  font-size: var(--fs-body-s);
  color: var(--muted);
}
.planes-estreno b { color: var(--ink); }
.planes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--hair);
  border-radius: var(--r);
  background: var(--surface);
}
.plan-premium { border-color: var(--line); box-shadow: var(--sombra); }
.plan.tuyo::before {
  content: "tu plan";
  position: absolute;
  top: 14px;
  right: 14px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--surface2);
  font: 500 var(--fs-caps-l) / 1.2 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
}
.plan h2 { margin: 0; font-size: var(--fs-subhead); }
.plan-precio { margin: 6px 0 0; display: flex; align-items: baseline; gap: 8px; }
.plan-precio b { font: 600 var(--fs-figure) / 1 var(--font-mono); letter-spacing: -0.03em; }
.plan-precio span { font-size: var(--fs-ui-s); color: var(--muted); }
.plan-lista { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; flex: 1; }
.plan-lista li {
  position: relative;
  padding-left: 22px;
  font-size: var(--fs-body-s);
  line-height: 1.45;
}
.plan-lista li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.45em;
  width: 9px;
  height: 5px;
  border-left: 1.6px solid var(--deep);
  border-bottom: 1.6px solid var(--deep);
  transform: rotate(-45deg);
}
.plan-cta { align-self: flex-start; }
.plan-nota { margin: -6px 0 0; }
.planes-faq { max-width: 68ch; margin-top: 30px; }
.planes-faq h2 { margin: 0 0 8px; font-size: var(--fs-subhead); }
.planes-faq details { border-top: 1px solid var(--hair); }
.planes-faq summary { padding: 12px 0; min-height: var(--tap-min); cursor: pointer; font-weight: 500; }
.planes-faq details p { margin: 0 0 14px; color: var(--muted); font-size: var(--fs-body-s); }

/* ---- el móvil --------------------------------------------------------- */
@media (max-width: 760px) {
  .topbar .zonas { display: none; }
  .tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));
    background: color-mix(in srgb, var(--surface) 90%, transparent);
    -webkit-backdrop-filter: saturate(1.4) blur(14px);
    backdrop-filter: saturate(1.4) blur(14px);
    border-top: 1px solid var(--hair);
  }
  .tab {
    position: relative;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 3px;
    min-height: 50px;
    color: var(--muted);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.01em;
  }
  .tab .zona-ico { width: 20px; height: 20px; }
  .tab.activa { color: var(--ink); }
  .tab.activa::before {
    content: "";
    position: absolute;
    top: -5px;
    width: 22px;
    height: 2px;
    border-radius: 2px;
    background: var(--ink);
  }
  .tab[data-zona="follows"].activa::before { background: var(--deep); }
  body { padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px)); }
  .instalar { bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }

  .masthead { padding: 18px var(--pad-page) 14px; gap: 16px; }
  .masthead h1 { font-size: 30px; }
  .como-pasos { grid-template-columns: 1fr; }
  .como-pasos li + li { border-left: 0; border-top: 1px solid var(--hair); }
  .planes { grid-template-columns: 1fr; }
  .pestanas [role="tab"] { flex: 1; }
}

/* El renglón de encima del titular: un dato, en mono, sin gritar. */
.antetitulo {
  margin: 0;
  font: 500 var(--fs-caps-l) / 1.3 var(--font-mono);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--muted);
}

/* El chollo del día, sin el hueco: los dos botones secundarios van juntos y
   los tramos siguen al titular en vez de irse al fondo de la tarjeta. */
.ticket-izq, .ticket-der { padding: 20px; }
.ticket-izq { gap: 14px; }
.ticket-izq .legs { margin-top: 6px; }
.ticket-der { gap: 14px; justify-content: flex-start; }
.ticket .actions { grid-template-columns: 1fr 1fr; }
.ticket .actions > :first-child { grid-column: 1 / -1; }
.ticket .actions .btn { padding-inline: 12px; }

@media (max-width: 760px) {
  /* Las cuatro cifras en una fila: en el móvil eran media pantalla. */
  .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stats > div { padding: 8px 8px; }
  .stats dt { font-size: 8.5px; letter-spacing: 0.06em; }
  .stats dd { font-size: 16px; }
  .stats .stats-pie { padding: 7px 8px; }
  /* Los pasos, solo con su titular. */
  .como-pasos li { padding: 8px 12px; }
  .como-pasos span { display: none; }
  .como-pasos li::before { grid-row: auto; width: 18px; height: 18px; }
}
.foot-in { align-items: baseline; }

/* Lo de la cabecera que se encoge, solo donde hay ratón: en el móvil el tema y
   los enlaces del pie siguen llegando a los 44 px del dedo. */
@media (min-width: 761px) {
  .tema { width: 36px; height: 36px; }
}
@media (max-width: 760px) {
  .topbar-in { gap: 8px; padding: 9px var(--pad-page) 7px; min-height: 0; }
  .tema { width: var(--tap-min); height: var(--tap-min); }
  .cuenta, #tfCuenta { padding: 10px 12px; }
}
.foot-enlace { display: inline-flex; align-items: center; min-width: var(--tap-min); min-height: var(--tap-min); justify-content: center; }

/* «Hace falta una cuenta»: el texto y, debajo, los dos botones a su tamaño.
   En columna, Entrar era una barra naranja de lado a lado. */
.token-box { flex-direction: row; flex-wrap: wrap; align-items: center; }
.token-box > strong, .token-box > :not(.btn) { flex-basis: 100%; }
.token-box .btn { flex: none; }
.ir-ev-ico svg { display: inline-block; vertical-align: -3px; }

/* El número de lo que sigues, pegado al nombre de la pestaña. Verde: es lo que
   se vigila, no un precio. */
.insignia {
  display: inline-grid;
  place-items: center;
  min-width: 17px;
  height: 17px;
  padding: 0 5px;
  margin-left: 2px;
  border-radius: var(--r-pill);
  background: var(--deep);
  color: var(--paper);
  font: 600 10px / 1 var(--font-mono);
  letter-spacing: 0;
}
.tab .insignia { position: absolute; top: 4px; left: calc(50% + 6px); margin: 0; }

/* La tecla del atajo, dentro del buscador del feed. */
.field.con-tecla { position: relative; }
.tecla {
  position: absolute;
  right: 8px;
  bottom: 10px;
  min-width: 20px;
  padding: 2px 5px;
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 5px;
  color: var(--muted);
  font: 500 var(--fs-meta) / 1 var(--font-mono);
  text-align: center;
  pointer-events: none;
  transition: opacity var(--t) var(--ease);
}
.field.con-tecla:focus-within .tecla { opacity: 0; }
@media (max-width: 760px) { .tecla { display: none; } }
.cuenta-planes { margin-left: 4px; color: var(--accent-txt); border-bottom: 1px solid currentColor; }

/* El mapa del Interrail, con Europa de verdad debajo. El mar es el papel, la
   tierra una tarjeta, y los países de la ruta se tiñen del verde de lo que se
   vigila. Las paradas llevan su número de orden. */
.ir-mapa { overflow: hidden; background: var(--paper); }
.ir-mar { fill: var(--paper); }
.ir-pais { fill: var(--surface2); stroke: var(--line); stroke-width: 0.6; stroke-linejoin: round; transition: fill var(--t) var(--ease); }
.ir-pais.visita { fill: color-mix(in srgb, var(--deep) 22%, var(--surface2)); }
.ir-mapa-lineas line { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.45; }
.ir-mapa-ruta-fondo { fill: none; stroke: var(--paper); stroke-width: 8; stroke-linejoin: round; stroke-linecap: round; }
.ir-mapa-ruta { stroke-width: 4; }
.ir-nodo-punto { stroke: var(--surface2); }
.ir-nodo text { stroke: var(--surface2); }
.ir-nodo.parada .ir-nodo-punto { fill: var(--deep); stroke: var(--paper); stroke-width: 2; }
.ir-nodo text.ir-nodo-num { fill: var(--paper); stroke: none; font: 600 10px var(--font-mono); }
.ir-nodo.parada text:not(.ir-nodo-num) { font-weight: 600; }

/* El mapamundi para elegir países. Gris lo que no tiene chollo hoy, tinta lo
   que sí, y verde lo elegido (es lo que se queda vigilando el feed). */
.mundo-btn {
  min-height: 38px;
  padding: 6px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mundo-btn::after { content: " ›"; color: var(--muted); }
#tfModal .modal-caja:has(.mundo) { width: min(980px, calc(100vw - 24px)); max-width: none; }
.mundo { display: grid; gap: 10px; }
.mundo-svg { display: block; width: 100%; height: auto; border-radius: var(--r-s); background: var(--paper); }
.mp { fill: var(--surface2); stroke: var(--paper); stroke-width: 0.5; cursor: pointer; transition: fill var(--t-micro) var(--ease); }
.mp.con { fill: color-mix(in srgb, var(--ink) 38%, var(--surface2)); }
.mp:hover, .mp:focus-visible { fill: var(--muted); outline: none; }
.mp.sel { fill: var(--deep); }
.mundo-leyenda { margin: 0; display: flex; align-items: center; gap: 6px; font-size: var(--fs-ui-s); color: var(--muted); }
.mundo-muestra { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-left: 8px; }
.mundo-muestra.con { margin-left: 0; background: color-mix(in srgb, var(--ink) 38%, var(--surface2)); }
.mundo-muestra.sel { background: var(--deep); }
.mundo-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.mundo-chip { min-height: 36px; padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--r-pill); background: none; color: var(--ink); font-size: var(--fs-ui-s); cursor: pointer; }
.mundo-chip.sel { background: var(--deep); border-color: var(--deep); color: var(--paper); }
.mundo-pie { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.mundo-cuenta { flex: 1 1 200px; font-size: var(--fs-body-s); color: var(--muted); }
.mp { fill: color-mix(in srgb, var(--ink) 13%, var(--paper)); }
.mp.con { fill: color-mix(in srgb, var(--ink) 45%, var(--paper)); }
.mp.sel { fill: var(--deep); }
.mundo-pie .btn { font-family: var(--font-sans); letter-spacing: 0; text-transform: none; }

/* «Mi cuenta»: arriba quién eres y tu plan; debajo, lo que se cambia. */
.cuenta-ficha { display: flex; align-items: center; gap: 12px; padding: 12px; border: 1px solid var(--hair); border-radius: var(--r); background: var(--surface2); }
.cuenta-avatar { flex: none; width: 40px; height: 40px; display: grid; place-items: center; border-radius: 50%; background: var(--btn-bg); color: var(--btn-ink); font-weight: 700; }
.cuenta-ficha-txt { flex: 1; min-width: 0; display: grid; }
.cuenta-ficha-txt span { color: var(--muted); font-size: var(--fs-ui-s); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-chip { flex: none; display: inline-flex; align-items: center; min-height: 32px; padding: 4px 12px; border: 1px solid var(--line); border-radius: var(--r-pill); font: 500 var(--fs-caps-l) / 1 var(--font-mono); letter-spacing: var(--ls-caps); text-transform: uppercase; }
.plan-chip.premium { border-color: var(--deep); color: var(--deep); }
.cuenta-linea { margin: 10px 0 0; font-size: var(--fs-body-s); color: var(--muted); }
.cuenta-linea b { color: var(--ink); }
.cuenta-bloque { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--hair); }
.cuenta-guardado { margin: 4px 0 0; font-size: var(--fs-ui-s); color: var(--muted); min-height: 1.4em; }
#nubeClaveCaja summary { min-height: var(--tap-min); display: flex; align-items: center; cursor: pointer; font-weight: 500; }
#nubeClaveCaja[open] summary { margin-bottom: 8px; }
@media (max-width: 720px) {
  .mundo-btn { min-height: 44px; }
}

/* ---- entrar / crear cuenta: dos pestañas y Google */
.login-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; border: 1px solid var(--line); border-radius: 999px; }
.login-tabs button { min-height: 40px; border: 0; border-radius: 999px; background: transparent; color: var(--muted); font: 600 0.95rem/1 var(--font-sans, inherit); cursor: pointer; }
.login-tabs button[aria-selected="true"] { background: var(--ink); color: var(--paper); }
.login-google-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; width: 100%; max-width: 360px; min-height: 44px; }
.login-solo-registro { display: none; flex-direction: column; gap: 6px; }
.login.es-alta .login-solo-registro { display: flex; }
.login-lede a { color: inherit; }

/* ---- privacidad y condiciones: centradas, y en el ordenador cada apartado
   con su título a la izquierda y el texto a la derecha, como un índice. */
body:has(.privacidad) .masthead,
body:has(.privacidad) main { max-width: 920px; margin-inline: auto; }
body:has(.privacidad) .masthead { text-align: center; justify-items: center; grid-template-columns: 1fr; display: grid; }
body:has(.privacidad) .masthead > div { margin-inline: auto; }
body:has(.privacidad) .masthead .lede { margin-inline: auto; }
.privacidad { max-width: none; margin-inline: auto; }
.privacidad p + h2 { margin-top: 0; }
@media (min-width: 760px) {
  .privacidad {
    display: grid; grid-template-columns: 220px 1fr; column-gap: 0;
    border-top: 1px solid var(--line);
  }
  .privacidad h2, .privacidad p { padding-block: 18px; border-bottom: 1px solid var(--line); margin: 0; }
  .privacidad h2 { grid-column: 1; align-self: stretch; padding-top: 22px; padding-right: 32px; }
  .privacidad p { grid-column: 2; }
  .privacidad .acciones-fila { grid-column: 1 / -1; justify-content: center; display: flex; }
}

.privacidad a { color: var(--deep); text-decoration: underline; text-underline-offset: 3px; }
.privacidad .acciones-fila a { color: inherit; text-decoration: none; }

/* ---- EL ORDENADOR SE NOTA. En pantallas anchas la web se abre: más ancho
   útil, y en el feed los filtros pasan a una columna fija a la izquierda
   (como cualquier buscador de vuelos de escritorio) y la lista ocupa el resto.
   En el móvil todo sigue en una columna, con la hoja de filtros de abajo. */
@media (min-width: 1400px) {
  :root { --ancho: 1280px; }
}
@media (min-width: 1400px) {
  .feed {
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr);
    column-gap: 28px;
    align-items: start;
  }
  .feed > .feed-head { grid-column: 1 / -1; }
  .feed > .controls {
    grid-column: 1;
    position: sticky; top: 76px;
    display: flex; flex-direction: column; align-items: stretch; gap: 14px;
    padding: 18px; max-height: calc(100vh - 96px); overflow: auto;
  }
  .feed > .controls .field,
  .feed > .controls .switch { width: 100%; min-width: 0; flex: none; }
  .feed > .controls .switch { justify-content: flex-start; }
  .feed > .tabla, .feed > :not(.feed-head):not(.controls):not(.filtros-movil):not(.backdrop) { grid-column: 2; }
}

/* ---- EL MÓVIL, COMO UNA APP. Arriba vuelve el nombre, y el botón del test
   se encoge para caber al lado. Las cifras de la cabecera, en dos columnas
   que se llenan enteras. */
@media (max-width: 430px) and (min-width: 375px) {
  .marca-trip, .marca-finder { display: inline; }
  .marca { min-width: 0; justify-content: flex-start; }
  .topbar .flap-boton { margin-left: 4px; padding: 8px 10px; }
  .topbar-in { gap: 6px; }
}
@media (max-width: 760px) {
  .masthead .stats, .masthead.ancha .stats { grid-template-columns: 1fr 1fr; max-width: none; }
  .masthead .stats > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .acciones-fila { flex-wrap: wrap; }
  .acciones-fila > .btn { flex: 1 1 auto; justify-content: center; }
}
.login-google-btn.btn { background: var(--ink); color: var(--paper); border-color: var(--ink); font-weight: 600; }
