/* ══════════════════════════════════════════════════════════════
   EXPEDICIÓN VERNE — landing scroll-telling
   Identidad definitiva: marino + ámbar + blanco · solo Montserrat
   ──────────────────────────────────────────────────────────────
   ⚠️ Esta hoja DA POR CARGADO `css/base.css`, que trae la fuente,
   los design tokens (`:root`), el reset, el anillo de foco, el
   skip-link y el grano. Se extrajeron ahí al nacer `formulario.html`
   para no tener la identidad escrita dos veces. `index.html` los
   enlaza en ese orden: base.css primero, esta después.
   ══════════════════════════════════════════════════════════════ */


/* ── Preloader: la bienvenida de la expedición ───────────────
   Tres tiempos, y ninguno es decorativo:
   1. El instrumento se ENCIENDE — el aro se dibuja, la aguja aparece
      y empieza a oscilar buscando el norte mientras la página carga.
   2. La bienvenida ENTRA — cada línea sale de detrás de su máscara
      (`.pre-mask`), y el lockup letra a letra. Nada se funde: todo
      llega de fuera del recorte, que es lo que da peso al texto.
   3. Se ZARPA — la aguja fija el norte, el horizonte se enciende en
      ámbar y el telón se abre en dos por esa costura, descubriendo
      el hero que ya está animándose debajo.

   Regla de oro de esta pantalla: en la salida SOLO se animan
   transform y opacity. Las dos hojas ocupan la pantalla entera con un
   degradado grande; animar cualquier otra cosa las obligaría a
   repintarse en cada frame del momento más visible de la landing. */
.preloader {
  position: fixed; inset: 0;
  z-index: 500;
  color: var(--blanco);
  display: grid; place-items: center;
  overflow: hidden;
}

/* Cada hoja pinta el degradado a TAMAÑO DE PANTALLA COMPLETA y enseña
   solo su mitad (`background-position`): juntas son indistinguibles de
   un fondo único. El 50.4% —y no 50%— es un solape deliberado de
   medio píxel: sin él, el redondeo del subpíxel deja una costura clara
   en el centro en pantallas con DPR fraccionario. */
.preloader-panel {
  position: absolute; left: 0; width: 100%;
  height: 50.4%;
  background-image:
    radial-gradient(ellipse 75% 65% at 50% 44%, var(--marino-claro) 0%, var(--marino) 55%, var(--marino-hondo) 100%);
  background-size: 100% 100vh;
  background-size: 100% 100lvh;   /* móvil: la barra del navegador no debe recortar el degradado */
  background-repeat: no-repeat;
  will-change: transform;
}
.preloader-panel-sup { top: 0; background-position: 50% 0; }
.preloader-panel-inf { bottom: 0; background-position: 50% 100%; }

/* El filo del horizonte. Nace invisible y sin escala: la timeline le
   da xPercent/yPercent (no el CSS) para poder tocar `scaleX` sin
   perder el centrado — GSAP reescribe la propiedad `transform` entera. */
.preloader-costura {
  position: absolute; top: 50%; left: 50%;
  /* De borde a borde: el corte es el horizonte de la escena, no un
     subrayado. La luz se concentra en el centro y se apaga en las
     esquinas, así las dos hojas parecen separarse por una rendija. */
  width: 100%; height: 1px;
  z-index: 2;
  opacity: 0;
  background: linear-gradient(90deg,
    transparent 0%, rgba(232, 160, 32, 0.35) 20%,
    var(--ambar) 38%, #fff3d6 50%, var(--ambar) 62%,
    rgba(232, 160, 32, 0.35) 80%, transparent 100%);
  box-shadow: 0 0 26px rgba(232, 160, 32, 0.5);
  pointer-events: none;
}

.preloader-inner { position: relative; z-index: 3; text-align: center; }

.preloader-brujula-wrap {
  position: relative;
  display: grid; place-items: center;
  margin: 0 auto 2rem;
}
.preloader-brujula {
  width: clamp(84px, 11vw, 116px);
  color: rgba(243, 237, 222, 0.85);
  display: block;
}
/* La onda del norte fijado. Solo existe durante la salida. */
.preloader-pulso {
  position: absolute; top: 50%; left: 50%;
  width: clamp(84px, 11vw, 116px); aspect-ratio: 1;
  border: 1px solid var(--ambar);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.brujula-letra {
  font-family: 'Montserrat', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  fill: currentColor;
  opacity: 0.8;
}

/* Máscara de línea: el recorte que convierte un fade en una entrada.
   El `padding-bottom` da aire a las descendentes y a la cursiva, que
   sin él quedaban rebanadas por el propio overflow. */
.pre-mask { display: block; overflow: hidden; padding-bottom: 0.12em; }
.pre-line { display: block; }
.preloader-lockup .mch { display: inline-block; }

.preloader-bienvenida {
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1rem, 2.1vw, 1.35rem);
  letter-spacing: 0.04em;
  color: rgba(245, 244, 239, 0.75);
  margin-bottom: 0.5rem;
}
.preloader-lockup {
  font-weight: 800;
  font-size: clamp(1.6rem, 4vw, 2.6rem);
  letter-spacing: 0.22em;
  line-height: 1.22;
  /* El `letter-spacing` abre un hueco al final de cada línea que
     descentra el lockup. Se compensa aquí, no en cada línea. */
  text-indent: 0.22em;
}

/* Medidor de carga: 2px de hairline. El relleno se mueve por scaleX
   desde el borde izquierdo (nunca por `width`: eso sería layout). */
.preloader-medidor {
  width: min(56vw, 15rem); height: 2px;
  margin: 2.3rem auto 1.1rem;
  background: rgba(243, 237, 222, 0.16);
  border-radius: 2px;
  overflow: hidden;
}
.preloader-medidor-fill {
  display: block; height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, rgba(232, 160, 32, 0.6), var(--ambar));
}
.preloader-status, .pre-status-txt { display: block; }
.preloader-status {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(243, 237, 222, 0.55);
}

/* ── Velo de salto: el índice corta, no recorre ───────────────
   Los enlaces del nav ya no viajan por toda la película de scroll
   para llegar a su sección (seis segundos de escenas en avance
   rápido que, además, Lenis abortaba a mitad en cuanto el dedo
   rozaba la pantalla). Ahora el scroll salta en seco y este velo
   cubre el corte: se cierra, la página aparece ya en el destino,
   se abre. Lo gobierna `saltar()` en main.js — si se tocan estas
   duraciones, hay que tocar allí VELO_CIERRA y VELO_ABRE.

   z-index 400: por encima de todo el chrome (nav 110, panel móvil
   105, rail de progreso 120) y por debajo del preloader (500), que
   sigue mandando mientras la expedición carga. */
.velo-salto {
  position: fixed; inset: 0;
  z-index: 400;
  opacity: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 75% 65% at 50% 44%, var(--marino-claro) 0%, var(--marino) 55%, var(--marino-hondo) 100%);
  transition: opacity 320ms var(--ease-estandar);
}
.velo-salto.visible {
  opacity: 1;
  pointer-events: auto;   /* congela la interacción mientras dura el corte */
  transition-duration: 200ms;
}

/* ── Chrome fijo ────────────────────────────────────────────── */
.progress-rail {
  position: fixed; top: 0; left: 0; right: 0;
  height: 2px; z-index: 120;
  background: transparent;
}
.progress-fill {
  display: block; height: 100%;
  background: var(--ambar);
  transform-origin: left center;
  transform: scaleX(0);
}

/* ── Barra de mando flotante ──────────────────────────────────
   Tres zonas y una jerarquía: co-marca (Expedición Verne · Aludium)
   — índice con píldora viva — acción. Arriba del todo la cáscara es
   transparente para no pisar la portada; al deslizar condensa en una
   píldora de cristal. El color NO se repite selector a selector: lo
   gobiernan cinco variables que reescriben las clases de superficie
   (night / dark / paper), así que añadir un estado es una regla, no
   ocho. Esas clases las pinta una sola máquina de estado en main.js. */
.nav {
  --nav-fg: var(--blanco);
  --nav-fg-suave: rgba(245, 244, 239, 0.62);
  --nav-shell-bg: transparent;
  --nav-shell-bd: transparent;
  --nav-shell-sombra: none;
  --nav-blob: rgba(245, 244, 239, 0.13);
  --nav-filete: rgba(245, 244, 239, 0.28);

  position: fixed; top: 0; left: 0; right: 0;
  z-index: 110;
  padding: clamp(0.6rem, 1.5vh, 1rem) clamp(0.8rem, 3vw, 1.7rem);
  color: var(--nav-fg);
  transition: color var(--dur-2) var(--ease-estandar), padding var(--dur-3) var(--ease-premium);
}
.nav-shell {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(0.9rem, 3vw, 2.4rem);
  max-width: 78rem;
  margin-inline: auto;
  padding: 0.45rem 0.45rem 0.45rem clamp(0.85rem, 1.5vw, 1.25rem);
  border: 1px solid var(--nav-shell-bd);
  border-radius: var(--radio-pill);
  background: var(--nav-shell-bg);
  box-shadow: var(--nav-shell-sombra);
  transition: background-color var(--dur-3) var(--ease-estandar),
    border-color var(--dur-3) var(--ease-estandar),
    box-shadow var(--dur-3) var(--ease-estandar);
}

/* ── Co-marca ── */
.nav-marca {
  display: inline-flex; align-items: center;
  gap: clamp(0.55rem, 1.1vw, 0.9rem);
}
.nav-marca-filete {
  flex-shrink: 0;
  width: 1px; height: 2.05rem;
  background: var(--nav-filete);
  transition: background-color var(--dur-2) var(--ease-estandar);
}
.nav-logo { display: inline-flex; align-items: center; }
/* Los ficheros permanecen ocultos hasta que logosDeMarca() confirma que
   AMBAS versiones han cargado: un logo a medias es peor que ninguno. */
.nav-logo img { display: none; width: auto; }
/* Jerarquía de la co-marca: Verne protagoniza, Aludium endosa.
   Los dos máster son de naturaleza distinta —Verne es una brújula maciza
   con su rótulo dentro (1.39:1), Aludium un wordmark fino y muy apaisado
   (4.67:1)— así que igualar alturas invierte el peso óptico: a la misma
   altura el wordmark salía casi el doble de ancho y el endosante
   gritaba más que el producto. Se compensa con la altura. */
.nav-logo-verne img { height: clamp(2.65rem, 3.75vw, 3.35rem); }
.nav-logo-aludium img { height: clamp(1rem, 1.35vw, 1.18rem); }
.nav-logo-txt {
  font-weight: 800;
  font-size: clamp(0.7rem, 1vw, 0.8rem);
  letter-spacing: 0.2em;
  white-space: nowrap;
}
.nav-logo-txt-aludium {
  font-weight: 600;
  font-size: clamp(0.85rem, 1.15vw, 0.96rem);
  letter-spacing: 0.02em;
  text-transform: lowercase;
}
.nav-logo.con-logo .nav-logo-txt { display: none; }
.nav-logo.con-logo .logo-claro,
.nav-logo.con-logo .logo-oscuro { display: block; }
/* Sobre papel manda la versión oscura; en cualquier otra superficie, la clara */
.nav-papel-scrolled .nav-logo.con-logo .logo-claro { display: none; }
.nav:not(.nav-papel-scrolled) .nav-logo.con-logo .logo-oscuro { display: none; }

/* ── Índice con píldora viva ──
   La píldora la mueve navIndice() (x + width por GSAP): sigue al
   puntero y regresa al acto activo al soltarlo. Nunca se anima con
   `transform: translateY` desde CSS — GSAP escribe ahí. */
.nav-links {
  position: relative;
  display: flex; justify-content: center;
  gap: 0.15rem;
  font-size: 0.94rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.nav-links a {
  position: relative; z-index: 1;
  padding: 0.58rem 1rem;
  border-radius: var(--radio-pill);
  color: var(--nav-fg-suave);
  white-space: nowrap;
  transition: color var(--dur-2) var(--ease-estandar);
}
.nav-links a:hover,
.nav-links a.es-activo { color: var(--nav-fg); }
.nav-blob {
  position: absolute;
  left: 0; top: calc(50% - 1.2rem);
  width: 0; height: 2.4rem;
  border-radius: var(--radio-pill);
  background: var(--nav-blob);
  opacity: 0;
  pointer-events: none;
  will-change: transform, width;
}

/* ── Acción ── */
.nav-acciones {
  display: flex; align-items: center; gap: 0.45rem;
  justify-self: end;
}
.nav-btn {
  display: inline-flex; align-items: center; gap: 0.45rem;
  height: 2.85rem;
  padding: 0 1.15rem 0 1.35rem;
  border-radius: var(--radio-pill);
  background: var(--ambar);
  color: var(--marino);
  font-size: 0.9rem; font-weight: 600;
  white-space: nowrap;
  box-shadow: 0 8px 20px -10px rgba(232, 160, 32, 0.6);
  transition: filter var(--dur-2) var(--ease-estandar), box-shadow var(--dur-2) var(--ease-estandar);
}
.nav-btn:hover { filter: brightness(1.06); box-shadow: 0 12px 26px -10px rgba(232, 160, 32, 0.72); }

/* ── Sonido: un ecualizador, no un altavoz ──
   El icono ES el estado. En silencio son cuatro barras al mínimo (un
   ecualizador parado); sonando, cada una late a su ritmo con duraciones
   primas entre sí para que no marchen a compás. Un altavoz tachado
   obligaría a leer una tachadura para saber si suena o no. */
.nav-sonido {
  display: grid;
  place-items: center;
  width: 2.55rem; height: 2.55rem;
  flex-shrink: 0;
  border: 1px solid var(--nav-filete);
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  transition: border-color var(--dur-2) var(--ease-estandar),
    background var(--dur-2) var(--ease-estandar), color var(--dur-2) var(--ease-estandar);
}
.nav-sonido[hidden] { display: none; }
.nav-sonido:hover { background: var(--nav-blob); }
.nav-sonido-barras {
  display: flex; align-items: center; gap: 2px;
  height: 0.8rem;
}
.nav-sonido-barras i {
  display: block;
  width: 2px; height: 24%;
  border-radius: 1px;
  background: currentColor;
  transform-origin: 50% 50%;
  transition: height var(--dur-2) var(--ease-estandar);
}
.nav-sonido.is-sonando {
  color: var(--ambar);
  border-color: rgba(232, 160, 32, 0.55);
}
.nav-sonido.is-sonando i { animation: ecualizador 1s var(--ease-cine) infinite alternate; }
.nav-sonido.is-sonando i:nth-child(1) { animation-duration: 0.83s; }
.nav-sonido.is-sonando i:nth-child(2) { animation-duration: 1.19s; }
.nav-sonido.is-sonando i:nth-child(3) { animation-duration: 0.67s; }
.nav-sonido.is-sonando i:nth-child(4) { animation-duration: 1.03s; }
@keyframes ecualizador { from { height: 22%; } to { height: 100%; } }
/* El campamento no está en el índice: cuando se está leyendo, es la
   propia acción la que se señala. Así ninguna franja de la página
   queda sin decir dónde estás. */
.nav-btn.es-activo { box-shadow: 0 0 0 3px var(--nav-blob), 0 12px 26px -10px rgba(232, 160, 32, 0.72); }
.nav-btn-flecha { width: 15px; height: 15px; flex-shrink: 0; transition: transform var(--dur-2) var(--ease-premium); }
.nav-btn-flecha path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.nav-btn:hover .nav-btn-flecha { transform: translateX(3px); }

/* ── Superficies ──
   Noche arriba del todo: cero cáscara, la portada manda. */
.nav-invert {
  --nav-fg: var(--blanco);
  --nav-fg-suave: rgba(245, 244, 239, 0.62);
  --nav-blob: rgba(245, 244, 239, 0.13);
  --nav-filete: rgba(245, 244, 239, 0.28);
}
/* Cristal marino */
.nav.nav-scrolled,
.nav.nav-dark-surface {
  --nav-fg: var(--blanco);
  --nav-fg-suave: rgba(245, 244, 239, 0.68);
  --nav-shell-bg: rgba(10, 24, 45, 0.6);
  --nav-shell-bd: rgba(245, 244, 239, 0.14);
  --nav-shell-sombra: inset 0 1px 0 rgba(245, 244, 239, 0.07), 0 18px 40px -22px rgba(2, 8, 20, 0.9);
  --nav-blob: rgba(245, 244, 239, 0.13);
  --nav-filete: rgba(245, 244, 239, 0.26);
}
/* Cristal papel */
.nav.nav-papel-scrolled {
  --nav-fg: var(--tinta);
  --nav-fg-suave: var(--tinta-suave);
  --nav-shell-bg: rgba(250, 249, 244, 0.76);
  --nav-shell-bd: rgba(15, 35, 64, 0.1);
  --nav-shell-sombra: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 16px 36px -22px rgba(6, 15, 31, 0.5);
  --nav-blob: rgba(15, 35, 64, 0.07);
  --nav-filete: rgba(15, 35, 64, 0.16);
}
/* El desenfoque solo existe cuando hay cáscara: a fondo transparente
   dibujaría una banda borrosa sobre la escena sin nada que la explique. */
.nav.nav-scrolled .nav-shell,
.nav.nav-papel-scrolled .nav-shell {
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
}
.nav.nav-scrolled,
.nav.nav-papel-scrolled { padding-top: 0.5rem; padding-bottom: 0.5rem; }

/* Con el panel móvil abierto la barra flota POR ENCIMA de él (110 vs
   105): adopta su superficie nocturna para no dejar una píldora de
   cristal claro recortada sobre el marino del panel. */
body.menu-open .nav {
  --nav-fg: var(--blanco);
  --nav-fg-suave: rgba(245, 244, 239, 0.62);
  --nav-shell-bg: transparent;
  --nav-shell-bd: transparent;
  --nav-shell-sombra: none;
  --nav-blob: rgba(245, 244, 239, 0.13);
  --nav-filete: rgba(245, 244, 239, 0.28);
}
body.menu-open .nav .nav-shell { backdrop-filter: none; -webkit-backdrop-filter: none; }
body.menu-open .nav .nav-logo.con-logo .logo-claro { display: block; }
body.menu-open .nav .nav-logo.con-logo .logo-oscuro { display: none; }

/* Cortes: con la acción larga («Completar mi Perfil de Explorador»)
   los cuatro rótulos + la acción piden ~1180px de barra. Por debajo
   de 1220 el índice cede al menú; la acción aguanta hasta 620, donde
   el panel móvil ya la lleva de primera. */
@media (max-width: 1220px) {
  .nav-links { display: none; }
}
@media (max-width: 620px) {
  .nav-btn { display: none; }
  .nav-marca { gap: 0.5rem; }
}

/* ── Tipos comunes ──────────────────────────────────────────── */

.line { display: block; overflow: hidden; }
.line-inner { display: inline-block; will-change: transform; }

.btn {
  display: inline-block;
  border: 1.5px solid var(--tinta);
  padding: 0.95rem 2.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  position: relative;
  overflow: hidden;
  transition: color var(--dur-2) var(--ease-estandar);
  z-index: 1;
  background: transparent;
}
.btn::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--tinta);
  transform: translateY(101%);
  transition: transform var(--dur-3) var(--ease-cine);
}
.btn:hover { color: var(--papel); }
.btn:hover::before { transform: translateY(0); }

/* ══════════ ACTO 0 · HERO — MIRADOR → VALLE → LENTE (paper-cut) ══════════ */
.hero {
  /* El vuelo y el manifiesto comparten un único plano sticky. La altura
     mantiene la misma densidad de scroll que tenían ambas escenas separadas.
     (543vh, no 760: el manifiesto se acorta a un único beat — sin las
     dos tesis previas — así que la caja de scroll baja en la misma
     proporción para no dejar tramo muerto al final.) */
  height: 543vh;
  position: relative;
  /* ── La cola muerta del hero ──────────────────────────────────────
     Un `sticky` de 100vh dentro de una caja de altura H queda clavado
     hasta H−100vh y luego se desliza 100vh hasta salir. Esos 100vh de
     cola son ESTRUCTURALES —no dependen de H— y durante ellos solo se
     ve el último fotograma del hero mientras La Ruta, que no empieza a
     subir hasta que la cola acaba, tarda otra pantalla en llegar.
     Resultado: una pantalla entera de vacío.
     Este margen negativo sube la sección siguiente justo esa cola, de
     modo que La Ruta ocupa el encuadre en el instante en que la
     timeline termina. Va en el HERO a propósito, no en `.etapas`: esa
     sección la envuelve un pin-spacer de ScrollTrigger y tocar su caja
     descuadraría el pin horizontal. */
  margin-bottom: -100vh;
  margin-bottom: -100svh;
}
.hero-sticky {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
  overflow: clip;
  display: grid; place-items: center;
  background:
    linear-gradient(180deg, rgba(6, 15, 31, 0) 58%, rgba(46, 32, 16, 0.14) 100%),
    radial-gradient(ellipse 75% 65% at 50% 44%, var(--marino-claro) 0%, var(--marino) 52%, var(--marino-hondo) 100%);
}

/* Wrappers de Mouse Tilt 3D (el scroll anima los hijos; el tilt, el wrapper) */
.tilt-capa {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  will-change: transform;
}
.tilt-cielo { z-index: 0; }
.tilt-repisa { z-index: 6; }

.cielo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  will-change: transform;
}
.twinkles { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.twinkle {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: #eaf2ff;
  box-shadow: 0 0 8px 2px rgba(190, 215, 250, 0.55);
}

/* ── El paisaje paper-cut: el valle nocturno ────────────────── */
.paisaje {
  position: absolute; inset: 0;
  z-index: 2;
  pointer-events: none;
  will-change: transform;
}
/* Resplandor de horizonte tras las montañas: luna fría + calidez de aldea */
.paisaje::before {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 46% 30% at 62% 84%, rgba(224, 164, 84, 0.18) 0%, transparent 70%),
    radial-gradient(ellipse 80% 45% at 52% 80%, rgba(108, 142, 204, 0.18) 0%, transparent 65%);
}
.capa {
  position: absolute; left: 0; bottom: 0;
  width: 100%;
  will-change: transform;
}
/* Perspectiva aérea: lo lejano, más claro y desaturado.
   Las montañas van OSCURAS: son escenario, no protagonistas */
.capa-lejos {
  z-index: 1;
  bottom: 14vh;
  opacity: 0.62;
  filter: brightness(0.96) saturate(0.6);
}
.capa-cerca {
  z-index: 3;
  bottom: -2px;
  filter: brightness(0.64) contrast(1.08) saturate(0.85);
}

/* Luna velada: presencia atmosférica, no protagonista */
.luna-papel {
  position: absolute;
  top: 7vh; right: 13vw;
  width: clamp(64px, 6.5vw, 104px);
  opacity: 0.55;
  filter: blur(1.5px) drop-shadow(0 0 44px rgba(240, 220, 170, 0.5));
  will-change: transform;
}

.globo-wrap {
  position: absolute;
  z-index: 2;
  top: 7vh; right: 5vw;
  width: clamp(270px, 24vw, 450px);
  will-change: transform;
}
.js #globoWrap {
  opacity: 0;
  visibility: hidden;
}
.globo-img {
  width: 100%; display: block;
  filter: drop-shadow(0 34px 60px rgba(0, 0, 0, 0.55));
  will-change: transform;
}
/* Halo del farol que cuelga de la cesta (fracciones de la imagen) */
.globo-farol-glow {
  position: absolute;
  left: 79%; top: 78.5%;
  width: 34%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 214, 130, 0.5) 0%, rgba(255, 180, 80, 0) 68%);
  will-change: transform, opacity;
}

/* Iluminación volumétrica y bruma atmosférica */
.rayos-luz {
  position: absolute; inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    radial-gradient(ellipse 65% 55% at 50% 45%, rgba(127, 178, 217, 0.1) 0%, rgba(232, 176, 75, 0.07) 45%, transparent 75%);
  opacity: 0.68;
  animation: pulseBruma 9s ease-in-out infinite alternate;
}
@keyframes pulseBruma {
  0% { opacity: 0.5; transform: scale(1) rotate(0deg); }
  100% { opacity: 0.85; transform: scale(1.06) rotate(1deg); }
}

/* Bandas de bruma flotando sobre el valle (profundidad atmosférica) */
.bruma {
  position: absolute;
  left: -12%; width: 124%;
  z-index: 3;
  pointer-events: none;
  background: radial-gradient(ellipse 55% 90% at 50% 50%, rgba(140, 170, 220, 0.1), transparent 70%);
}
.bruma-a { bottom: 5vh; height: 24vh; animation: brumaDrift 26s ease-in-out infinite alternate; }
.bruma-b { bottom: 17vh; height: 18vh; opacity: 0.7; animation: brumaDrift 34s ease-in-out infinite alternate-reverse; }
@keyframes brumaDrift {
  from { transform: translateX(-2.5%); }
  to { transform: translateX(2.5%); }
}
/* Con el hero fuera de pantalla, su vida ambiental se congela
   (el JS pone .fuera-hero en <body> al cruzar el límite). */
.fuera-hero .bruma-a,
.fuera-hero .bruma-b,
.fuera-hero .rayos-luz { animation-play-state: paused; }

/* ── Primer plano: la repisa de roca del mirador ────────────── */
.repisa {
  position: absolute;
  left: -2vw; right: -2vw; bottom: -7vh;
  width: 104vw;
  will-change: transform;
  /* Solo brightness (una multiplicación de color, gratis). El
     drop-shadow de 40px que llevaba se re-aplicaba EN CADA FRAME sobre
     una textura de 104vw mientras el vuelo de dron la escala a 2.2 —
     justo solapado con la travesía de nubes, que es donde la página
     se atragantaba. Sobre un valle nocturno con la escena-scrim encima
     su aporte visual era inapreciable; su coste, no. */
  filter: brightness(0.82);
}
/* ── Luciérnagas ────────────────────────────────────────────── */
.luciernagas {
  position: absolute; inset: 0;
  z-index: 7;
  pointer-events: none;
}
.luciernaga {
  position: absolute;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #ffd98c;
  box-shadow: 0 0 10px 3px rgba(255, 200, 110, 0.45);
  opacity: 0;
  will-change: transform, opacity;
}

/* ── El farol del visitante: haz cálido que sigue al puntero ──
   Va bajo el scrim (z-7): ilumina el paisaje sin ensuciar los textos */
.farol-cursor {
  position: absolute;
  left: 0; top: 0;
  z-index: 7;
  width: 58vmin; aspect-ratio: 1;
  margin: -29vmin 0 0 -29vmin; /* centrado en el puntero */
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}
.farol-cursor-halo {
  position: absolute; inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 214, 130, 0.15) 0%,
    rgba(255, 190, 90, 0.07) 40%,
    rgba(255, 180, 80, 0) 68%);
  mix-blend-mode: screen;
  will-change: transform, opacity;
}
.farol-cursor-nucleo {
  position: absolute; inset: 36%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 226, 160, 0.18) 0%, rgba(255, 200, 110, 0) 70%);
  mix-blend-mode: screen;
}
@media (hover: none), (pointer: coarse) {
  .farol-cursor { display: none; }
}

/* ── Portada fotográfica (beat 0) ────────────────────────────
   Un fotograma real de la expedición sobre el paper-cut. Va a z-9
   —por encima de la escena entera— porque
   durante el primer pantallazo ES la escena: el valle por capas
   espera intacto debajo y aparece cuando esta se disuelve.
   Va DESNUDA, sin velo ni viñeteado propios (queda sobre `.escena-scrim`
   y `.hero-sticky::after`, ambos z-8, así que ninguno la toca): el
   contraste del bloque editorial lo sostiene la penumbra local de
   `.portada::before`, que es la mitad izquierda de la foto —mar y
   noche abierta— haciendo de fondo. */
.hero-foto {
  position: absolute; inset: 0;
  z-index: 9;
  overflow: hidden;
  pointer-events: none;
}
.hero-foto picture { display: contents; }
.hero-foto img {
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
  object-position: 62% 56%;
  transform-origin: 64% 54%;
  /* Sin velo y SIN tratamiento: ni filtro de color ni enfoque. El
     máster (`fondo-landing.png`) ya viene con su luz corregida y se
     entrega tal cual — solo conversión a WebP de alta calidad. */
  /* La deriva vive en la imagen; el contenedor lo gobierna GSAP
     (disolución al arrancar el vuelo). Dos transformaciones que no
     se pisan. Y el recorrido de escala se mantiene CORTO: cada punto
     de zoom es resolución que se pierde — se sirve a 1672px (el
     máster es 4096, así que hay margen si algún día se quiere más). */
  animation: fotoDeriva 38s ease-in-out infinite alternate;
}
@keyframes fotoDeriva {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.045) translate3d(-0.8%, -0.6%, 0); }
}
.fuera-hero .hero-foto img { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .hero-foto img { animation: none; transform: scale(1.04); }
}
@media (max-width: 760px) {
  /* En vertical el recorte deja fuera medio encuadre: se centra en los
     exploradores y el faro, y el velo pasa a mandar de abajo arriba
     porque el texto ya no tiene una mitad libre a la izquierda. */
  /* ── En vertical, la foto y el texto dejan de compartir sitio ──
     Superponerlos en móvil no tiene salida: a 390×844 `cover` ajusta la
     imagen al alto exacto, el eje vertical se queda sin juego y los
     exploradores caen clavados a media pantalla — justo donde el bloque
     editorial necesita ponerse. Cualquier reparto del encuadre acaba
     tapando al sujeto o forzando un velo que apaga la escena.
     Así que se reparte la PANTALLA, no el encuadre: la foto ocupa la
     banda alta y el texto vive debajo, sobre el marino limpio del
     propio hero. La imagen no lleva nada encima y el texto llega a
     contraste pleno. En escritorio no cambia nada: sigue a sangre. */
  /* Las tres medidas del reparto vertical, en un solo sitio: alto del
     bloque editorial, su pie y el aire que lo separa de la foto. La
     banda de imagen es lo que sobra. `--portada-alto` está MEDIDO y es
     el MÁXIMO del rango móvil (firma + claim de dos líneas + subtítulo
     + una acción): 13,65rem a 600-760px, que es donde más crece, y
     13,55rem a 320px, donde el subtítulo se va a tres líneas.
     Bajó de 15,75rem al retirarse el segundo CTA («Ver el itinerario»):
     sobraban 3,4rem y el hueco entre foto y texto se iba a ~98px en vez
     de los ~45px del reparto. Si el copy cambia de líneas, se remide. */
  .hero-sticky {
    --portada-alto: 13.75rem;
    /* Pie de seguridad para pantallas bajas (móvil en horizontal): con
       el bloque editorial midiendo 13,75rem, subirlo aquí lo empujaría
       contra el suelo de 30svh de la imagen y se solaparían. En
       vertical manda el valor generoso de la media query de abajo. */
    --portada-pie: clamp(3.75rem, 9vh, 5.5rem);
    --portada-aire: 2.75rem;
  }

  /* La CAPA sigue cubriendo el viewport entero —debajo espera el
     paper-cut y no puede asomar por la banda de texto— y lleva el
     marino del propio hero como suelo. Lo que se reduce es la IMAGEN. */
  .hero-foto {
    background: linear-gradient(180deg,
      #040b17 0%, var(--marino-hondo) 34%, #071324 100%);
  }
  .hero-foto img {
    /* La banda de imagen se calcula CONTRA el bloque de texto, no en
       fracciones fijas de pantalla: en una de 640px un 62svh dejaba el
       titular encima del mapa. Descontando bloque, pie y aire, el hueco
       entre foto y texto sale igual (~45px) en cualquier alto. */
    height: 56vh;
    height: max(30svh, calc(100svh - var(--portada-alto) - var(--portada-pie) - var(--portada-aire)));
    /* Sin la presión del texto, el encuadre puede abrirse: entran los
       dos exploradores, el camino de luces, el faro y el mapa, que es
       donde está el gancho. */
    object-position: 58% 42%;
    /* El corte inferior se disuelve en el marino en vez de cortar en
       seco. Es una máscara de composición, no un velo: no toca el color
       de la foto, solo dónde deja de existir. */
    -webkit-mask-image: linear-gradient(180deg, #000 68%, rgba(0,0,0,0.72) 84%, rgba(0,0,0,0.26) 94%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 68%, rgba(0,0,0,0.72) 84%, rgba(0,0,0,0.26) 94%, transparent 100%);
    /* La deriva se retira aquí: la máscara viaja con el transform de la
       imagen y el borde del fundido bailaría con ella. */
    animation: none;
    transform: none;
  }
}

/* El bloque editorial se despega del pie: pegado al borde inferior la
   portada no respiraba y el CTA quedaba en el filo. Como `--portada-pie`
   RESTA en el alto de `.hero-foto img`, subirlo mueve el texto hacia
   arriba y encoge la banda de imagen en la misma medida, así que el aire
   entre foto y texto (`--portada-aire`) sigue intacto.
   Va con `min-height` porque solo hay margen para regalar cuando la
   pantalla es alta: en horizontal el reparto no da de sí y se queda con
   el pie de seguridad de arriba. */
@media (max-width: 760px) and (min-height: 640px) {
  .hero-sticky { --portada-pie: clamp(8rem, 24vh, 15rem); }
}

/* ══════════ EL MAR DE NUBES · la costura del primer acto ══════════
   La portada fotográfica y el paisaje por capas NO se cruzan en fundido.
   Un fundido obliga a que exista un fotograma con las dos escenas a la
   vez al 50 %, y ahí es donde se delata el cambio de registro (foto ↔
   recorte): el ojo compara texturas y lee «cambio de imagen», no
   «avance de cámara».
   En su lugar la cámara atraviesa un banco de nubes. El corte real
   sucede con el encuadre cubierto al 100 %, así que no hay fotograma
   comparable, y al otro lado el paisaje ya está en marcha a la misma
   velocidad que traía la foto: se lee como un plano continuo.

   Sin imagen a propósito: son gradientes radiales desenfocados. Eso lo
   hace agnóstico del arte —sirve igual para el paper-cut de hoy que
   para los recortes fotográficos de mañana— y deja toda la animación
   en transform + opacity, lo único que el compositor mueve gratis.
   El `blur` va FIJO en el CSS y nunca lo toca la timeline: animar
   `filter` dentro de un scrub repinta la capa entera en cada frame.  */
.mar-nubes {
  position: absolute;
  /* Sobresale del encuadre: al escalar hacia la cámara, los bordes de
     las bandas no pueden asomar nunca por los laterales. */
  inset: -20% -25%;
  z-index: 10;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity;
}
/* El banco entero es UN canvas pre-horneado (pintarNubes, js/main.js):
   la misma composición de cúmulos —panza oscura + cresta clara, poso
   ámbar del farol abajo— pintada una vez con el desenfoque incluido.
   Aquí solo queda su geometría: llena el contenedor y el compositor lo
   estira con el transform del scrub sin volver a rasterizar nada.
   Las cifras de cada cúmulo viven en NUBE_BANDAS (js/main.js). */
.nube-lienzo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* Velo de cierre: garantiza opacidad TOTAL en el instante del cambio —
   entre cúmulo y cúmulo queda hueco a propósito, y por uno de esos
   huecos se vería el corte.
   Va CLARO, no oscuro. Atravesar un banco de nubes con luna llena
   ILUMINA: la primera versión usaba marino profundo y el cruce parecía
   un fundido a negro. Este es el vapor recibiendo la luna, con el poso
   cálido del farol abajo — la escena se blanquea un instante y sale al
   otro lado, que es como se ve de verdad desde el aire. */
.nube-velo {
  position: absolute; inset: 0;
  display: block;
  background:
    radial-gradient(ellipse 58% 40% at 47% 90%, rgba(198, 138, 66, 0.4) 0%, rgba(198, 138, 66, 0) 72%),
    /* Núcleo luminoso pero CAÍDA a marino en los bordes. Plano y pálido
       de lado a lado —como salió la primera vez— es un pico de valor
       que se sale de la paleta y delata que hay una placa encima; con
       la caída, el encuadre lee «luna detrás del vapor» y conserva el
       viñeteado que tiene el resto del hero. */
    /* Paradas OPACAS (sin alpha). Con 0.94-0.96 —que es como salió la
       primera vez— el 5 % restante bastaba para ver el fantasma de la
       foto a través del sello: se distinguían la brújula y el logo de
       la mochila justo en el frame del cambio. El volumen lo pone el
       COLOR, nunca la transparencia; la que se anima es la opacidad del
       elemento, que sí llega a 1. */
    radial-gradient(ellipse 74% 58% at 52% 40%, rgb(136, 172, 214) 0%, rgb(74, 110, 158) 44%, rgb(32, 60, 100) 100%);
  will-change: opacity;
  opacity: 0;
}
@media (max-width: 760px) {
  /* En vertical el banco salía como un BLOQUE azul, no como vapor: las
     elipses van en % del ancho de la banda, y a 390px de ancho salen
     siete cúmulos diminutos que se funden en una pared lisa.
     Un encuadre estrecho pide lo contrario —tres o cuatro panzas
     GRANDES— así que se ensancha el contenedor muy por fuera del
     viewport: las mismas elipses, medidas contra un ancho mayor, se
     vuelven grandes en píxeles y solo se ve el tramo central.
     El resto del ajuste vertical (bandas más altas, blur 17px) vive en
     pintarNubes (js/main.js), que repinta el lienzo al redimensionar. */
  .mar-nubes { inset: -26% -62%; }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin travesía no hay banco de nubes que cruzar: la capa no debe
     poder aparecer ni siquiera un frame. */
  .mar-nubes { display: none; }
}

/* ── Scrim: grading azul noche en gradiente — protege la zona del
   texto (izquierda) sin apagar la escena entera ── */
.escena-scrim {
  position: absolute; inset: 0;
  z-index: 8;
  pointer-events: none;
  background: linear-gradient(100deg,
    rgba(6, 15, 31, 0.6) 0%,
    rgba(8, 19, 38, 0.38) 44%,
    rgba(8, 19, 38, 0.3) 100%);
}

/* Scrim de lectura: marino profundo por la izquierda, solo mientras
   las páginas de la bitácora están en pantalla (lo anima el JS) */
.scrim-lectura {
  position: absolute; inset: 0;
  z-index: 8;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(95deg,
    rgba(6, 15, 31, 0.85) 0%,
    rgba(8, 19, 38, 0.55) 34%,
    rgba(8, 19, 38, 0) 62%);
  will-change: opacity;
}

/* El recorte circular vive en variables CSS que anima GSAP. Escribirlo
   a mano desde un onUpdate dejaba el radio desincronizado al invertir
   el scroll (GSAP no revierte lo que no gobierna) y el día tapaba o
   destapaba a destiempo. Ahora la timeline es la única fuente. */
.amanecer {
  position: absolute;
  inset: auto;
  top: 0; left: 0;
  width: 100%; height: 100%;
  align-self: start;
  justify-self: start;
  z-index: 10;
  opacity: 0;
  visibility: hidden;
  background: transparent;
  pointer-events: none;
  overflow: hidden;
  --iris-r: 0px;
  --iris-x: 50%;
  --iris-y: 50%;
  clip-path: circle(var(--iris-r) at var(--iris-x) var(--iris-y));
}
/* El lienzo interior: siempre a pantalla completa y sin transform
   (el reveal es el clip-path del padre, no una escala de esta capa). */
.amanecer-lienzo {
  position: absolute;
  inset: 0;
}

/* El día se revela con un clip-path circle() sobre .amanecer (círculo
   de verdad, anclado a la lente): el fondo va siempre pintado y es el
   recorte el que lo descubre. Detrás sigue el valle, vivo y creciendo,
   hasta que el recorte lo tapa del todo — sin túnel negro de por medio. */
/* Superficie de día: papel técnico. Tres capas, no una — la rejilla
   ENMARCA (enmascarada hacia los bordes, nunca papel milimetrado bajo
   la tipografía) y la luz da el volumen: cálida arriba, donde acaba de
   entrar el amanecer; fría abajo, para asentar la escena. */
.amanecer-bg {
  position: absolute;
  inset: 0;
  background-color: var(--papel);
}
/* 1 · Estructura: rejilla fina con una línea maestra cada 4 módulos.
   La máscara radial le abre un claro al centro-izquierda, que es
   donde viven las tesis. */
.amanecer-bg::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(90deg, rgba(15,35,64,0.075) 1px, transparent 1px),
    linear-gradient(rgba(15,35,64,0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(15,35,64,0.04) 1px, transparent 1px),
    linear-gradient(rgba(15,35,64,0.033) 1px, transparent 1px);
  background-size: 22rem 22rem, 22rem 22rem, 5.5rem 5.5rem, 5.5rem 5.5rem;
  /* Caída larga (12% → 100%): con un corte corto las líneas maestras
     dibujaban rectángulos y la rejilla se leía como paneles. */
  -webkit-mask-image: radial-gradient(ellipse 72% 68% at 40% 50%, transparent 12%, #000 100%);
  mask-image: radial-gradient(ellipse 72% 68% at 40% 50%, transparent 12%, #000 100%);
}
/* 1·bis · El territorio: lo que se ve por el catalejo.
   Vive DENTRO de `.amanecer-bg`, así que pinta sobre su color de papel
   y bajo su capa de luz (`::after`), que es la que cohesiona todo. No
   toca el iris: el recorte es `clip-path` del abuelo `.amanecer` y le da
   igual lo que haya pintado dentro. Y no lleva transform ni escala —la
   regla dura de esta capa— así que no añade coste de compositor al
   tramo caro; es una textura estática que se sube una vez.
   ⚠️ La FUERZA vive en el alfa de la máscara, NO en `opacity`: esa
   propiedad la gobierna GSAP (el mapa se disuelve antes del relevo a La
   Ruta) y dos escritores sobre la misma propiedad es el fallo clásico
   de la casa. La geometría de la máscara es la misma que la de la
   rejilla, para que territorio y retícula estén de acuerdo, y abre un
   claro en el centro-izquierda: ahí viven las tesis y ahí el mapa tiene
   que desaparecer del todo. Nunca relieve bajo la tipografía. */
.amanecer-mapa {
  position: absolute;
  inset: 0;
  background-image: url(../assets/escenas/mapa-expedicion.webp);
  background-size: cover;
  background-position: 50% 45%;
  /* Tres máscaras que se multiplican (`intersect`):
     1 · el claro central-izquierdo, donde se leen las tesis;
     2 · la banda superior, que es donde va la firma del marco;
     3 · la banda derecha, que es donde va el folio vertical.
     Las dos últimas no son estética: MEDIDO, el relieve marino dejaba
     esos dos rótulos de 9.6px a 1.30:1 y 1.61:1 sobre un suelo de 4.5:1.
     Y son `--tinta-suave`, un tono medio que necesita fondo claro sí o
     sí: oscurecerlos no arregla nada (marino sobre ese gris da 3.04:1) y
     aclararlos los mata en el resto de la página, que es papel liso.
     Además es lo correcto de diseño: el marco en L es el invariante del
     manifiesto, así que el territorio vive DENTRO del marco, no debajo. */
  -webkit-mask-image:
    radial-gradient(ellipse 72% 68% at 40% 50%, transparent 10%, rgba(0,0,0,0.38) 52%, rgba(0,0,0,0.62) 100%),
    linear-gradient(180deg, transparent 0%, transparent 9%, #000 19%),
    linear-gradient(270deg, transparent 0%, transparent 4%, #000 13%);
  mask-image:
    radial-gradient(ellipse 72% 68% at 40% 50%, transparent 10%, rgba(0,0,0,0.38) 52%, rgba(0,0,0,0.62) 100%),
    linear-gradient(180deg, transparent 0%, transparent 9%, #000 19%),
    linear-gradient(270deg, transparent 0%, transparent 4%, #000 13%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  pointer-events: none;
}

/* 2 · Luz: el rescoldo del amanecer arriba y el peso del marino abajo.
   Sin esto el papel es plano y la escena se cae. */
.amanecer-bg::after {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 74% 44% at 52% -8%, rgba(232, 160, 32, 0.14), transparent 68%),
    radial-gradient(ellipse 60% 40% at 8% 96%, rgba(15, 35, 64, 0.09), transparent 70%),
    linear-gradient(180deg, transparent 62%, rgba(15, 35, 64, 0.055) 100%);
}

/* (Sin aro de latón ni bloom de lente: el círculo entra desnudo. Además
   de ser lo pedido, ambos eran capas caras justo en el peor momento —
   cinco box-shadows escalados y un mix-blend-mode a pantalla completa
   sobre el valle ampliado.) */

.hero-beat {
  position: absolute;
  z-index: 9;
  opacity: 0;
  visibility: hidden;
}

/* Portada-póster: composición asimétrica anclada a la izquierda */
.hero-title {
  inset: 0;
  opacity: 1; visibility: visible;
  will-change: transform, opacity;
}
.portada {
  position: absolute;
  /* Centrada: el explorador (izq.) y el globo (dcha.) la enmarcan */
  left: 50%;
  top: 45%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: max-content;
  max-width: min(92vw, 64rem);
}
/* Penumbra ambiental tras el bloque de título (sin cajas recortadas:
   las sombras de texto grandes se clipaban con el overflow de .line) */
.portada::before {
  content: '';
  position: absolute;
  inset: -4rem -6rem;
  z-index: -1;
  background: radial-gradient(ellipse 58% 56% at 50% 48%, rgba(2, 5, 11, 0.5), transparent 72%);
  pointer-events: none;
}
/* Badge: una firma discreta, no un componente que compita */
.hero-badge {
  display: inline-flex; align-items: center; gap: 0.55rem;
  margin-bottom: 2.2rem;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(245, 244, 239, 0.68);
}
.badge-dot {
  position: relative;
  width: 5px; height: 5px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--ambar);
}
.badge-dot::after {
  content: '';
  position: absolute; inset: -4px;
  border-radius: 50%;
  border: 1px solid rgba(232, 160, 32, 0.6);
  animation: badgePulse 2.6s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
}
@keyframes badgePulse {
  0% { transform: scale(0.4); opacity: 1; }
  70%, 100% { transform: scale(1.8); opacity: 0; }
}

.hero-h1 { color: var(--blanco); }
.hero-h1 .ch { display: inline-block; will-change: transform; }

.hero-sub {
  margin-top: 1.4rem;
  font-weight: 400;
  font-size: clamp(0.88rem, 1.15vw, 1rem);
  color: rgba(245, 244, 239, 0.68);
  line-height: 1.65;
  text-shadow: 0 0 24px rgba(6, 15, 31, 0.9);
}

/* ── CTA único + text-link: jerarquía de acción clara ── */
.hero-ctas {
  margin-top: 2.2rem;
  display: flex; align-items: center; justify-content: center;
  gap: 1.8rem;
  flex-wrap: wrap;
}
.btn-hero {
  position: relative;
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.9rem 1.7rem;
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  overflow: hidden;
  will-change: transform;
  transition: box-shadow var(--dur-2) var(--ease-estandar);
}
.btn-hero:focus-visible {
  outline: 2px solid var(--ambar);
  outline-offset: 3px;
}
.btn-hero-primario {
  background: var(--ambar);
  color: var(--marino);
  box-shadow: 0 12px 30px -12px rgba(232, 160, 32, 0.5);
}
.btn-flecha {
  width: 13px; height: 13px;
  flex-shrink: 0;
}
.btn-flecha path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Misma cápsula que el primario y mismo tratamiento que `.est-video`
   (píldora blanca, sin borde): un solo lenguaje para «esto abre un
   vídeo» en toda la bitácora. */
.btn-hero-secundario {
  background: var(--blanco);
  color: var(--marino);
  border: 0;
  box-shadow: none;
}
.btn-hero-secundario .btn-hero-play {
  width: 1.15em; height: 1.15em;
  flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.6;
}
.btn-hero-secundario .btn-hero-play path { fill: currentColor; stroke: none; }


/* Línea muda de metadatos: ficha técnica sin ornamento */
.hero-meta {
  margin-top: 2.6rem;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--texto-noche-3);
  text-wrap: balance;
}
.hero-meta b {
  font-weight: 800;
  color: rgba(232, 160, 32, 0.85);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 760px) {
  .portada { top: 44%; }
  .hero-badge { letter-spacing: 0.22em; font-size: var(--fs-micro); }
  .hero-ctas { flex-direction: column; gap: 1.1rem; }
  .hero-meta { letter-spacing: 0.18em; max-width: 84vw; margin-left: auto; margin-right: auto; }
}


/* Viñeteado cinematográfico + protección de lectura arriba y abajo */
.hero-sticky::after {
  content: '';
  position: absolute; inset: 0;
  z-index: 8;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(3, 5, 10, 0.55) 0%, transparent 18%, transparent 64%, rgba(2, 4, 8, 0.68) 100%),
    radial-gradient(ellipse 92% 82% at 50% 45%, transparent 50%, rgba(2, 3, 7, 0.66) 100%);
}

/* ── La bitácora de travesía: la senda de hitos hacia el globo ── */
.bitacora {
  position: absolute; inset: 0;
  z-index: 9;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}


/* ── La estación de lectura: composición fija a la izquierda ──
   Los 3 hitos rotan siempre en el mismo sitio; el stepper de
   debajo va conquistando banderines */
.estacion {
  position: absolute;
  left: clamp(1.6rem, 6vw, 8rem);
  top: 50%;
  transform: translateY(-50%);
  width: min(24rem, 84vw);
  z-index: 2;
}
.est-pasos {
  position: relative;
  min-height: 11.5rem;
}
.est-paso {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity;
}
.est-titulo {
  font-weight: 800;
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  line-height: 1.18;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--blanco);
  text-shadow: 0 2px 18px rgba(4, 10, 20, 0.8);
}
.est-cuerpo {
  margin-top: 0.8rem;
  max-width: 21rem;
  font-size: 0.85rem;
  line-height: 1.62;
  color: rgba(245, 244, 239, 0.74);
  text-shadow: 0 1px 12px rgba(4, 10, 20, 0.9);
}

/* El enlace al vídeo de la expedición. Único elemento interactivo de
   la bitácora: el contenedor lleva pointer-events:none, así que el
   enlace lo recupera aquí. */
.est-video {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.2rem;
  padding: 0.55rem 1.05rem;
  border: 0;
  border-radius: var(--radio-pill);
  background: var(--blanco);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--marino);
  pointer-events: auto;
}
.est-video svg {
  width: 1.1em; height: 1.1em;
  fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.est-video svg path { fill: currentColor; stroke: none; }


.fugaz {
  position: absolute;
  top: 18%; right: 14%;
  width: 150px; height: 2px;
  z-index: 1;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0));
  transform: rotate(-33deg);
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 760px) {
  .luna-papel { top: 6vh; right: 7vw; width: 74px; }
  .globo-wrap { top: 9vh; right: 2vw; width: min(52vw, 250px); }
  /* ── Una sola sierra en vertical ──────────────────────────
     `montanas-lejos` y `montanas-cerca` son dos recortes MUY parecidos:
     misma paleta, mismo lenguaje de silueta. En apaisado leen como
     profundidad porque el encuadre es ancho y el texto vive a la
     izquierda. En vertical no: comprimidas a 390px quedan dos bandas
     de picos casi idénticos —medido, la lejana en y538→663 y la
     cercana en y703→861, SIN llegar a solaparse— y eso no se lee como
     lejos-y-cerca, se lee como la misma montaña duplicada.
     Encima la lejana caía justo a la altura del titular y le metía
     picos por detrás.
     En móvil se queda una sola sierra, la cercana, haciendo de
     horizonte bajo el bloque de texto. La profundidad la sostienen el
     cielo, la bruma y el propio globo, que sí crece de verdad. */
  .capa-lejos { display: none; }
  /* Y baja para hacer de horizonte, no de textura tras el titular. */
  .capa-cerca { bottom: -5vh; }
  .estacion {
    left: 1.2rem; right: 1.2rem;
    top: 50%; bottom: auto;
    transform: translateY(-50%);
    width: auto; max-width: 26rem;
    margin: 0 auto;
  }
  .est-pasos { min-height: 10.5rem; }
  .est-titulo { font-size: 1.2rem; }
  .est-cuerpo { font-size: 0.8rem; }
}


.scroll-hint {
  position: absolute;
  bottom: 2.2rem; left: 50%;
  transform: translateX(-50%);
  z-index: 9;
}
/* Rueda de ratón: cápsula con punto ámbar que cae */
.scroll-rueda {
  width: 22px; height: 34px;
  border: 1.5px solid rgba(245, 244, 239, 0.35);
  border-radius: 999px;
  display: flex; justify-content: center;
  padding-top: 6px;
}
.scroll-punto {
  width: 3px; height: 7px;
  border-radius: 3px;
  background: var(--ambar);
  box-shadow: 0 0 8px 1px rgba(232, 160, 32, 0.6);
  animation: puntoCae 1.9s var(--ease-cine) infinite;
}
@keyframes puntoCae {
  0% { transform: translateY(0); opacity: 0; }
  25% { opacity: 1; }
  70% { transform: translateY(13px); opacity: 1; }
  100% { transform: translateY(16px); opacity: 0; }
}

/* ══════════ ACTO I · MANIFIESTO — secuencia cinematográfica (pinned) ══════════ */
.manifiesto {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: transparent;
  /* Retícula de página: un solo margen y una sola calle para el raíl.
     Todo el acto se alinea contra estas dos medidas. */
  --mani-margen: clamp(1.4rem, 6vw, 6rem);
}

/* La luz del amanecer aún baña la escena al aterrizar */
.manifiesto-alba {
  position: absolute; left: 50%; top: -20%;
  transform: translateX(-50%);
  width: 130%; height: 80%;
  pointer-events: none;
  background: radial-gradient(ellipse 50% 70% at 50% 20%, rgba(255, 214, 130, 0.26) 0%, rgba(255, 214, 130, 0) 70%);
}

/* Marco editorial en L — lo único que NO cambia entre tesis.
   Firma arriba (con su regla que respira hasta el borde), raíl de
   índice a la izquierda y folio abajo. El encuadre es el sistema;
   las tres tesis son el contenido que pasa por él. */
.mani-chrome {
  position: absolute;
  top: clamp(4.6rem, 9vh, 6.2rem);
  left: var(--mani-margen);
  right: var(--mani-margen);
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2.4vw, 2rem);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--tinta-suave);
  opacity: 0;
  z-index: 4;
}
.chrome-sig {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  white-space: nowrap;
  color: var(--tinta);
}
/* El mismo punto ámbar que firma el hero: continuidad de marca */
.chrome-punto {
  width: 5px; height: 5px;
  border-radius: var(--radio-pill);
  background: var(--ambar);
  box-shadow: 0 0 0 3px rgba(232, 160, 32, 0.16);
}
.chrome-regla {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(15,35,64,0.2), rgba(15,35,64,0.05));
}
.chrome-meta {
  white-space: nowrap;
  letter-spacing: var(--track-1);
  font-variant-numeric: tabular-nums;
}

.cuaderno-folio {
  position: absolute;
  right: clamp(0.9rem, 2.6vw, 2.4rem);
  bottom: clamp(3rem, 8vh, 5.5rem);
  writing-mode: vertical-rl;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--sepia);
  z-index: 4;
}

/* Los beats: escenas centradas que se montan y desmontan con el scroll */
.mani-beat {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: clamp(0.8rem, 2.2vh, 1.6rem);
  padding: 0 1.4rem;
  text-align: center;
  will-change: transform, opacity;
}
/* Capitular de beat: numeral en oro + regla ámbar + rótulo. El mismo
   sistema de señalética que la cabecera de La Ruta y el Kit. */
.mani-cap {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--sepia);
}
.mani-cap span {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: var(--oro-tinta);
}
.cap-regla {
  width: clamp(1.5rem, 3.2vw, 2.8rem);
  height: 1px;
  background: var(--ambar);
  opacity: 0.65;
}

.palabra-clip {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding: 0 0.06em;
}
.palabra-txt { display: inline-block; }
.mch { display: inline-block; will-change: transform; }

/* Beat 3: ¿ZARPAMOS? y la marea de tinta que invierte la pantalla.
   Único acto del manifiesto: la decisión se planta en mitad del
   encuadre. */
.mani-juntos {
  font-weight: 800;
  font-size: clamp(2.8rem, 8.9vw, 7.9rem);
  line-height: 0.95;
  letter-spacing: -0.015em;
  color: var(--tinta);
}
.mani-beat-3 { z-index: 1; }
/* Capitular y sello van en ABSOLUTO a propósito: así .mani-juntos es
   el único hijo en flujo y queda exactamente donde queda su copia
   dentro de la marea. Si entran en flujo, el relevo entre las dos da
   un salto vertical al barrer la tinta. */
.mani-beat-3 .mani-cap,
.mani-beat-3 .mani-sello {
  position: absolute;
  left: 50%;
  top: 50%;
  white-space: nowrap;
}
.mani-beat-3 .mani-cap {
  transform: translate(-50%, calc(-50% - clamp(5rem, 10.5vh, 8.5rem)));
}
.mani-beat-3 .mani-sello {
  transform: translate(-50%, calc(-50% + clamp(5rem, 10.5vh, 8.5rem)));
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--tinta-suave);
}
.mani-sello i {
  width: clamp(1.4rem, 3vw, 2.6rem);
  height: 1px;
  background: rgba(15, 35, 64, 0.24);
}
.mani-sello b {
  font-weight: 800;
  letter-spacing: var(--track-1);
  font-variant-numeric: tabular-nums;
  color: var(--oro-tinta);
}
.tinta-flood {
  position: absolute; inset: 0;
  z-index: 2;
  background: transparent;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
}
/* La marea es un DISCO plano (cuadrado + radius 50%, círculo de
   verdad) escalado por transform: GPU puro, cero repaints. Al ser
   color liso no necesita contraescalado del contenido. */
.tinta-fondo {
  position: absolute;
  left: 50%; top: 55%;
  width: 250vmax; height: 250vmax;
  margin: -125vmax 0 0 -125vmax;
  border-radius: 50%;
  background: var(--tinta);
  transform: scale(0.002);
  will-change: transform;
}
.tinta-flood .mani-juntos { position: relative; z-index: 1; color: var(--papel); }
.palabra-txt-luz { display: inline-block; }


/* ══════════ ACTO II · LA RUTA ══════════ */
/* Por encima de la cola del hero (que ahora queda debajo, deslizándose
   fuera sin que se vea). 3 está muy por debajo del nav (110). */
.etapas { position: relative; z-index: 3; }
/* Velo de tinta de la llegada: NO es una sábana — es un degradado
   que solo cubre la franja superior (donde vive la costura con el
   azul de JUNTOS). El cuerpo de la sección entra visible desde el
   primer píxel del cruce. Invisible por defecto (sin JS no estorba);
   el JS lo enciende y lo disuelve al asentarse la sección. */
/* Retirado. Este velo existía para que el corte de sección sucediera
   bajo el mismo azul con el que remataba el hero; con la marea de tinta
   ya disuelta, el hero entrega papel y La Ruta es papel, así que no hay
   costura que tapar — y el velo solo servía para lavar su propio
   titular durante todo el recorrido de entrada. */
.etapas-velo { display: none; }
/* Flujo vertical, sin pin: el carril horizontal (barco navegando una
   ruta dibujada, vitrina de El Kit al final) era un mecanismo de
   navegación propio de esta sección y se retiró. Base = columna del
   móvil; desde 900px, rejilla de cartas de producto (ver el bloque
   «ETAPAS · escritorio» al final de la capa CARTA DE DERROTA). */
.etapas-sticky {
  height: auto;
  overflow: visible;
  display: block;
  /* El top no baja de 11rem a propósito: el nav flotante es un overlay
     fijo (no reserva alto, ~93px) y el scroll tiene inercia — con menos
     margen la cabecera aparecía ya tapada o pegada al nav nada más
     entrar en la sección, y apenas se apreciaba. */
  padding: 11rem 0 2.6rem;
  position: relative;
}
.etapas-head {
  position: static;
  margin: 0 1.4rem 3rem;
}
.etapas-titulo {
  margin-top: 0;
  font-weight: 800;
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.etapas-sub {
  margin-top: var(--sp-2);
  font-family: 'Montserrat', sans-serif;
  font-style: normal;
  font-size: 0.98rem;
  color: var(--tinta-suave);
}

.etapas-track {
  display: block;
  width: auto;
  position: relative;
}
.ruta-svg,
.nautilus,
.brujula,
.etapas-contador,
.etapa-arribo { display: none; }
.etapa-panel {
  --nota-y: 0rem;
  width: auto;
  padding: 3rem 1.4rem;
  position: relative; z-index: 1;
}
.etapa-inner {
  position: relative;
  max-width: 24rem;
  min-height: 0;
  padding: 1.5rem 1.4rem;
  margin-inline: auto;
  margin-block: 0.9rem;
}
.etapa-num {
  position: absolute;
  top: -0.65em; left: -0.32em;
  font-weight: 800;
  font-size: clamp(7rem, 17vw, 15rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(47, 99, 144, 0.4);
  z-index: -1;
  user-select: none;
}
.etapa-nombre {
  font-weight: 800;
  font-size: clamp(2.6rem, 6vw, 5rem);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1;
}
/* Rampa de la carta sobre marino: el «qué» es la promesa (blanco), la
   descripción es el cuerpo (rampa 2) y el objetivo remata en pie.
   Tres voces, no cuatro grises indistinguibles como antes. */
.etapa-que {
  margin-top: 0.55rem;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--texto-noche-1);
}
.etapa-desc {
  margin-top: 0.85rem;
  max-width: 44ch;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--texto-noche-2);
}
.etapa-objetivo {
  margin-top: auto;
  padding-top: 0.95rem;
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.4;
  color: var(--texto-noche-1);
  border-top: 1px solid rgba(245, 244, 239, 0.14);
  max-width: none;
}
.etapa-objetivo span {
  display: block;
  margin-bottom: 0.4rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--ambar);
}

.brujula {
  position: absolute;
  right: clamp(1.2rem, 4vw, 3rem);
  bottom: clamp(1.2rem, 4vh, 2.4rem);
  width: clamp(64px, 8vw, 104px);
  color: var(--tinta-suave);
  opacity: 0.75;
  z-index: 5;
}

/* Odómetro de travesía (abajo a la izquierda) */
.etapas-contador {
  position: absolute;
  left: clamp(1.4rem, 6vw, 6rem);
  bottom: clamp(1.4rem, 4vh, 2.6rem);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 1rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}
#etapaIdx { font-size: 1.6rem; color: var(--azul); line-height: 1; }
.contador-linea {
  width: clamp(4rem, 9vw, 9rem);
  height: 2px;
  background: rgba(15, 35, 64, 0.16);
  position: relative;
  overflow: hidden;
}
#contadorFill {
  position: absolute; inset: 0;
  display: block;
  background: var(--ambar);
  transform: scaleX(0);
  transform-origin: left center;
}
.contador-total { color: var(--tinta-suave); font-size: 0.8rem; }

/* La ruta recorrida se entinta; los waypoints se encienden al paso */
.ruta-trail {
  fill: none;
  stroke: var(--azul);
  stroke-width: 2.6;
  stroke-linecap: round;
  opacity: 0.9;
}
.ruta-marker { fill: var(--ambar); }
.nautilus {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  width: 3.2rem;
  margin: -0.65rem 0 0 -1.6rem; /* centra el casco sobre el punto de la ruta */
  pointer-events: none;
  will-change: transform;
  filter: drop-shadow(0 3px 6px rgba(15, 35, 64, 0.3));
}
.nautilus svg { display: block; width: 100%; }
.nautilus path { fill: currentColor; }
.nautilus { color: var(--marino); }
.nautilus .nau-luz { fill: var(--ambar); }
/* Al cruzar el corte, el casco pasa a blanco: en marino sobre el mar
   sería literalmente invisible. Va en `color` (una sola propiedad
   heredada por los tres trazos del casco) y con transición corta, para
   que el cambio acompañe al cruce sin parecer un parpadeo. Los faroles
   se quedan en ámbar siempre. */
.nautilus { transition: color var(--dur-2) var(--ease-estandar); }
.nautilus.en-mar {
  color: var(--blanco);
  filter: drop-shadow(0 3px 10px rgba(6, 15, 31, 0.55));
}

/* ── ARRIBO · la bocana de El Kit, dentro del propio carril ─────
   No es una etapa: es la última columna, y mide un viewport entero, así
   que el carril te deja con el mar de estrellas llenando la pantalla y
   el pin suelta ya en marino — el mismo material con que arranca El Kit.
   Sin sección intermedia, sin scroll de relleno: el paso de La Ruta a El
   Kit es el mismo gesto horizontal que ya venías haciendo.
   ⚠️ Va por DEBAJO de la ruta (`z-index: 0` contra el 1 del SVG) para
   que el Nautilus y el rastro ámbar naveguen POR ENCIMA del mar. Las
   columnas de etapa suben a 2 para conservar su relación de siempre:
   la ruta pasa por detrás de ellas. */
/* Respiro de papel entre la etapa 05 y el corte: pegados, el mar
   parecía guillotinar la última columna. */
.etapa-respiro { display: none; }
/* LA BOCANA · la última columna del carril ES el primer fotograma de
   El Kit. No replica su diseño: RECIBE POR JS LAS CLASES `kit kit-pinned`
   y hereda el CSS de la sección entera —paddings, escalas, posiciones,
   fondo—, así que los dos encuadres son el mismo por construcción.
   Aquí solo vive lo que la convierte en columna de carril.
   ⚠️ Nada de medidas propias. La versión anterior copiaba paddings y
   tamaños a mano y divergía: la placa salía a 276px contra los 400 de la
   sección, y la cabecera y la escena caían en otra altura. Si algo no
   encaja, se arregla en `.kit` / `.kit-pinned`, nunca aquí.
   ⚠️ En ≤899px SÍ se oculta (ago 2026). El aviso anterior decía lo
   contrario —que se quedara como bloque normal, sin `kit-pinned`— pero
   eso es justo lo que la rompe: sin carril horizontal no hay raccord que
   coser, así que el fotograma se queda en el flujo y el visitante ve la
   cabecera del Kit, su primera pieza y su pie DOS VECES seguidas. Ocultarla
   es seguro: el carril y todo lo que la mide viven dentro de un
   `gsap.matchMedia('(min-width: 900px)')`, y el clon sigue en el DOM para
   cuando el viewport crece. Sigue en pie lo de no darle medidas propias. */
.etapa-arribo {
  position: relative;
  z-index: 0;
  flex-shrink: 0;
  width: 100vw;
}

/* ── EL RACCORD ────────────────────────────────────────────────
   Con los dos encuadres idénticos, entre el final del carril y el pin de
   El Kit quedaban 860px (el alto del propio sticky al soltarse) en los
   que el MISMO fotograma se cruzaba consigo mismo: lo veías subir y
   entrar duplicado por abajo. Eso no se arregla con un fundido encima —
   se arregla quitando el hueco.
   Es el mismo patrón con que el hero entrega a La Ruta: la sección que
   sale se come su cola con un margen negativo y la siguiente pasa por
   encima. Aquí el corte es invisible porque lo que hay a un lado y otro
   es idéntico al píxel: un raccord de montaje, no una transición. */
/* El chrome de la carta se RETIRA a medida que entra el arribo.
   Titular, odómetro, brújula, atlas y los velos de borde son mobiliario
   de papel: sobre el mar de estrellas quedaban flotando —y los velos,
   que son degradados de `--papel`, pintaban dos franjas claras sobre el
   marino, justo el vacío que había que quitar—. `--chartUI` la escribe
   el propio scrub del carril (una sola variable, una sola escritura por
   frame) y va de 1 a 0 según cuánto encuadre ocupa ya el arribo. */
.etapas-sticky { --chartUI: 1; }
@media (min-width: 900px) {
  /* ⚠️ TODOS scopeados con `.etapas-sticky` (0,2,0). Sin ese prefijo,
     `.brujula { opacity: .6 }`, `.etapas-atlas` y `.atlas-grid` tienen
     reglas de opacidad más abajo en la hoja que, a igual especificidad,
     ganan por orden: medido, el fundido no llegaba a aplicarse y la
     brújula seguía visible sobre la pantalla de El Kit. */
  .etapas-sticky .etapas-head,
  .etapas-sticky .etapas-contador,
  .etapas-sticky .etapas-borde-i,
  .etapas-sticky .etapas-borde-d { opacity: var(--chartUI); }
  /* ⚠️ La disolución de la ruta y del Nautilus NO se hace aquí.
     Ambos tienen reglas de `opacity` más abajo en la hoja (`.ruta-svg
     { opacity: 1 }`, `.ruta-wp.lit { opacity: 1 }`) que, a igual
     especificidad, ganan por orden y dejarían el fundido sin efecto.
     Lo escribe GSAP desde el scrub del carril — inline, sin discusión
     con la cascada. Ver `setRutaOp` / `setNaveOp` en js/main.js. */
  /* Estos tres tienen opacidad propia de reposo: se multiplica */
  .etapas-sticky .brujula { opacity: calc(0.6 * var(--chartUI)); }
  .etapas-sticky .etapas-atlas { opacity: var(--chartUI); }
  .etapas-sticky .atlas-grid { opacity: calc(0.18 * var(--chartUI)); }
}

@media (min-width: 900px) {
  /* (El `display` lo fija la regla de arriba: flex en columna y centrado.
     Un `display: block` aquí la pisaba por orden y dejaba el fotograma
     pegado al techo con un tercio de pantalla vacío debajo.) */
  /* El espaciador de cola centraba la última etapa. Con el arribo detrás
     ya no hace falta —y si se queda, deja media pantalla de papel DESPUÉS
     del mar, que es exactamente el vacío que había que quitar. */
  .etapas-track::after { flex: 0 0 0; }
  /* La ruta sube por encima del mar; las columnas de etapa, por encima
     de la ruta (su relación de siempre). */
  .ruta-svg { z-index: 1; }
  .etapa-panel { z-index: 2; }
  .ruta-wp, .nautilus { z-index: 3; }
}


}
.ruta-wp { color: var(--sepia); transition: color var(--dur-2) var(--ease-estandar); }
.ruta-wp .wp-ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  opacity: 0.45;
  transition: opacity var(--dur-2) var(--ease-estandar);
}
.ruta-wp .wp-dot { fill: currentColor; opacity: 0.55; transition: opacity var(--dur-2) var(--ease-estandar); }
.ruta-wp.lit { color: var(--ambar); }
.ruta-wp.lit .wp-ring, .ruta-wp.lit .wp-dot { opacity: 1; }

/* Icono de línea de cada etapa: se dibuja a trazo al entrar */
.etapa-icon {
  width: clamp(26px, 2vw, 32px);
  height: clamp(26px, 2vw, 32px);
  display: block;
  color: var(--azul);
  margin-bottom: 1rem;
}
.etapa-icon path, .etapa-icon circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Fallback vertical (móvil) */
@media (max-width: 899px) {
  /* Sin padding inferior: el último hijo del carril es la bocana, que ya
     es marino y entrega directamente a El Kit. Esos 4rem dejaban una
     franja de papel entre el bloque azul y su propia sección. */
  .etapas-sticky { height: auto; overflow: visible; display: block; padding: 6rem 0 0; }
  .etapas-head { position: static; margin: 0 1.4rem 3rem; }
  .etapas-track { display: block; width: auto; }
  .ruta-svg,
  .nautilus { display: none; }
  .etapa-panel { --nota-y: 0rem; }
  .etapa-panel { width: auto; padding: 3.4rem 1.4rem; }
  .brujula { display: none; }
  .etapas-contador { display: none; }
}

@media (max-width: 760px) {
  .cuaderno-folio { display: none; }
  /* La firma se queda; los metadatos no caben en una línea y partirla
     rompería la regla del marco. El raíl sí sobrevive: es 3rem. */
  .chrome-meta { display: none; }
  /* Y con el folio fuera, la banda DERECHA de la máscara del territorio
     se queda despejando un rótulo que ya no está: se lee como un
     degradado blanco lateral sin motivo. Se retira. La banda superior se
     queda, porque la firma sí sigue en su sitio y la necesita. */
  .amanecer-mapa {
    -webkit-mask-image:
      radial-gradient(ellipse 72% 68% at 40% 50%, transparent 10%, rgba(0,0,0,0.38) 52%, rgba(0,0,0,0.62) 100%),
      linear-gradient(180deg, transparent 0%, transparent 9%, #000 19%);
    mask-image:
      radial-gradient(ellipse 72% 68% at 40% 50%, transparent 10%, rgba(0,0,0,0.38) 52%, rgba(0,0,0,0.62) 100%),
      linear-gradient(180deg, transparent 0%, transparent 9%, #000 19%);
  }
  .mani-beat-3 .mani-cap { transform: translate(-50%, calc(-50% - 7.5rem)); }
  .mani-beat-3 .mani-sello {
    transform: translate(-50%, calc(-50% + 7rem));
    gap: 0.55rem;
  }
  .mani-sello i { width: 1.1rem; }
}

/* ══════════ ACTO III · KIT — inventario en rejilla ══════════
   Rejilla de tarjetas sobre contenedor centrado (78rem, el ancho
   estándar de los bloques anchos del sitio): cabecera centrada y
   ocho piezas en dos columnas, cada una con su esquemático en
   tésera, numeral fantasma y cuerpo de texto. Sin vitrina ni fila
   activa: cada tarjeta es autosuficiente y la sección llena el
   encuadre a cualquier ancho. */
.kit {
  position: relative;
  overflow: clip;
  padding: var(--seccion-y) var(--seccion-x);
  color: var(--blanco);
  background:
    radial-gradient(circle at 85% 8%, rgba(232,160,32,0.1), transparent 30rem),
    radial-gradient(circle at 6% 92%, rgba(58,113,160,0.14), transparent 34rem),
    var(--marino);
}
.kit-head { max-width: 78rem; margin-inline: auto; }
.kit-telemetry {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  padding-bottom: 0.7rem;
  border-bottom: var(--borde-noche);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  color: var(--texto-noche-3);
}
.kit-titulo {
  margin-top: clamp(2rem, 4.5vh, 3rem);
  font-weight: 800;
  font-size: var(--fs-h2);
  letter-spacing: -0.02em;
  line-height: 1.08;
  text-align: center;
}
.kit-sub {
  margin: var(--sp-3) auto 0;
  max-width: 42rem;
  font-size: var(--fs-sub);
  color: var(--texto-noche-3);
  text-align: center;
}

/* ── La escena: rejilla de tarjetas ──────────────────────────────
   Dos columnas desde 900px, una debajo. La lista anterior dejaba
   todo el contenido pegado al margen izquierdo de una sección a
   ancho completo; la rejilla reparte las ocho piezas por el
   encuadre como una features grid de producto. */
.kit-escena {
  position: relative;
  max-width: 78rem;
  margin: var(--bloque-y) auto 0;
}

.kit-manifiesto {
  list-style: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(0.9rem, 1.8vw, 1.4rem);
}
@media (min-width: 900px) {
  .kit-manifiesto { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* La tarjeta: superficie de producto sobre el marino — borde fino,
   radio de card y un lift contenido al pasar. El hover desplaza con
   `translate` (no `transform`): el reveal de GSAP anima transform y
   una transición CSS sobre esa misma propiedad lo haría tartamudear. */
.kit-pieza {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.1rem, 2vw, 1.5rem);
  align-items: start;
  padding: clamp(1.5rem, 2.6vw, 2.1rem);
  border: 1px solid rgba(245,244,239,0.1);
  border-radius: var(--radio-card);
  background-color: rgba(245,244,239,0.035);
  transition:
    translate var(--dur-2) var(--ease-premium),
    border-color var(--dur-2) var(--ease-estandar),
    background-color var(--dur-2) var(--ease-estandar),
    box-shadow var(--dur-2) var(--ease-estandar);
}
/* `con-mini` la pone el JS al clonar el esquemático de la vitrina:
   sin JS no hay tésera y el cuerpo ocupa la tarjeta entera. */
.kit-pieza.con-mini { grid-template-columns: auto minmax(0, 1fr); }
@media (hover: hover) {
  .kit-pieza:hover {
    translate: 0 -4px;
    border-color: rgba(245,244,239,0.22);
    background-color: rgba(245,244,239,0.055);
    box-shadow:
      0 18px 44px -20px rgba(3, 8, 18, 0.8),
      0 0 30px -10px rgba(232, 160, 32, 0.2);
  }
}
/* La tésera del esquemático (svg clonado por JS desde la vitrina) */
.kit-mini {
  display: block;
  box-sizing: content-box;
  width: 2.7rem;
  padding: 0.8rem;
  border: 1px solid rgba(245,244,239,0.12);
  border-radius: 0.85rem;
  background-color: rgba(245,244,239,0.04);
  background-image: radial-gradient(circle at 30% 22%, rgba(232,160,32,0.14), transparent 72%);
  color: rgba(245,244,239,0.82);
}
.kit-mini :is(path, circle, rect, ellipse) { stroke-width: 2.8px; } /* unidades de usuario del viewBox */
.kit-mini .oro { color: var(--ambar); }
.kit-mini .tapa { fill: var(--marino-claro); }
/* Aire a la derecha del cuerpo: que el kicker y el título no se
   metan debajo del numeral fantasma */
.kit-cuerpo { min-width: 0; padding-right: clamp(2.2rem, 3vw, 3rem); }
/* En anchos muy cortos la tésera roba demasiada columna al texto:
   se apila encima, patrón de card móvil de toda la vida */
@media (max-width: 480px) {
  .kit-pieza.con-mini { grid-template-columns: minmax(0, 1fr); }
}
/* Numeral fantasma: índice de la pieza sin robar jerarquía */
.kit-num {
  position: absolute;
  top: 1.1rem;
  right: 1.25rem;
  font-size: clamp(1.7rem, 2.4vw, 2.2rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: rgba(245,244,239,0.1);
  user-select: none;
}
.kit-rol {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  /* 0.55 ≈ 4.9:1 sobre marino — AA para texto pequeño */
  color: rgba(245,244,239,0.55);
  transition: color var(--dur-3) var(--ease-estandar);
}
/* La palabra que NOMBRA la pieza va en ámbar: en el paso de una en
   una es lo que deja leer el titular de un vistazo. El resto del
   título es contexto. */
.kit-pieza h3 em {
  font-style: normal;
  font-weight: inherit;
  color: var(--ambar);
}
.kit-pieza h3 {
  margin-top: 0.55rem;
  font-weight: 700;
  font-size: clamp(1.12rem, 1.6vw, 1.45rem);
  letter-spacing: -0.01em;
  line-height: 1.25;
  transition: color var(--dur-3) var(--ease-estandar);
}
.kit-desc {
  margin-top: 0.65rem;
  max-width: 34rem;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--texto-noche-2);
  transition: color var(--dur-3) var(--ease-estandar);
}
.kit-desc em {
  font-style: normal;
  font-weight: 600;
  color: var(--blanco);
}
/* ── La vitrina: retirada. Solo queda en el HTML como fuente de los
   esquemáticos que el JS clona en `.kit-mini` — nunca se muestra. ── */
.kit-vitrina { display: none; }
/* ── Pie de sección: sello de carga ──────────────────────────── */
.kit-pie {
  max-width: 78rem;
  margin: clamp(2.6rem, 6vh, 4rem) auto 0;
  padding-top: 1.1rem;
  border-top: var(--borde-noche);
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--texto-noche-3);
}


/* ── Footer ─────────────────────────────────────────────────── */
.footer {
  border-top: var(--fino);
  padding: var(--sp-7) var(--seccion-x);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
/* Tres elementos en una fila llevaban tres tamaños y tres trackings
   distintos. Un solo tamaño; la jerarquía la da el peso. */
.footer-lockup { font-weight: 800; font-size: var(--fs-label); letter-spacing: var(--track-3); }
.footer-meta { font-size: var(--fs-label); font-weight: 500; letter-spacing: var(--track-1); color: var(--tinta-suave); }
.footer-claim {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--sepia);
}
/* Los emails llaman a esta página «la Bitácora del Explorador». Quien
   llega desde el Capítulo IV o V tiene que poder confirmar que está
   donde le mandaron — de ahí que el nombre se declare literalmente. */
.footer-bitacora {
  flex-basis: 100%;
  order: -1;
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid rgba(245, 244, 239, 0.1);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--tinta-suave);
}
.footer-bitacora b { font-weight: 700; }

/* Estado inicial de los reveals: lo fija GSAP en JS (única fuente
   de verdad del transform — mezclarlo con CSS hornea px en `y`). */

/* ── Reduced motion: todo visible, nada pinned ──────────────── */
@media (prefers-reduced-motion: reduce) {
  .js .line-inner { transform: none !important; }
  /* Sin sticky no hay cola que recuperar: el margen negativo que
     solapa La Ruta con esa cola aquí solo taparía contenido real. */
  .hero { height: auto; margin-bottom: 0; }
  .etapas { opacity: 1 !important; visibility: visible !important; }
  .hero-sticky {
    position: static; height: auto; min-height: 100vh;
    padding: 7rem 1.4rem 4rem;
    display: block;
  }
  .cielo { height: 100%; }
  .twinkles, .fugaz, .bruma,
  .repisa, .luciernagas, .farol-cursor { display: none; }
  /* El paisaje queda como escena estática de fondo */
  .paisaje { position: absolute; }
  .capa-cerca { opacity: 1; }
  .globo-wrap { opacity: 1; }
  .hero-beat {
    position: static; opacity: 1; visibility: visible;
    transform: none; margin: 3rem auto; max-width: 34rem;
    text-align: center;
  }
  .bitacora {
    position: static; opacity: 1; visibility: visible;
  }
  .estacion {
    position: static; transform: none;
    width: min(24rem, 90vw); margin: 2.5rem auto;
  }
  .est-pasos { min-height: 0; }
  .est-paso {
    position: static; opacity: 1 !important; visibility: visible !important;
    margin: 2.5rem 0;
  }
  .scroll-hint { display: none; }
  /* El mapa y el manifiesto permanecen disponibles en flujo estático. */
  .amanecer {
    position: relative;
    inset: auto;
    display: block;
    width: 100%;
    opacity: 1 !important;
    visibility: visible !important;
    clip-path: none !important;
    -webkit-clip-path: none !important;
    margin-top: 4rem;
  }
  .amanecer-lienzo { position: static; transform: none !important; }
  .manifiesto { height: auto; overflow: visible; padding: 5rem 1.4rem; }
  .mani-chrome { position: static; opacity: 1; margin-bottom: 1.5rem; }
  .cuaderno-folio { position: static; writing-mode: horizontal-tb; margin-bottom: 2rem; }
  .mani-beat {
    position: static;
    opacity: 1 !important; visibility: visible !important;
    margin: 3.5rem auto;
  }
  /* En flujo estático el capitular y el sello del beat 3 vuelven al
     flujo bajo la palabra. */
  .mani-beat-3 { align-items: flex-start; text-align: left; }
  .mani-beat-3 .mani-cap,
  .mani-beat-3 .mani-sello {
    position: static;
    transform: none;
    white-space: normal;
  }
  .tinta-flood, .manifiesto-alba { display: none; }
  /* La ruta, en columna estática (el pin horizontal necesita JS) */
  .etapas-sticky { height: auto; overflow: visible; display: block; padding: 6rem 0 4rem; }
  .etapas-head { position: static; margin: 0 1.4rem 3rem; }
  .etapas-track { display: block; width: auto; }
  .ruta-svg, .nautilus, .brujula, .etapas-contador, .etapas-velo { display: none; }
  .etapa-panel { transition: none; --nota-y: 0rem; }
  .etapa-panel { width: auto; padding: 3rem 1.4rem; }
  .grain { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   EXPEDICIÓN VERNE · PREMIUM ART DIRECTION 2026
   Cartografía editorial, instrumentación y continuidad de marca
   ══════════════════════════════════════════════════════════════ */

html { scroll-padding-top: 5rem; }

body {
  background:
    radial-gradient(circle at 12% 30%, rgba(232, 160, 32, 0.04), transparent 30rem),
    var(--papel);
  font-feature-settings: "kern" 1, "liga" 1;
  text-rendering: optimizeLegibility;
}

/* El anillo de foco base y el reset de tap-highlight viven ahora en
   `css/base.css`; aquí solo queda la EXCEPCIÓN de esta página.
   Sobre papel el ámbar no marca (1.9:1): el anillo pasa a tinta.
   ⚠️ El campamento salió de esta lista al pasar a sección nocturna:
   sobre marino el anillo vuelve al ámbar por defecto, que allí marca
   de sobra. Si algún día vuelve a papel, hay que devolverlo aquí. */
.nav-papel-scrolled :focus-visible,
.etapas :focus-visible,
.cuaderno :focus-visible,
.faq :focus-visible {
  outline-color: var(--marino);
}


.nav-toggle {
  display: none;
  width: 2.55rem;
  height: 2.55rem;
  border: 1px solid var(--nav-filete);
  border-radius: 50%;
  color: inherit;
  background: transparent;
  cursor: pointer;
  position: relative;
  transition: border-color var(--dur-2) var(--ease-estandar), background var(--dur-2) var(--ease-estandar);
}
.nav-toggle:hover { background: var(--nav-blob); }
.nav-toggle span {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1rem;
  height: 1px;
  background: currentColor;
  transition: transform var(--dur-3) var(--ease-premium);
}
.nav-toggle span:first-child { transform: translate(-50%, calc(-50% - 3px)); }
.nav-toggle span:last-child { transform: translate(-50%, calc(-50% + 3px)); }
.nav-toggle[aria-expanded="true"] span:first-child { transform: translate(-50%, -50%) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child { transform: translate(-50%, -50%) rotate(-45deg); }

.nav-mobile {
  position: fixed;
  inset: 0;
  z-index: 105;
  display: none;
  flex-direction: column;
  justify-content: center;
  padding: 7rem 1.4rem 3rem;
  color: var(--blanco);
  background:
    radial-gradient(circle at 88% 18%, rgba(232, 160, 32, 0.17), transparent 22rem),
    var(--marino-hondo);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-3) var(--ease-estandar), visibility var(--dur-3) var(--ease-estandar);
}
.nav-mobile.is-open { opacity: 1; visibility: visible; }
.nav-mobile::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.15;
  background-image:
    linear-gradient(rgba(245,244,239,0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(245,244,239,0.12) 1px, transparent 1px);
  background-size: 4rem 4rem;
  mask-image: radial-gradient(circle at 80% 20%, #000, transparent 72%);
  pointer-events: none;
}
.nav-mobile-eyebrow,
.nav-mobile-coord {
  position: relative;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.27em;
  text-transform: uppercase;
  color: var(--texto-noche-3);
}
.nav-mobile-eyebrow { margin-bottom: 1.4rem; }
.nav-mobile a {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 1.2rem;
  width: 100%;
  padding: 0.85rem 0;
  border-top: 1px solid rgba(245,244,239,0.12);
  font-size: clamp(1.5rem, 6.6vw, 2.4rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.nav-mobile a span {
  width: 2ch;
  font-family: 'Montserrat', sans-serif;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--ambar);
}
/* «Inscribirse» va en ámbar dentro del menú: en móvil es el motivo
   número uno por el que alguien abre esta página, así que es la única
   entrada que se distingue del resto. */
.nav-mobile a.nav-mobile-cta { color: var(--ambar); }
.nav-mobile-coord { margin-top: 2rem; line-height: 1.8; }
body.menu-open { overflow: hidden; }


/* ── Portada: más editorial, más mundo ─────────────────────── */
.portada {
  top: 47%;
  max-width: min(91vw, 70rem);
}
.portada::before { inset: -8rem -10rem; opacity: 0.9; }
.hero-telemetry {
  display: flex;
  justify-content: space-between;
  gap: 4rem;
  margin-bottom: clamp(1.6rem, 3vh, 2.5rem);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid rgba(245,244,239,0.18);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--texto-noche-3);
}
.hero-badge { margin-bottom: 1.3rem; color: rgba(245,244,239,0.62); }
.hero-sub {
  max-width: 34rem;
  margin: 1.7rem auto 0;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  line-height: 1.55;
  color: rgba(245,244,239,0.74);
}
.hero-ctas { margin-top: 1.8rem; }
.btn-hero { padding: 1rem 1.8rem; }
.hero-meta { margin-top: 1.6rem; }

/* ── Papel editorial y continuidad cromática ───────────────── */
.mani-juntos { color: var(--marino); }
.tinta-fondo { background: var(--marino); }

/* ── La ruta: carta de navegación técnica sobre superficie limpia ── */
.etapas { background: var(--papel); }
.etapas-sticky { isolation: isolate; }
.etapas-sticky::before,
.etapas-sticky::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
/* Velo blanco suave que protege la lectura sin ensuciar el grid */
.etapas-sticky::before {
  background: linear-gradient(90deg, rgba(250,249,244,0.95) 0%, rgba(250,249,244,0.42) 38%, rgba(250,249,244,0.3) 72%, rgba(250,249,244,0.78) 100%);
}
.etapas-sticky::after {
  background: radial-gradient(ellipse 70% 50% at 82% 0%, rgba(232,160,32,0.06), transparent 70%);
}
.etapas-atlas {
  position: absolute;
  inset: -3%;
  z-index: -2;
  width: 106%;
  height: 106%;
  opacity: 1;
  background: var(--papel);
}
.atlas-grid {
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.18;
  background-image:
    linear-gradient(rgba(15,35,64,0.25) 1px, transparent 1px),
    linear-gradient(90deg, rgba(15,35,64,0.25) 1px, transparent 1px);
  background-size: 8rem 8rem;
  mask-image: linear-gradient(to right, #000, transparent 42%, transparent 76%, #000);
}
.etapas-head {
  /* 34rem partía «Cinco etapas. Un rumbo.» dejando «rumbo.» solo en
     la segunda línea al subir el titular al escalón del sistema. */
  max-width: 40rem;
  padding: 0;
  background: transparent;
}
.etapas-kicker {
  margin-bottom: 0.9rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--oro-tinta);
}
.etapas-titulo {
  font-size: var(--fs-h2);
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: none;
}
.etapas-sub { font-size: var(--fs-sub); }
.etapa-panel { width: clamp(300px, 36vw, 540px); }
/* Tarjetas de producto en leve contrapunto vertical: el ritmo del
   carril sin el desorden del cuaderno. El scrub de GSAP mueve el
   track, no los paneles: cero conflicto de escritores. El hover
   eleva vía --lift (el transform del panel es 100% CSS). */
.etapa-panel {
  transform: translateY(calc(var(--nota-y, 0rem) + var(--lift, 0rem)));
  transition: transform var(--dur-3) var(--ease-premium);
}
/* Contrapunto de 1.4rem arriba/abajo = 2.8rem de salto entre vecinas:
   con alturas de tarjeta ya desiguales, el carril se leía como
   desalineación, no como ritmo. 0.5rem sugiere el pulso sin romper la
   línea de lectura. */
.etapa-panel:nth-of-type(odd) { --nota-y: -0.5rem; }
.etapa-panel:nth-of-type(even) { --nota-y: 0.5rem; }
.etapa-panel:hover { --lift: -0.45rem; }
/* Velos de canto: por encima de las tarjetas (z 3) y por debajo del
   chrome de la sección (z 5). Solo disuelven; no tapan contenido
   legible porque el carril siempre centra la tarjeta activa. */
.etapas-borde {
  position: absolute;
  top: 0; bottom: 0;
  width: clamp(4rem, 13vw, 13rem);
  z-index: 3;
  pointer-events: none;
}
.etapas-borde-i {
  left: 0;
  background: linear-gradient(90deg, var(--papel) 12%, rgba(250,249,244,0.86) 46%, rgba(250,249,244,0) 100%);
}
.etapas-borde-d {
  right: 0;
  background: linear-gradient(270deg, var(--papel) 12%, rgba(250,249,244,0.86) 46%, rgba(250,249,244,0) 100%);
}

/* ── CARTA DE NAVEGACIÓN ──────────────────────────────────────────
   Antes esto era una tarjeta blanca con radius y sombra: correcta,
   pero podía ser de cualquier web. Ahora la carta es MARINO sobre el
   atlas claro. La inversión cromática hace tres cosas a la vez: da
   dramatismo al carril, deja por fin brillar al ámbar (que sobre
   blanco tenía que apagarse a oro-tinta para ser legible) y rima con
   las planchas del Kit, así que los dos actos centrales se leen como
   un mismo sistema y no como dos webs distintas. */
.etapa-inner {
  max-width: 26.5rem;
  /* Altura mínima común + objetivo anclado abajo: sin esto cada
     tarjeta medía lo que medía su texto y la fila parecía descuadrada. */
  display: flex;
  flex-direction: column;
  min-height: clamp(20rem, 44vh, 26rem);
  padding: clamp(1.9rem, 2.8vw, 2.5rem) clamp(1.6rem, 2.4vw, 2.1rem) clamp(1.6rem, 2.4vw, 2rem);
  overflow: hidden;
  border: 1px solid rgba(245, 244, 239, 0.1);
  border-radius: var(--radio-card);
  color: var(--blanco);
  background:
    radial-gradient(ellipse 90% 60% at 82% 0%, rgba(232, 160, 32, 0.13), transparent 62%),
    linear-gradient(rgba(245,244,239,0.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(245,244,239,0.028) 1px, transparent 1px),
    linear-gradient(168deg, #16304f 0%, var(--marino) 52%, #0b1c33 100%);
  background-size: 100% 100%, 2.6rem 2.6rem, 2.6rem 2.6rem, 100% 100%;
  box-shadow: var(--sombra-3);
  transition: box-shadow var(--dur-3) var(--ease-premium), border-color var(--dur-2) var(--ease-estandar);
}
.etapa-panel:hover .etapa-inner {
  border-color: rgba(232, 160, 32, 0.34);
  box-shadow: var(--sombra-3), 0 0 44px -12px rgba(232, 160, 32, 0.3);
}
/* Filo superior: la trayectoria ámbar firma la carta */
.etapa-inner::before {
  content: '';
  position: absolute;
  top: 0;
  left: clamp(1.6rem, 2.4vw, 2.1rem);
  width: 2.6rem;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--ambar);
}
.etapa-num {
  position: static;
  display: block;
  margin-bottom: 1.05rem;
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  /* Sobre marino el ámbar YA es legible: no hace falta el oro-tinta
     apagado que exigía el fondo claro. */
  color: var(--ambar);
  -webkit-text-stroke: 0;
}
.etapa-num::before { content: 'Etapa\00a0'; }
.etapa-nombre {
  color: var(--blanco);
  font-size: clamp(1.7rem, 2.4vw, 2.3rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.05;
  text-transform: none;
}
/* El icono deja la tesela gris: a trazo ámbar y al doble de tamaño,
   como el sello de la carta. La tesela lo empequeñecía y lo volvía
   un pictograma de formulario. */
.etapa-icon {
  box-sizing: content-box;
  width: clamp(34px, 2.6vw, 42px);
  height: clamp(34px, 2.6vw, 42px);
  padding: 0;
  margin-bottom: 1.1rem;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--ambar);
}
/* El 0.28 vivía en el <svg>, así que multiplicaba a TODO lo que el JS
   le cuelga dentro: también al tramo entintado y a los waypoints
   encendidos, que son el único premio visual de la sección (el ámbar
   salía crema, 1.24:1). El apagado baja al trazo base, que es a quien
   le tocaba: la ruta por recorrer se insinúa, la recorrida manda. */
.ruta-svg { color: var(--marino); opacity: 1; }
#rutaPath { stroke: var(--marino); stroke-opacity: 0.3; }
.ruta-trail { stroke: var(--ambar); opacity: 1; }
.ruta-wp .wp-ring { opacity: 0.4; }
.ruta-wp .wp-dot { opacity: 0.45; }
.ruta-wp.lit .wp-ring { opacity: 0.9; }
.ruta-wp.lit .wp-dot { opacity: 1; }
#etapaIdx { color: var(--marino); }

.footer {
  border-color: rgba(245,244,239,0.1);
  color: var(--blanco);
  background: var(--marino-hondo);
}
.footer-meta,
.footer-claim,
.footer-bitacora { color: var(--texto-noche-3); }
.footer-bitacora b { color: var(--blanco); }

/* ── Respuesta táctil, pantallas pequeñas y ahorro de movimiento */
@media (max-width: 899px) {
  .etapas-atlas {
    inset: 0 0 auto;
    width: 100%;
    height: 100svh;
    opacity: 0.42;
    transform: none !important;
  }
  .atlas-grid { mask-image: linear-gradient(#000, transparent 85%); }
  .etapas-sticky::before { background: rgba(250,249,244,0.8); }
  .etapas-track::before,
  .etapas-track::after { display: none; }
  /* En columna las tarjetas se tocaban (y con el contrapunto --nota-y
     llegaban a solaparse): aquí el carril ya no existe, así que se
     anula el contrapunto y se separan con un margen de verdad. */
  .etapa-panel { padding: 1rem 1.4rem; --nota-y: 0rem; }
  .etapa-inner {
    max-width: 24rem;
    min-height: 0;
    padding: 1.5rem 1.4rem;
    margin-inline: auto;
    margin-block: 0.9rem;
  }
  .etapas-borde { display: none; }
}

/* El menú móvil entra donde cede el índice de la barra (1080), no a 760:
   entre ambos anchos la nav se quedaba sin navegación de ningún tipo. */
@media (max-width: 1080px) {
  .nav-toggle { display: block; }
  .nav-mobile { display: flex; }
}

@media (max-width: 760px) {
  /* Más corto que el escritorio (543vh): en vertical el globo no está,
     así que ese tramo de scroll no cuenta nada — solo se hace largo.
     Misma proporción que la caja de escritorio, así que la densidad de
     lectura de cada capítulo no cambia entre anchos. */
  .hero { height: 443vh; }
  .portada { top: 45%; width: min(90vw, 32rem); }
  .hero-telemetry { gap: 1rem; margin-bottom: 1.3rem; letter-spacing: 0.13em; }
  .hero-telemetry span:last-child { text-align: right; }
  .hero-sub { max-width: 25rem; font-size: 1.05rem; }
  .hero-ctas { margin-top: 1.5rem; }
  .hero-meta { margin-top: 1.3rem; }
  .globo-wrap { right: -10vw; width: 56vw; }
  .kit { padding-inline: 1.1rem; }
  .kit-telemetry { gap: 1rem; letter-spacing: 0.13em; }
  .kit-telemetry span:last-child,
  .kit-pie span:last-child { text-align: right; }
  .kit-pie { letter-spacing: 0.13em; }
}

@media (max-width: 430px) {
  .hero-badge { max-width: 17rem; justify-content: center; line-height: 1.6; }
  .hero-meta { max-width: 19rem; line-height: 1.7; }
}

@media (prefers-reduced-motion: reduce) {
  .kit-filo,
  .kit-num,
  .etapas-atlas { transform: none !important; }
  /* El control de sonido sigue funcionando: no querer movimiento no es
     no querer oír. Solo deja de latir el ecualizador. */
  .nav-sonido.is-sonando i { animation: none; height: 62%; }
}

/* ══════════════════════════════════════════════════════════════
   CONCEPTO 02 · CINEMATIC EXPEDITION
   Menos interfaz. Más paisaje, escala tipográfica y ritmo de cámara.
   ══════════════════════════════════════════════════════════════ */


/* La portada se comporta como una cubierta editorial, no como un hero SaaS */
.portada {
  left: clamp(1.5rem, 7vw, 7.5rem);
  top: 51%;
  width: min(72vw, 76rem);
  max-width: none;
  transform: translateY(-50%);
  text-align: left;
}
.portada::before {
  inset: -10rem -14rem;
  background: radial-gradient(ellipse 56% 58% at 28% 48%, rgba(2,5,11,0.65), transparent 74%);
}
.hero-telemetry {
  max-width: 36rem;
  margin-bottom: clamp(2rem, 4vh, 3.2rem);
}
.hero-badge { margin-bottom: 1.25rem; }
.hero-sub {
  max-width: 31rem;
  margin: 2rem 0 0;
  font-size: clamp(1.08rem, 1.7vw, 1.48rem);
}
.hero-ctas { justify-content: flex-start; margin-top: 2.1rem; }
.hero-meta { max-width: 40rem; margin-top: 2rem; }
.escena-scrim {
  background:
    linear-gradient(90deg, rgba(3,10,22,0.74) 0%, rgba(3,10,22,0.38) 46%, rgba(3,10,22,0.06) 74%),
    linear-gradient(180deg, rgba(3,10,22,0.18), transparent 48%, rgba(3,10,22,0.45));
}

/* Capítulos: texto grande, aire y una única lectura por escena */
.bitacora { overflow: hidden; }
.scrim-lectura {
  background:
    linear-gradient(90deg, rgba(3,10,22,0.93) 0%, rgba(3,10,22,0.8) 34%, rgba(3,10,22,0.18) 67%, transparent 82%),
    linear-gradient(180deg, rgba(3,10,22,0.12), transparent 60%, rgba(3,10,22,0.38));
}
.estacion {
  left: clamp(1.5rem, 6.8vw, 7.5rem);
  top: 52%;
  width: min(61vw, 58rem);
  transform: translateY(-50%);
}
.est-pasos { min-height: clamp(18rem, 42vh, 29rem); }
.est-paso {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-right: 1rem;
  will-change: transform, opacity, clip-path;
}
.est-titulo {
  max-width: 12ch;
  font-size: clamp(3.25rem, 6.8vw, 7.5rem);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.065em;
  text-transform: none;
  text-wrap: balance;
  color: var(--blanco);
  text-shadow: 0 0.15em 0.5em rgba(0,0,0,0.24);
}
.est-cuerpo {
  max-width: 38ch;
  margin-top: clamp(1.5rem, 3vh, 2.4rem);
  padding-left: clamp(0rem, 7vw, 6rem);
  font-size: clamp(0.98rem, 1.4vw, 1.2rem);
  line-height: 1.55;
  color: rgba(245,244,239,0.72);
  text-shadow: none;
}
/* El globo conserva presencia pero nunca pisa la lectura */
.globo-wrap { right: 4vw; width: clamp(300px, 27vw, 490px); }
.globo-img { filter: drop-shadow(0 2.5rem 4.5rem rgba(0,0,0,0.55)); }

@media (max-width: 899px) {
  .portada { width: min(80vw, 44rem); }
  .estacion { width: min(67vw, 42rem); }
  .est-titulo { font-size: clamp(3.2rem, 8vw, 5.4rem); }
  .est-cuerpo { padding-left: 0; }
  .globo-wrap { right: -1vw; width: 34vw; }
}

@media (max-width: 760px) {
  .nav { min-height: 4.4rem; background: linear-gradient(180deg, rgba(3,10,22,0.74), transparent); }
  .portada {
    left: 1.2rem;
    top: 47%;
    width: calc(100vw - 2.4rem);
  }
  .hero-telemetry { max-width: 100%; }
  .hero-sub { max-width: 22rem; }
  .hero-ctas { align-items: flex-start; }
  .globo-wrap {
    top: 8vh;
    right: -18vw;
    width: 68vw;
    opacity: 0.78;
  }
  /* ── El velo de lectura, centrado ─────────────────────────
     Era un degradado vertical que terminaba en 0,94 abajo: una banda
     oscura pegada al pie que se veía COMO banda, con su borde y todo,
     y que además anclaba visualmente el texto al fondo de la pantalla.
     Ahora es un charco de penumbra centrado en el texto, que se
     desvanece hacia arriba y hacia abajo: oscurece donde hace falta
     leer y en ningún punto forma un canto. */
  .scrim-lectura {
    background:
      radial-gradient(ellipse 150% 46% at 50% 50%,
        rgba(3, 10, 22, 0.88) 0%,
        rgba(3, 10, 22, 0.66) 46%,
        rgba(3, 10, 22, 0.22) 76%,
        rgba(3, 10, 22, 0) 100%);
  }
  /* ── Los capítulos, en el centro del encuadre ─────────────
     Vivían anclados al pie (`bottom: 3.2rem`) con el paso alineado a
     flex-end: el texto se leía como un pie de foto, apretado contra el
     borde inferior. Centrado, el bloque ocupa el eje del encuadre y
     respira por arriba y por abajo. */
  .estacion {
    left: 1.2rem;
    right: 1.2rem;
    /* 54%, no 50%: el centro geométrico del viewport NO es el centro
       ÓPTICO, porque los primeros ~82px los ocupa la nav y ahí no cabe
       nada. Centrado al 50% quedaban 156px de aire arriba contra 294
       abajo —descompensado— y el globo se quedaba sin banda. Centrado
       en el hueco REAL (de la nav al pie) el reparto sale parejo y el
       globo recupera sitio. */
    top: 54%;
    bottom: auto;
    width: auto;
    max-width: none;
    transform: translateY(-50%);
  }
  .est-pasos { min-height: 15rem; }
  .est-paso { justify-content: center; padding-right: 0; }
  .est-titulo { max-width: 11ch; font-size: clamp(2.8rem, 13.5vw, 4.7rem); }
  .est-cuerpo {
    max-width: 31ch;
    margin-top: 1.1rem;
    font-size: 1rem;
    line-height: 1.4;
  }
}

@media (max-width: 430px) {
  .hero-telemetry span:last-child { display: none; }
  .hero-telemetry { justify-content: flex-start; }
  .est-titulo { font-size: clamp(2.65rem, 13vw, 4rem); }
  .est-cuerpo { font-size: 0.95rem; }
}

@media (prefers-reduced-motion: reduce) {
  .hero { height: auto !important; }
  .bitacora { position: static; overflow: visible; }
  .estacion {
    position: static;
    width: min(36rem, 100%);
    transform: none;
    margin: 3rem auto;
  }
  .est-pasos { min-height: 0; }
  .est-paso {
    position: static;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
    margin: 3rem 0;
  }
  .est-paso { clip-path: none !important; }
  /* Sin coreografía las tres tesis se leen seguidas, así que el índice
     deja de tener función: no hay «dónde estoy». Y sus piezas van en
     absoluto sobre un `.bitacora` que aquí pasa a flujo estático, así
     que se quedarían flotando. Mismo criterio que `.mani-rail`. */
  .est-chrome,
  .est-rail { display: none !important; }
}

/* ── Ajuste de composición · feedback 2026-08-14 ─────────────
   El texto y el globo forman ahora una sola unidad visual. */
@media (min-width: 900px) {
  .estacion {
    left: clamp(2rem, 5vw, 5.5rem);
    top: 50%;
    width: min(66vw, 66rem);
  }
  .est-pasos { min-height: clamp(20rem, 45vh, 31rem); }
  .est-paso { isolation: isolate; }
  .est-titulo {
    max-width: 10ch;
    font-size: clamp(4rem, 7.7vw, 8rem);
    line-height: 0.88;
  }
  .est-cuerpo {
    max-width: 36ch;
    margin-top: clamp(1.4rem, 2.5vh, 2rem);
    padding-left: clamp(2.5rem, 5vw, 5rem);
    font-size: clamp(1.08rem, 1.5vw, 1.3rem);
  }
  .globo-wrap {
    top: 5vh;
    right: 8.5vw;
    width: clamp(330px, 31vw, 540px);
  }
  .globo-img { position: relative; z-index: 1; }
}

@media (min-width: 900px) and (max-height: 760px) {
  .est-titulo { font-size: clamp(3.4rem, 6.8vw, 6.5rem); }
  .est-pasos { min-height: clamp(17rem, 42vh, 24rem); }
  .est-cuerpo { margin-top: 1.15rem; }
  .globo-wrap { top: 3vh; width: clamp(300px, 29vw, 470px); }
}

@media (max-width: 899px) {
  .estacion { width: min(72vw, 44rem); }
  .est-titulo { max-width: 10ch; }
  .globo-wrap { right: 3vw; width: 39vw; }
}

@media (max-width: 760px) {
  .estacion { width: auto; }
  .globo-wrap { right: -14vw; width: 70vw; }
}

/* ── Corrección de alcance: la portada conserva su composición centrada ── */
.hero-title .portada {
  left: 50%;
  top: 47%;
  width: max-content;
  max-width: min(91vw, 70rem);
  transform: translate(-50%, -50%);
  text-align: center;
}
.hero-title .portada::before {
  inset: -8rem -10rem;
  background: radial-gradient(ellipse 58% 56% at 50% 48%, rgba(2,5,11,0.5), transparent 72%);
}
.hero-title .hero-telemetry {
  max-width: none;
  margin-bottom: clamp(1.6rem, 3vh, 2.5rem);
}
.hero-title .hero-badge { margin-bottom: 1.3rem; }
.hero-title .hero-sub {
  max-width: 34rem;
  margin: 1.7rem auto 0;
  font-size: clamp(1.05rem, 1.7vw, 1.38rem);
}
.hero-title .hero-ctas { justify-content: center; margin-top: 1.8rem; }
.hero-title .hero-meta { max-width: none; margin-top: 1.6rem; }
.escena-scrim {
  background: linear-gradient(100deg,
    rgba(6,15,31,0.6) 0%,
    rgba(8,19,38,0.38) 44%,
    rgba(8,19,38,0.3) 100%);
}

@media (max-width: 760px) {
  .nav { min-height: 4.4rem; padding: 0.75rem 1rem; }
  .hero-title .portada {
    left: 50%;
    top: 44%;
    width: min(90vw, 32rem);
    transform: translate(-50%, -50%);
    text-align: center;
  }
  .hero-title .hero-telemetry { max-width: 100%; }
  .hero-title .hero-sub { max-width: 25rem; margin-inline: auto; }
  .hero-title .hero-ctas { align-items: center; justify-content: center; }
  .hero-title .hero-meta { max-width: 19rem; margin-inline: auto; }
}

/* ── Cabina de vuelo · densidad editorial en la secuencia del globo ── */
.bitacora::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 72% 29%, rgba(232,160,32,0.07), transparent 22rem),
    linear-gradient(115deg, transparent 45%, rgba(127,178,217,0.035) 66%, transparent 82%);
}
.estacion { z-index: 3; }


/* ── Alineación editorial y acentos de capítulo ────────────── */
.est-titulo,
.est-cuerpo { text-align: left; }
.est-data {
  display: flex;
  width: min(46rem, 58vw);
  margin-top: clamp(1.3rem, 2.5vh, 2rem);
  margin-left: 0;
  border-top: var(--borde-noche);
  border-bottom: var(--borde-noche-sutil);
  text-align: left;
}
.est-data p {
  flex: 1;
  min-width: 0;
  padding: 0.85rem 1.4rem 0.9rem 0;
}
.est-data p + p {
  padding-left: 1.4rem;
  border-left: 1px solid rgba(245,244,239,0.12);
}
.est-data span,
.est-data strong { display: block; }
.est-data span {
  margin-bottom: 0.34rem;
  color: var(--texto-noche-3);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.est-data strong {
  overflow: hidden;
  color: rgba(245,244,239,0.82);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}
.est-data .data-accent-value { color: #f0c66f; }
.text-accent {
  --accent-reveal: 0;
  position: relative;
  display: inline-block;
  color: var(--ambar);
  font: inherit;
  font-style: inherit;
  font-weight: inherit;
  white-space: nowrap;
}
.text-accent::after {
  content: '';
  position: absolute;
  left: 0.02em;
  right: 0.02em;
  bottom: -0.08em;
  height: max(2px, 0.045em);
  border-radius: 999px;
  background: var(--ambar);
  box-shadow: 0 0 1.2rem rgba(232,160,32,0.3);
  transform: scaleX(var(--accent-reveal));
  transform-origin: left center;
}
.text-accent-soft {
  color: #f0c66f;
  font-weight: 600;
}
@media (min-width: 900px) {
  .est-titulo { max-width: 11.5ch; }
  .est-cuerpo {
    width: min(46rem, 58vw);
    max-width: 54ch;
    margin-left: 0;
    padding-left: 0;
    font-size: clamp(1.06rem, 1.35vw, 1.24rem);
    text-wrap: pretty;
  }
}

@media (max-width: 899px) {
  .est-cuerpo,
  .est-data { margin-left: 0; padding-left: 0; }
  .est-cuerpo { width: min(34rem, 66vw); max-width: 48ch; }
  .est-data { width: min(34rem, 66vw); }
}

@media (max-width: 760px) {
  .est-cuerpo,
  .est-data { width: min(28rem, 88vw); }
  .est-data { margin-top: 0.9rem; }
  .est-data p { padding-block: 0.65rem; }
  .est-data strong { font-size: var(--fs-micro); }
  .text-accent { white-space: normal; }
}

@media (prefers-reduced-motion: reduce) {
  .js #globoWrap {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }
  .text-accent { --accent-reveal: 1 !important; }
  .est-data p { opacity: 1 !important; transform: none !important; }
}

/* ── Globo limpio: sin instrumentación, máxima presencia visual ── */
.globo-img {
  opacity: 1;
  filter:
    brightness(1.2)
    contrast(1.07)
    saturate(1.06)
    drop-shadow(0 2.2rem 3.6rem rgba(0,0,0,0.4));
  backface-visibility: hidden;
}
.scrim-lectura {
  background:
    linear-gradient(90deg,
      rgba(3,10,22,0.94) 0%,
      rgba(3,10,22,0.78) 32%,
      rgba(3,10,22,0.16) 52%,
      transparent 66%),
    linear-gradient(180deg, rgba(3,10,22,0.1), transparent 62%, rgba(3,10,22,0.3));
}
.bitacora::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(ellipse 28% 48% at 80% 30%, rgba(145,188,232,0.16), transparent 72%);
  mix-blend-mode: screen;
}

@media (max-width: 760px) {
  .globo-img {
    filter:
      brightness(1.16)
      contrast(1.06)
      saturate(1.04)
      drop-shadow(0 1.5rem 2.5rem rgba(0,0,0,0.36));
  }
  .bitacora::after {
    background: radial-gradient(ellipse 55% 32% at 82% 18%, rgba(145,188,232,0.12), transparent 74%);
  }
}

/* ── Globo protagonista ─────────────────────────────────────── */

@media (min-width: 900px) {
  .globo-wrap {
    top: 3.5vh;
    right: 6vw;
    width: clamp(380px, 34vw, 590px);
  }
  .globo-img {
    filter:
      brightness(1.28)
      contrast(1.08)
      saturate(1.08)
      drop-shadow(0 2.4rem 4rem rgba(0,0,0,0.38));
  }
  .scrim-lectura {
    background:
      linear-gradient(90deg,
        rgba(3,10,22,0.94) 0%,
        rgba(3,10,22,0.76) 30%,
        rgba(3,10,22,0.08) 47%,
        transparent 59%),
      linear-gradient(180deg, rgba(3,10,22,0.08), transparent 64%, rgba(3,10,22,0.26));
  }
  .bitacora::after {
    background: radial-gradient(ellipse 32% 54% at 79% 29%, rgba(155,199,241,0.22), transparent 72%);
  }
}

@media (max-width: 760px) {
  .globo-wrap { right: -11vw; width: 76vw; }
  .globo-img {
    filter:
      brightness(1.2)
      contrast(1.07)
      saturate(1.05)
      drop-shadow(0 1.5rem 2.5rem rgba(0,0,0,0.34));
  }
}

/* Escala editorial contenida para los capítulos del vuelo.
   El hero de portada queda fuera de este ámbito. */
.bitacora .est-titulo {
  max-width: 13ch;
  font-size: clamp(2.5rem, 4.45vw, 4.8rem);
  line-height: 0.96;
  letter-spacing: -0.045em;
}
.bitacora .est-cuerpo {
  margin-top: clamp(1rem, 1.8vh, 1.45rem);
  font-size: clamp(0.96rem, 1.12vw, 1.08rem);
  line-height: 1.5;
}
.bitacora .est-data { margin-top: clamp(1rem, 1.8vh, 1.4rem); }

@media (min-width: 900px) {
  .bitacora .est-pasos { min-height: clamp(17rem, 38vh, 25rem); }
}

@media (max-width: 899px) {
  .bitacora .est-titulo {
    max-width: 12ch;
    font-size: clamp(2.25rem, 6.2vw, 3.8rem);
  }
  .bitacora .est-cuerpo { font-size: clamp(0.92rem, 1.8vw, 1.02rem); }
}

@media (max-width: 760px) {
  .bitacora .est-titulo {
    max-width: 13ch;
    font-size: clamp(2rem, 9.5vw, 3.15rem);
    line-height: 0.98;
  }
  .bitacora .est-cuerpo {
    margin-top: 0.9rem;
    font-size: 0.92rem;
  }
}

@media (min-width: 1440px) {
  .globo-wrap {
    top: 6vh;
    right: 8vw;
    width: clamp(400px, 27vw, 500px);
  }
  .bitacora .est-titulo {
    max-width: 13ch;
    font-size: clamp(3.1rem, 3.7vw, 4.1rem);
  }
  .bitacora .est-cuerpo,
  .bitacora .est-data { width: min(40rem, 44vw); }
  .bitacora .est-cuerpo { font-size: 1rem; }
}

/* ══════════ PERFORMANCE · promoción de capas con criterio ══════════ */
.nav,
.nav.nav-scrolled,
.nav.nav-papel-scrolled,
.nav.nav-dark-surface {
  min-height: 4.2rem;
  padding-top: 0.72rem;
  padding-bottom: 0.72rem;
}

.hero *,
.line-inner,
/* `.hero-h1 .ch` (0,2,0) le gana en especificidad a `.hero *` (0,1,0),
   así que se escapaba del reset: 34 letras del titular quedaban
   promocionadas a capa propia durante toda la vida de la página, para
   una animación de intro que dura un segundo. Y encima el hero las
   escala en bloque a 1.9 en la transición, con las 34 texturas
   colgando. Se listan aquí explícitamente, igual que `.mch`. */
.hero-h1 .ch,
.mch,
.etapas-atlas { will-change: auto; }

/* Se promueve el contenedor, no sus hijos: con `.paisaje` escalado y
   además `.capa`/`.globo-img` promovidas por separado, cada hija se
   rasterizaba a la escala compuesta y se guardaban texturas de ambos
   sentidos del scroll — de ahí los artefactos al volver atrás. */
body:not(.fuera-hero) .hero .cielo,
body:not(.fuera-hero) .hero .paisaje,
body:not(.fuera-hero) .hero .globo-wrap,
body:not(.fuera-hero) .hero .repisa,
/* El banco de nubes DEBE estar aquí. `.hero *` de arriba resetea
   will-change a `auto`, así que sin esta línea la capa no se promueve:
   como la timeline la escala de 1.04 a 2.6, el compositor la
   re-rasterizaba —con el blur incluido— en cada frame del scrub, justo
   en el tramo con la superficie pintada más grande de todo el hero. */
body:not(.fuera-hero) .hero .mar-nubes { will-change: transform; }

/* Los dos hijos del banco también, cada uno a lo suyo. El lienzo es
   una textura GPU que el transform del padre estira sin repintar; el
   velo anima SU opacidad mientras el padre escala — sin capa propia,
   cada frame del fundido repintaba la textura del contenedor entero
   (150vw × 140vh), que era la otra mitad del tirón de la travesía. */
body:not(.fuera-hero) .hero .nube-lienzo { will-change: transform; }
body:not(.fuera-hero) .hero .nube-velo { will-change: opacity; }

/* El amanecer ya no se transforma: solo se descubre (clip-path) */
body:not(.fuera-hero) .hero .amanecer { will-change: opacity; }

body.fuera-hero .hero * { will-change: auto !important; }

@media (prefers-reduced-motion: reduce) {
  .rayos-luz,
  .bruma,
  .scroll-punto { animation: none !important; }
  .amanecer-bg { opacity: 1 !important; }
}

/* ══════════════════════════════════════════════════════════════
   HERO · PORTADA SAAS
   Menos interfaz: firma, claim a una voz, una acción.
   La escena queda intacta; esto es solo el chrome que la habita.
   ══════════════════════════════════════════════════════════════ */
.hero-title .portada {
  top: 47%;
  width: min(92vw, 72rem);
  max-width: none;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero-title .portada::before {
  inset: -5rem -12rem -6rem;
  background:
    radial-gradient(ellipse 56% 54% at 50% 48%, rgba(3, 10, 22, 0.72), rgba(3, 10, 22, 0.2) 57%, transparent 78%);
}

/* Fuera telemetría y ficha de métricas: un hero es una promesa y
   una acción, no un salpicadero (jerarquía: un solo mensaje). */
.hero-title .hero-telemetry,
.hero-title .hero-meta { display: none; }

/* La firma: texto desnudo con su pulso ámbar, sin cápsula ni blur */
.hero-title .hero-badge {
  margin: 0 0 clamp(1.1rem, 2.4vh, 1.6rem);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  backdrop-filter: none;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: 0.32em;
  color: var(--texto-noche-3);
}

/* El claim: DOS líneas, nunca tres. El enunciado se dice en voz
   medida y el verbo se grita en ámbar — la promesa entera cabe en un
   solo golpe de vista.
   La escala la fija SOLO la línea ámbar (es la corta: si cabe ella,
   cabe el bloque). La primera la justifica justificarClaim() en
   main.js a ese mismo ancho medido, así que el lockup es un rectángulo
   exacto a cualquier viewport y con cualquier métrica de fuente. El
   font-size que va aquí es el que rige antes de esa medida y sin JS:
   0.4928× es la razón de anchos de ambas frases en Montserrat 800. */
.hero-title .hero-h1 {
  width: 100%;
  display: grid;
  justify-items: center;
  text-transform: uppercase;
}

.hero-title .claim-l1,
.hero-title .claim-l2 {
  margin: 0;
  font-family: 'Montserrat', sans-serif;
  font-weight: 800;
  letter-spacing: -0.035em;
  -webkit-text-stroke: 0;
  transform: none;
  white-space: nowrap;
}

.hero-title .claim-l1 {
  font-size: clamp(1.18rem, 3.55vw, 2.17rem);
  line-height: 1.12;
  color: var(--blanco);
}

.hero-title .claim-l2 {
  position: relative;
  z-index: 0;
  margin-top: 0.04em;
  /* La escala la fija ESTA línea, y su techo lo fija la escena: a 9vw
     el claim llegaba al 45% del encuadre y el punto final caía sobre el
     sombrero de la exploradora, que entra al 43%. A 7.2vw / 4.4rem el
     lockup cierra sobre el mar abierto y la pareja queda limpia. Si se
     recompone la foto, esta es la medida que hay que volver a mirar. */
  font-size: clamp(2.4rem, 7.2vw, 4.4rem);
  line-height: 1;
  color: var(--ambar);
}

/* El resplandor no puede vivir dentro del recorte.
   `.line { overflow: hidden }` es la máscara del revelado por
   caracteres (entran desde abajo a yPercent 118) y clipa en caja
   cualquier sombra grande — es el aviso histórico del proyecto. En vez
   de renunciar al glow, se suelta el recorte cuando el revelado ya ha
   terminado: la clase la pone intro() al aterrizar la palabra, así que
   el ámbar se enciende justo cuando cae. Sin JS o con reduced motion se
   pone de salida y no hay nada que recortar. */
body.claim-listo .hero-title .claim-l1,
body.claim-listo .hero-title .claim-l2 { overflow: visible; }

/* El encendido del ámbar: una luz que prende a tirones, aguanta un
   momento y se consume, dejando el texto en amarillo plano. Es un
   one-shot con `forwards`, así que **el estado final —sin resplandor—
   es el que se queda** durante toda la vida de la página: el glow es un
   acontecimiento, no una decoración permanente.
   Los tramos del parpadeo llevan `steps(1, end)`: una luz que falla no
   hace fundidos, salta. Y de paso el navegador solo repinta el
   text-shadow en los bordes de fotograma clave en vez de interpolarlo
   en cada frame — que es lo caro de animar una sombra sobre tipografía
   a esta escala. El último tramo sí es un fundido largo: ahí la luz se
   apaga de verdad.
   Los cuatro estratos de la sombra se mantienen en TODOS los pasos, con
   los mismos radios: solo viaja el alfa. Si cambiara el número de capas
   o los radios entre pasos, el navegador no podría interpolar el tramo
   final y el apagado saltaría en seco. */
body.claim-listo .hero-title .claim-l2 {
  animation: claimPrende 3s both;
}

/* UN solo destello: sube, aguanta y se consume. La versión anterior
   tenía DOS picos (subía, caía al 0.13, volvía a subir y se apagaba) y
   eso no se lee como «un parpadeo lento» sino como dos destellos
   seguidos. Un pico = un parpadeo. La subida es más corta que la caída
   —0.6s contra 1.7s—: así prende como una luz y se consume como una
   brasa, en vez de leerse como un fundido simétrico de vídeo. */
@keyframes claimPrende {
  /* — prende — */
  0%   { animation-timing-function: var(--ease-estandar);
         text-shadow: 0 0 0.03em rgba(255,238,196,0), 0 0 0.18em rgba(255,198,96,0), 0 0 0.5em rgba(232,160,32,0), 0 0 1.3em rgba(232,160,32,0); }
  20%  { animation-timing-function: linear;
         text-shadow: 0 0 0.03em rgba(255,238,196,1), 0 0 0.18em rgba(255,198,96,0.78), 0 0 0.5em rgba(232,160,32,0.62), 0 0 1.3em rgba(232,160,32,0.4); }
  /* — aguanta — */
  43%  { animation-timing-function: var(--ease-estandar);
         text-shadow: 0 0 0.03em rgba(255,238,196,1), 0 0 0.18em rgba(255,198,96,0.78), 0 0 0.5em rgba(232,160,32,0.62), 0 0 1.3em rgba(232,160,32,0.4); }
  /* — se consume — */
  100% { text-shadow: 0 0 0.03em rgba(255,238,196,0), 0 0 0.18em rgba(255,198,96,0), 0 0 0.5em rgba(232,160,32,0), 0 0 1.3em rgba(232,160,32,0); }
}

/* La brasa: el halo ambiental que el text-shadow no alcanza a dar.
   Va detrás del propio texto (z-index -1 dentro del contexto de apilado
   que abre `.claim-l2`, para no caer por debajo de la penumbra de
   `.portada`, que también usa -1) y parpadea al mismo compás, por
   opacidad — compuesta, no repintada. Acaba en `visibility: hidden`
   para que el compositor suelte la capa desenfocada: quedarse en
   `opacity: 0` deja la textura viva sin que se vea nada. */
body.claim-listo .hero-title .claim-l2::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  z-index: -1;
  width: 132%; height: 250%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  /* Sin filtro: el desenfoque lo da la propia caída del gradiente
     (paradas más tendidas que compensan el blur(16px) retirado). El
     filtro obligaba a re-rasterizar el halo en cada frame mientras la
     timeline escala `.hero-title` a 1.9 al entrar en las nubes — y
     quien hace scroll nada más cargar pillaba la brasa aún encendida
     justo en ese tramo. */
  background: radial-gradient(ellipse 50% 40% at 50% 50%,
    rgba(232, 160, 32, 0.34), rgba(232, 160, 32, 0.14) 40%, rgba(232, 160, 32, 0.04) 62%, transparent 82%);
  pointer-events: none;
  animation: claimBrasaPrende 3s both;
}

@keyframes claimBrasaPrende {
  0%   { opacity: 0; animation-timing-function: var(--ease-estandar); }
  20%  { opacity: 1; animation-timing-function: linear; }
  43%  { opacity: 1; animation-timing-function: var(--ease-estandar); }
  99%  { opacity: 0; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}

.hero-title .hero-sub {
  max-width: 36rem;
  margin: clamp(1.1rem, 2.3vh, 1.5rem) auto 0;
  font-family: 'Montserrat', sans-serif;
  font-size: clamp(0.95rem, 1.1vw, 1.05rem);
  font-style: normal;
  font-weight: 400;
  line-height: 1.65;
  color: rgba(245, 244, 239, 0.72);
}

.hero-title .hero-sub strong {
  font-style: normal;
  font-weight: 600;
  color: rgba(245, 244, 239, 0.95);
}

/* Una acción primaria y un enlace tranquilo. Sentence case,
   cápsula sólida: el botón de un producto, no un artefacto. */
.hero-title .hero-ctas {
  margin-top: clamp(1.8rem, 3.6vh, 2.4rem);
  justify-content: center;
  gap: 1rem;
}

.hero-title .btn-hero {
  min-height: 3.25rem;
  border-radius: var(--radio-pill);
  font-family: 'Montserrat', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
}
.hero-title .btn-hero-label { white-space: nowrap; }

.btn-hero-index { display: none; }
.btn-hero-label-corta { display: none; }

.hero-title .btn-hero-primario {
  min-width: 0;
  justify-content: center;
  gap: 0.6rem;
  padding: 0 1.9rem;
  border: 0;
  background: var(--ambar);
  color: var(--marino);
  clip-path: none;
  box-shadow: 0 10px 28px -10px rgba(232, 160, 32, 0.55);
}

.hero-title .btn-hero-primario::before { display: none; }

.hero-title .btn-hero-secundario {
  min-width: 0;
  justify-content: center;
  gap: 0.55rem;
  padding: 0 1.6rem;
  background: var(--blanco);
  color: var(--marino);
  border: 0;
  box-shadow: none;
}

.btn-hero-orbit {
  display: grid;
  place-items: center;
  width: auto;
  height: auto;
  border-radius: 0;
  background: transparent;
  color: currentColor;
}

.hero-title .btn-flecha { width: 15px; height: 15px; }



@media (max-width: 760px) {
  .hero-title .portada {
    top: 46%;
    /* El encuadre es el que fija la escala del claim (la línea ámbar se
       mide contra él), así que en móvil se le da todo el ancho que la
       caja tolera sin pegarse al borde. */
    width: calc(100vw - 1.75rem);
  }
  .hero-title .hero-badge { letter-spacing: 0.22em; }
  /* Sin override de escala: el 13vw de `.claim-l2` ya cabe aquí (11
     caracteres en nowrap) y justificarClaim() ajusta la otra línea. */
  .hero-title .hero-sub {
    max-width: 24rem;
    margin-top: 1.1rem;
    font-size: 0.98rem;
  }
  /* Estructura de la fila: el ajuste fino (tamaños, relleno, tipo)
     vive en la cascada de «PORTADA A LA IZQUIERDA» más abajo, que es
     la que manda de verdad en este ancho — aquí solo se fija que la
     fila NO se apile. */
  .hero-title .hero-ctas { flex-direction: row; flex-wrap: nowrap; }
  .hero-title .btn-hero-primario,
  .hero-title .btn-hero-secundario {
    width: auto;
    flex: 1 1 0;
    min-width: 0;
    margin-inline: 0;
  }
  /* La fila estrecha no tiene sitio para la frase entera sin partirla:
     se cambia por la etiqueta corta en vez de dejar que salte de línea. */
  .hero-title .btn-hero-label-completa { display: none; }
  .hero-title .btn-hero-label-corta { display: inline; }
}

@media (max-height: 740px) and (min-width: 761px) {
  .hero-title .portada { top: 48%; }
  .hero-title .hero-badge { margin-bottom: 0.8rem; }
  /* Pantallas bajas: el bloque de dos líneas cede altura, no legibilidad */
  .hero-title .claim-l2 { font-size: clamp(2rem, 7.2vw, 4.4rem); }
  .hero-title .claim-l1 { font-size: clamp(0.99rem, 3.55vw, 2.17rem); }
  .hero-title .hero-sub { margin-top: 0.9rem; }
  .hero-title .hero-ctas { margin-top: 1.3rem; }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin parpadeo: se entrega de salida el estado final de la animación
     —texto en amarillo plano, sin resplandor—, que es exactamente donde
     acaba el encendido. Nadie se pierde nada de la información. */
  body.claim-listo .hero-title .claim-l2 { animation: none; text-shadow: none; }
  body.claim-listo .hero-title .claim-l2::after { display: none; }
}

/* ── Respuesta táctil: el press confirma sin retrasar ──────────
   .btn-hero recibe x/y inline de GSAP (magnético): ahí el press es
   brightness, nunca transform, para no pelear con el script. */
.btn:active { transform: translateY(1px); }
.hero-title .btn-hero-primario:active,

/* ── Reduced motion: la portada entra en el flujo estático ──────
   (las capas de composición absoluta la dejaban flotando a mitad
   del hero; aquí, al final de la cascada, vuelve al documento) */
@media (prefers-reduced-motion: reduce) {
  .hero-title .portada {
    position: static;
    width: min(92vw, 40rem);
    max-width: none;
    margin: 3rem auto;
    transform: none;
    text-align: center;
  }
}


/* ══════════════════════════════════════════════════════════════
   HERO · PORTADA A LA IZQUIERDA
   El fotograma manda con su mitad derecha —los exploradores, el faro,
   la bitácora abierta—, así que el bloque editorial se ancla al tercio
   izquierdo, que en la foto es mar y noche abierta. Firma, claim,
   subtítulo y acciones comparten un único eje de bandera.
   Va al final de la cascada del hero: rehace los `top` de las media
   queries de altura y el reposo de reduced-motion, que quedaban antes.
   ══════════════════════════════════════════════════════════════ */
.hero-title .portada {
  left: clamp(1.5rem, 6.5vw, 7rem);
  top: 57%;
  width: min(76vw, 58rem);
  max-width: none;
  transform: translateY(-50%);
  text-align: left;
  align-items: flex-start;
}
/* La penumbra se descentra con el bloque: se abre hacia el margen
   izquierdo y no mancha el centro del encuadre, que ahora es foto. */
.hero-title .portada::before {
  inset: -4rem -10rem -5rem -9rem;
  background: radial-gradient(ellipse 60% 56% at 26% 50%,
    rgba(3, 10, 22, 0.58), rgba(3, 10, 22, 0.16) 58%, transparent 78%);
}
/* El lockup sigue siendo un rectángulo exacto —justificarClaim() mide
   la línea ámbar y ajusta la otra a ese ancho—: lo único que cambia es
   el borde por el que se alinean las dos. */
.hero-title .hero-h1 { justify-items: start; }
.hero-title .hero-badge { align-self: flex-start; }
.hero-title .hero-sub {
  max-width: 34rem;
  margin-inline: 0;
}
.hero-title .hero-ctas { justify-content: flex-start; }

@media (max-height: 740px) and (min-width: 761px) {
  .hero-title .portada { top: 49%; }
}

/* ── El bloque cede escala cuanto más pequeño es el encuadre ──
   En pantalla grande el claim a 9vw es el espectáculo; en una de mano
   ese mismo 9vw tapa la foto entera y el hero deja de ser una imagen
   con un titular para ser un titular con una imagen detrás. Se baja el
   conjunto ~15% en tableta y ~20% en móvil —el equivalente a mirarlo
   al 80%—, así que la escena vuelve a respirar por arriba y por abajo.
   Solo hace falta tocar la línea ámbar: es la que fija la escala del
   lockup y justificarClaim() ajusta la otra a su ancho medido. */
@media (max-width: 899px) {
  .hero-title .claim-l2 { font-size: clamp(2.1rem, 7.9vw, 4.4rem); }
  .hero-title .claim-l1 { font-size: clamp(1.03rem, 3.9vw, 2.17rem); }
  .hero-title .hero-sub { font-size: clamp(0.92rem, 1.5vw, 1.02rem); }
  .hero-title .hero-ctas { margin-top: clamp(1.4rem, 3vh, 1.9rem); }
  .hero-title .btn-hero { min-height: 3rem; font-size: 0.8rem; }
}

@media (max-width: 760px) {
  /* La portada baja a su propia banda, anclada al pie: el bloque crece
     hacia arriba, así que el ritmo entre foto y texto no se descuadra
     cuando el copy cambia de largo o la barra del navegador aparece. */
  .hero-title .portada {
    left: 1.25rem;
    top: auto;
    bottom: var(--portada-pie);
    width: calc(100vw - 2.5rem);
    transform: none;
  }
  .hero-title .claim-l2 { font-size: clamp(1.7rem, 7.4vw, 2.6rem); }
  .hero-title .claim-l1 { font-size: clamp(0.84rem, 3.65vw, 1.28rem); }
  .hero-title .hero-badge {
    margin-bottom: 0.85rem;
    letter-spacing: 0.2em;
    font-size: 0.56rem;
  }
  .hero-title .hero-sub {
    max-width: 21rem;
    margin-top: 0.9rem;
    font-size: 0.86rem;
    line-height: 1.55;
  }
  /* La columna de acciones deja de centrarse: el botón sólido conserva
     su superficie de toque y el enlace se ciñe a su texto. */
  .hero-title .hero-ctas {
    align-items: stretch;
    margin-top: 1.4rem;
    gap: 0.5rem;
  }
  .hero-title .btn-hero {
    min-height: 2.8rem;
    font-size: 0.62rem;
    letter-spacing: 0;
  }
  .hero-title .btn-hero-primario,
  .hero-title .btn-hero-secundario {
    padding-left: 0.55rem;
    padding-right: 0.55rem;
    margin-inline: 0;
  }
  .hero-title .btn-hero-primario { gap: 0.28rem; }
  .hero-title .btn-hero-secundario { gap: 0.26rem; }
  .hero-title .btn-hero-play { width: 1.1em; height: 1.1em; }
}

@media (prefers-reduced-motion: reduce) {
  /* Sin coreografía el hero se despliega en vertical y todas sus capas
     de escena siguen siendo absolutas. Un elemento estático no puntúa
     el z-index, así que el bloque editorial se pintaba DEBAJO de ellas:
     se posiciona sin moverse (relative sin desplazamiento) para
     recuperar el orden. Y la foto se queda en el primer pantallazo, que
     es lo que ilustra — estirada a toda la sección pierde el encuadre. */
  .hero-foto {
    height: 100vh; height: 100svh;
    bottom: auto;
  }
  .hero-beat { position: relative; }
  .bitacora { position: relative; z-index: 3; }
  /* El contenedor del beat 0 deja de centrarse: el eje de bandera es
     el mismo que con animación. */
  .hero-title {
    margin-inline: clamp(1.25rem, 6vw, 5rem) auto;
    max-width: min(46rem, 92vw);
  }

  /* Sin coreografía la portada vuelve al flujo, pero mantiene el eje */
  .hero-title .portada {
    position: static;
    width: min(92vw, 46rem);
    max-width: none;
    margin: 3rem 0;
    transform: none;
    text-align: left;
    align-items: flex-start;
  }
}


@media (prefers-reduced-motion: reduce) and (max-width: 760px) {
  /* El reparto del móvil vale también sin coreografía: el texto va
     DEBAJO de la banda de foto, nunca encima. Sin sticky el bloque está
     en flujo y la capa sigue anclada arriba, así que la banda se
     reserva con un margen —el mismo cálculo, menos el `padding-top` de
     `.hero-sticky` (7rem) que ya empuja al bloque. */
  .hero-title {
    margin-top: calc(
      max(30svh, 100svh - var(--portada-alto) - var(--portada-pie) - var(--portada-aire))
      - 7rem + var(--portada-aire));
  }
}


/* ══════════════════════════════════════════════════════════════
   PRUEBAS · VARIANTES DE HERO MÓVIL  (TEMPORAL — borrar al decidir)
   ──────────────────────────────────────────────────────────────
   ⚠️ Se diseñaron sobre un máster compuesto para vertical
   (`hero-mobile.webp`), que luego se retiró: ahora todas montan sobre el
   apaisado de siempre, así que las que van a sangre (B, D, E, F) vuelven
   a recortar la escena. Si se recupera aquel máster, vuelven a lucir.
   Se activan con ?hero=b|c|d, que pone la clase en <html>. Sin
   parámetro manda la A. TODO va dentro de `max-width: 760px`.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {

  /* ── B · A SANGRE, TEXTO SOBRE EL CIELO ───────────────────────
     La que el máster vertical pide sola: la escena llena la pantalla
     y el texto se posa en la banda de cielo estrellado, que está
     vacía por composición. Sin velo, sin máscara, sin partir nada —
     nadie tapa a nadie porque la foto ya reservó el hueco. */
  .hero-var-b .hero-foto { background: none; }
  .hero-var-b .hero-foto img {
    height: 100%;
    object-position: 50% 50%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero-var-b .hero-title .portada {
    top: clamp(4.75rem, 11vh, 6.5rem);
    bottom: auto;
  }

  /* ── C · VENTANA ──────────────────────────────────────────────
     La foto deja de ser fondo y pasa a ser OBJETO: una lámina con
     esquinas redondeadas, aire por los cuatro costados y sombra
     propia. El marino del hero hace de mesa. Cambia el registro: de
     escena en la que estás a pieza que te enseñan. */
  .hero-var-c .hero-foto img {
    height: max(30svh, calc(100svh - 4.5rem - var(--portada-alto) - var(--portada-pie) - var(--portada-aire)));
    width: calc(100% - 1.8rem);
    margin: 4.5rem 0.9rem 0;
    border-radius: 1.35rem;
    object-position: 50% 32%;
    box-shadow: 0 2rem 3.5rem -2rem rgba(2, 6, 14, 0.95);
    -webkit-mask-image: none;
    mask-image: none;
  }
  /* Filo claro de un píxel: separa la lámina del marino sin dibujar
     una caja. Sombra interior para no alterar la medida. */
  .hero-var-c .hero-foto::after {
    content: '';
    position: absolute;
    top: 4.5rem; left: 0.9rem; right: 0.9rem;
    height: max(30svh, calc(100svh - 4.5rem - var(--portada-alto) - var(--portada-pie) - var(--portada-aire)));
    border-radius: 1.35rem;
    box-shadow: inset 0 0 0 1px rgba(245, 244, 239, 0.16);
    pointer-events: none;
  }

  /* ── D · SÁNDWICH ─────────────────────────────────────────────
     Foto a sangre y el texto PARTIDO: la promesa arriba, en el
     cielo; las acciones ancladas al pie, sobre la bitácora. Los
     exploradores se quedan enteros en la franja del medio, que es la
     que nadie pisa. Un velo mínimo solo bajo las acciones, donde el
     mapa se aclara. */
  .hero-var-d .hero-foto { background: none; }
  .hero-var-d .hero-foto img {
    height: 100%;
    object-position: 50% 50%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero-var-d .hero-foto::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(0deg,
      rgba(3, 9, 19, 0.88) 0%, rgba(3, 9, 19, 0.45) 12%, transparent 26%);
  }
  /* La caja ocupa el alto entero y el `margin-top: auto` de las
     acciones las manda al pie: una sola pieza, dos anclajes. */
  .hero-var-d .hero-title .portada {
    top: clamp(4.75rem, 11vh, 6.5rem);
    bottom: clamp(2.25rem, 5.5vh, 3.5rem);
    display: flex;
    flex-direction: column;
  }
  .hero-var-d .hero-title .portada::before { display: none; }
  .hero-var-d .hero-title .hero-ctas { margin-top: auto; }

  /* ── E · CENTRADA AL MEDIO ────────────────────────────────────
     Todo al eje: firma, claim, subtítulo y las dos acciones. El
     bloque se planta en mitad de la pantalla y pisa a los
     exploradores — el precio aceptado a cambio de una composición
     simétrica, de cartel. La penumbra se recentra con él para que el
     texto no dependa de lo que haya detrás. */
  .hero-var-e .hero-foto { background: none; }
  .hero-var-e .hero-foto img {
    height: 100%;
    object-position: 50% 50%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero-var-e .hero-title .portada,
  .hero-var-f .hero-title .portada {
    left: 1.25rem; right: 1.25rem;
    width: auto;
    align-items: center;
    text-align: center;
  }
  .hero-var-e .hero-title .portada { top: 50%; bottom: auto; transform: translateY(-50%); }
  .hero-var-e .hero-title .portada::before {
    inset: -2.5rem -1.5rem;
    background: radial-gradient(ellipse 64% 56% at 50% 50%,
      rgba(3, 10, 22, 0.74), rgba(3, 10, 22, 0.3) 56%, transparent 80%);
  }
  .hero-var-e .hero-title .hero-h1,
  .hero-var-f .hero-title .hero-h1 { justify-items: center; }
  .hero-var-e .hero-title .hero-badge,
  .hero-var-f .hero-title .hero-badge { align-self: center; }
  .hero-var-e .hero-title .hero-sub,
  .hero-var-f .hero-title .hero-sub { margin-inline: auto; }
  .hero-var-e .hero-title .hero-ctas,
  .hero-var-f .hero-title .hero-ctas { align-items: center; }
  .hero-var-e .hero-title .btn-hero-primario,
  .hero-var-f .hero-title .btn-hero-primario { margin-inline: auto; }

  /* ── F · CENTRADA SOBRE EL CIELO ──────────────────────────────
     El mismo eje simétrico de la E, pero apoyado en la banda de
     cielo: se gana la composición de cartel sin pisar a nadie. */
  .hero-var-f .hero-foto { background: none; }
  .hero-var-f .hero-foto img {
    height: 100%;
    object-position: 50% 50%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero-var-f .hero-title .portada {
    top: clamp(4.75rem, 11vh, 6.5rem);
    bottom: auto;
    transform: none;
  }
  .hero-var-f .hero-title .portada::before { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   ACTO II · LA RUTA — CARTA DE DERROTA (rediseño desde cero)
   ──────────────────────────────────────────────────────────────
   Antes: cinco tarjetas en fila sobre un papel casi vacío. El
   scroll horizontal —el recurso más expresivo de la página— se
   gastaba en el patrón más genérico que existe, un carrusel de
   cajas, y el 60% del encuadre no tenía nada dentro.

   Ahora la sección ES la carta náutica. Tres decisiones:
   1. Carta de PAPEL a sangre, del color de la letra de ¿ZARPAMOS?
      Además el hero remata en papel, así que el cruce Manifiesto →
      Ruta ya no tiene salto de color: entrega papel sobre papel.
   2. La ruta deja de ser adorno en la banda baja y pasa a ser el
      EJE: cruza el encuadre por el 58% y cada etapa cuelga de su
      nodo — rótulo sobre el eje, letra pequeña bajo él.
   3. Las etapas dejan de ser cajas y pasan a ser COLUMNAS de la
      carta, separadas por el filete de la retícula. Sin tarjeta
      que dibujar, el peso lo lleva la tipografía: numeral macizo
      en ámbar a escala de sondeo y el verbo a escala de titular.
   ══════════════════════════════════════════════════════════════ */

.etapas {
  --etapa-ancho: clamp(300px, 33vw, 470px);
  --etapa-gotera: clamp(1.5rem, 2.6vw, 2.6rem);  /* margen interno de columna */
  --calle: clamp(3.4rem, 8vh, 5rem);             /* medio ancho de la calle del eje */
  background: var(--papel);
  color: var(--tinta);
}

/* ── El fondo de la carta: papel, luz cálida al norte ── */
.etapas-atlas {
  background:
    radial-gradient(ellipse 70% 55% at 78% 4%, rgba(232,160,32,0.13), transparent 62%),
    radial-gradient(ellipse 60% 50% at 8% 96%, rgba(15,35,64,0.07), transparent 68%),
    var(--papel);
  opacity: 1;
}
/* Carta antigua grabada bajo todo lo demás: da textura de papel real a
   la sección sin competir con el eje ni con la retícula.
   Va en un ::after propio —y no como capa más de `background`— porque
   `background-image` no admite opacidad por capa: aquí sí podemos
   bajarla y multiplicarla contra el papel para que la tinta del grabado
   se asiente en vez de flotar por encima.

   Va a sangre y ENTERA: `100% 100%`, no `cover`. La hoja es 3:2 y el
   encuadre 16:9, así que `cover` se comía un 16% por arriba y por abajo
   —justo el viñeteado de los bordes, que es lo que la hace leer como
   una hoja y no como un zoom—. Deformarla no se nota porque es textura;
   recortarla sí se notaba. */
.etapas-atlas::after {
  content: '';
  position: absolute;
  inset: 0;
  background: url(../assets/escenas/fondo-ruta.webp) center / 100% 100% no-repeat;
  opacity: 0.32;
  mix-blend-mode: multiply;
  pointer-events: none;
}
/* Retícula de la carta: fina cada 5.5rem, maestra cada 22rem */
.atlas-grid {
  opacity: 1;
  background-image:
    linear-gradient(rgba(15,35,64,0.085) 1px, transparent 1px),
    linear-gradient(90deg, rgba(15,35,64,0.085) 1px, transparent 1px),
    linear-gradient(rgba(15,35,64,0.038) 1px, transparent 1px),
    linear-gradient(90deg, rgba(15,35,64,0.038) 1px, transparent 1px);
  background-size: 22rem 22rem, 22rem 22rem, 5.5rem 5.5rem, 5.5rem 5.5rem;
  -webkit-mask-image: radial-gradient(ellipse 78% 72% at 50% 50%, transparent 6%, #000 96%);
  mask-image: radial-gradient(ellipse 78% 72% at 50% 50%, transparent 6%, #000 96%);
}
/* Viñeteado suave del papel: asienta la carta sin ensuciarla */
.etapas-sticky::before {
  background: radial-gradient(ellipse 86% 72% at 50% 50%, transparent 46%, rgba(15,35,64,0.07) 100%);
}
.etapas-sticky::after { background: none; }

/* ── Cabecera de la carta ─────────────────────────────────────── */
.etapas-kicker { color: var(--oro-tinta); }
.etapas-titulo { color: var(--marino); }
.etapas-sub { color: var(--tinta-suave); }

/* ── La columna-estación ──────────────────────────────────────── */
.etapa-panel {
  width: var(--etapa-ancho);
  height: 100%;
  padding: 0;
  display: block;
  /* Sin contrapunto: las columnas de una carta no bailan */
  --nota-y: 0rem;
  transform: none;
  border-left: 1px solid rgba(15,35,64,0.12);
}
.etapa-panel:last-of-type { border-right: 1px solid rgba(15,35,64,0.12); }
.etapa-panel:hover { --lift: 0rem; }

/* Sin caja: la columna ES el continente. El hover enciende el aire. */
.etapa-inner {
  position: relative;
  display: block;
  /* Ancho explícito: al pasar los hijos a posición absoluta la caja se
     queda sin contenido en flujo y colapsa a 0 heredando el
     dimensionado shrink-to-fit de la versión anterior (item de grid
     centrado). Es también la declaración correcta para lo que hace:
     ser el bloque contenedor de las dos bandas. */
  width: 100%;
  height: 100%;
  max-width: none;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  transition: background var(--dur-3) var(--ease-estandar);
}
.etapa-inner::before { content: none; }
.etapa-panel:hover .etapa-inner {
  border: 0;
  box-shadow: none;
  background: linear-gradient(180deg, transparent, rgba(232,160,32,0.09) 50%, transparent);
}

/* Las dos bandas cuelgan del eje: se separan de él por la calle, así
   que el eje siempre cruza por aire limpio pase por donde pase. */
.etapa-sobre,
.etapa-bajo {
  position: absolute;
  left: var(--etapa-gotera);
  right: var(--etapa-gotera);
}
/* El eje no va al 50% sino al 58%: la cabecera del acto ocupa los
   primeros ~200px y con el eje centrado el numeral de sondeo subía
   hasta pisarle el subtítulo. Bajándolo, la banda alta respira bajo la
   cabecera y la baja sigue despejando el odómetro. */
.etapa-sobre { bottom: calc(42% + var(--calle)); }
.etapa-bajo { top: calc(58% + var(--calle)); }

/* Numeral de sondeo: MACIZO en ámbar, a escala de carta. Es lo que da
   presencia sin necesidad de dibujar una tarjeta. */
.etapa-num {
  display: block;
  margin: 0 0 0.5rem;
  font-size: clamp(2.6rem, 4.4vw, 4.8rem);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  color: var(--ambar);
  -webkit-text-stroke: 0;
  text-transform: none;
}
.etapa-num::before { content: none; }

/* El icono va DENTRO del titular, en su misma línea: la estación se
   lee «[icono] Verbo» y el subtítulo debajo. Suelto encima, el icono
   era un adorno huérfano; junto al verbo, lo ilustra.
   Se dimensiona en `em` para que escale con el titular pase lo que
   pase, y baja a oro-tinta: es un trazo de 1.5px y en ámbar puro
   sobre papel se deshace (el numeral macizo aguanta, una línea fina no). */
.etapa-nombre {
  display: flex;
  align-items: center;
  gap: 0.5em;
  font-size: clamp(1.8rem, 2.8vw, 2.8rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--marino);
  text-transform: none;
}
/* De trazo suelto a icono de producto: una tesela con fondo y borde
   propios, como los iconos de feature de cualquier SaaS (Stripe,
   Linear...). Sin caja, un trazo fino de 26px se leía como un boceto,
   no como parte de un sistema de diseño. */
.etapa-icon {
  box-sizing: border-box;
  flex: 0 0 auto;
  width: 3.1rem;
  height: 3.1rem;
  padding: 0.7rem;
  margin: 0;
  border: 1px solid rgba(232, 160, 32, 0.28);
  border-radius: 0.85rem;
  background: rgba(232, 160, 32, 0.12);
  color: var(--oro-tinta);
}
.etapa-icon path, .etapa-icon circle { stroke-width: 2.3; }
/* Última estación: la llegada se entinta en ámbar macizo. */
.etapa-panel:last-of-type .etapa-icon {
  border-color: var(--ambar);
  background: var(--ambar);
  color: var(--marino);
}
.etapa-que {
  margin-top: 0.6rem;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--tinta-suave);
}

/* Nodo de estación: el meridiano de la columna cruzando la calle.
   Los waypoints (círculos) los dibuja el JS sobre la propia ruta. */
.etapa-nodo {
  position: absolute;
  left: 50%;
  top: calc(58% - var(--calle));
  height: calc(var(--calle) * 2);
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(232,160,32,0.6), transparent);
  transform: translateX(-50%);
  pointer-events: none;
}

.etapa-desc {
  margin: 0;
  max-width: 32ch;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--tinta-suave);
}
.etapa-objetivo {
  margin-top: clamp(0.9rem, 2.2vh, 1.5rem);
  padding-top: 0.9rem;
  border-top: 1px solid rgba(15, 35, 64, 0.14);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--marino);
  max-width: none;
}
.etapa-objetivo span {
  display: block;
  margin-bottom: 0.35rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--oro-tinta);
}

/* ── Instrumentos sobre la carta ──────────────────────────────── */
.ruta-svg { color: var(--marino); opacity: 1; }
#rutaPath { stroke: var(--marino); stroke-opacity: 0.3; }
.ruta-trail { stroke: var(--ambar); opacity: 1; }
/* Waypoint = estación. Es un <span> en el carril (ver el porqué en
   js/main.js): así el círculo lo hace `border-radius` y es redondo,
   en vez de salir ovalado por el estirado del viewBox. */
.ruta-wp {
  position: absolute;
  z-index: 2;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  display: grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: var(--radio-pill);
  color: var(--sepia);
  opacity: 0.45;
  pointer-events: none;
  transition: color var(--dur-2) var(--ease-estandar), opacity var(--dur-2) var(--ease-estandar);
}
.ruta-wp i {
  width: 7px;
  height: 7px;
  border-radius: var(--radio-pill);
  background: currentColor;
}
.ruta-wp.lit { color: var(--ambar); opacity: 1; }
/* El casco va en `currentColor` (ver `.nautilus` arriba): esta regla
   repetía `fill: var(--marino)` y, por vivir más abajo en la hoja con
   la misma especificidad, dejaba el submarino azul para siempre — el
   viraje a blanco al entrar en el mar no llegaba a verse nunca. */
.nautilus .nau-luz { fill: var(--ambar); }
.brujula { color: var(--tinta-suave); opacity: 0.6; }
.etapas-contador { color: var(--tinta-suave); }
.etapas-contador #etapaIdx { color: var(--marino); }
.contador-linea { background: rgba(15,35,64,0.16); }
.contador-total { color: var(--tinta-suave); }

/* Los velos de canto, del color de la carta */
.etapas-borde-i { background: linear-gradient(90deg, var(--papel) 10%, rgba(250,249,244,0.84) 46%, rgba(250,249,244,0) 100%); }
.etapas-borde-d { background: linear-gradient(270deg, var(--papel) 10%, rgba(250,249,244,0.84) 46%, rgba(250,249,244,0) 100%); }

/* ── Las bandas, en flujo normal a todos los anchos: sin carril
   horizontal no hay columnas que anclar. ──────────────────────── */
.etapa-panel {
  width: auto;
  height: auto;
  border-left: 0;
  border-bottom: 1px solid rgba(15,35,64,0.12);
  padding: clamp(2.4rem, 6vh, 3.4rem) var(--seccion-x);
}
.etapa-panel:last-of-type { border-right: 0; border-bottom: 0; }
/* Fila ancha, no columna angosta: el título (con su numeral e icono)
   vive en una banda de identidad a la izquierda y la descripción
   corre en una banda de lectura más generosa a la derecha — la misma
   gramática de «término / definición» que usan las páginas de specs
   de Apple o las listas numeradas de Stripe. Sin esto, `.etapa-sobre`
   y `.etapa-bajo` se apilaban dentro de una sola columna de 42rem que
   dejaba la mitad de la página en blanco. */
.etapa-inner {
  height: auto;
  max-width: 78rem;
  display: grid;
  grid-template-columns: minmax(15rem, 30%) 1fr;
  column-gap: clamp(2.4rem, 5vw, 5rem);
  align-items: start;
  /* Una generación anterior de este mismo bloque dejó `overflow: hidden`
     puesto (pensado para una tarjeta con borde propio); sin anularlo
     aquí, recorta el numeral fantasma en cuanto asoma fuera de la caja. */
  overflow: visible;
}
.etapa-sobre,
.etapa-bajo { position: static; left: auto; right: auto; }
.etapa-bajo { margin-top: 0.3rem; }
.etapa-nodo { display: none; }
/* La descripción vuelve a tener un tope de línea legible: la columna
   derecha es ancha, pero un párrafo entero a ese ancho se vuelve
   difícil de seguir. */
.etapa-desc { max-width: 42rem; }
.etapas-borde { display: none; }

/* Por debajo de los ~15rem mínimos de la columna de identidad, la fila
   ya no tiene sitio para partirse en dos sin apretar el título: vuelve
   a apilarse, igual que hacía toda la sección antes de este ancho. */
@media (max-width: 900px) {
  .etapa-inner { grid-template-columns: 1fr; }
  .etapa-bajo { margin-top: clamp(1.2rem, 3vh, 1.8rem); }
}

/* ── La carta, de pie ────────────────────────────────────────────
   En escritorio la sección ES la carta de derrota: un eje que cruza el
   encuadre y cinco estaciones colgando de sus nodos. Al plegarse en
   vertical se perdía justo eso —el eje, los waypoints, la idea de
   travesía— y quedaba una lista suelta: el numeral huérfano en su
   propia línea, un filete a sangre por etapa y un tercio del panel
   vacío. Aquí el eje se pone DE PIE: baja por el margen, cada etapa
   cuelga de su waypoint con el numeral dentro, y la última estación se
   entinta en ámbar porque es la llegada. Mismo lenguaje que arriba,
   girado 90°. Se aplica a todos los anchos: sin carril horizontal
   la carta siempre está «de pie». */
  /* El eje va por TRAMOS, uno por etapa, en vez de una línea única de
     punta a punta: así nace en el waypoint 01, cose cada estación con
     la siguiente y muere en la llegada, sin cola sobrante hacia el Kit.
     Cada tramo asoma un poco por debajo de su panel y el disco de la
     etapa siguiente —opaco, de papel— le tapa el remate. */
  .etapa-panel::before {
    content: '';
    display: block;
    position: absolute;
    /* La escala la anima el revelado de la estación (`--eje-esc`): un
       pseudoelemento no se puede animar directamente, una variable sí.
       Nace en 1, así que sin JS el eje está entero desde el principio. */
    transform: scaleY(var(--eje-esc, 1));
    transform-origin: top center;
    left: calc(var(--seccion-x) + 1.1rem);
    top: 2.45rem;
    bottom: -1.2rem;
    width: 1px;
    background: repeating-linear-gradient(180deg,
      rgba(15, 35, 64, 0.3) 0 13px, transparent 13px 25px);
  }
  .etapa-panel:last-of-type::before { display: none; }

  /* ── El fondo, para una sección que ahora mide 2.400px ──────────
     Tres capas pensadas para un encuadre apaisado de una pantalla de
     alto se rompían al desplegarse en columna:
     1. `.etapas-atlas` medía `100svh` y moría EN SECO a media
        sección — el corte feo. Ahora cubre la sección entera, que es
        lo que hace en escritorio.
     2. La hoja grabada es 3:2 y va a `100% 100%`: estirada a un
        lienzo de 1:6 sería un borrón de bandas, y repetida enseñaría
        su viñeteado una y otra vez. Se queda en la banda alta —donde
        acompaña a la cabecera— y se DISUELVE en el papel.
     3. Las máscaras elípticas del grid y del viñeteado se calculan
        contra la caja: en vertical dibujan su propia curva a media
        página. Pasan a degradados rectos, que no dependen del alto. */
  .etapas-atlas {
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 1;
  }
  .etapas-atlas::after {
    inset: 0 0 auto;
    height: 116svh;
    opacity: 0.26;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 38%, rgba(0,0,0,0.5) 72%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 38%, rgba(0,0,0,0.5) 72%, transparent 100%);
  }
  .atlas-grid {
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 74%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 74%, transparent 100%);
  }
  .etapas-sticky::before {
    background: linear-gradient(180deg,
      rgba(15, 35, 64, 0.05) 0%, transparent 22%,
      transparent 88%, rgba(15, 35, 64, 0.05) 100%);
  }

  /* La bocana es un fotograma del Kit para coser el corte del carril
     horizontal. Sin carril no hay corte que coser: aquí solo duplica la
     sección entera unos centímetros antes de la de verdad. */
  .etapa-arribo { display: none; }

  .etapa-panel {
    padding: 0 var(--seccion-x) clamp(1.4rem, 3.4vh, 2rem);
    border: 0;
  }
  /* Hueco para la cifra fantasma: a su tamaño, «01» pesa más que los
     3.4rem que bastaban para la placa pequeña — sin este margen se
     comía el icono. */
  .etapa-inner { padding-left: clamp(4.6rem, 6.2vw, 5.6rem); }

  /* Numeral fantasma a escala del icono, no de cartel: el intento
     anterior lo llevó a 4-5 veces el tamaño del título y aplastaba
     todo lo demás. A esta escala acompaña sin dominar — la misma
     proporción que un numeral de lista de Stripe o Linear. */
  .etapa-num {
    position: absolute;
    left: -0.03em; top: -0.05em;
    font-weight: 800;
    font-size: clamp(2.3rem, 2.9vw, 3.1rem);
    line-height: 1;
    color: transparent;
    -webkit-text-stroke: 1.5px rgba(15, 35, 64, 0.22);
    z-index: -1;
    user-select: none;
  }
  /* Última estación: la llegada se entinta en ámbar, como el resto de
     la carta marca la llegada. */
  .etapa-panel:last-of-type .etapa-num {
    -webkit-text-stroke: 1.5px rgba(232, 160, 32, 0.6);
  }

  .etapa-nombre { font-size: clamp(1.5rem, 1.9vw, 1.9rem); gap: 0.42em; }
  .etapa-icon { color: var(--ambar); }
  .etapa-que {
    margin-top: 0.5rem;
    font-size: 0.92rem;
    line-height: 1.4;
  }
  .etapa-bajo { margin-top: 0.9rem; }
  .etapa-desc { font-size: 0.92rem; line-height: 1.55; }
  .etapa-objetivo {
    margin-top: 0.9rem;
    padding-top: 0.7rem;
    font-size: 0.86rem;
  }

/* ── ETAPAS · escritorio: la derrota, de pie y a dos orillas ──────
   La lista término/definición dejaba la cabecera pegada al margen
   izquierdo y media página de papel vacía a la derecha de cada fila.
   Desde 900px la travesía se cuelga de una ESPINA CENTRAL: las
   etapas alternan a babor y estribor de un eje vertical con su
   waypoint ámbar, y la llegada (Transformar) remata centrada sobre
   el propio eje. Sin cajas: bloques de tipografía sobre la carta,
   deliberadamente distintos de las tarjetas del Kit — allí rejilla
   de planchas en marino, aquí una ruta trazada en el papel.
   El móvil (<900px) no se toca: conserva su columna. */
@media (min-width: 900px) {
  .etapas-head {
    max-width: 44rem;
    margin: 0 auto clamp(3.4rem, 7vh, 5.5rem);
    text-align: center;
  }
  .etapas-sticky { padding-bottom: clamp(3rem, 7vh, 5rem); }
  /* Odómetro del carril: se quedó sin motor — nada lo actualiza */
  .etapas-contador { display: none; }

  .etapas-track {
    --calle-gap: clamp(2.6rem, 4vw, 4.2rem); /* orilla texto ↔ eje */
    max-width: 72rem;
    margin-inline: auto;
    padding-inline: var(--seccion-x);
  }
  /* El eje punteado del margen pertenece a la lista vertical */
  .etapa-panel::before { display: none; }

  /* Cada estación es media página; las pares cruzan a estribor.
     El tramo de espina lo dibuja el propio panel (::after) sobre su
     borde interior — trazo CONTINUO: los tramos de paneles vecinos
     se solapan por el entrelazado y un punteado doblado se ve sucio. */
  .etapa-panel {
    width: 50%;
    padding: 0 var(--calle-gap) clamp(2.2rem, 5vh, 3.2rem) 0;
    border: 0;
  }
  .etapa-panel::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 1px;
    transform: translateX(50%);
    background: rgba(15, 35, 64, 0.22);
  }
  .etapa-panel:first-of-type::after { top: 1.4rem; }
  .etapa-panel:nth-of-type(even) {
    margin-left: 50%;
    padding: 0 0 clamp(2.2rem, 5vh, 3.2rem) var(--calle-gap);
  }
  .etapa-panel:nth-of-type(even)::after {
    right: auto;
    left: 0;
    transform: translateX(-50%);
  }
  /* Entrelazado: cada estación remonta parte del hueco que su vecina
     de la otra orilla deja libre — la ruta se lee trenzada, no como
     cinco filas con media página vacía al lado. */
  .etapa-panel + .etapa-panel { margin-top: clamp(-6rem, -8vh, -3rem); }

  /* El bloque de texto se ancla a su orilla del eje */
  .etapa-inner {
    display: block;
    max-width: 28rem;
    margin: 0 0 0 auto;
  }
  .etapa-panel:nth-of-type(even) .etapa-inner { margin: 0 auto 0 0; }

  /* El waypoint: cada estación cuelga de su punto en el eje —
     el mismo anillo+disco que los `.ruta-wp` de la carta original */
  .etapa-nodo {
    display: grid;
    place-items: center;
    position: absolute;
    top: 0.85rem;
    left: auto; /* la capa del meridiano lo anclaba a left: 50% */
    right: calc(-1 * var(--calle-gap));
    transform: translateX(50%);
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--papel);
    border: 1px solid rgba(15, 35, 64, 0.4);
  }
  .etapa-panel:nth-of-type(even) .etapa-nodo {
    right: auto;
    left: calc(-1 * var(--calle-gap));
    transform: translateX(-50%);
  }
  .etapa-nodo i {
    display: block;
    width: 0.42rem;
    height: 0.42rem;
    border-radius: 50%;
    background: var(--ambar);
  }

  /* Escala editorial: el verbo manda un punto por encima del Kit */
  .etapa-nombre { font-size: clamp(1.7rem, 2.1vw, 2.2rem); }

  /* ── La llegada: Transformar arriba centrada SOBRE el eje ────── */
  .etapa-panel:last-of-type {
    width: 100%;
    margin-top: clamp(1.6rem, 4vh, 3rem);
    padding: 0 0 1rem;
    text-align: center;
  }
  .etapa-panel:last-of-type::after { display: none; }
  .etapa-panel:last-of-type .etapa-inner {
    max-width: 40rem;
    margin: 0 auto;
    padding-left: 0; /* sin hueco del numeral: aquí va sobre el título */
  }
  /* El waypoint de arribo: macizo en ámbar, cosido al final del eje */
  .etapa-panel:last-of-type .etapa-nodo {
    position: absolute;
    top: -1.9rem;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: 1.35rem;
    height: 1.35rem;
    background: var(--ambar);
    border-color: var(--ambar);
    box-shadow: 0 0 0 5px rgba(232, 160, 32, 0.18);
  }
  .etapa-panel:last-of-type .etapa-nodo i { background: var(--marino); }
  .etapa-panel:last-of-type .etapa-num {
    position: static;
    display: block;
    margin: 0 0 0.5rem;
  }
  .etapa-panel:last-of-type .etapa-nombre { justify-content: center; }
  .etapa-panel:last-of-type .etapa-desc { margin-inline: auto; }
  .etapa-panel:last-of-type .etapa-objetivo { max-width: 34rem; margin-inline: auto; }
}


/* ── Cielo del Kit: partículas vivas + estrella fugaz ─────────────
   Estrellas por radial-gradient, no por canvas ni por DOM: el Kit ya
   tiene la placa girando en 3D y una lámina dibujándose a trazo, y no
   conviene meterle otra capa animada compitiendo por el compositor.

   TRES planos con parpadeo independiente (duraciones primas entre sí y
   desfases negativos, para que arranquen ya desacompasados): con un
   solo plano el parpadeo se lee como un pulso global de la sección, no
   como estrellas. Cada plano deriva además muy despacio en vertical,
   que es lo que quita del todo la sensación de calcomanía.
   Las de mayor tamaño llevan HALO: sobre marino, a punto plano se
   pierden. Posiciones deterministas (semilla fija) y esquivan la banda
   donde vive el texto de la pieza activa. */
.kit-estrellas {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.kit-capa {
  position: absolute;
  inset: -6% 0;
  will-change: opacity, transform;
}
.kit-capa-1 {
  background-image:
    radial-gradient(1.46px 1.46px at 12.7% 78.2%, rgba(245,244,239,0.66), transparent 64%),
    radial-gradient(1.54px 1.54px at 11.1% 23.4%, rgba(245,244,239,0.57), transparent 64%),
    radial-gradient(1.66px 1.66px at 77.8% 54.6%, rgba(245,244,239,0.63), transparent 64%),
    radial-gradient(1.22px 1.22px at 74.6% 58.3%, rgba(245,244,239,0.58), transparent 64%),
    radial-gradient(1.4px 1.4px at 11.9% 80.4%, rgba(245,244,239,0.64), transparent 64%),
    radial-gradient(1.19px 1.19px at 68.1% 67.2%, rgba(245,244,239,0.48), transparent 64%),
    radial-gradient(1.72px 1.72px at 97.0% 91.2%, rgba(245,244,239,0.7), transparent 64%),
    radial-gradient(1.31px 1.31px at 51.3% 9.3%, rgba(245,244,239,0.57), transparent 64%),
    radial-gradient(1.79px 1.79px at 29.6% 73.9%, rgba(245,244,239,0.61), transparent 64%),
    radial-gradient(1.64px 1.64px at 57.6% 4.4%, rgba(245,244,239,0.51), transparent 64%),
    radial-gradient(1.53px 1.53px at 42.4% 68.3%, rgba(245,244,239,0.55), transparent 64%),
    radial-gradient(1.68px 1.68px at 12.4% 78.6%, rgba(245,244,239,0.58), transparent 64%),
    radial-gradient(1.23px 1.23px at 49.1% 90.0%, rgba(245,244,239,0.53), transparent 64%),
    radial-gradient(1.47px 1.47px at 91.8% 48.0%, rgba(245,244,239,0.41), transparent 64%),
    radial-gradient(1.04px 1.04px at 23.0% 14.4%, rgba(245,244,239,0.61), transparent 64%),
    radial-gradient(1.56px 1.56px at 87.9% 11.8%, rgba(245,244,239,0.54), transparent 64%),
    radial-gradient(1.8px 1.8px at 48.2% 24.0%, rgba(245,244,239,0.59), transparent 64%),
    radial-gradient(1.84px 1.84px at 45.8% 75.1%, rgba(245,244,239,0.7), transparent 64%),
    radial-gradient(1.6px 1.6px at 54.5% 55.7%, rgba(245,244,239,0.49), transparent 64%),
    radial-gradient(1.43px 1.43px at 79.4% 50.2%, rgba(245,244,239,0.67), transparent 64%),
    radial-gradient(1.24px 1.24px at 43.4% 30.3%, rgba(245,244,239,0.41), transparent 64%),
    radial-gradient(1.41px 1.41px at 65.3% 59.3%, rgba(245,244,239,0.56), transparent 64%),
    radial-gradient(1.23px 1.23px at 49.0% 90.5%, rgba(245,244,239,0.55), transparent 64%),
    radial-gradient(1.73px 1.73px at 51.1% 81.3%, rgba(245,244,239,0.57), transparent 64%),
    radial-gradient(1.28px 1.28px at 89.9% 81.8%, rgba(245,244,239,0.68), transparent 64%),
    radial-gradient(1.71px 1.71px at 10.6% 40.2%, rgba(245,244,239,0.55), transparent 64%),
    radial-gradient(1.87px 1.87px at 45.4% 94.7%, rgba(245,244,239,0.65), transparent 64%),
    radial-gradient(1.24px 1.24px at 48.0% 8.2%, rgba(245,244,239,0.55), transparent 64%),
    radial-gradient(1.37px 1.37px at 10.5% 73.8%, rgba(245,244,239,0.53), transparent 64%),
    radial-gradient(1.52px 1.52px at 2.4% 2.0%, rgba(245,244,239,0.68), transparent 64%);
  animation: kitTitila1 5.4s var(--ease-cine) 0s infinite alternate,
             kitDeriva1 34s linear infinite;
}
@keyframes kitTitila1 { from { opacity: 0.5; } to { opacity: 1; } }
@keyframes kitDeriva1 { from { transform: translateY(0); } to { transform: translateY(2.2%); } }
.kit-capa-2 {
  background-image:
    radial-gradient(1.82px 1.82px at 9.1% 78.2%, rgba(245,244,239,0.81), rgba(245,244,239,0.24) 34%, transparent 72%),
    radial-gradient(2.37px 2.37px at 74.7% 93.8%, rgba(245,244,239,0.81), rgba(245,244,239,0.24) 34%, transparent 72%),
    radial-gradient(2.26px 2.26px at 16.2% 32.1%, rgba(245,244,239,0.85), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(2.44px 2.44px at 94.1% 49.2%, rgba(245,244,239,0.66), rgba(245,244,239,0.2) 34%, transparent 72%),
    radial-gradient(2.75px 2.75px at 22.8% 30.4%, rgba(245,244,239,0.88), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(2.37px 2.37px at 50.5% 10.1%, rgba(245,244,239,0.9), rgba(245,244,239,0.27) 34%, transparent 72%),
    radial-gradient(1.9px 1.9px at 77.8% 89.8%, rgba(245,244,239,0.74), rgba(245,244,239,0.22) 34%, transparent 72%),
    radial-gradient(1.76px 1.76px at 80.2% 51.9%, rgba(245,244,239,0.62), rgba(245,244,239,0.19) 34%, transparent 72%),
    radial-gradient(1.57px 1.57px at 11.4% 87.2%, rgba(245,244,239,0.72), rgba(245,244,239,0.22) 34%, transparent 72%),
    radial-gradient(1.53px 1.53px at 35.6% 75.9%, rgba(245,244,239,0.77), rgba(245,244,239,0.23) 34%, transparent 72%),
    radial-gradient(1.92px 1.92px at 33.1% 31.2%, rgba(245,244,239,0.66), rgba(245,244,239,0.2) 34%, transparent 72%),
    radial-gradient(2.55px 2.55px at 94.0% 56.9%, rgba(245,244,239,0.67), rgba(245,244,239,0.2) 34%, transparent 72%),
    radial-gradient(1.94px 1.94px at 51.9% 43.6%, rgba(245,244,239,0.8), rgba(245,244,239,0.24) 34%, transparent 72%),
    radial-gradient(2.02px 2.02px at 67.5% 8.7%, rgba(245,244,239,0.68), rgba(245,244,239,0.2) 34%, transparent 72%),
    radial-gradient(2.21px 2.21px at 91.3% 6.3%, rgba(245,244,239,0.87), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(1.75px 1.75px at 45.3% 74.5%, rgba(245,244,239,0.83), rgba(245,244,239,0.25) 34%, transparent 72%),
    radial-gradient(2.19px 2.19px at 87.0% 14.4%, rgba(245,244,239,0.86), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(1.71px 1.71px at 51.7% 93.8%, rgba(245,244,239,0.87), rgba(245,244,239,0.26) 34%, transparent 72%);
  animation: kitTitila2 7.9s var(--ease-cine) -2.6s infinite alternate,
             kitDeriva2 52s linear infinite;
}
@keyframes kitTitila2 { from { opacity: 0.35; } to { opacity: 1; } }
@keyframes kitDeriva2 { from { transform: translateY(0); } to { transform: translateY(-2.6%); } }
.kit-capa-3 {
  background-image:
    radial-gradient(2.52px 2.52px at 39.2% 70.8%, rgba(245,244,239,0.77), rgba(245,244,239,0.23) 34%, transparent 72%),
    radial-gradient(2.3px 2.3px at 30.9% 35.0%, rgba(245,244,239,0.87), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(2.6px 2.6px at 77.5% 41.9%, rgba(245,244,239,0.83), rgba(245,244,239,0.25) 34%, transparent 72%),
    radial-gradient(3.09px 3.09px at 48.2% 13.5%, rgba(245,244,239,0.95), rgba(245,244,239,0.28) 34%, transparent 72%),
    radial-gradient(2.25px 2.25px at 81.0% 83.4%, rgba(245,244,239,0.99), rgba(245,244,239,0.3) 34%, transparent 72%),
    radial-gradient(2.51px 2.51px at 87.1% 64.0%, rgba(245,244,239,0.95), rgba(245,244,239,0.28) 34%, transparent 72%),
    radial-gradient(3.34px 3.34px at 84.3% 66.4%, rgba(245,244,239,0.84), rgba(245,244,239,0.25) 34%, transparent 72%),
    radial-gradient(2.76px 2.76px at 16.4% 28.0%, rgba(245,244,239,0.88), rgba(245,244,239,0.26) 34%, transparent 72%),
    radial-gradient(2.73px 2.73px at 11.7% 70.7%, rgba(245,244,239,0.89), rgba(245,244,239,0.27) 34%, transparent 72%),
    radial-gradient(2.3px 2.3px at 22.0% 30.3%, rgba(245,244,239,0.89), rgba(245,244,239,0.27) 34%, transparent 72%),
    radial-gradient(3.33px 3.33px at 10.9% 27.3%, rgba(245,244,239,0.79), rgba(245,244,239,0.24) 34%, transparent 72%),
    radial-gradient(2.98px 2.98px at 68.1% 74.9%, rgba(245,244,239,0.8), rgba(245,244,239,0.24) 34%, transparent 72%);
  animation: kitTitila3 4.6s var(--ease-cine) -1.3s infinite alternate,
             kitDeriva3 68s linear infinite;
}
@keyframes kitTitila3 { from { opacity: 0.45; } to { opacity: 0.95; } }
@keyframes kitDeriva3 { from { transform: translateY(0); } to { transform: translateY(2.2%); } }

/* La fugaz, con el mismo lenguaje que la del hero: un trazo que se
   apaga por la cola. La gobierna GSAP en js/main.js. */
.kit-fugaz {
  position: absolute;
  top: 16%;
  right: 12%;
  width: 132px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(245,244,239,0.95), rgba(245,244,239,0));
  transform: rotate(-32deg);
  opacity: 0;
  pointer-events: none;
}

/* El contenido del acto, por encima del cielo */
.kit-head,
.kit-escena,
.kit-pie { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .kit-capa { animation: none; opacity: 0.85; }
  .kit-fugaz { display: none; }
}


/* ══════════════════════════════════════════════════════════════
   ACTOS V y VI · CUADERNO DE RUTA + PREGUNTAS DEL EXPLORADOR
   ──────────────────────────────────────────────────────────────
   Los dos cierres comparten la misma cabecera de sección, así que
   la cabecera se tokeniza aquí (`.seccion-kicker/-titulo/-sub`) en
   vez de repetir tres recetas distintas como pasaba antes en el
   resto de actos.
   ══════════════════════════════════════════════════════════════ */

.seccion-kicker {
  margin-bottom: 0.9rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--oro-tinta);
}
.seccion-titulo {
  font-size: var(--fs-h2);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--marino);
}
.seccion-sub {
  margin-top: var(--sp-3);
  max-width: 64ch;
  font-size: var(--fs-sub);
  line-height: 1.6;
  color: var(--tinta-suave);
}

/* ══════════ ACTO V · CUADERNO DE RUTA ══════════
   Calendario de a bordo, no otra ruta: la fecha manda en su propia
   columna y el hito cuelga de una espina. Deliberadamente VERTICAL
   para no repetir el carril horizontal del Acto II. */
.cuaderno {
  position: relative;
  padding: var(--seccion-y) var(--seccion-x);
  background: var(--papel);
}
/* ── El acto clavado ────────────────────────────────────────────────
   La pone `cuadernoTemporal()` en `js/main.js` SOLO cuando el pin se
   monta, y solo si con ella el acto cabe entero en la ventana: una
   sección clavada más alta que el viewport esconde su propio final.
   Todo lo de aquí es compresión vertical —paddings y aire—, nunca
   cuerpo de letra: el calendario se lee igual de grande, ocupa menos.
   El grid se come el alto sobrante, así que la carta sigue teniendo
   el alto de la sección, que ahora es la pantalla. */
.cuaderno.esta-pinneada {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* El aire de ARRIBA no se toca: por debajo de esto la cabecera se
     mete bajo la píldora del nav. Lo que se comprime es el resto. */
  padding-top: clamp(5rem, 9.8vh, 7rem);
  padding-bottom: clamp(0.8rem, 1.6vh, 1.6rem);
}
.cuaderno.esta-pinneada .cuaderno-head .seccion-sub { margin-top: 0.5rem; }
.cuaderno.esta-pinneada .cuaderno-grid {
  flex: 1;
  min-height: 0;
  margin-top: clamp(0.7rem, 1.6vh, 1.4rem);
}
.cuaderno.esta-pinneada .hitos {
  display: flex;
  flex-direction: column;
}
/* Los hitos se reparten el alto a partes iguales: así la espina no
   deja huecos y cada nodo cae a la altura del suyo en la carta. */
.cuaderno.esta-pinneada .hito {
  flex: 1 1 0;
  align-content: start;
  padding: clamp(0.35rem, 0.85vh, 0.9rem) 0;
}
.cuaderno.esta-pinneada .hito-cuerpo p {
  margin-top: 0.3rem;
  line-height: 1.45;
}
/* Clavado, el mapa no puede OPINAR sobre el alto: un <svg> al 100% de
   ancho arrastra su alto intrínseco (716px con este lienzo) y estiraba
   la fila hasta ahí, con lo que el acto no cabía en pantalla y el pin
   no llegaba a montarse nunca. En absoluto no mide: se limita a llenar
   el alto que le deja el calendario. */
.cuaderno.esta-pinneada .carta { position: relative; }
.cuaderno.esta-pinneada .carta-marco { position: absolute; inset: 0; }

.cuaderno-head { max-width: 46rem; }
.cuaderno-cuenta {
  display: inline-block;
  font-weight: 700;
  color: var(--marino);
  font-variant-numeric: tabular-nums;
}
.cuaderno-cuenta span { color: var(--oro-grande); }

.hitos {
  position: relative;
  margin-top: var(--bloque-y);
  list-style: none;
  max-width: 62rem;
  /* Lo escribe `lineaTemporal()` en cada frame de scroll: 0 → 1. */
  --hitos-prog: 0;
  /* La X de la espina, en una sola variable: la comparten la espina de
     cada hito, el nodo y el trazo de progreso, así que un cambio de
     rejilla no puede descuadrarlos entre sí. */
  --espina-x: calc(14rem + clamp(1.2rem, 4vw, 3.5rem) / 2);
}

/* El trazo de progreso: la misma espina, entintada de arriba abajo al
   ritmo del scroll. Es el hilo que amarra la lista a la carta — el
   navío va justo por donde va este trazo. */
.hitos::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--espina-x);
  width: 1px;
  height: calc(var(--hitos-prog) * 100%);
  background: linear-gradient(to bottom, rgba(15, 35, 64, 0.34), var(--ambar));
}
.hito {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  gap: clamp(1.2rem, 4vw, 3.5rem);
  padding: clamp(1.5rem, 3.4vh, 2.3rem) 0 clamp(1.5rem, 3.4vh, 2.3rem) 0;
  border-top: var(--fino);
}
.hito:last-child { border-bottom: var(--fino); }

/* La espina: recorre la junta entre las dos columnas y lleva el nodo
   de cada hito. No es decoración — es lo que convierte una tabla en
   una línea de tiempo. */
.hito::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: var(--espina-x);
  width: 1px;
  background: rgba(15, 35, 64, 0.16);
}
.hito::after {
  content: '';
  position: absolute;
  top: calc(clamp(1.5rem, 3.4vh, 2.3rem) + 0.42em);
  left: var(--espina-x);
  width: 9px; height: 9px;
  margin: -4px 0 0 -4px;
  border-radius: var(--radio-pill);
  background: var(--papel);
  box-shadow: inset 0 0 0 1.5px var(--tinta-suave);
  transition: background var(--dur-3) var(--ease-estandar),
              box-shadow var(--dur-3) var(--ease-estandar),
              width var(--dur-3) var(--ease-estandar),
              height var(--dur-3) var(--ease-estandar);
}

/* ── La lista se ENCIENDE al paso del scroll ────────────────────────
   Los hitos ya no entran con un fundido suelto cada uno: esperan
   apagados y se van entintando conforme el navío alcanza su nodo en
   la carta. Es la misma progresión contada dos veces —lista y mapa—,
   que es lo que hace que se lean como una sola línea de tiempo.
   El apagado atenúa (no oculta): el texto sigue ahí para quien llegue
   con Ctrl+F o con un lector de pantalla. */
.hito {
  opacity: 0.38;
  transition: opacity var(--dur-4) var(--ease-estandar);
}
.hito.is-lit { opacity: 1; }
.hito.is-lit::after {
  background: var(--marino);
  box-shadow: 0 0 0 4px rgba(15, 35, 64, 0.10);
}

.hito-fecha {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--tinta-suave);
}
.hito-cuerpo h3 {
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--marino);
}
.hito-cuerpo p {
  margin-top: 0.55rem;
  max-width: 46ch;
  font-size: 0.94rem;
  line-height: 1.65;
  color: var(--tinta-suave);
}

/* El hito clave: es el único ámbar de la lista. Si se entintaran dos,
   dejaría de señalar nada. */
.hito-clave .hito-fecha { color: var(--oro-tinta); }
.hito-clave .hito-cuerpo h3 { font-size: clamp(1.4rem, 2.1vw, 1.9rem); }
.hito-clave::after,
.hito-clave.is-lit::after {
  width: 13px; height: 13px;
  margin: -6px 0 0 -6px;
  background: var(--ambar);
  box-shadow: 0 0 0 5px rgba(232, 160, 32, 0.16);
}
/* Encendido, el nodo clave abre el halo: sigue siendo el único ámbar
   de la lista y ahora además es el único que crece al llegar. */
.hito-clave.is-lit::after { box-shadow: 0 0 0 9px rgba(232, 160, 32, 0.18); }

/* ══════════ ACTO V·B · CAMPAMENTO BASE ══════════
   La sección de SERVICIO: aquí se viene a saber a qué puerto se
   pertenece y qué se sabe ya de la salida. La primera versión la
   resolvía sobre papel con una rejilla de sedes y una tabla de
   horarios por sede, y fallaba en dos cosas a la vez.

   La grave era de HONESTIDAD: los horarios eran de MUESTRA
   (09:00—13:00) y alguien podía tomárselos por buenos — plantarse a
   las nueve en una sala que abre a las dos. Con la logística sin
   cerrar no hay nada que tabular: una tabla de dos columnas con
   «Por definir» seis veces es una tabla vacía disfrazada.

   La otra era de PRESENCIA: sobre papel, entre el Cuaderno y la FAQ
   —las dos también de papel—, la única sección con una acción real
   se leía como un anexo del relato.

   El rediseño invierte el material y se apoya en cinco decisiones:

   (1) MARINO CON CIELO, como el Kit. La logística deja de ser una
       nota al pie y pasa a ser una escala más de la travesía. De paso
       recupera el ritmo papel → noche → papel que la página ya usa,
       y le da al ámbar un sitio donde por fin contrasta (7.6:1).
   (2) UN EJE con sus nodos, no tarjetas: los tres puertos cuelgan de
       una línea horizontal — el gesto de la carta de derrota del Acto
       II, girado. El eje NACE EN ÁMBAR sobre el único puerto que ya
       tiene fecha y se apaga hacia los otros dos.
   (3) FUERA LAS TABLAS. Un `<dl>` es la estructura correcta para
       pares dato/valor y los lectores de pantalla lo leen igual de
       bien, sin fingir una tabla que no existe.
   (4) «POR DEFINIR» COMO COMPONENTE, no como texto atenuado. Cápsula
       con filete discontinuo en ámbar: se ve a la legua que ese dato
       AÚN NO ES, que es la información honesta a día de hoy.
   (5) Los tres tramos finales pasan a SECUENCIA NUMERADA colgada de
       un filete común: son un orden (antes → día uno → después), no
       tres columnas sueltas.

   ⚠️ Al ser sección oscura hay dos consecuencias fuera de este
   bloque: el anillo de foco vuelve a ÁMBAR (`.campamento` sale de la
   lista de secciones de papel, arriba), y `navSuperficie()` en
   `js/main.js` necesita su disparador `dark` — si no, el nav se queda
   en modo papel sobre marino. */
.campamento {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: var(--seccion-y) var(--seccion-x);
  background:
    radial-gradient(ellipse 90% 70% at 50% 12%, var(--marino-claro) 0%, var(--marino) 52%, var(--marino-hondo) 100%);
  color: var(--blanco);
}
/* Cielo. Dos planos de puntos a tamaños distintos, estáticos y
   enmascarados hacia abajo: la sección de servicio no necesita una
   capa animada más compitiendo por el compositor — de eso ya se
   encarga el Kit. */
.campamento::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle, rgba(245, 244, 239, 0.85) 0 1px, transparent 1.6px),
    radial-gradient(circle, rgba(245, 244, 239, 0.5) 0 0.8px, transparent 1.3px);
  background-size: 190px 150px, 110px 95px;
  background-position: 20px 30px, 70px 10px;
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(#000, transparent 70%);
  mask-image: linear-gradient(#000, transparent 70%);
}
.campamento .seccion-kicker { color: var(--ambar); }
.campamento .seccion-titulo { color: var(--blanco); }
.campamento .seccion-sub { color: var(--texto-noche-2); }
.campamento-head { max-width: 46rem; }

/* Estado de la logística. Es ANDAMIO, no componente: se retira cuando
   no quede ningún `.por-definir` en la sección. Filete lateral ámbar +
   degradado que se disuelve — pesa lo justo para leerse como aviso sin
   convertirse en la primera mancha de color de la sección. */
.campamento-estado {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  margin-top: var(--sp-6);
  max-width: 56rem;
  padding: 1rem 1.3rem;
  border-left: 3px solid var(--ambar);
  background: linear-gradient(90deg, rgba(232, 160, 32, 0.16), rgba(232, 160, 32, 0));
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--texto-noche-2);
}
.campamento-estado b { color: var(--blanco); font-weight: 700; }
/* Señal de radio: punto vivo + anillo que se expande. Dice «esto está
   en curso» mejor que cualquier icono de exclamación. */
.estado-senal {
  position: relative;
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 0.55rem;
  border-radius: var(--radio-pill);
  background: var(--ambar);
}
.estado-senal::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: var(--radio-pill);
  border: 1px solid var(--ambar);
  animation: senalPulso 2.6s var(--ease-estandar) infinite;
}
@keyframes senalPulso {
  0%   { transform: scale(0.7); opacity: 0.9; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}

/* ── El eje y sus tres puertos ──────────────────────────────────────
   `repeat(3, 1fr)` y no `auto-fit`: el eje es una línea única que ha de
   cruzar los tres nodos, y con las columnas replegándose solo se
   sostiene en el tramo horizontal. El caso de 4+ sedes se resuelve
   pasando al eje vertical, que es lo que ya hace en móvil. */
.puertos {
  position: relative;
  list-style: none;
  margin-top: calc(var(--bloque-y) + 1rem);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.6rem, 3vw, 3.2rem);
}
/* El eje. Nace en ámbar bajo el primer nodo y se apaga: es el mismo
   recurso del rastro del Nautilus —lo recorrido se entinta, lo que
   queda no— aplicado a una línea estática. */
.puertos::before {
  content: '';
  position: absolute;
  top: 7px;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    var(--ambar) 0 12%,
    rgba(245, 244, 239, 0.22) 34%,
    rgba(245, 244, 239, 0.22));
}
.puerto {
  position: relative;
  padding-top: 2.6rem;
}
.puerto-nodo {
  position: absolute;
  top: 0;
  left: 0;
  width: 15px;
  height: 15px;
  border-radius: var(--radio-pill);
  border: 1px solid rgba(245, 244, 239, 0.35);
  background: var(--marino);
}
.puerto-nodo::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: var(--radio-pill);
  background: rgba(245, 244, 239, 0.4);
}
/* El único puerto con fecha es el único que enciende el nodo y abre
   halo — si se entintaran dos dejaría de señalar nada, que es la misma
   regla del hito clave del Cuaderno de Ruta. Cuelga de `is-primera` y
   no de `:first-child`: marca el que zarpa antes, no el que va delante
   en el DOM. */
.puerto.is-primera .puerto-nodo { border-color: var(--ambar); }
.puerto.is-primera .puerto-nodo::after {
  background: var(--ambar);
  box-shadow: 0 0 0 6px rgba(232, 160, 32, 0.16);
}

.puerto-coord {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--texto-noche-3);
  font-variant-numeric: tabular-nums;
}
.puerto-nombre {
  margin-top: 0.5rem;
  font-size: clamp(1.7rem, 3vw, 2.5rem);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--blanco);
}
.puerto-chip {
  display: inline-block;
  margin-top: 0.8rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid rgba(245, 244, 239, 0.25);
  border-radius: var(--radio-pill);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  color: var(--texto-noche-2);
}
.puerto.is-primera .puerto-chip {
  border-color: transparent;
  background: var(--ambar);
  color: var(--marino);
}

.puerto-datos { margin-top: 1.5rem; display: grid; gap: 0.9rem; }
.puerto-dato {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.9rem;
  border-bottom: var(--borde-noche-sutil);
}
.puerto-dato:last-child { border-bottom: 0; padding-bottom: 0; }
.puerto-dato dt,
.paso-dato span:first-child {
  flex: none;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--texto-noche-3);
}
.puerto-dato dd {
  text-align: right;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--blanco);
}

/* ── «Por definir»: el hueco declarado ──────────────────────────────
   Un dato de muestra que pase por bueno hace más daño que un hueco
   vacío. Esta cápsula lo dice sin ambigüedad: ámbar sobre marino son
   7.6:1, muy por encima del suelo AA del proyecto. */
.por-definir {
  display: inline-block;
  padding: 0.18rem 0.6rem;
  border: 1px dashed rgba(232, 160, 32, 0.5);
  border-radius: var(--radio-pill);
  background: rgba(232, 160, 32, 0.12);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ambar);
  white-space: nowrap;
}

/* ── Los tres tramos: antes · el día uno · después ───────────────── */
/* «Guardar en mi calendario»: nace `hidden` y se descubre al cerrar la
   convocatoria de cada sede (ver el comentario del HTML). Abre Outlook
   con el evento precargado. Ámbar macizo con tinta marino — el par de
   la identidad: es LA acción de la ficha de cada sede. */
.puerto-cal {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.1rem;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radio-pill);
  background: var(--ambar);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--marino);
  transition: filter var(--dur-2) var(--ease-estandar),
              box-shadow var(--dur-2) var(--ease-estandar),
              transform var(--dur-2) var(--ease-premium);
}
.puerto-cal:hover {
  filter: brightness(1.06);
  transform: translateY(-2px);
  box-shadow: 0 12px 26px -10px rgba(232, 160, 32, 0.72);
}
.puerto-cal svg {
  width: 1em; height: 1em;
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
@media (prefers-reduced-motion: reduce) {
  .puerto-cal { transition: none; }
  .puerto-cal:hover { transform: none; }
}

/* El aviso que cierra la lista de sedes: cada explorador, a su salida. */
.campamento-cierre {
  margin-top: var(--sp-7);
  max-width: 46rem;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--texto-noche-2);
}
.campamento-cierre b { color: var(--blanco); font-weight: 700; }

/* ── «Tu ruta hasta el día uno» — CAMBIO DE REGISTRO, SIN CAJA ──────
   Es otra clase de información que las fichas de sede: allí la
   convocatoria (fecha, hora, lugar), aquí las instrucciones del
   explorador. El cambio no se encapsula — se ROTULA, como el paso de
   un acto a otro dentro de la misma noche: un filete de corte con su
   telemetría, un titular de pleno derecho con la subraya ámbar, y
   los tres pasos convertidos en waypoints sobre una derrota
   punteada, el mismo dibujo de la ruta del carril. */
.campamento-filas {
  margin-top: var(--bloque-y);
  max-width: 78rem;
  padding-top: clamp(1.6rem, 3vw, 2.4rem);
  border-top: var(--borde-noche);
}
.filas-telemetry {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.4rem 1.4rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  color: var(--texto-noche-3);
}
.campamento-filas .pasos-rotulo {
  margin-top: 1.2rem;
  padding-bottom: 0;
  border-bottom: none;
  font-size: clamp(1.45rem, 2.6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  text-transform: none;
  line-height: 1.08;
  color: var(--blanco);
}
.campamento-filas .pasos-rotulo::after {
  content: '';
  display: block;
  width: 3.2rem;
  height: 3px;
  margin-top: 0.75rem;
  border-radius: 2px;
  background: var(--ambar);
}
.campamento-filas .pasos { margin-top: clamp(2rem, 3.4vw, 2.8rem); }

/* La derrota: punteada, como la ruta del carril y la carta náutica. */
.campamento-filas .paso::before {
  top: 1.15rem;
  left: 3.1rem;
  height: 0;
  background: none;
  border-top: 1px dashed rgba(245, 244, 239, 0.3);
}
/* Waypoints: el halo marino separa el nodo de la línea, como los
   nodos de la carta separan su punto del trazo. El primer paso lleva
   el nodo entintado en ámbar — es donde está el lector ahora mismo,
   la misma regla del hito clave del Cuaderno de Ruta. */
.campamento-filas .paso-num {
  width: 2.3rem;
  height: 2.3rem;
  box-shadow: 0 0 0 6px var(--marino);
}
.campamento-filas .paso:first-child .paso-num {
  border-color: transparent;
  background: var(--ambar);
  color: var(--marino);
  box-shadow: 0 0 0 6px var(--marino), 0 0 0 7px rgba(232, 160, 32, 0.45);
}
.pasos-rotulo {
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--texto-noche-3);
  padding-bottom: 0.9rem;
  border-bottom: var(--borde-noche);
}
.pasos {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: clamp(1.8rem, 3vw, 3rem);
  margin-top: clamp(1.8rem, 3vw, 2.6rem);
}
.paso { position: relative; }
/* El filete de secuencia: nace en el numeral y se estira hacia el
   siguiente tramo. El último no lo lleva — la ruta termina ahí. */
.paso::before {
  content: '';
  position: absolute;
  top: 0.95rem;
  left: 2.9rem;
  right: calc(clamp(1.8rem, 3vw, 3rem) * -1);
  height: 1px;
  background: rgba(245, 244, 239, 0.18);
}
.paso:last-child::before { display: none; }
.paso-num {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid rgba(245, 244, 239, 0.4);
  border-radius: var(--radio-pill);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--blanco);
  background: var(--marino);
  font-variant-numeric: tabular-nums;
}
.paso-eyebrow {
  margin-top: 1.1rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  color: var(--ambar);
}
.paso-titulo {
  margin-top: 0.5rem;
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--blanco);
}
.paso-texto,
.paso-nota {
  margin-top: 0.6rem;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--texto-noche-2);
}
.paso-nota { font-size: 0.86rem; color: var(--texto-noche-3); }
.paso-dato {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 0.9rem;
}

.equipaje {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.8rem;
  list-style: none;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--texto-noche-2);
}
.equipaje li { position: relative; padding-left: 1.1rem; }
.equipaje li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: var(--radio-pill);
  background: var(--ambar);
}
.equipaje b { color: var(--blanco); font-weight: 700; }

/* Enlaces en cuerpo de texto. El campamento se separa de la FAQ y del
   Cuaderno: allí van sobre papel y necesitan `--oro-tinta`; aquí van
   sobre marino, donde ese oro cae a 2.4:1 y el ámbar puro sube a 7.6. */
.faq-cuerpo a,
.hito-cuerpo a {
  color: var(--oro-tinta);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--dur-2) var(--ease-estandar);
}
.faq-cuerpo a:hover,
.hito-cuerpo a:hover { color: var(--marino); }
.paso-nota a {
  color: var(--ambar);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color var(--dur-2) var(--ease-estandar);
}
.paso-nota a:hover { color: var(--blanco); }

/* El CTA se invierte respecto a la versión de papel: sobre marino, un
   botón marino no existe. Ámbar macizo con texto en tinta — el par de
   la identidad, y el único botón sólido de la sección. */
.paso-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 1rem;
  padding: 0.7rem 1.2rem;
  border-radius: var(--radio-pill);
  background: var(--ambar);
  color: var(--marino);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  transition: background-color var(--dur-2) var(--ease-estandar),
    transform var(--dur-2) var(--ease-premium);
}
.paso-cta svg {
  width: 1.05em;
  height: 1.05em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.paso-cta:hover { background: var(--blanco); transform: translateX(2px); }
/* El CTA pendiente ya va en ámbar macizo, así que el hueco NO puede
   marcarse en ámbar otra vez: el filete pasa a blanco. */
.paso-cta.pendiente {
  text-decoration: none;
  outline: 2px dashed var(--blanco);
  outline-offset: 3px;
}

/* Bajo 3 columnas el eje GIRA: pasa a vertical y los puertos cuelgan de
   él en columna, igual que la espina del Cuaderno de Ruta. El filete de
   la secuencia de pasos, en cambio, se retira — apilado no une nada. */
@media (max-width: 899px) {
  .puertos {
    grid-template-columns: 1fr;
    gap: 2.6rem;
    padding-left: 2.2rem;
  }
  .puertos::before {
    top: 7px;
    bottom: 0;
    left: 7px;
    right: auto;
    width: 1px;
    height: auto;
    background: linear-gradient(180deg,
      var(--ambar) 0 8%,
      rgba(245, 244, 239, 0.22) 26%,
      rgba(245, 244, 239, 0.22));
  }
  .puerto { padding-top: 0; }
  .puerto-nodo { left: -2.2rem; top: 2px; }
  .paso::before { display: none; }
  .paso-cta:hover { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .estado-senal::after { animation: none; }
}


/* ══════════ ACTO VI · PREGUNTAS DEL EXPLORADOR ══════════
   Acordeón con <details> nativo: navegable por teclado y plenamente
   funcional sin JS. Se maqueta a dos columnas —cabecera fija a la
   izquierda, lista a la derecha— para que la cabecera no obligue a
   scrollear antes de llegar a la primera pregunta. */
.faq {
  padding: var(--seccion-y) var(--seccion-x) var(--seccion-y-amplia);
  background: var(--papel);
  border-top: var(--fino);
}
.faq-head { max-width: 46rem; }
.faq-lista {
  margin-top: var(--bloque-y);
  max-width: 62rem;
  border-top: var(--fino);
}
.faq-item { border-bottom: var(--fino); }
.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  /* 44px de alto mínimo: objetivo táctil accesible */
  min-height: 3.4rem;
  padding: clamp(1.1rem, 2.6vh, 1.6rem) 0;
  cursor: pointer;
  list-style: none;
  font-size: clamp(1rem, 1.35vw, 1.18rem);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--marino);
  transition: color var(--dur-2) var(--ease-estandar);
}
.faq-item summary::-webkit-details-marker { display: none; }
/* El <h3> de la pregunta hereda todo del summary: el intercambio es
   idéntico al píxel y devuelve las 5 preguntas al mapa de encabezados
   (antes el h2 de la sección era el último del documento). */
.faq-item summary h3 { font: inherit; letter-spacing: inherit; color: inherit; }
.faq-item summary:hover { color: var(--oro-tinta); }
/* Tinta, no ambar: sobre papel el ambar da 2.10:1 y WCAG exige 3:1
   para indicadores de foco (1.4.11). El marino da 14.93:1. Hay que
   tocarlo AQUI: al ser el atajo `outline` resetea el color y gana a
   cualquier regla de solo `outline-color` aguas arriba. */
.faq-item summary:focus-visible {
  outline: 2px solid var(--marino);
  outline-offset: 4px;
  border-radius: 2px;
}

/* El signo: dos trazos que se cruzan y el vertical desaparece al
   abrir. Más limpio que un chevron que gira, y se lee igual. */
.faq-mas {
  position: relative;
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
}
.faq-mas::before,
.faq-mas::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  border-radius: 2px;
  background: var(--oro-tinta);
  transform: translateY(-50%);
  transition: transform var(--dur-3) var(--ease-premium), opacity var(--dur-2) var(--ease-estandar);
}
.faq-mas::after { transform: translateY(-50%) rotate(90deg); }
.faq-item[open] .faq-mas::after { transform: translateY(-50%) rotate(0deg); opacity: 0; }

.faq-cuerpo {
  padding-bottom: clamp(1.2rem, 2.8vh, 1.8rem);
}
.faq-cuerpo p {
  max-width: 62ch;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--tinta-suave);
}
.faq-cuerpo strong { font-weight: 700; color: var(--marino); }

/* Apertura animada. `details` no transiciona su altura por sí solo,
   así que el cuerpo entra con su propia animación al abrirse. */
.faq-item[open] .faq-cuerpo {
  animation: faqAbre var(--dur-4) var(--ease-premium) both;
}
@keyframes faqAbre {
  from { opacity: 0; transform: translateY(-0.4rem); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 760px) {
  .hito {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
    padding-left: 1.5rem;
  }
  /* En columna la espina se va al margen izquierdo. Basta mover la
     variable: la siguen la espina, el nodo y el trazo de progreso. */
  .hitos { --espina-x: 0px; }
  .hito::after { top: calc(clamp(1.5rem, 3.4vh, 2.3rem) + 0.42em); }
  .faq-item summary { gap: 1.2rem; font-size: 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .faq-item[open] .faq-cuerpo { animation: none; }
}


/* ══════════════════════════════════════════════════════════════
   CARTA NÁUTICA DEL CUADERNO DE RUTA
   ──────────────────────────────────────────────────────────────
   Copiada de la travesía de `landing-verne`: misma geometría de
   ruta, mismos topónimos, mismas sondas, misma rosa y mismo navío.
   Lo único que cambia es la PALETA, que aquí la manda el sistema —
   la ruta se entinta en ámbar (como la del Acto II) y la placa es
   marino, el mismo material que la vitrina del Kit, así que la
   carta se lee como un objeto apoyado sobre el papel.

   La carta va PEGAJOSA: la lista de hitos scrollea a su lado y el
   navío avanza con ella. Sin pin — ya hay tres secciones clavadas
   en la página y una cuarta encarece el scroll sin dar nada.
   ══════════════════════════════════════════════════════════════ */

.cuaderno-grid {
  margin-top: var(--bloque-y);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 34rem);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: stretch;
}
.cuaderno-grid .hitos { margin-top: 0; max-width: none; }

/* La carta ocupa el ALTO de la sección, no el de una tarjeta: la
   columna se estira a la altura de la lista y el dibujo se ajusta
   dentro (`meet`, sin deformar). Ya no va pegajosa — pegada, la mitad
   de arriba se perdía tras el nav justo cuando se leían los últimos
   hitos, y además el mapa dejaba de estar a la altura de su hito.
   Como el mar es el papel de la sección, no hay borde que delate la
   caja: se lee como una carta trazada sobre la propia página. */
.carta {
  display: flex;
  align-items: center;
}
.carta-marco {
  width: 100%;
  height: 100%;
}
.carta-marco svg { display: block; width: 100%; height: 100%; }

.carta-mar {
  fill: var(--papel);
  stroke: none;
}
.carta-reticula { color: var(--marino); }
.carta-rosa { color: rgba(15, 35, 64, 0.34); }
.carta-rosa-norte { fill: var(--ambar); }
.carta-cardinal {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.08em;
  fill: rgba(15, 35, 64, 0.5);
}
/* Los topónimos van en cursiva: es la convención de las cartas
   náuticas para los accidentes de agua. Cursiva sintética de
   Montserrat — el proyecto es de una sola familia. */
.carta-nombres text {
  font-style: italic;
  font-size: 16.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  fill: rgba(15, 35, 64, 0.52);
}
.carta-sondas text {
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  fill: rgba(15, 35, 64, 0.3);
}

.carta-estela {
  stroke: rgba(15, 35, 64, 0.3);
  stroke-width: 2;
  stroke-dasharray: 0.1 11;
  stroke-linecap: round;
}
/* Sobre papel el resplandor de la derrota sobra: lo que sobre marino
   era brillo, aquí es una mancha. Trazo limpio y punto. */
.carta-ruta {
  stroke: var(--ambar);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.nodo-halo {
  fill: rgba(232, 160, 32, 0);
  transition: fill var(--dur-3) var(--ease-estandar);
}
.nodo-punto {
  fill: rgba(15, 35, 64, 0.12);
  stroke: rgba(15, 35, 64, 0.34);
  stroke-width: 1;
  transition: fill var(--dur-3) var(--ease-estandar), stroke var(--dur-3) var(--ease-estandar);
}
.nodo-rotulo {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  fill: rgba(15, 35, 64, 0.42);
  transition: fill var(--dur-3) var(--ease-estandar);
}
.carta-nodo.is-active .nodo-punto { fill: var(--ambar); stroke: rgba(232, 160, 32, 0.6); }
.carta-nodo.is-active .nodo-halo { fill: rgba(232, 160, 32, 0.18); }
.carta-nodo.is-active .nodo-rotulo { fill: var(--marino); }

.carta-navio path { fill: var(--ambar); }
.carta-navio { filter: drop-shadow(0 0 6px rgba(232, 160, 32, 0.45)); }

/* ── Sin carril lateral: la carta se pone encima, a lo ancho ──── */
@media (max-width: 1024px) {
  .cuaderno-grid { grid-template-columns: minmax(0, 1fr); }
  .carta {
    order: -1;
    height: auto;
    max-width: 26rem;
    margin: 0 auto var(--bloque-y);
  }
  .carta-marco { height: auto; }
  .carta-marco svg { height: auto; }
}

/* ══════════════════════════════════════════════════════════════
   CUADERNO EN MÓVIL · LA CARTA ES LA SECCIÓN
   ──────────────────────────────────────────────────────────────
   En escritorio el acto son dos columnas —la lista de hitos y la
   carta— contando LO MISMO. Apiladas en vertical eso se vuelve una
   repetición larguísima: primero cinco textos, luego el mismo viaje
   otra vez dibujado.
   Aquí se queda solo la carta, y los hitos dejan de ser una lista para
   ser lo que siempre fueron en un mapa: ANOTACIONES junto a su punto.
   El acto se clava en pantalla y el scroll se gasta en navegar de
   Rumores a Bitácora; al atracar, se suelta. La anotación se releva
   sola porque cada una vive pegada a su nodo y solo se ve la del punto
   al que ha llegado el navío (`es-actual`, que pone `aplicar()`).
   ⚠️ La caja de `.cuaderno-grid` tiene EXACTAMENTE la razón del viewBox
   (760:1000) y el SVG va con `meet`: así un `translate(96 125)` del
   nodo es el 12,6% / 12,5% de la caja, y las coordenadas que escribe
   `anclarHitos()` valen sin más conversión. Si se cambia el viewBox,
   se cambia aquí.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 899px) {
  html.carta-anotada .cuaderno.esta-pinneada { min-height: 100svh; }
  html.carta-anotada .cuaderno-head { margin-bottom: 0; }
  html.carta-anotada .cuaderno-head .seccion-sub { margin-top: 0.5rem; }

  /* ⚠️ `flex: none` a (0,3,0): clavada, la sección es una columna flex
     y su regla de escritorio estira el grid (`flex: 1`) hasta llenar el
     alto. Estirado, la caja deja de tener la razón del viewBox, el SVG
     se centra con `meet` dejando franjas vacías arriba y abajo, y las
     anotaciones —que se sitúan en % de la CAJA— apuntan a otro sitio.
     Aquí manda la razón; el aire sobrante se reparte con `margin: auto`. */
  html.carta-anotada .cuaderno.esta-pinneada .cuaderno-grid { flex: none; }
  html.carta-anotada .cuaderno-grid {
    position: relative;
    display: block;
    /* La razón la fija el recuadre vigente, que escribe `ajustarCarta()`
       en `--carta-ar` / `--carta-k`. Una sola fuente para JS y CSS: si
       la caja y el viewBox no coinciden, el SVG se centra con `meet` y
       las anotaciones dejan de caer sobre sus puntos. */
    aspect-ratio: var(--carta-ar, 760 / 1000);
    /* Se dimensiona por el ANCHO y la razón deriva el alto: es la
       dirección natural de un bloque. El ancho es el menor entre el que
       hay y el que permite la altura libre bajo la cabecera — lo que
       ate primero, manda. */
    width: min(100%, calc((100svh - 13.5rem) * var(--carta-k, 0.76)));
    height: auto;
    margin: clamp(0.9rem, 2.4vh, 1.6rem) auto auto;
  }

  /* Dos piezas del dibujo viven fuera del recuadre vertical y se
     recolocan dentro. Es reencuadre, no maquillaje: en el lienzo ancho
     siguen donde estaban. */
  html.carta-anotada .carta-rosa { transform: translate(500px, 150px); }
  html.carta-anotada .carta-nombres .nombre-este { transform: translateX(-165px); }
  /* ⚠️ Tres selectores a (0,3,0): el estado `esta-pinneada` de
     escritorio también manda aquí —la sección se clava igual— y su
     `.cuaderno.esta-pinneada .carta { position: relative }` gana a un
     `.cuaderno-grid .carta` (0,2,0). Con el prefijo `.cuaderno` empatan
     y decide el orden, que es este. */
  html.carta-anotada .cuaderno .cuaderno-grid .carta {
    position: absolute;
    inset: 0;
    order: 0;
    max-width: none;
    margin: 0;
  }
  html.carta-anotada .cuaderno .cuaderno-grid .carta-marco {
    position: relative;
    inset: auto;
    width: 100%;
    height: 100%;
  }
  html.carta-anotada .carta-marco svg { width: 100%; height: 100%; }

  /* La lista deja de ser lista: es la capa de anotaciones */
  html.carta-anotada .cuaderno .cuaderno-grid .hitos {
    position: absolute;
    inset: 0;
    /* Va DESPUÉS de la carta en pintado aunque vaya antes en el DOM: el
       mar del SVG es un rect opaco a sangre y se comía las anotaciones. */
    z-index: 2;
    display: block;
    margin: 0;
    padding: 0;
    list-style: none;
    pointer-events: none;
  }
  .cuaderno-grid .hitos::before,
  html.carta-anotada .cuaderno-grid .hitos::after { display: none; }

  html.carta-anotada .cuaderno .cuaderno-grid .hito {
    /* Compacta a propósito: la anotación es una nota al margen de la
       carta, no una tarjeta de contenido. Cuanto menos tape, mejor se
       lee la derrota, que es lo que la sección viene a contar. */
    --anota-w: min(56vw, 12.25rem);
    --anota-sep: 1.15rem;
    position: absolute;
    display: block;
    flex: none;
    /* Cuelga del punto: se descuelga hacia abajo si el nodo está en la
       mitad alta y hacia arriba si está en la baja, nunca al costado.
       En horizontal se arrima al nodo pero el `clamp` la empuja hacia
       dentro antes que dejarla salirse de la carta. */
    left: clamp(0rem, calc(var(--nx) - 2rem), calc(100% - var(--anota-w)));
    top: calc(var(--ny) + var(--anota-sep));
    width: var(--anota-w);
    margin: 0;
    padding: 0.5rem 0.65rem 0.6rem;
    border: 0;
    border-top: 2px solid var(--ambar);
    border-radius: 0 0 7px 7px;
    /* Translúcida y con desenfoque: la derrota se sigue intuyendo por
       debajo, así la nota se lee como papel de calco sobre la carta y no
       como un agujero recortado en ella. El desenfoque mantiene el texto
       limpio sobre lo que haya detrás. */
    background: rgba(250, 249, 244, 0.86);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    box-shadow: 0 0.7rem 1.8rem -0.7rem rgba(15, 35, 64, 0.34);
    transform: translateY(-0.4rem) scale(0.98);
    transform-origin: 20% top;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-3) var(--ease-estandar),
                transform var(--dur-3) var(--ease-premium),
                visibility 0s linear var(--dur-3);
  }
  html.carta-anotada .cuaderno .cuaderno-grid .hito.anota-arriba {
    top: auto;
    bottom: calc(100% - var(--ny) + var(--anota-sep));
    border-top: 0;
    border-bottom: 2px solid var(--ambar);
    border-radius: 7px 7px 0 0;
    transform: translateY(0.4rem) scale(0.98);
    transform-origin: 20% bottom;
  }
  .cuaderno .cuaderno-grid .hito::before,
  html.carta-anotada .cuaderno .cuaderno-grid .hito::after { display: none; }

  html.carta-anotada .cuaderno .cuaderno-grid .hito.es-actual {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
    transition-delay: 0s;
  }

  html.carta-anotada .hito-fecha { font-size: 0.5rem; letter-spacing: 0.14em; line-height: 1.3; }
  html.carta-anotada .hito-cuerpo h3 { margin-top: 0.1rem; font-size: 0.88rem; line-height: 1.15; }
  html.carta-anotada .hito-cuerpo p {
    margin-top: 0.25rem;
    max-width: none;
    font-size: 0.7rem;
    line-height: 1.38;
  }
  html.carta-anotada .hito-clave .hito-cuerpo h3 { font-size: 0.98rem; }

  /* La rotulación de la carta cede sitio: con la anotación encima, el
     topónimo y el rótulo del nodo solo estorban a esa escala. */
  /* El recuadre vertical amplía el dibujo (560 unidades en vez de 760),
     así que la rotulación crece con él y los topónimos largos se salen.
     Se compensa a la misma proporción: en pantalla se leen igual que en
     el lienzo ancho, y vuelven a caber. */
  html.carta-anotada .carta-nombres text { font-size: 12.5px; }
  html.carta-anotada .carta-sondas text { font-size: 9px; }
  html.carta-anotada .carta-cardinal { font-size: 11.5px; }
  html.carta-anotada .carta-nombres,
  html.carta-anotada .carta-sondas { opacity: 0.55; }
  html.carta-anotada .nodo-rotulo { display: none; }
}

/* Sin motor de scroll, la carta se muestra completa: ruta entera,
   todos los nodos encendidos y sin navío (no habría qué moverlo). */
html:not(.js) .carta-ruta,
html.no-motion .carta-ruta { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
html:not(.js) .nodo-punto,
html.no-motion .nodo-punto { fill: var(--ambar); stroke: rgba(232, 160, 32, 0.6); }
html:not(.js) .nodo-rotulo,
html.no-motion .nodo-rotulo { fill: var(--marino); }
html:not(.js) .carta-navio,
html.no-motion .carta-navio { display: none; }
/* Sin motor de scroll no hay nada que encender: la línea de tiempo se
   entrega entera y con la espina completa. */
html:not(.js) .hito,
html.no-motion .hito { opacity: 1; }
html:not(.js) .hitos,
html.no-motion .hitos { --hitos-prog: 1; }

@media (prefers-reduced-motion: reduce) {
  .carta {
    order: -1; height: auto;
    max-width: 26rem; margin: 0 auto var(--bloque-y);
  }
  .carta-marco, .carta-marco svg { height: auto; }
  .carta-ruta { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
  .nodo-punto { fill: var(--ambar); stroke: rgba(232, 160, 32, 0.6); }
  .nodo-rotulo { fill: var(--marino); }
  .carta-navio { display: none; }
  .hito { opacity: 1; transition: none; }
  .hitos { --hitos-prog: 1; }
}


/* ══════════════════════════════════════════════════════════════════
   ACTO 0 · LA BITÁCORA EN VERTICAL — «ficha de expedición»
   ══════════════════════════════════════════════════════════════════
   Escritorio es cine: el globo manda y el texto lo acompaña por la
   izquierda, flotando sobre la escena. En vertical eso no se traduce —
   el globo no cabe y el texto suelto sobre el cielo deja la pantalla
   medio vacía.
   Así que en móvil NO se adapta el mismo diseño: se hace otro. Cada
   capítulo es una FICHA a pantalla casi completa, con superficie
   propia —panel de vidrio sobre la noche—, su numeral gigante de fondo
   y una barra de progreso segmentada al pie. El lenguaje es de app, no
   de película, y ocupa el encuadre entero.
   TODO lo de aquí es exclusivo de vertical. Escritorio no se toca.
   ────────────────────────────────────────────────────────────────── */

/* Piezas que solo existen en vertical. Van fuera de la media query
   porque el `display` que las enciende vive dentro: sin esto se
   pintarían en escritorio como cajas sueltas. */
.est-chrome,
.est-rail,
.est-glifo { display: none; }

@media (max-width: 760px) {

  /* El globo, fuera. `display:none` lo saca también del árbol de
     composición, no solo de la vista. */
  .globo-wrap { display: none !important; }

  /* El velo de lectura se retira: la ficha trae su propia superficie y
     ya no hace falta oscurecer la escena entera para poder leer. Un
     velo encima solo apagaría el contraste del panel. */
  .scrim-lectura { opacity: 0 !important; }

  /* ── Rótulo de sección, sobre la ficha ── */
  .est-chrome {
    display: flex;
    position: absolute;
    top: clamp(4.9rem, 9.5vh, 6.4rem);
    left: 1.15rem;
    right: 1.15rem;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--fs-micro);
    font-weight: 700;
    letter-spacing: var(--track-2);
    text-transform: uppercase;
    color: var(--texto-noche-3);
    opacity: 0;
    z-index: 4;
  }
  .est-chrome .chrome-sig { color: var(--texto-noche-2); }
  .est-chrome .chrome-regla {
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, rgba(245,244,239,0.22), rgba(245,244,239,0.04));
  }
  .est-chrome-idx {
    display: inline-flex;
    align-items: baseline;
    gap: 0.12rem;
    font-variant-numeric: tabular-nums;
  }
  .est-chrome-idx b { color: var(--ambar); font-weight: 700; }
  .est-chrome-idx i { font-style: normal; opacity: 0.45; }

  /* ── La ficha ocupa el encuadre ── */
  .estacion {
    left: 1.15rem;
    right: 1.15rem;
    top: 50%;
    bottom: auto;
    width: auto;
    max-width: none;
    transform: translateY(-50%);
  }
  /* Alto contenido: al 73vh la ficha obligaba al glifo a hincharse
     para rellenar el aire sobrante y todo se leía desproporcionado
     (ago 2026). Al ~62 % el panel sigue mandando en el encuadre pero
     el dibujo, el numeral y el texto recuperan su escala relativa. */
  .est-pasos { min-height: min(33rem, 62vh); }

  .est-paso {
    /* Centrado, no anclado al pie. Con `flex-end` y el glifo empujado
       arriba por `margin-bottom:auto`, todo el aire sobrante caía de
       golpe entre el dibujo y el titular — un agujero en mitad de la
       ficha. Centrado, ese aire se reparte arriba y abajo y el bloque
       se lee como una unidad. */
    justify-content: center;
    /* El pie lleva algo más de aire que la cabeza: el filete de la
       ficha técnica se comía 3px contra el borde del panel. */
    padding: 1.7rem 1.35rem 1.95rem;
    border-radius: 1.35rem;
    border: 1px solid rgba(245, 244, 239, 0.10);
    /* Vidrio sobre la noche: el panel toma el azul de la escena y lo
       densifica, en vez de tapar con un gris neutro. */
    background:
      linear-gradient(168deg,
        rgba(34, 58, 96, 0.60) 0%,
        rgba(14, 30, 55, 0.72) 52%,
        rgba(6, 15, 30, 0.84) 100%);
    box-shadow:
      0 26px 64px -22px rgba(0, 0, 0, 0.78),
      inset 0 1px 0 rgba(245, 244, 239, 0.07);
    overflow: hidden;
  }
  /* El numeral gigante como marca de agua. Va DESBORDADO a propósito
     —se sale por arriba y por la derecha, y el panel lo recorta— para
     que se lea como textura del propio panel y no como un número
     puesto encima. Es lo que llena la mitad alta sin añadir ni un
     elemento más de interfaz. */
  .est-paso::before {
    content: attr(data-chapter);
    position: absolute;
    top: -1.8rem;
    /* Dentro del panel en horizontal: a este tamaño, desbordar por la
       derecha guillotinaba el «1» a media asta y se leía como un
       fallo, no como textura. El sangrado queda solo arriba. */
    right: 0.6rem;
    font-family: 'Montserrat', sans-serif;
    /* 19rem llenaba media ficha y competía con el titular: a 12rem
       sigue siendo textura del panel, pero ya no lo domina. */
    font-size: 12rem;
    font-weight: 800;
    line-height: 0.82;
    letter-spacing: -0.08em;
    color: rgba(245, 244, 239, 0.038);
    pointer-events: none;
  }
  /* Y un resplandor cálido en la esquina alta: el farol de la escena
     entrando en el panel, que es lo que lo ata a la noche de detrás. */
  .est-paso::after {
    content: '';
    position: absolute;
    top: -35%; right: -25%;
    width: 80%; aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(232, 160, 32, 0.16) 0%, rgba(232, 160, 32, 0) 68%);
    pointer-events: none;
  }
  .est-paso > * { position: relative; z-index: 1; }

  /* ── Los glifos ──────────────────────────────────────────
     Un dibujo por capítulo, encima del texto, diciendo lo mismo que
     el titular. Monolínea y del grosor de la tipografía, para que
     lean como parte del mismo sistema y no como un icono pegado.
     `margin-bottom: auto` los empuja arriba del panel: el texto sigue
     anclado al pie y el dibujo ocupa el aire que quedaba. */
  .est-glifo {
    display: block;
    /* Al 90 % del panel el dibujo era el protagonista de la ficha y
       aplastaba al titular. A ~55 % ilustra, que es su papel. */
    width: min(55%, 11rem);
    height: auto;
    margin-bottom: clamp(1.1rem, 2.6vh, 1.6rem);
    overflow: visible;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  /* El plan: trazo tenue y punteado, siempre visible. */
  .gl-guia {
    stroke: rgba(245, 244, 239, 0.20);
    stroke-width: 2;
    stroke-dasharray: 3 6;
  }
  /* Lo real: se dibuja encima del plan. */
  .gl-trazo {
    stroke: var(--ambar);
    stroke-width: 2.6;
  }
  .gl-remate { fill: var(--ambar); stroke: none; }

  .gl-ruta {
    stroke: rgba(245, 244, 239, 0.55);
    stroke-width: 2;
  }
  .gl-sede { fill: rgba(245, 244, 239, 0.9); stroke: none; }
  .gl-nucleo {
    fill: none;
    stroke: var(--ambar);
    stroke-width: 2.6;
  }

  /* Los colores del glifo 03 son los del IRIS, no una elección libre.
     El recorte del manifiesto descubre papel (`--papel`) y lo hace
     justo dentro del anillo ámbar de este dibujo, así que:
       · los anillos exteriores van en ámbar tenue — son la onda,
       · el anillo interior va en ámbar pleno — es el borde del iris,
       · y el ojo va en PAPEL, no en ámbar.
     Con el ojo ámbar, el iris abría crema sobre un disco naranja y se
     veía el relevo. En papel, el círculo que crece nace exactamente
     del mismo color que ya estaba ahí: no hay salto. */
  .gl-anillo {
    stroke: rgba(232, 160, 32, 0.34);
    stroke-width: 2;
  }
  .gl-anillo-3 {
    stroke: var(--ambar);
    stroke-width: 3.2;
  }
  .gl-ojo {
    fill: var(--papel);
    stroke: none;
  }

  /* En pantallas BAJAS el contenido no cabe: a 640px de alto la ficha
     son ~376px y el bloque completo (glifo + titular + cuerpo + ficha
     técnica) medía hasta 32px más, así que se salía por arriba y por
     abajo a la vez —el centrado reparte el desbordamiento—. El glifo es
     lo primero que cede: es el elemento decorativo, no el mensaje. */
  @media (max-height: 720px) {
    .est-glifo {
      width: min(44%, 8.5rem);
      margin-bottom: clamp(0.7rem, 2vh, 1.1rem);
    }
    .bitacora .est-titulo { font-size: clamp(1.55rem, 7.4vw, 2.2rem); }
    .bitacora .est-cuerpo {
      margin-top: 0.75rem;
      font-size: 0.9rem;
      line-height: 1.46;
    }
    .bitacora .est-data { margin-top: 1rem; padding-top: 0.75rem; }
    .est-paso { padding: 1.3rem 1.2rem 1.5rem; }
  }
  /* Y por debajo de 600px de alto no cabe ni reducido: fuera. La ficha
     encoge con él — si se quedara al 73 % sin glifo dentro, el vacío
     interior se disparaba al 42 %. */
  @media (max-height: 600px) {
    .est-glifo { display: none; }
    /* 68vh y no 58: sin glifo pero con el titular a tres líneas, a
       568px de alto el texto no cabía en 58vh y se salía del panel. */
    .est-pasos { min-height: 68vh; }
    .bitacora .est-titulo { font-size: clamp(1.4rem, 6.8vw, 1.9rem); }
  }
  /* Último escalón: encuadres muy bajos (móvil apaisado, pantallas
     antiguas). Aquí la ficha ocupa casi todo lo que hay. */
  @media (max-height: 500px) {
    .est-pasos { min-height: 80vh; }
    .est-paso { padding: 1rem 1.1rem 1.1rem; }
    .bitacora .est-cuerpo { margin-top: 0.6rem; font-size: 0.85rem; }
    .bitacora .est-data { margin-top: 0.75rem; padding-top: 0.6rem; }
  }

  /* ── Tipografía de la ficha: un punto por debajo de la versión
     anterior — con la ficha al 62 % ya no hay hueco que justificar
     con cuerpo de cartel. ── */
  .bitacora .est-titulo {
    max-width: none;
    font-size: clamp(1.6rem, 7.6vw, 2.3rem);
    line-height: 1.06;
    letter-spacing: -0.035em;
    text-wrap: balance;
  }
  .bitacora .est-cuerpo {
    width: 100%;
    max-width: none;
    margin-top: 1.05rem;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--texto-noche-2);
  }
  /* Datos en rejilla, pegados al pie del panel */
  .bitacora .est-data {
    width: 100%;
    margin-top: 1.9rem;
    padding-top: 1.15rem;
    border-top: 1px solid rgba(245, 244, 239, 0.13);
    border-bottom: 0;
  }
  .bitacora .est-data p { padding: 0 0.9rem 0 0; }
  .bitacora .est-data p + p { padding: 0 0 0 0.9rem; }

  /* ── Progreso segmentado, al pie ──
     Tres barras que se llenan. Es lenguaje de aplicación —el de un
     carrusel de historias— y sustituye al raíl vertical de escritorio:
     en una mano, el progreso se lee abajo, no en el lateral. */
  .est-rail {
    display: flex;
    position: absolute;
    left: 1.15rem;
    right: 1.15rem;
    top: auto;
    bottom: clamp(2.2rem, 5.4vh, 3.4rem);
    height: auto;
    gap: 0.4rem;
    opacity: 0;
    z-index: 4;
    transform: none;
  }
  /* El eje vertical del manifiesto aquí no pinta nada. */
  .est-rail .rail-eje { display: none; }
  .est-rail .rail-pasos {
    display: flex;
    /* El raíl del manifiesto es VERTICAL y su `.rail-pasos` hereda
       `flex-direction: column`. Aquí la barra es horizontal: sin este
       reset los tres tramos se apilaban uno encima de otro y la barra
       no se veía. */
    flex-direction: row;
    flex: 1;
    gap: 0.4rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .est-rail .rail-paso {
    /* Y `.rail-paso` es un contenedor flex centrado en el manifiesto,
       lo que impedía que su `::before` tomase el alto completo. */
    display: block;
    flex: 1;
    height: 3px;
    border-radius: 999px;
    background: rgba(245, 244, 239, 0.14);
    opacity: 1;
    overflow: hidden;
  }
  /* La marca redonda del raíl del manifiesto no aplica a una barra. */
  .est-rail .rail-paso::before {
    content: '';
    display: block;
    width: 100%;
    height: 100%;
    border-radius: inherit;
    background: var(--ambar);
    transform-origin: left center;
    transform: scaleX(var(--seg, 0));
  }
}
