/* ═══════════════════════════════════════════════════════════════════════════
   TURISMOS ORCA — landing inmersiva · Diseñado por Operaria
   v7 · las reseñas, los tres idiomas y los cinco defectos heredados.
   Concepto SE QUEDAN · la página baja hasta el capítulo 3 y vuelve a subir.

   Esta hoja la comparten las TRES páginas —`index.html`, `en/index.html` y
   `fr/index.html`—, que se escriben desde `respaldo/plantilla.html` con
   `respaldo/genera-paginas.mjs`. Una sola hoja, un solo motor, tres copys.

   Qué cambia respecto de la v6, y por qué:
     · SECCIÓN 7.5 · LAS RESEÑAS. Entre el capítulo 7 y la banda de preguntas,
       sin pin y sin efecto —como la banda de preguntas—: un bloque que tiene
       que leerse aunque el motor de scroll no arranque. Tira con
       desplazamiento lateral en teléfono, rejilla de tres en escritorio.
       Nada de estrellas dibujadas, nada de comillas decorativas.
     · EL SELECTOR DE IDIOMA, en la barra y repetido en el pie.
     · LOS CINCO DEFECTOS que la revisión de las capturas de la v6 dejó
       anotados se cierran acá, cada uno donde vive:
         1 · cap. 1 en vertical — el párrafo caía sobre las casas de colores
             sin velo propio. El velo del ticket deja de ser el genérico.
         2 · cap. 2 — el pie del timón era gris sobre la chaqueta naranja: el
             pie de TODA placa sube a `--espuma` y su filo de sombra llega más
             abajo y más firme.
         3 · cap. 4 en vertical — los pies de la tira de especies, mismo
             arreglo, por la misma regla.
         4 · cap. 8 en escritorio — las filas 2 y 3 del cierre (los dos botones
             de línea) vivían sin relleno sobre la foto aérea, fuera del
             alcance del velo lateral. Ahora llevan su propia tinta.
         5 · sin JS — la barra fija se quedaba sin fondo y sobreimprimía el
             cierre. Ahora `html:not(.js)` la posa de entrada.
   Todo lo demás es la v6 y no se toca. `orca-v6.css` queda intacto.

   Qué cambió la v6 respecto de la v5, y por qué:
     · CAP. 7 · LA FAMILIA. El tercer video del cliente —la cola que se levanta
       chorreando, se hunde y deja la huella en el mar quieto frente a la costa
       del desierto— entra con el mismo gesto que el hero y el capítulo 3:
       sesenta fotogramas sobre la fotografía a sangre, que es el fotograma 1,
       sigue siendo el `og:image` y sigue siendo lo que se ve sin JS.
     · El velo del capítulo 7 se refuerza, y era necesario: el último tercio de
       la secuencia es mar claro con la costa iluminada detrás, y el titular
       blanco se caía del contraste. Medido, no estimado (`respaldo/contraste.mjs`).
   Todo lo demás es la v5 y no se toca. `orca-v5.css` queda intacto.

   Qué cambió la v5 respecto de la v4, y por qué:
     · CAP. 3 · EL FRÍO. El segundo video del cliente —la cámara entrando al
       enjambre de krill bajo los haces de luz— entra con el mismo gesto que el
       hero: sesenta fotogramas que avanzan con el scroll, sobre la imagen
       generada, que es el fotograma 1 y sigue siendo el poster.
     · El video de Veo que la v3 cableaba en ese capítulo se retira: el scrub lo
       reemplaza y el archivo volvió a `respaldo/generado/`.
   Todo lo demás es la v4 y no se toca. `orca-v4.css` queda intacto.

   Qué cambió la v4 respecto de la v3, y por qué:
     · CAP. 0 · EL HERO. El video que entregó el cliente —la lancha y los
       delfines bajo la camanchaca— ya no se reproduce solo: avanza con el
       desplazamiento. Sesenta fotogramas en un `<canvas>` sobre la fotografía,
       que sigue siendo el LCP y sigue siendo el fotograma 1. El riel del hero
       ya medía 210vh en escritorio y 180vh en vertical, que es justo lo que
       este gesto necesita: no se tocó.
     · El titular se retira a 0.35 de opacidad en el último 10% del riel, para
       dejar ver el fotograma final, que ahí ya está quieto.
   Todo lo demás es la v3 y no se toca. `orca-v3.css` queda intacto.

   Qué cambió la v3 respecto de la v2, y por qué:
     · CAP. 3 · EL FRÍO. En la v2 la escena quedaba turbia y la fotografía del
       dron no se leía: era una cortina, no un velo. Ahora el fondo es la
       columna de agua (imagen y video generados, Iris · Vertex), la foto del
       dron es una PLACA con su propio brillo —fuera del oscurecimiento del
       descenso— y el apagón del fondo baja de 22% a 12%.
     · CAP. 4 · una ballena fin COMIENDO abre el capítulo, y las tres especies
       tienen su fotografía en la banda. El encuadre vertical entra por
       `<picture>` en el breakpoint chico.
     · CAP. 5 · el chungungo deja de ser ficha tipográfica y el muro iguala
       alturas y recortes a 4:5.
     · CAP. 8 · dos columnas y el bloque «Lo que tienes que saber», con el
       precio en grande.
   El resto —la arquitectura, la paleta, los cuatro bloques— es el de la v2 y
   no se toca. `orca-v2.css` queda intacto.

   Nace de `orca-v1.css` y conserva su arquitectura: cuatro bloques, dos
   variables escritas por el JS (`--depth` en <html>, `--p` en cada capítulo
   pineado) y todo lo demás resuelto con `calc()` y `clamp()`.

   Qué cambia respecto de v1, y por qué:
     · La paleta es la del concepto (§7 de `01-alma-y-concepto.md`): abisal,
       profundo, corriente, ocre. El ámbar de v1 sale; el acento es el
       verde-agua de la corriente.
     · La columna de agua se lee como agua y no como cielo nocturno: base
       verde-azul, haces de luz que no se apagan del todo, partículas de
       tamaño y difusión variables, turbidez creciente y cáusticas suaves.
     · Nueve capítulos con riel, no cinco. El pin vive en el BLOQUE B
       (ancho + movimiento); el hero es el único que pinea en vertical.
     · La sonda es la del guion: una línea de 1px con su dato al lado.

   Cuatro bloques, y el orden importa:

     1. BASE — tokens y el estado RESUELTO: apilado, legible, sin pin, sin
               transform. Cada capítulo pinta acá su propio degradado de mar,
               así que la página cuenta el descenso por color aunque el JS no
               corra nunca.
     2. M    — movimiento: `@media (prefers-reduced-motion: no-preference)` +
               `html.js`. El océano fijo, el pin del hero y la coreografía que
               no depende del ancho.
     3. A    — ancho: `@media (min-width: 1025px)`. Solo layout.
     4. B    — ancho + movimiento. Los ocho pines restantes y lo que difiere.

   La trampa de especificidad es la de la casa: las reglas de M y B van
   prefijadas con `html.js` (0,2,0) y las de A no (0,1,0). Lo que se puede
   resolver con una VARIABLE se resuelve con una variable: una variable no
   pelea especificidad.

   Un solo número de ancho, 1025, declarado dos veces (A y B).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────── 1 · TOKENS ─────────────────────────
   Los nombres son los de §7 del concepto, sin renombrar. Los OKLCH están
   calculados desde el hex que decidió el concepto, no estimados. */
:root{
  /* superficie */
  --abisal:          oklch(0.185 0.029 230);  /* #04151d · fondo dominante */
  --profundo:        oklch(0.268 0.043 227);  /* #0a2a36 · barra, fichas, pie */
  --borde:           oklch(0.351 0.055 222);  /* #12414f · reglas de 1px */
  /* texto */
  --espuma:          oklch(0.969 0.005 197);  /* #f1f6f6 · CR 17,04 */
  --espuma-2:        oklch(0.855 0.017 201);  /* #c3d3d4 · CR 12,02 */
  --camanchaca:      oklch(0.702 0.024 214);  /* #8fa3a8 · CR 7,05 */
  --niebla:          oklch(0.549 0.030 217);  /* #5e767d · CR 3,86 · SOLO ≥18px */
  /* corriente — el acento */
  --corriente:       oklch(0.497 0.082 189);  /* #12716c · líneas, sonda, relleno de botón */
  --corriente-luz:   oklch(0.701 0.110 184);  /* #36b5a6 · palabra marcada y enlaces · CR 7,36 */
  --corriente-claro: oklch(0.814 0.102 181);  /* #6fd8c6 · hover, foco, filo de luz · CR 10,90 */
  /* tierra — SOLO capítulos 1 y 8 */
  --ocre:            oklch(0.606 0.109 58);   /* #b2703a */
  --ocre-luz:        oklch(0.732 0.105 65);   /* #d69a5e · CR 7,65 */

  /* LA COLUMNA DE AGUA · de la superficie al fondo.
     Ninguno de los cuatro es negro: el más hondo sigue siendo verde-azul.
     Ése es el arreglo de la v1, donde el fondo se leía como cielo nocturno. */
  --mar-sup:   oklch(0.472 0.063 197);        /* la superficie iluminada */
  --mar-medio: oklch(0.352 0.058 202);
  --mar-hondo: oklch(0.262 0.050 206);
  --mar-fondo: oklch(0.196 0.041 202);        /* −60 m · verde-azul profundo */

  /* el cielo del norte, con camanchaca colgada */
  --cielo-alto: oklch(0.878 0.017 222);
  --cielo-bajo: oklch(0.806 0.020 212);
  --camanchaca-aire: oklch(0.848 0.012 216);

  --borde-2: color-mix(in oklab, var(--espuma) 9%, transparent);
  --vidrio:  color-mix(in oklab, var(--abisal) 78%, transparent);

  /* voces */
  --display: "Newsreader", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --texto:   "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono:    "DM Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;

  /* geometría y tiempo — los valores de la pieza VERTICAL */
  --sangra:  max(22px, 5.4vw);
  --barra-h: 48px;
  --tope:    var(--barra-h);
  --pildora-h: 46px;
  --pie-libre: calc(var(--pildora-h) + env(safe-area-inset-bottom) + 10px);
  --medida:  38rem;
  --ease:    cubic-bezier(0.16, 1, 0.3, 1);
  --piso:    11px;                            /* nada bajo 11px en vertical */

  /* recorridos: los de la pieza vertical, ver §3 del guion */
  --hundir:  9vh;
  --paneo:   6vw;

  /* la profundidad. El JS la escribe en <html>; acá vive su reposo. */
  --depth: 0;

  /* trama de respaldo de las placas de imagen: una ola de 1px, sin archivo */
  --trama: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='54' viewBox='0 0 180 54'%3E%3Cpath d='M0 30C22 12 45 12 68 30s45 18 68 0 44-18 66 0' fill='none' stroke='%23ffffff' stroke-opacity='0.085' stroke-width='1.1'/%3E%3C/svg%3E");
}

*, *::before, *::after { box-sizing: border-box; }

html{
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;                      /* el ancla instantáneo; smooth le pelea al scrub */
  scrollbar-color: var(--borde) var(--abisal);
  scrollbar-width: thin;
  background: var(--abisal);
}

body{
  margin: 0;
  background: var(--mar-hondo);
  color: var(--espuma);
  font-family: var(--texto);
  font-size: clamp(max(1rem, var(--piso)), .97rem + .2vw, 1.0625rem);
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }
/* `height: auto` NO es opcional: los atributos width/height del HTML actúan
   como CSS de baja prioridad y sin esto el alto del atributo manda. */

svg { display: block; max-width: 100%; }

::selection { background: color-mix(in oklab, var(--corriente-luz) 62%, transparent); color: var(--abisal); }
:focus-visible { outline: 2px solid var(--corriente-claro); outline-offset: 3px; border-radius: 2px; }

a { color: var(--corriente-luz); text-decoration-thickness: 1px; text-underline-offset: .22em; }
a:hover, a:focus-visible { color: var(--corriente-claro); }

/* El patrón de la casa: «reserva por WhatsApp» es lo enlazado. El número
   jamás es texto de enlace. */
.wa{ color: var(--corriente-luz); text-decoration: underline;
     text-decoration-thickness: 1px; text-underline-offset: .22em; white-space: nowrap; }
a:hover .wa, a:focus-visible .wa { color: var(--corriente-claro); }

/* ───────────────────────── TIPOGRAFÍA ─────────────────────────
   Una sola escala, y UNA regla de h2 para los nueve capítulos. Todo lo que
   vive dentro de un pin mide también por `vh`. */
h1, h2, h3{
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.015em;
  text-wrap: balance;
  margin: 0;
}
h1      { font-size: clamp(2.4rem, min(7.4vw, 9vh), 5.4rem); font-weight: 500; }
h2      { font-size: clamp(1.9rem, min(5.2vw, 6vh), 3.3rem); }
h3      { font-size: clamp(1.02rem, min(1.9vw, 2.3vh), 1.22rem); font-weight: 600; }

p { text-wrap: pretty; margin: 0 0 .9em; }
p:last-child { margin-bottom: 0; }
/* La medida de lectura se pide donde hay lectura, no a todo <p>. */
.prosa { max-width: 62ch; color: var(--espuma-2); }

.mono, .dato, .rotulo{
  font-family: var(--mono); font-weight: 500;
  font-size: clamp(max(.72rem, var(--piso)), min(2.6vw, 1.4vh), .8125rem);
  letter-spacing: .12em; text-transform: uppercase; color: var(--camanchaca);
  line-height: 1.5;
}
.rotulo { margin: 0 0 clamp(.5rem, 1.6vh, .9rem); }
.dato   { margin: clamp(.45rem, 1.2vh, .8rem) 0 0; }

.lede{ font-size: clamp(max(1.04rem, var(--piso)), min(4.4vw, 2.3vh), 1.28rem);
       color: var(--espuma-2); max-width: 38ch; line-height: 1.5; }

.micro{ font-size: clamp(max(.86rem, var(--piso)), min(3.4vw, 1.7vh), .95rem);
        color: var(--espuma-2); margin-top: clamp(.6rem, 1.6vh, 1rem); }

/* La palabra marcada. Versalitas, verde-agua y subrayado capilar. Una vez por
   bloque, y no más de cuatro veces en toda la página: caps. 5, 6 y 7. */
.res{
  font-variant: small-caps; letter-spacing: .08em;
  color: var(--corriente-luz);
  border-bottom: 1px solid var(--corriente);
  padding-bottom: 1px;
}

/* Lo que el cliente todavía no entregó se ve faltar. No se rellena. */
.pendiente{
  font-family: var(--mono);
  font-size: clamp(max(.7rem, var(--piso)), 2.6vw, .78rem);
  line-height: 1.6; letter-spacing: .04em; color: var(--niebla);
  text-transform: none;
  border-left: 1px solid var(--borde); padding-left: .85rem;
  margin-top: clamp(.8rem, 2.2vh, 1.2rem); max-width: 54ch;
}
.pendiente b { font-weight: 500; color: var(--camanchaca); }

/* La cita: Newsreader, sola, sin comillas tipográficas de adorno. */
.cita{
  font-family: var(--display); font-weight: 500;
  font-size: clamp(1.1rem, min(3.8vw, 2.6vh), 1.42rem);
  line-height: 1.32; color: var(--espuma);
  margin: clamp(.7rem, 2.2vh, 1.2rem) 0 0; max-width: 36ch;
  border-left: 1px solid var(--corriente); padding-left: clamp(.9rem, 2.4vw, 1.3rem);
}
.cita + .dato { color: var(--camanchaca); }
/* v7 · el rótulo de traducción. La frase de Maritza Sepúlveda y la del capitán
   se publicaron en español: en las páginas en inglés y en francés la cita es
   una traducción y se dice, en chico, bajo el crédito. */
.dato--trad{ margin-top: .2rem; color: var(--niebla); }

/* ───────────────────────── 2 · ESTRUCTURA ─────────────────────────
   El riel va por fuera y el sticky por dentro. La sección NUNCA se pinea a sí
   misma. `.cap__pin` recibe `position` en DOS lugares de toda la hoja
   —`static` acá, `sticky` en B— más la regla propia del hero en M. */
main { position: relative; z-index: 1; }

.cap  { position: relative; }
.riel { position: relative; }
.cap__pin { position: static; }              /* ÚNICA declaración base de `position` */

/* Cada capítulo pinta su mar. Éste es el estado que se ve sin JS y bajo
   `prefers-reduced-motion`: el descenso contado con color, sin una sola
   propiedad animada. Con JS y movimiento el bloque M los vuelve transparentes
   y deja pasar el océano fijo. */
.cap{ background: linear-gradient(to bottom, var(--tono-a, var(--mar-hondo)), var(--tono-b, var(--mar-hondo))); }
.cap--hero       { --tono-a: var(--mar-sup);   --tono-b: var(--mar-medio); }
.cap--ticket     { --tono-a: var(--mar-medio); --tono-b: color-mix(in oklab, var(--mar-medio), var(--mar-hondo) 55%); }
.cap--zarpar     { --tono-a: color-mix(in oklab, var(--mar-medio), var(--mar-hondo) 55%); --tono-b: var(--mar-hondo); }
.cap--frio       { --tono-a: var(--mar-hondo); --tono-b: var(--mar-fondo); }
.cap--encuentro  { --tono-a: var(--mar-fondo); --tono-b: var(--mar-medio); }
.cap--vecinos    { --tono-a: var(--mar-medio); --tono-b: var(--mar-hondo); }
.cap--calendario { --tono-a: var(--profundo);  --tono-b: var(--profundo); }
.cap--familia    { --tono-a: var(--profundo);  --tono-b: color-mix(in oklab, var(--profundo), var(--mar-medio) 50%); }
.cap--cierre     { --tono-a: var(--mar-medio); --tono-b: var(--mar-sup); }

.cap__marco{
  position: relative; z-index: 2;
  padding-inline: var(--sangra);
  padding-block: clamp(3rem, 9vh, 5rem)
                 calc(clamp(3rem, 9vh, 5rem) + var(--pie-libre));
}
.cap__marco--pie   { display: grid; align-content: end; gap: clamp(1.1rem, 3vh, 1.8rem); }
.cap__marco--centro{ display: grid; align-content: center; }

.cap__lienzo{ position: relative; z-index: 0; overflow: clip; }

/* Bandas en flujo: miden lo que tienen que decir, ni un pixel más. */
.banda{
  position: relative; z-index: 2;
  padding-inline: var(--sangra);
  padding-block: clamp(2.2rem, 7vh, 3.6rem)
                 calc(clamp(2.2rem, 7vh, 3.6rem) + var(--pie-libre));
  border-top: 1px solid var(--borde-2);
  background: color-mix(in oklab, var(--abisal) 82%, transparent);
}
.descarga{ display: grid; gap: clamp(1.1rem, 3vh, 1.6rem); }
.descarga > * { min-width: 0; }
.descarga.otras-salidas{ gap: .5rem; }
.banda--fina{ padding-block: clamp(1.4rem, 4vh, 2.2rem)
                             calc(clamp(1.4rem, 4vh, 2.2rem) + var(--pie-libre)); }

.cap__col{ display: grid; align-content: start; gap: clamp(.6rem, 1.7vh, 1rem); }
/* Dos columnas dentro del pin, donde el capítulo tiene demasiado que decir
   para una sola: sin esto, los capítulos 6, 7 y 8 se pasan del alto a 900 y el
   pin, que centra, se come el rótulo por arriba. */
.cap__doble{ display: grid; gap: clamp(.9rem, 2.6vh, 1.4rem); }

/* ───────────────────────── 3 · PIEZAS COMUNES ───────────────────────── */

/* Cinta de propuesta: se funde con la barra en vertical y vuelve en A. */
.cinta{
  display: none; margin: 0;
  position: fixed; inset: 0 0 auto 0; z-index: 41;
  height: 26px; align-items: center; justify-content: center;
  background: var(--abisal); border-bottom: 1px solid var(--borde-2);
  font-family: var(--mono); font-size: max(11px, .66rem); letter-spacing: .1em;
  text-transform: uppercase; color: var(--camanchaca);
  white-space: nowrap; overflow: clip;
}

/* La barra. Es `fixed` y no reclama el borde del documento, así que todos los
   pines pueden usar `top: 0`: lo que reservan es el relleno de su marco. */
.barra{
  position: fixed; inset: 0 0 auto 0; z-index: 40;
  height: var(--barra-h);
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding-inline: var(--sangra);
  color: var(--espuma);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background .35s linear, border-color .35s linear;
}
.barra--posada{
  background: color-mix(in oklab, var(--profundo) 92%, transparent);
  -webkit-backdrop-filter: blur(9px);
          backdrop-filter: blur(9px);
  border-bottom-color: var(--borde);
}
/* v7 · DEFECTO 5. Sin JS nadie le pone `--posada`, así que la barra se quedaba
   transparente toda la página y al pie sobreimprimía el cierre: dos textos
   ocupando el mismo sitio. Sin motor la barra nace posada —no tiene hero claro
   que respetar, porque tampoco hay pin que lo sostenga— y el cierre se lee.
   La clase `js` la pone el <head> y se retira sola si el motor no arrancó, así
   que esta regla cubre también el archivo que no llegó. */
html:not(.js) .barra{
  background: color-mix(in oklab, var(--profundo) 94%, transparent);
  -webkit-backdrop-filter: blur(9px);
          backdrop-filter: blur(9px);
  border-bottom-color: var(--borde);
}
.barra__marca{ text-decoration: none; color: inherit;
               display: inline-flex; align-items: center; gap: .55rem; }
/* El logo es el del cliente. Si el archivo faltara, el nombre en Newsreader
   queda de marcador y nada se rompe. */
.barra__logo{ width: clamp(30px, 8vw, 38px); height: auto; flex: none;
               filter: invert(1); }
.barra__marca.falta .barra__logo{ display: none; }
.barra__nombre{ display: none; }
.barra__marca.falta .barra__nombre{ display: inline; }
/* [DATO PENDIENTE] el logo. Mientras no llegue, el nombre en Newsreader es un
   MARCADOR, no una decisión tipográfica de marca. */
.barra__marca .barra__nombre{
  font-family: var(--display); font-size: clamp(1.02rem, 4vw, 1.18rem);
  font-weight: 600; letter-spacing: -.01em; color: var(--espuma);
}
.barra__derecha{ margin: 0; display: flex; align-items: center; gap: .8rem;
                 font-family: var(--mono); font-size: max(11px, .7rem);
                 letter-spacing: .12em; text-transform: uppercase; }
.barra__dato{ display: none; color: var(--camanchaca); }
/* Antes de posarse la barra no tiene fondo y el hero es una foto clara: el
   dato y el enlace suben a espuma para no perderse contra el cielo. El verde
   de la corriente sobre gris claro no llega a AA; el subrayado sigue diciendo
   que es un enlace. */
.barra:not(.barra--posada) .barra__dato{ color: var(--espuma-2); }
.barra:not(.barra--posada) .barra__cta,
.barra:not(.barra--posada) .barra__cta .wa{ color: var(--espuma); }
.barra__cta{ color: var(--corriente-luz); text-decoration: none; white-space: nowrap;
             text-transform: none; letter-spacing: .01em; font-family: var(--texto);
             font-size: .88rem; }
.barra__cta:hover, .barra__cta:focus-visible{ color: var(--corriente-claro); }

/* ─── EL SELECTOR DE IDIOMA · v7 ──────────────────────────────
   Tres páginas estáticas que comparten motor, hoja y fotografías. El selector
   va en la barra y se repite en el pie, y el idioma activo se marca: lleva
   `aria-current="page"`, la letra en espuma y la regla de la corriente debajo.
   Sigue siendo un enlace —la misma marca en las tres páginas— para que el
   marcado sea idéntico y el generador no tenga que decidir nada. */
.idiomas{
  margin: 0; display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--mono); font-weight: 500;
  font-size: max(10px, .64rem); letter-spacing: .1em; text-transform: uppercase;
  white-space: nowrap;
}
.idiomas a{ color: var(--camanchaca); text-decoration: none; padding-bottom: 1px;
            border-bottom: 1px solid transparent; }
.idiomas a:hover, .idiomas a:focus-visible{ color: var(--corriente-claro); }
.idiomas .activo{ color: var(--espuma); border-bottom-color: var(--corriente-luz); }
.idiomas__sep{ color: var(--borde); }
/* Sobre el hero claro, antes de que la barra se pose, el selector sube de tono
   por la misma razón que el dato y el enlace de al lado. */
.barra:not(.barra--posada) .idiomas a{ color: var(--espuma-2); }
.barra:not(.barra--posada) .idiomas .activo{ color: var(--espuma); }

/* La píldora fija «reserva por WhatsApp». Puesta sin JS; con JS se estrena al
   entrar el capítulo 4 y se retira sobre el cierre. */
.pildora{
  position: fixed; z-index: 42;
  right: var(--sangra); bottom: calc(10px + env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: var(--pildora-h); padding-inline: 1.05rem;
  border-radius: 6px;                          /* nunca ≥24px */
  text-decoration: none;
  background: var(--corriente); color: var(--espuma);
  font-weight: 600; font-size: clamp(.86rem, 3.4vw, .94rem);
  box-shadow: 0 12px 34px rgba(0,0,0,.55);
  will-change: opacity, transform;             /* el ÚNICO will-change de la hoja */
}
.pildora:hover, .pildora:focus-visible{
  background: color-mix(in oklab, var(--corriente) 82%, var(--corriente-claro));
  color: var(--espuma);
}
.pildora__icono{ width: 20px; height: 20px; fill: currentColor; flex: none; }
.pildora__largo{ display: none; }

/* La sonda — el único adorno estructural de la página.
   Línea de 1px en el borde izquierdo que se llena con el scroll y lleva su
   dato al lado. Vive del capítulo 0 al 5, se retira en el 6 y 7, y VUELVE en
   el 8 marcando 0 m: es el cierre del arco y el JS lo pide con `.sonda--fin`.
   (Excepción anotada al guion §1.5, que la retiraba para siempre en el 6.) */
.sonda{
  position: fixed; left: max(14px, 2.2vw); top: 28vh; bottom: 28vh; z-index: 30;
  width: 1px; margin: 0; pointer-events: none;
  background: color-mix(in oklab, var(--borde) 80%, transparent);
  opacity: 1; transition: opacity .4s linear;
}
.sonda--fuera{ opacity: 0; }
.sonda__lleno{
  position: absolute; inset: 0 0 auto 0; width: 100%;
  height: calc(100% * var(--sonda, 0));
  background: var(--corriente);
}
/* El rótulo va VERTICAL y a la izquierda de la línea, dentro de la canaleta de
   32px que queda antes de la sangría: escrito en horizontal se montaba encima
   del titular en 1025, 1280 y 1440 (checklist §5.9 del guion). En vertical la
   canaleta no existe y el rótulo no se muestra: queda la línea sola. */
/* El rótulo baja por la línea con un TRANSFORM, no con `top`. Con `top` cada
   fotograma del scroll era un reflow, y el navegador lo contaba además como
   layout shift: 0,0067 acumulado en una bajada. El alto de la sonda es
   44vh —`top: 28vh; bottom: 28vh`— y de ahí sale el recorrido. */
.sonda__dato{
  display: none;
  position: absolute; right: 8px; top: 0;
  writing-mode: vertical-rl;
  transform: translateY(calc(44vh * var(--sonda, 0))) translateY(-50%) rotate(180deg);
  white-space: nowrap; margin: 0;
  font-family: var(--mono); font-size: max(10px, .62rem); letter-spacing: .16em;
  text-transform: uppercase; color: var(--camanchaca);
  font-variant-numeric: tabular-nums;
  transition: opacity .28s linear;
}
html:not(.js) .sonda{ display: none; }        /* sin scrub no dibuja nada */

/* La pista de scroll del hero. */
.pista{
  position: absolute; z-index: 3; left: 50%; bottom: calc(10px + var(--pie-libre));
  transform: translateX(-50%);
  margin: 0; display: flex; flex-direction: column; align-items: center; gap: .5rem;
  font-family: var(--mono); font-size: max(10px, .64rem);
  letter-spacing: .18em; text-transform: uppercase; color: var(--espuma-2);
  white-space: nowrap;
}
.pista::after{
  content: ""; width: 1px; height: 26px;
  background: linear-gradient(to bottom, var(--espuma-2), transparent);
}

/* LAS PLACAS DE IMAGEN — la corrección 3.
   Mientras el archivo no existe, la placa se ve como agua: degradado frío,
   trama de ola muy suave y una etiqueta en mono con el nombre que espera.
   Nada de siluetas dibujadas. Cuando el archivo llegue, `onerror` no dispara
   y toda esta capa se apaga sola, sin tocar una línea de CSS. */
.placa{
  position: relative; margin: 0; overflow: clip;
  border-radius: 3px;
  background:
    var(--trama),
    radial-gradient(120% 80% at 28% 18%,
      color-mix(in oklab, var(--corriente) 26%, transparent) 0%, transparent 62%),
    linear-gradient(152deg,
      color-mix(in oklab, var(--mar-sup) 62%, var(--abisal)) 0%,
      color-mix(in oklab, var(--mar-medio) 72%, var(--abisal)) 46%,
      color-mix(in oklab, var(--mar-fondo) 88%, var(--abisal)) 100%);
  background-size: auto 54px, cover, cover;
  border: 1px solid var(--borde-2);
}
.placa img{ width: 100%; height: 100%; object-fit: cover; }
.placa--alta   { aspect-ratio: 4 / 5; }
.placa--ancha  { aspect-ratio: 3 / 2; }
.placa--fondo  { position: absolute; inset: 0; border: 0; border-radius: 0; }
/* Sobre el océano fijo, una placa a sangre que falta NO pinta su agua propia:
   deja pasar el mar de la página. Si pintara, taparía el descenso. */
.placa--fondo.falta{ background: none; border: 0; }
.placa.falta img{ opacity: 0; }
.placa__chip{
  display: none;
  position: absolute; left: 10px; bottom: 10px; z-index: 2;
  font-family: var(--mono); font-size: max(10px, .62rem); letter-spacing: .08em;
  color: var(--camanchaca); background: var(--vidrio);
  border: 1px solid var(--borde-2); border-radius: 3px; padding: .3em .7em;
}
.placa.falta .placa__chip{ display: block; }
.placa--fondo .placa__chip{ left: 6%; bottom: 8%; }
/* El pie de la placa cae encima de la fotografía —la chaqueta naranja del
   capitán, por ejemplo—: lleva su propio filo de sombra para leerse siempre.
   v7 · DEFECTOS 2 y 3, y son el mismo defecto en dos capítulos. El pie iba en
   `--camanchaca` y el filo se abría demasiado pronto: sobre la chaqueta naranja
   del timón (cap. 2) y sobre las barbas blancas de la ballena fin y el cielo
   claro de la jorobada (cap. 4, en vertical) el texto se caía del contraste.
   El pie sube a `--espuma`, y la tinta va en DOS capas, porque una sola no
   alcanzaba —medido—: el filo de
   la placa hace la transición fotográfica, y el pie lleva ADEMÁS su propia
   tinta, pegada a él. Eso último es lo que lo vuelve a prueba de recortes: el
   pie de la tira ocupa una línea en escritorio y tres en vertical, y un filo de
   alto fijo no puede cubrir las tres. Con la tinta en el pie, el fondo que le
   toca al texto es siempre el mismo, mida lo que mida. */
.placa:has(figcaption)::after{
  content: ""; position: absolute; inset: auto 0 0 0; height: 56%;
  background: linear-gradient(to top, rgba(0,0,0,.70) 0%, rgba(0,0,0,.44) 34%,
                                      rgba(0,0,0,.18) 62%, rgba(0,0,0,0) 100%);
  pointer-events: none;
}
.placa.falta:has(figcaption)::after{ display: none; }
.placa figcaption{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  padding: .5rem 12px .55rem;
  background: linear-gradient(to top, rgba(0,0,0,.90) 0%, rgba(0,0,0,.84) 100%);
}
.placa figcaption.dato, .placa figcaption .dato{ color: var(--espuma); }
.placa.falta figcaption{ display: none; }

/* El velo: negro puro, degradado vertical 0 → 70%. Techo absoluto 70%.
   Ningún velo verde ni azul: el mar ya es azul y un velo de marca lo apaga.
   En vertical no hay velo lateral y el texto cae a lo largo de toda la foto,
   así que lleva además un plano parejo de 36% —el techo sigue siendo 70%. */
.velo{
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to top, rgba(0,0,0,.70) 0%, rgba(0,0,0,.42) 34%, rgba(0,0,0,0) 72%),
    linear-gradient(rgba(0,0,0,.36), rgba(0,0,0,.36));
}

/* La estela y la línea de tierra: reglas de 1px que se dibujan con scaleX. */
.estela{ height: 1px; background: var(--corriente); transform-origin: left;
         box-shadow: 0 -1px 0 color-mix(in oklab, var(--corriente-claro) 40%, transparent); }
.tierra{ height: 1px; background: var(--ocre); transform-origin: left; }

/* Filas de dato: la unidad de la página. */
.filas{ list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding: 0; display: grid; }
.filas li{
  position: relative;
  display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: .4rem 1rem; align-items: baseline;
  padding-block: clamp(.42rem, 1.5vh, .9rem);
  border-top: 1px solid var(--borde-2);
  font-size: clamp(max(.95rem, var(--piso)), min(1.5vw, 2.1vh), 1.0625rem);
}
/* La línea de tierra de cada salida. Va absoluta, así que no entra en la
   rejilla de la fila, y su `scaleX` por defecto es 1: sin JS está puesta. */
.filas .tierra{ position: absolute; left: 0; right: 0; top: 0; }
.filas li:last-child{ border-bottom: 1px solid var(--borde-2); }
.filas b{
  font-family: var(--mono); font-weight: 500;
  font-size: clamp(max(.72rem, var(--piso)), 2.6vw, .8rem);
  letter-spacing: .12em; text-transform: uppercase; color: var(--camanchaca);
  white-space: nowrap;
}
.filas span{ color: var(--espuma); font-family: var(--mono); font-size: .86em;
             letter-spacing: .08em; }
.filas .falta-dato{ color: var(--niebla); }

/* ═══════════ 4 · LOS NUEVE CAPÍTULOS · capa base ═══════════ */

/* ─── cap. 0 · SUPERFICIE (hero) ──────────────────────────────── */
.cap--hero .cap__pin{ min-height: 88svh; display: grid; align-content: end; }
.cap--hero .cap__lienzo{ position: absolute; inset: 0; z-index: 0; }

/* El cielo del norte con la camanchaca colgada sobre la costa. */
.hero__cielo{
  position: absolute; inset: 0;
  background:
    radial-gradient(130% 46% at 50% 26%,
      color-mix(in oklab, var(--camanchaca-aire) 62%, transparent) 0%, transparent 64%),
    linear-gradient(to bottom,
      var(--cielo-alto) 0%,
      var(--cielo-bajo) 20%,
      var(--camanchaca-aire) 32%,
      color-mix(in oklab, var(--cielo-bajo) 55%, var(--mar-sup)) 38%,
      var(--mar-sup) 44%,
      var(--mar-medio) 72%,
      var(--mar-hondo) 100%);
}
/* LA FOTO DEL HERO · es el LCP. Foto propia del cliente: la lancha lejana
   bajo la camanchaca con los delfines saltando. El video se monta encima
   cuando el archivo exista. */
.hero__foto{
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1;
  object-fit: cover; object-position: 52% 56%;
}
.hero__foto.falta{ display: none; }

/* EL CANVAS DE FOTOGRAMAS (v4). Nace oculto y ocupa exactamente la caja de la
   fotografía: el JS pinta cada cuadro con la misma lógica de `cover` y le
   PREGUNTA al CSS el `object-position` de `.hero__foto`, para que el encuadre
   sea el mismo a los dos anchos y no haya dos verdades.
   Se monta cuando el primer fotograma está decodificado, y ése es el que ya
   está pintado debajo: el cambio no se ve. La fotografía sigue siendo el LCP
   y se queda abajo, intacta, por si el canvas nunca llega. */
.hero__cuadros{
  display: none;                               /* sin JS no existe: queda la foto */
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2;
}
/* Con JS el canvas SÍ tiene caja desde el principio —transparente y vacía—
   porque un `display: none` no se puede medir, y sin medida no hay `cover`.
   Se enciende recién cuando el primer fotograma ya está pintado dentro. */
html.js .hero__cuadros{ display: block; opacity: 0; transition: opacity .25s linear; }
html.js .hero__cuadros.listo{ opacity: 1; }

/* RED DE SEGURIDAD del hero: la línea de costa dibujada y el reflejo de la
   camanchaca sobre el agua. Solo se ven si la fotografía no carga; con la
   foto puesta sobran, y una capa de más sobre una foto la ensucia. */
.hero__costa, .hero__reflejo{ display: none; }
.hero__foto.falta ~ .hero__costa,
.hero__foto.falta ~ .hero__reflejo{ display: block; }

.hero__costa{
  position: absolute; left: -4%; right: -4%; bottom: 60%; z-index: 1;
  height: clamp(28px, 7vh, 62px);
  opacity: .5; pointer-events: none;
}
.hero__costa svg{ width: 100%; height: 100%; }
.hero__costa .lejos{ fill: color-mix(in oklab, var(--camanchaca-aire) 58%, var(--ocre)); opacity: .34; }
.hero__costa .cerca{ fill: color-mix(in oklab, var(--ocre) 48%, var(--camanchaca-aire)); opacity: .44; }

/* El reflejo de la camanchaca sobre el agua: la luz del cielo cayendo en la
   superficie, justo bajo el horizonte. Un degradado, jamás un `filter`. */
.hero__reflejo{
  position: absolute; left: 0; right: 0; bottom: 0; top: 38%; z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(58% 34% at 50% 2%,
      color-mix(in oklab, var(--camanchaca-aire) 34%, transparent) 0%, transparent 72%),
    radial-gradient(26% 62% at 50% 0%,
      color-mix(in oklab, var(--espuma) 16%, transparent) 0%, transparent 78%);
}
/* El video del hero nace OCULTO y solo lo muestra el JS cuando el archivo
   existe y puede reproducirse (`canplay`). Al revés —mostrarlo y esconderlo
   con `onerror`— sin JS quedaba un reproductor vacío con su barra de controles
   encima de la foto, que es justo lo que se ve en el modo degradado. */
.hero__video{
  display: none;
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1;
  object-fit: cover; object-position: 52% 70%;
  opacity: .88;
}
html.js .hero__video.listo{ display: block; }
/* Las olas dibujadas son la otra mitad de la red de seguridad: con la foto
   propia puesta, un canvas de olas encima le taparía el agua de verdad. Solo
   entran cuando la foto falta. El JS lee esto y no dibuja si están ocultas:
   así el rAF en reposo sigue en 0/s. */
.hero__olas{
  display: none;
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  width: 100%; height: 62%;
}
.hero__foto.falta ~ .hero__olas{ display: block; }
/* El hero abre con la foto clara y la barra no tiene fondo todavía: sin este
   filo de arriba, «09:30 · 12:00 · 14:30» y el enlace se pierden sobre el
   cielo. Es el único velo de la página que oscurece por arriba. */
/* EL VELO DEL HERO. En vertical el titular vive en la mitad baja del cuadro y
   los sesenta fotogramas no son igual de oscuros: algunos son agua clara a
   plena luz. El filo de abajo sube más arriba y más firme que en la v3, que es
   lo que mantiene el claim sobre AA en los sesenta, no solo en el primero. */
.cap--hero .velo{
  z-index: 3;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.62) 0%, rgba(0,0,0,.34) 7%, rgba(0,0,0,.10) 13%, rgba(0,0,0,0) 20%),
    linear-gradient(to top, rgba(0,0,0,.80) 0%, rgba(0,0,0,.72) 26%, rgba(0,0,0,.56) 48%, rgba(0,0,0,.28) 68%, rgba(0,0,0,0) 90%);
}
.cap--hero .cap__marco{
  padding-block: calc(var(--tope) + 2rem) calc(var(--pie-libre) + clamp(3.4rem, 11vh, 6rem));
}
.hero__texto h1{ margin-top: .12em; }
.hero__bajada{ font-family: var(--mono); font-size: clamp(max(.72rem, var(--piso)), 2.7vw, .82rem);
               letter-spacing: .1em; text-transform: uppercase; color: var(--espuma-2);
               margin: clamp(.7rem, 2vh, 1.1rem) 0 0; }
.hero__pie .dato{ color: var(--espuma-2); }

/* ─── cap. 1 · EL TICKET ──────────────────────────────────────── */
.cap--ticket .cap__lienzo{ position: absolute; inset: 0; }
.cap--ticket .caleta{ position: absolute; inset: 0 -8% 0 -8%; }
/* v7 · DEFECTO 1. Éste era el peor contraste de la página en vertical: el
   párrafo blanco caía directo sobre el pueblo —casas naranjas, verdes y
   celestes, todas claras— con el velo genérico, que está pensado para agua.
   La fotografía es aérea y no tiene una zona oscura donde apoyar el texto, así
   que el velo del capítulo se escribe entero: filo arriba, filo abajo y un
   plano parejo más firme. Ningún degradado pasa del 70%, que es el techo. */
.cap--ticket .velo{
  background:
    linear-gradient(to top,    rgba(0,0,0,.70) 0%, rgba(0,0,0,.52) 30%, rgba(0,0,0,.24) 58%, rgba(0,0,0,0) 86%),
    linear-gradient(to bottom, rgba(0,0,0,.46) 0%, rgba(0,0,0,.26) 26%, rgba(0,0,0,.08) 48%, rgba(0,0,0,0) 66%),
    linear-gradient(rgba(0,0,0,.46), rgba(0,0,0,.46));
}
/* Y la prosa de ESTE capítulo va en `--espuma`, no en `--espuma-2`. Es medio
   punto de blanco y evita un cuarto de velo: con la prosa al tono de siempre
   había que enterrar la fotografía bajo un 85% de negro para llegar a AA, y la
   fotografía es el pueblo —lo que el capítulo está contando—. Se sube la letra
   antes que apagar la imagen. Medido: 1,87 : 1 en la v6 → 6,1 : 1. */
.cap--ticket .prosa{ color: var(--espuma); }
.cap--ticket .rotulo{ color: var(--ocre-luz); }
.cap--ticket .filas li{ border-top-color: color-mix(in oklab, var(--ocre) 34%, transparent); }
.cap--ticket .filas li:last-child{ border-bottom-color: color-mix(in oklab, var(--ocre) 34%, transparent); }

/* ─── cap. 2 · ZARPAR ─────────────────────────────────────────── */
.cap--zarpar .cap__lienzo{ position: absolute; inset: 0; }
.abordo{ list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding: 0;
         display: grid; gap: clamp(.55rem, 1.7vh, .95rem); }
.abordo li{ display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .1rem .9rem;
            align-items: baseline; }
.abordo__n{ font-family: var(--mono); font-size: .76rem; letter-spacing: .12em;
            color: var(--corriente-luz); }
.abordo__txt{ display: block; color: var(--espuma-2);
              font-size: clamp(max(.95rem, var(--piso)), min(1.5vw, 2.1vh), 1.0625rem); }
.abordo__txt b{ color: var(--espuma); font-weight: 600; }
.cap--zarpar .estela{ margin: clamp(.9rem, 2.6vh, 1.4rem) 0 0; }
.capitan{ margin-top: clamp(1rem, 3vh, 1.6rem); max-width: min(62vw, 240px); }

/* ─── cap. 3 · EL FRÍO · bajo el agua ─────────────────────────── */
.cap--frio .cap__lienzo{ position: absolute; inset: 0; }
/* Sobrante generoso abajo: la capa sube hasta 16vh con el descenso y sin ese
   margen el borde inferior se despegaba y dejaba una franja del capítulo
   siguiente asomando. */
/* EN VERTICAL LA ESCENA PIERDE UN PUNTO DE LUZ, y es una decisión medida. Acá
   el texto cae A LO LARGO de toda la columna de agua —no tiene una banda
   propia como en escritorio— y algunos fotogramas son el enjambre a
   contraluz: sin atenuar, el titular sobre ellos daba 2,78:1, bajo el 3:1 que
   pide AA para texto grande. Con la escena al 86% da 3,7:1 y el krill se ve
   igual de krill: es un punto de luz, no un apagón.
   Es luz de la fotografía, no velo: el techo del velo (70%) queda intacto.
   En escritorio se retira —el velo lateral ya hace el trabajo—. */
.cap--frio .agua      { position: absolute; inset: -12% -6% -30% -6%; pointer-events: none;
                        filter: brightness(.86); }
.cap--frio .particulas{ position: absolute; inset: -12% -6% -40% -6%; pointer-events: none; }

/* LA COLUMNA DE AGUA · imagen y video GENERADOS (recreación declarada al pie).
   La foto es la que se ve siempre; el video se monta encima cuando el JS le
   pone el `src` —solo en escritorio— y comparte su encuadre exacto. */
.cap--frio .agua > *{
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 58%;
}
.cap--frio .agua__foto.falta{ display: none; }
/* EL CANVAS DEL KRILL (v5), como el del hero: sin JS no existe —queda la
   imagen, que es el fotograma 1— y con JS tiene caja desde el principio,
   transparente y vacía, porque un `display: none` no se puede medir y sin
   medida no hay `cover`. Se enciende cuando el primer fotograma ya está
   pintado dentro. */
.cap--frio .agua__cuadros{ display: none; }
html.js .cap--frio .agua__cuadros{ display: block; opacity: 0; transition: opacity .25s linear; }
html.js .cap--frio .agua__cuadros.listo{ opacity: 1; }
/* La capa media: partículas en suspensión, de distinto tamaño y difusión.
   No son puntos blancos iguales: las cercanas son grandes y difusas. */
.cap--frio .particulas{
  background:
    radial-gradient(3px 3px at 18% 24%, color-mix(in oklab, var(--espuma) 34%, transparent) 0%, transparent 70%),
    radial-gradient(6px 6px at 62% 14%, color-mix(in oklab, var(--espuma) 18%, transparent) 0%, transparent 72%),
    radial-gradient(2px 2px at 80% 42%, color-mix(in oklab, var(--espuma) 40%, transparent) 0%, transparent 70%),
    radial-gradient(8px 8px at 34% 68%, color-mix(in oklab, var(--espuma) 13%, transparent) 0%, transparent 74%),
    radial-gradient(2px 2px at 48% 86%, color-mix(in oklab, var(--espuma) 36%, transparent) 0%, transparent 70%),
    radial-gradient(5px 5px at 88% 78%, color-mix(in oklab, var(--espuma) 16%, transparent) 0%, transparent 74%);
  opacity: .8;
}
/* EL MANCHÓN DE KRILL ya no se dibuja: en la v5 el enjambre es el del video,
   fotograma a fotograma, y los degradados verdes que lo insinuaban solo le
   sumaban luz al fondo —justo donde cae el texto en vertical—. La capa salió
   del HTML y con ella su regla; el gesto de «el krill sube con el visitante»
   lo hace ahora la cámara, que es lo que el guion pedía. */

.cap--frio .versos{ margin-top: clamp(.8rem, 2.4vh, 1.2rem); }

/* LA PLACA DEL DRON · la protagonista del capítulo, y la corrección que pedía
   la v2. Va en el FLUJO del texto —como la placa del capitán en el capítulo
   2—, así que en vertical se apila donde le toca y en escritorio se posa a la
   derecha del pin. Lleva su propio brillo: el velo del agua y el apagón del
   descenso quedan detrás, en el fondo, y no encima de ella. */
.dron{
  margin-top: clamp(1rem, 3vh, 1.5rem);
  max-width: min(72vw, 300px);
  border-color: color-mix(in oklab, var(--corriente-luz) 34%, transparent);
  box-shadow: 0 18px 44px rgba(0,0,0,.45);
}
.dron img{ object-position: 50% 42%; filter: saturate(1.06) contrast(1.05); }
/* En vertical el capítulo pierde el descenso; gana la regla con los tres
   datos de profundidad. Es la compensación explícita del guion. */
.profundidades{
  list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding-left: 1rem;
  border-left: 1px solid var(--corriente);
  display: grid; gap: clamp(.5rem, 1.6vh, .9rem);
  font-family: var(--mono); font-size: max(11px, .72rem); letter-spacing: .14em;
  color: var(--camanchaca); font-variant-numeric: tabular-nums;
}

/* Los versos que entran uno a uno: líneas cortas, una bajo otra. */
.versos{ list-style: none; margin: 0; padding: 0;
         display: grid; gap: clamp(.3rem, 1.1vh, .6rem); }
.versos li{ font-family: var(--display); font-weight: 500;
            font-size: clamp(1.1rem, min(4.2vw, 2.8vh), 1.5rem);
            line-height: 1.26; color: var(--espuma); }
.versos li > span { display: block; }

/* ─── cap. 4 · EL ENCUENTRO ───────────────────────────────────── */
.cap--encuentro .cap__lienzo{ position: absolute; inset: 0; }
.cap--encuentro .mar{ position: absolute; inset: 0; }
/* LA CAPA DEL ENCUENTRO. La segunda fotografía se funde sobre la primera en
   el punto más alto del recorrido. Su estado de reposo es visible: sin JS las
   dos fotos quedan puestas y el capítulo se lee. */
.revelado{ z-index: 1; }

/* La ballena fin, silueta y RED DE SEGURIDAD. Nunca una orca.
   Anatomía: cuerpo muy largo y esbelto (7,5:1), rostro puntiagudo, aleta
   dorsal PEQUEÑA, falcada y en el último tercio, pectoral corta y cola
   horizontal ancha. El ancho es una variable porque de él depende que el
   animal QUEPA ENTERO en algún fotograma del cruce.
   Con la fotografía puesta, la silueta se retira: una silueta dibujada encima
   de una ballena de verdad la ensucia. */
.ballena{ display: none; }
.placa--fondo.falta ~ .ballena{ display: block; }
.ballena{
  --ancho-ballena: min(86vw, 430px);
  position: absolute; z-index: 1; top: 44%;
  left: calc(50% - var(--ancho-ballena) / 2);
  width: var(--ancho-ballena);
  transform: translate3d(0, -50%, 0);
  opacity: .9;
}
.ballena svg{ width: 100%; height: auto; overflow: visible; }
.ballena path{ fill: color-mix(in oklab, var(--abisal) 58%, var(--espuma-2)); }

.especies{ list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding: 0;
           display: grid; gap: clamp(.8rem, 2.2vh, 1.2rem); }
.especie{ display: grid; gap: .22rem;
          border-top: 1px solid var(--borde-2); padding-top: clamp(.6rem, 1.7vh, .95rem); }
.especie p{ margin: 0; color: var(--espuma-2); font-size: .95em; }
.especie .dato{ margin-top: .2rem; color: var(--corriente-luz); }

/* CÓMO LAS ENCONTRAMOS · el bloque que reemplaza al «pre-avistamiento» de la
   v2. Son tres cosas concretas contadas por el cliente, así que se numeran
   como la ficha de a bordo: la numeración dice «esto es un método», que es
   justo lo que la frase anterior prometía sin poder demostrar. */
.hallazgo{
  margin-top: clamp(1rem, 3vh, 1.5rem);
  border-left: 1px solid var(--corriente);
  padding-left: clamp(.9rem, 2.4vw, 1.3rem);
}
.hallazgo h3{ margin-bottom: clamp(.5rem, 1.6vh, .8rem); }
.hallazgo__lista{ list-style: none; margin: 0 0 clamp(.7rem, 2vh, 1rem); padding: 0;
                  display: grid; gap: clamp(.5rem, 1.6vh, .85rem); }
.hallazgo__lista li{ display: grid; grid-template-columns: auto minmax(0, 1fr);
                     gap: .1rem .9rem; align-items: baseline; }
.hallazgo__lista b{ font-family: var(--mono); font-weight: 500; font-size: .76rem;
                    letter-spacing: .12em; color: var(--corriente-luz); }
.hallazgo__lista span{ color: var(--espuma-2);
                       font-size: clamp(max(.95rem, var(--piso)), min(1.5vw, 2.1vh), 1.0625rem); }
.hallazgo__lista span b{ font-family: var(--texto); font-size: inherit; letter-spacing: normal;
                         color: var(--espuma); font-weight: 600; text-transform: none; }

/* LA TIRA DE LAS TRES ESPECIES · en la banda del capítulo 4, fuera del pin.
   Las fichas del pin nombran las tres ballenas; acá se ven. Una foto por
   especie, el mismo recorte para las tres, y el pie en mono dice cuál es. */
.tira{ display: grid; gap: 8px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tira .placa{ aspect-ratio: 4 / 3; }
.tira > :last-child:nth-child(odd){ grid-column: 1 / -1; }
/* La jorobada arrastra el margen que tenía cuando era la única placa de la
   banda: dentro de la tira las tres miden igual. */
.tira .jorobada{ margin-bottom: 0; }

/* ─── cap. 5 · LOS VECINOS ────────────────────────────────────── */
.cap--vecinos .cap__lienzo{ position: absolute; inset: 0; }
.anio{
  font-family: var(--mono); font-weight: 500;
  font-size: clamp(2.2rem, min(9vw, 7vh), 4.2rem);
  letter-spacing: .04em; color: var(--corriente-luz);
  font-variant-numeric: tabular-nums; line-height: 1;
  margin: clamp(.6rem, 2vh, 1rem) 0 0;
}
.muro{
  position: relative; z-index: 2;
  padding-inline: var(--sangra);
  padding-block: clamp(1.8rem, 5vh, 2.8rem)
                 calc(clamp(2rem, 6vh, 3rem) + var(--pie-libre));
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
}
/* Las cinco son columna, también en vertical: con foto en las cinco, estirar
   la quinta a lo ancho de la pantalla le cambiaba el recorte a la única que
   no lo comparte. La rejilla de dos deja una celda libre al final y el muro
   se sigue leyendo como una sola pieza. */
/* EL MURO SE LEE COMO UNA SOLA PIEZA. Las cinco filas de cada tarjeta ocupan
   el mismo alto: la imagen (o su hueco), el nombre, la descripción y el dato.
   Sin esto, con tres fotos y dos fichas el muro era una escalera. */
.vecino{ margin: 0; display: grid; gap: .5rem; align-content: start;
         grid-template-rows: auto auto; }
.vecino figcaption{ display: grid; gap: .25rem; align-content: start; }
/* El mismo recorte para las cinco: 4:5, el de la placa alta de la casa. */
.vecino .placa{ width: 100%; height: auto; aspect-ratio: 4 / 5; }
/* La ficha sin foto —hoy no la usa nadie, y es a propósito: es el molde para
   el día que entre un vecino cuya fotografía todavía no llegó—. No se lee como
   una imagen que no cargó: lleva borde de 1px, vive sobre `--profundo` y ocupa
   el mismo 4:5 que las placas, así el muro no se desalinea. */
.vecino--ficha .vecino__hueco{
  aspect-ratio: 4 / 5;
  border: 1px solid var(--borde); border-radius: 3px;
  background: var(--profundo);
  display: grid; align-content: center; justify-items: center;
  padding: clamp(.8rem, 2.4vh, 1.1rem); text-align: center;
  gap: .5rem;
}
.vecino--ficha .vecino__hueco .dato{ color: var(--niebla); margin: 0; }
.vecino p{ margin: 0; color: var(--espuma-2); font-size: .92em; }
.vecino .dato{ color: var(--camanchaca); }
/* La línea de cierre: lo que se ve en la reserva y todavía no está en sus
   fotos. No es un pie de página, es contenido, así que va en cuerpo de lectura
   y no en mono. */
.muro__cierre{
  grid-column: 1 / -1; margin: clamp(.9rem, 2.6vh, 1.4rem) 0 0;
  color: var(--espuma-2); max-width: 62ch;
}
.muro__cierre b{ color: var(--espuma); font-weight: 600; }
.muro__pie{
  grid-column: 1 / -1; margin: clamp(.6rem, 2vh, 1rem) 0 0; text-align: center;
}

/* ─── cap. 6 · CUÁNDO VENIR ───────────────────────────────────── */
.cap--calendario .cap__marco{ display: grid; align-content: center;
                              gap: clamp(1rem, 3vh, 1.8rem); }
.calendario{ margin-top: clamp(1rem, 3vh, 1.6rem); }
.meses{
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 2px;
}
.mes{
  padding-block: clamp(.34rem, 1.3vh, .8rem);
  text-align: center;
  font-family: var(--mono);
  font-size: clamp(max(.66rem, var(--piso)), min(1.1vw, 1.6vh), .8125rem);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--espuma); background: color-mix(in oklab, var(--espuma) 7%, transparent);
  border-radius: 2px;
  opacity: 1;
}
.bandas{ display: grid; margin-top: clamp(.6rem, 2vh, 1rem); }
.franja{ display: grid; gap: .3rem; margin-block: clamp(.3rem, 1.1vh, .7rem); }
.franja__pista{ position: relative; height: clamp(6px, 1.2vh, 12px);
                background: color-mix(in oklab, var(--espuma) 6%, transparent);
                border-radius: 2px; overflow: clip; }
.banda-mes{
  position: absolute; top: 0; bottom: 0;
  left: calc(var(--ini) / 12 * 100%);
  width: calc(var(--largo) / 12 * 100%);
  background: var(--tinte, var(--corriente));
  border-radius: 2px; transform-origin: left;
}
.franja__rotulo{ display: flex; flex-wrap: wrap; gap: .3rem .8rem; align-items: baseline;
                 font-family: var(--mono); font-size: max(11px, .7rem);
                 letter-spacing: .1em; text-transform: uppercase; color: var(--camanchaca); }
.franja__rotulo em{ font-style: normal; color: var(--espuma-2); }
.franja--diversidad .franja__pista{ background: none; height: 1px;
                                    border-top: 1px solid var(--espuma-2); }
.franja--diversidad .banda-mes{ background: var(--espuma-2); height: 1px; top: 0; bottom: auto; }

/* ─── cap. 7 · LA FAMILIA ─────────────────────────────────────── */
.cap--familia .cap__lienzo{ position: absolute; inset: 0; }

/* EL CANVAS DE LA COLA (v6), como el del hero y el del krill: sin JS no existe
   —queda la fotografía, que es el fotograma 1 y es el `og:image`— y con JS
   tiene caja desde el principio, transparente y vacía, porque un
   `display: none` no se puede medir y sin medida no hay `cover`. Se enciende
   cuando el primer fotograma ya está pintado dentro, y ése es el que ya está
   debajo: el cambio no se ve. Vive DENTRO de la placa a sangre, así que el
   velo —que es hermano de la placa— le sigue quedando encima. */
.cap--familia .placa__cuadros{
  display: none;
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0;
}
html.js .cap--familia .placa__cuadros{ display: block; opacity: 0; transition: opacity .25s linear; }
html.js .cap--familia .placa__cuadros.listo{ opacity: 1; }
/* Si la fotografía falta, el capítulo cae a su agua pintada: el canvas se va
   con ella y no deja un rectángulo negro sobre el mar de la página. */
.cap--familia .placa--fondo.falta .placa__cuadros{ display: none; }

/* EL VELO DEL CAPÍTULO 7 EN VERTICAL (v6). Acá el texto cae a lo largo de toda
   la columna —no tiene banda propia como en escritorio— y la secuencia se
   ACLARA hacia el final: cuando la cola se hunde quedan el mar quieto y la
   costa del desierto a plena luz. El velo gana el filo de arriba que le
   faltaba, que es donde vive el titular, y un punto más de tinta plana.
   El techo del velo (70%) queda intacto. */
.cap--familia .velo{
  background:
    linear-gradient(to top,    rgba(0,0,0,.70) 0%, rgba(0,0,0,.42) 34%, rgba(0,0,0,0) 72%),
    linear-gradient(to bottom, rgba(0,0,0,.30) 0%, rgba(0,0,0,.17) 28%, rgba(0,0,0,.06) 46%, rgba(0,0,0,0) 64%),
    linear-gradient(rgba(0,0,0,.36), rgba(0,0,0,.36));
}
.ficha{ list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding: 0; display: grid; }
.ficha li{ position: relative; padding-block: clamp(.34rem, 1.1vh, .7rem);
           display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .3rem 1rem;
           align-items: baseline; }
.fila__regla{ position: absolute; left: 0; right: 0; top: 0; height: 1px;
              background: var(--corriente); transform-origin: left; }
.ficha__n{ font-family: var(--mono); font-size: .74rem; letter-spacing: .12em;
           color: var(--corriente-luz); }
.ficha__v{ font-family: var(--mono);
           font-size: clamp(max(.78rem, var(--piso)), min(1.2vw, 1.8vh), .9rem);
           letter-spacing: .1em; text-transform: uppercase; color: var(--espuma); }
.ficha__v.falta-dato{ color: var(--niebla); }
.nombre-orca{ margin-top: clamp(.8rem, 2.4vh, 1.2rem); color: var(--espuma-2);
              font-size: .94em; max-width: 46ch; }

/* ─── 7.5 · LOS QUE YA SUBIERON · las reseñas · v7 ─────────────
   Entre el capítulo 7 y la banda de preguntas: ahí el visitante ya sabe
   quiénes son y todavía no pregunta el precio, que es el punto donde una voz
   ajena pesa. SIN PIN Y SIN EFECTO, igual que la banda de preguntas: tiene que
   leerse aunque el motor de scroll no arranque.
   Lo que esta sección NO tiene, y es una decisión: estrellas dibujadas,
   comillas gigantes de adorno, fotos de perfil. Solo el texto en Newsreader y
   el crédito en mono, con la estela de 1px encima. La puntuación se muestra si
   existe; un relato de prensa no lleva estrellas inventadas. */
.resenas{
  position: relative; z-index: 2;
  background: color-mix(in oklab, var(--abisal) 84%, var(--profundo));
  border-top: 1px solid var(--borde-2);
}
.resenas .cap__marco{ display: grid; gap: clamp(1rem, 3vh, 1.5rem); }
/* La nota agregada. Mientras no lleguen la nota y el volumen de Google se ve
   FALTAR, igual que el punto de venta del capítulo 1: un 4,9 sin fuente es
   justo lo que el levantamiento de reseñas existe para impedir. */
.resenas__nota{ margin: clamp(.7rem, 2.2vh, 1.1rem) 0 0; color: var(--niebla); }
.resenas__intro{ max-width: 54ch; }
.resenas__intro p{ margin-bottom: .4em; }

/* LA TIRA. En teléfono es una tira de verdad: se desplaza de lado, con la
   siguiente ficha asomando —que es lo que dice que hay más— y el desplazamiento
   contenido, para que no se lo robe el documento. En escritorio se abre en
   rejilla de tres y las seis se leen sin arrastrar nada.
   Los márgenes negativos sacan la tira a sangre y el relleno le devuelve la
   sangría: así la primera ficha arranca alineada con el texto y la última no
   queda pegada al filo. */
.resenas__tira{
  list-style: none; margin: 0 calc(var(--sangra) * -1); padding: .2rem var(--sangra) .8rem;
  display: grid; grid-auto-flow: column; grid-auto-columns: min(76vw, 300px);
  gap: 10px; align-items: stretch;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.resena{
  scroll-snap-align: start; margin: 0;
  display: flex; flex-direction: column; gap: .65rem;
  background: color-mix(in oklab, var(--profundo) 70%, transparent);
  border: 1px solid var(--borde); border-radius: 4px;
  padding: clamp(.9rem, 2.6vh, 1.2rem) clamp(1rem, 3vw, 1.25rem);
}
/* Texto literal: no se corrige la ortografía, no se arregla la redacción, no
   se cambia una palabra. Si hay que acortar se corta con […] y nunca en mitad
   de una idea. */
.resena__texto{
  margin: 0; font-family: var(--display); font-weight: 500;
  font-size: clamp(1rem, min(3.4vw, 2.2vh), 1.12rem); line-height: 1.34;
  color: var(--espuma);
}
/* La traducción, en las páginas en inglés y en francés. La reseña se muestra en
   SU idioma y la traducción va debajo, más chica y con su rótulo: traducir una
   reseña y presentarla como original sería inventarla. */
.resena__trad{ margin: 0; color: var(--espuma-2); font-size: .92em; line-height: 1.5; }
.resena__rot{
  display: block; margin-top: .35rem;
  font-family: var(--mono); font-size: max(10px, .62rem); letter-spacing: .12em;
  text-transform: uppercase; color: var(--niebla);
}
/* El crédito, en mono, con la estela de 1px encima. El enlace va en la
   PLATAFORMA, no en el nombre de la persona. */
.resena__credito{
  margin: .2rem 0 0; padding-top: .7rem; margin-top: auto;
  border-top: 1px solid var(--corriente); color: var(--camanchaca);
}
.resena__credito a{ color: var(--corriente-luz); }
/* La sexta ficha se ve faltar. No se inventa un testimonio: o llega la reseña
   de Google o de TripAdvisor, o la tira baja a cinco. */
.resena--falta{ background: none; border-style: dashed; }
.resena--falta .resena__texto{
  font-family: var(--texto); font-weight: 400; color: var(--niebla);
  font-size: clamp(max(.86rem, var(--piso)), 3vw, .94rem); line-height: 1.55;
}
.resena--falta .resena__credito{ border-top-color: var(--borde); color: var(--niebla); }
/* Mientras las fichas sean relatos de prensa, la línea que lo dice es
   obligatoria. El día que lleguen las reseñas de plataforma, se reemplaza. */
.resenas__prensa{
  margin: 0; color: var(--niebla); max-width: 62ch;
  font-size: clamp(max(.78rem, var(--piso)), 2.8vw, .84rem); line-height: 1.55;
}

/* ─── la banda de preguntas · fuera del pin ───────────────────── */
.preguntas{ background: var(--profundo); }
.preguntas .cap__marco{ display: grid; gap: clamp(1.2rem, 3.4vh, 1.8rem); }
.pregunta{ border-top: 1px solid var(--borde); padding-top: clamp(.8rem, 2.2vh, 1.1rem); }
.pregunta h3{ margin-bottom: .3rem; }
.pregunta p{ color: var(--espuma-2); max-width: 62ch; margin: 0; }

/* ─── cap. 8 · RESERVA · cierre ───────────────────────────────── */
.cap--cierre .cap__lienzo{ position: absolute; inset: 0; }
.cap--cierre .rotulo{ color: var(--ocre-luz); }
.cierre__caja{ max-width: var(--medida); position: relative; }
.camino{ position: absolute; left: -.9rem; top: 22%; bottom: 6%; width: 1px;
         background: var(--ocre); transform-origin: top; }
.tramos{ list-style: none; margin: clamp(1rem, 3vh, 1.5rem) 0 0; padding-left: clamp(1rem, 3vw, 1.6rem);
         display: grid; gap: clamp(.6rem, 1.9vh, 1rem); }
.tramo{ display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .2rem .9rem;
        align-items: baseline; }
.tramo__n{ font-family: var(--mono); font-size: .74rem; letter-spacing: .12em; color: var(--ocre-luz); }
.tramo__txt{ display: block; color: var(--espuma-2); }
.tramo__txt b{ color: var(--espuma); font-weight: 600; }
/* ─── «LO QUE TIENES QUE SABER» · los cuatro datos, antes de los botones ───
   Es el bloque que contesta lo que el visitante pregunta antes de escribir:
   cuánto, para quién, en qué lancha y qué pasa si el mar cierra. El precio va
   grande porque es honesto decirlo así, y la letra chica va pegada a él y no
   escondida abajo. */
.saber{
  margin-top: clamp(1rem, 3vh, 1.5rem);
  border: 1px solid var(--borde); border-radius: 4px;
  background: color-mix(in oklab, var(--profundo) 82%, transparent);
  padding: clamp(.9rem, 2.6vh, 1.3rem) clamp(1rem, 3vw, 1.4rem);
}
.saber__titulo{ margin: 0; }   /* la voz la pone `.rotulo`: una sola escala en la hoja */
.precio{
  display: flex; align-items: baseline; flex-wrap: wrap; gap: .1rem .55rem;
  margin: clamp(.35rem, 1.2vh, .6rem) 0 0;
}
.precio b{
  font-family: var(--display); font-weight: 600;
  font-size: clamp(2rem, min(8vw, 5.4vh), 3rem); line-height: 1;
  letter-spacing: -.02em; color: var(--espuma);
  font-variant-numeric: tabular-nums;
}
.precio span{ color: var(--espuma-2); font-size: clamp(.95rem, 3.4vw, 1.05rem); }
.precio__pie{ margin-top: .3rem; color: var(--corriente-luz); }
.saber__lista{
  list-style: none; margin: clamp(.7rem, 2.2vh, 1.1rem) 0 0; padding: 0;
  display: grid;
}
.saber__lista li{
  display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: .2rem 1rem; align-items: baseline;
  padding-block: clamp(.4rem, 1.3vh, .65rem);
  border-top: 1px solid var(--borde-2);
}
.saber__lista b{
  font-family: var(--mono); font-weight: 500;
  font-size: clamp(max(.7rem, var(--piso)), 2.5vw, .78rem);
  letter-spacing: .12em; text-transform: uppercase; color: var(--camanchaca);
  white-space: nowrap;
}
.saber__lista span{ color: var(--espuma-2); font-size: .95em; }

.botones{ display: grid; gap: .6rem; margin: clamp(1.2rem, 3.4vh, 1.8rem) 0 0;
          justify-items: stretch; }
.btn{
  display: block; text-align: left;
  min-height: 48px; padding: .85rem 1.15rem; border-radius: 6px; line-height: 1.4;
  text-decoration: none; font-weight: 600;
  font-size: clamp(.9rem, 3.2vw, 1rem);
  background: var(--corriente);
  border: 1px solid var(--corriente);
  color: var(--espuma);
  transition: background .25s linear, color .25s linear, border-color .25s linear;
}
.btn:hover, .btn:focus-visible{ border-color: var(--corriente-claro); color: var(--espuma); }
/* v7 · DEFECTO 4. Los dos botones de línea —las filas 2 y 3 del cierre— vivían
   sobre `transparent`. En vertical el velo del capítulo trae un plano parejo y
   se leían; en escritorio el velo es LATERAL y los botones están en la columna
   derecha, donde ese velo ya se apagó: el enlace turquesa quedaba sobre la foto
   aérea a plena luz. La fila 1 nunca tuvo el problema porque su relleno es el
   verde de la corriente. Ahora las tres llevan tinta propia; la de línea es
   abisal translúcida, así que sigue siendo el botón secundario y no compite. */
.btn--linea{
  background: color-mix(in oklab, var(--abisal) 78%, transparent);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  border-color: var(--borde); color: var(--espuma);
}
.btn--linea:hover, .btn--linea:focus-visible{ border-color: var(--corriente-claro); color: var(--corriente-claro); }
.salidas{ margin-top: clamp(1rem, 3vh, 1.5rem); display: grid; gap: .5rem;
          font-size: .96em; color: var(--espuma-2); }

/* ─── PIE ─────────────────────────────────────────────────────── */
.pie{
  position: relative; z-index: 1;
  background: var(--profundo);
  border-top: 1px solid var(--borde);
  padding-inline: var(--sangra);
  padding-block: clamp(2.4rem, 7vh, 3.4rem) calc(clamp(2.4rem, 7vh, 3.4rem) + var(--pie-libre));
  display: grid; gap: .9rem;
}
.pie p{ margin: 0; }
/* [DATO PENDIENTE] pedir el logo en versión blanca o en vector. El archivo que
   publican es negro sobre transparente y sobre este mar no se ve: se invierte,
   que es su propio trazo en negativo, y no se rediseña nada. */
.pie__logo{ width: clamp(56px, 16vw, 78px); height: auto; margin-bottom: .3rem;
            filter: invert(1); }
.pie__marca{ font-family: var(--display); font-size: 1.2rem; font-weight: 600; color: var(--espuma); }
.pie__linea{ color: var(--espuma-2); font-size: .95rem; }
.pie__datos{ display: grid; gap: .3rem; }
.pie__enlaces{ display: flex; flex-wrap: wrap; gap: 1rem; }
.pie__enlaces a{ font-family: var(--mono); font-size: max(11px, .72rem);
                 letter-spacing: .1em; text-transform: uppercase; }
/* El selector de idioma, repetido al pie con los nombres enteros: el visitante
   que llegó hasta acá ya no está mirando la barra. */
.pie__idiomas{ gap: .5rem; font-size: max(11px, .72rem); }
.pie__idiomas a{ color: var(--corriente-luz); }
.pie__idiomas .activo{ color: var(--espuma); }
.pie__credito{ color: var(--espuma-2); font-size: .95rem; }
.pie__nota{ font-family: var(--mono); font-size: max(10px, .66rem); letter-spacing: .04em;
            color: var(--niebla); max-width: 54ch; line-height: 1.6; text-transform: none; }

/* ═══════════ 4b · ENCUADRES ═══════════
   `cover` + `object-position` decidido escena por escena, para vertical y para
   escritorio. NINGUNA foto se queda en `50% 50%` por defecto: cada una está
   escrita mirando el archivo y decidiendo qué sujeto debe sobrevivir al
   recorte. Los valores de acá son los VERTICALES; el bloque A trae los de
   escritorio. */
.cap--ticket   .placa--fondo img{ object-position: 58% 62%; } /* la poza y los botes */
.cierre__foto  img          { object-position: 34% 46%; }     /* el otro extremo de la caleta */
.cap--zarpar   .placa--fondo img{ object-position: 50% 40%; } /* la lancha y los chalecos */
.capitan       img          { object-position: 50% 28%; }     /* su mirada y el horizonte */
.cap--encuentro .placa--fondo img{ object-position: 50% 62%; }/* la boca abierta, no el cielo */
.cap--encuentro .revelado img{ object-position: 54% 52%; }    /* la lancha y la ballena */
.jorobada      img          { object-position: 50% 38%; }     /* la aleta pectoral blanca */
.cap--vecinos  .placa--fondo img{ object-position: 46% 56%; } /* los dorsos y el hocico */
.cap--familia  .placa--fondo img{ object-position: 50% 54%; } /* la cola y la costa detrás */
.equipo        img          { object-position: 50% 46%; }     /* la lancha y la cola */
.vecino:nth-child(1) .placa img{ object-position: 54% 34%; }  /* la cabeza del pingüino */
.vecino:nth-child(2) .placa img{ object-position: 46% 44%; }  /* los lobos sobre la roca */
.vecino:nth-child(3) .placa img{ object-position: 56% 42%; }  /* el chungungo sobre la roca */
.vecino:nth-child(4) .placa img{ object-position: 58% 52%; }  /* la cabeza del albatros */
.vecino:nth-child(5) .placa img{ object-position: 56% 48%; }  /* el pico rojo y el ala */

.jorobada{ margin-bottom: .55rem; }
/* Los encuadres de escritorio viven en el BLOQUE A, con el resto del ancho:
   el número 1025 se declara dos veces en toda la hoja y no una más. */

/* ═══════════ EL OCÉANO FIJO ═══════════
   Solo se monta donde hay movimiento. En base no existe: cada capítulo trae su
   propio degradado y la página se lee entera sin una capa fija. */
.oceano{ display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   5 · BLOQUE M — movimiento. Sin número de ancho: una preferencia y una clase.
   Acá viven el océano fijo, el pin del hero (el único que pinea en vertical) y
   la coreografía que no depende del ancho. Bajo `prefers-reduced-motion` el
   bloque entero no aplica: ningún pin se activa, el océano no se monta y la
   landing queda apilada, quieta, y narrando el descenso por color.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference){

  /* --- LA COLUMNA DE AGUA, detrás de todo --- */
  html.js .oceano{
    display: block; position: fixed; inset: 0; z-index: 0; pointer-events: none;
    overflow: clip;
  }
  /* (a) el color. Dos degradados fijos —la superficie y el fondo— y un
     fundido por OPACIDAD entre ellos. Se hace así y no con un `color-mix`
     gobernado por `--depth` porque un degradado a pantalla completa que se
     recalcula en cada fotograma repinta toda la ventana: medido con el
     piloto, ésa era la mitad del costo del scrub. Una opacidad la resuelve el
     compositor y no cuesta nada.
     El fondo NUNCA llega a negro: el tono más hondo es `--mar-fondo`, que es
     verde-azul. Ésa es la corrección 1 de la v2. */
  html.js .oceano__agua{
    position: absolute; inset: 0;
    background: linear-gradient(to bottom,
      var(--mar-sup) 0%, var(--mar-medio) 52%, var(--mar-hondo) 100%);
  }
  html.js .oceano__agua::after{
    content: ""; position: absolute; inset: 0;
    opacity: var(--depth);
    background: linear-gradient(to bottom,
      color-mix(in oklab, var(--mar-sup),   var(--mar-fondo) 82%) 0%,
      color-mix(in oklab, var(--mar-medio), var(--mar-fondo) 90%) 52%,
      var(--mar-fondo) 100%);
  }
  /* (b) LOS HACES DE LUZ. Diagonales, de ancho desigual, y se atenúan con la
     profundidad SIN apagarse: a −60 m queda un 16% y la escena se sigue
     leyendo como columna de agua. Es la corrección 1 de la v2: con opacidad 0
     el fondo negro con puntos se leía como cielo estrellado. */
  html.js .oceano__rayos{
    position: absolute; inset: -30% -40%;
    opacity: calc(.52 - .38 * var(--depth));
    background: repeating-linear-gradient(104deg,
      transparent 0 2.8vw,
      color-mix(in oklab, var(--espuma) 11%, transparent) 2.8vw 3.6vw,
      transparent 3.6vw 6.2vw,
      color-mix(in oklab, var(--corriente-claro) 8%, transparent) 6.2vw 6.9vw,
      transparent 6.9vw 11.4vw,
      color-mix(in oklab, var(--espuma) 5%, transparent) 11.4vw 12.8vw,
      transparent 12.8vw 17.8vw);
    -webkit-mask-image: linear-gradient(174deg, rgba(0,0,0,.98) 0%, rgba(0,0,0,.54) 44%, rgba(0,0,0,.16) 82%, transparent 100%);
            mask-image: linear-gradient(174deg, rgba(0,0,0,.98) 0%, rgba(0,0,0,.54) 44%, rgba(0,0,0,.16) 82%, transparent 100%);
    animation: deriva 38s ease-in-out infinite alternate;
    will-change: transform;
  }
  @keyframes deriva{
    from{ transform: translate3d(-2.2vw, 0, 0) skewX(-.6deg); }
    to  { transform: translate3d(2.2vw, 0, 0)  skewX(.6deg); }
  }
  /* (c) LAS CÁUSTICAS. El movimiento ondulante que hace que el agua se vea
     agua: dos redes de luz que se cruzan, lentas y desfasadas. Solo transform
     y opacidad —compositor puro—, nunca un `filter: blur` animado. */
  html.js .oceano__causticas{
    position: absolute; inset: -20% -20%;
    opacity: calc(.34 * (1 - var(--depth) * .62));
    background:
      radial-gradient(38% 16% at 22% 18%, color-mix(in oklab, var(--corriente-claro) 22%, transparent) 0%, transparent 72%),
      radial-gradient(30% 12% at 68% 34%, color-mix(in oklab, var(--espuma) 14%, transparent) 0%, transparent 74%),
      radial-gradient(44% 18% at 44% 62%, color-mix(in oklab, var(--corriente-claro) 16%, transparent) 0%, transparent 76%),
      radial-gradient(26% 12% at 82% 78%, color-mix(in oklab, var(--espuma) 10%, transparent) 0%, transparent 74%);
    animation: ondula 22s ease-in-out infinite alternate;
    will-change: transform;
  }
  @keyframes ondula{
    from{ transform: translate3d(-1.6vw, -1.2vh, 0) scale(1.02); }
    to  { transform: translate3d(1.8vw, 1.6vh, 0)  scale(1.07); }
  }
  /* (d) LA TURBIDEZ. Neblina que crece hacia el fondo: el agua se vuelve más
     opaca y más verde, no más negra. */
  html.js .oceano__turbidez{
    position: absolute; inset: 0;
    opacity: calc(.14 + .38 * var(--depth));
    background: linear-gradient(to bottom,
      transparent 0%,
      color-mix(in oklab, var(--mar-fondo) 42%, transparent) 46%,
      color-mix(in oklab, var(--mar-fondo) 78%, transparent) 100%);
  }
  /* (e) el plancton: canvas ligero, encendido solo bajo el agua. */
  html.js .oceano__plancton{
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: clamp(0, calc((var(--depth) - .10) * 2.4), .8);
  }
  /* Con el océano montado, los capítulos dejan de pintar su propio mar. */
  html.js .cap{ background: transparent; }
  html.js .cap--calendario,
  html.js .preguntas{ background: color-mix(in oklab, var(--profundo) 88%, transparent); }
  html.js .resenas{ background: color-mix(in oklab, var(--abisal) 86%, transparent); }
  html.js .pie{ background: color-mix(in oklab, var(--profundo) 94%, var(--abisal)); }

  /* --- el pin del HERO: el único que pinea en vertical --- */
  html.js .cap--hero .riel{ height: calc(100dvh + var(--riel-hero, 80vh)); }
  html.js .cap--hero .cap__pin{
    position: sticky; top: 0; height: 100dvh; min-height: 0;
    display: grid; align-content: end; overflow: clip;
  }
  html.js .cap--hero .cap__marco{
    padding-block: calc(var(--tope) + clamp(.8rem, 2.4vh, 1.6rem))
                   calc(var(--pie-libre) + clamp(4.2rem, 12vh, 6rem));
  }

  /* La entrada de los capítulos que no están pineados: una sola vez, por
     observador. Los pineados no entran por clase — los mueve `--p`. */
  html.js :is(.cap, .preguntas, .resenas):not(.pin-activo) .cap__entra{
    opacity: 0; transform: translate3d(0, 20px, 0);
    transition: opacity .7s var(--ease), transform .7s var(--ease);
  }
  html.js :is(.cap, .preguntas, .resenas):not(.pin-activo).is-on .cap__entra{ opacity: 1; transform: none; }

  /* ─── cap. 0 · la cámara se hunde ─────────────────────────────
     Las capas se montan MÁS ALTAS que el pin (−6% arriba, 124% de alto): la
     cámara sube 9–12vh y sin ese sobrante el borde inferior se despegaba y
     dejaba una franja negra de ~75px al pie del hero. */
  html.js .cap--hero .hero__capa{
    top: -6%; height: 124%;
    --e: clamp(0, calc((var(--p, 1) - .06) / .72), 1);
    transform: translate3d(0, calc(var(--hundir) * var(--e) * -1), 0)
               scale(calc(1 + .12 * var(--e)));
    transform-origin: 50% 88%;              /* el pivote está en el agua, no en el cielo */
    will-change: transform;
  }
  html.js .cap--hero .hero__olas{
    --e: clamp(0, calc((var(--p, 1) - .06) / .72), 1);
    transform: translate3d(0, calc(var(--e) * -6vh), 0);
    will-change: transform;
  }
  html.js .cap--hero .velo{
    opacity: calc(.6 + .4 * clamp(0, calc((var(--p, 1) - .18) / .5), 1));
  }
  /* El claim entra en 0.52, la bajada en 0.66 y el dato en 0.74. Como el
     capítulo abre SIN texto, los tres nacen en opacidad 0 y suben con `--p`;
     sin JS `var(--p,1)` los deja los tres puestos. */
  /* El claim entra en 0.38 y se queda en blanco pleno hasta el final del riel.
     (La v4 lo retiraba a 0.72 en el último tramo; Francisco lo vio como un cambio
     de color de las letras y pidió volver a como estaba: 17-sep-2026.) */
  /* El titular, la bajada y el dato ENTRAN AL CARGAR, sobre el primer fotograma —la
     lancha y los delfines— y se quedan en blanco pleno todo el riel. Antes entraban
     con `--p` a 0.38, 0.58 y 0.68: con la foto fija no se notaba; con el video, el
     titular aparecía sobre el fotograma de agua gris (Francisco, 17-sep-2026). */
  @keyframes hero-entra{
    from{ opacity: 0; transform: translate3d(0, 12px, 0); }
    to  { opacity: 1; transform: none; }
  }
  html.js .cap--hero .hero__texto{ opacity: 1; animation: hero-entra .9s .15s ease-out both; }
  html.js .cap--hero .hero__texto > *{ transform: none; }
  html.js .cap--hero .hero__bajada{ opacity: 1; animation: hero-entra .9s .4s ease-out both; }
  html.js .cap--hero .hero__pie{ opacity: 1; animation: hero-entra .9s .6s ease-out both; }
  html.js .cap--hero .hero__pie > *{ transform: none; }
  /* La pista no va ligada al scroll: un elemento que pide movimiento no puede
     depender del movimiento. Entra por temporizador y se va al primer gesto. */
  html.js .pista{ opacity: 0; transition: opacity .6s linear; }
  html.js .pista.is-on{ opacity: 1; }
  html.js .pista.se-fue{ opacity: 0; }
  html.js .pista span{ animation: respira 3.4s ease-in-out infinite; }
  @keyframes respira{ 0%,100%{ opacity: .6 } 50%{ opacity: 1 } }

  /* ─── la píldora se estrena y se retira ─────────────────────── */
  html.js .pildora{
    opacity: 0; transform: translate3d(0, 12px, 0); pointer-events: none;
    transition: opacity .6s var(--ease), transform .6s var(--ease), background .25s linear;
  }
  html.js .pildora.is-on{ opacity: 1; transform: none; pointer-events: auto; }
  html.js .pildora.se-va{ opacity: 0; pointer-events: none; transition: opacity .45s var(--ease); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   6 · BLOQUE A — el único breakpoint de la hoja, solo ancho. Layout, nunca
   movimiento: lo que se mueve distinto en escritorio vive en B.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1025px){
  :root{
    --sangra: max(40px, 5vw);
    --barra-h: 56px;
    --tope: calc(26px + var(--barra-h));
    --pildora-h: 48px;
    --pie-libre: env(safe-area-inset-bottom);
    --medida: 40rem;
    --piso: 0px;
    --hundir: 12vh;
    --paneo: 9vw;
  }

  .cinta{ display: flex; }
  .barra{ top: 26px; }
  .barra__dato{ display: inline; }
  .sonda__dato{ display: block; }
  .pildora{ right: max(40px, 5vw); bottom: 24px; }
  .pildora__largo{ display: inline; }

  .cap__marco{ padding-block: clamp(4.5rem, 11vh, 7rem); }
  .cap__marco--pie{ padding-bottom: clamp(3.2rem, 9vh, 5rem); }
  .banda{ padding-block: clamp(3.2rem, 9vh, 4.6rem); }
  .banda--fina{ padding-block: clamp(1.6rem, 4vh, 2.4rem); }

  /* Los encuadres de escritorio (§4b). Cada uno mirado contra su archivo.
     El hero baja a 62%: a 1440×900 la lancha caía justo sobre la primera línea
     del titular. Con la ventana más abajo, la embarcación sube al tercio alto
     y el claim se lee sobre agua limpia. */
  .hero__foto                     { object-position: 50% 62%; }
  .cap--ticket .placa--fondo img  { object-position: 56% 58%; }
  .cierre__foto img               { object-position: 32% 44%; }
  .cap--zarpar .placa--fondo img  { object-position: 46% 42%; }
  .capitan img                    { object-position: 50% 30%; }
  .cap--frio .agua > *            { object-position: 50% 50%; }
  .cap--encuentro .placa--fondo img{ object-position: 50% 58%; }
  .cap--encuentro .revelado img   { object-position: 52% 50%; }
  .cap--vecinos .placa--fondo img { object-position: 44% 58%; }
  .cap--familia .placa--fondo img { object-position: 50% 46%; }

  /* Dos columnas donde el contenido las pide: el texto a la izquierda, sobre
     el velo lateral, y el aire a la derecha para que respire la fotografía. */
  .cap__col{ max-width: 34rem; }
  /* Y dos columnas de verdad en los capítulos densos (6, 7 y 8): el pin centra
     su contenido, así que lo que se desborda se pierde POR ARRIBA —el rótulo y
     la cabecera— y no por abajo. Repartir en dos columnas es lo que hace que
     quepan a 900 y a 720. */
  .cap__doble{ grid-template-columns: 1fr 1fr; align-items: start;
               gap: clamp(2rem, 4vw, 4rem); max-width: 72rem; }
  .cap__doble .cap__col{ max-width: none; }

  /* La banda en flujo que descarga los capítulos 4, 7 y 8. Mide su contenido
     (ley 5) y queda fuera de la pista. */
  .descarga{ display: grid; grid-template-columns: 1.15fr .85fr;
             gap: clamp(2rem, 4vw, 4rem); align-items: start;
             max-width: 74rem; margin-inline: auto; }
  /* El bloque del hero BAJA. A 1440×900 la primera línea del titular caía
     justo sobre el casco de la lancha: con menos relleno abajo, el texto se
     posa más cerca del pie y la embarcación queda entera, sola, arriba. */
  .cap--hero .cap__marco{ padding-block: calc(var(--tope) + 2.5rem) clamp(2.2rem, 6vh, 3.2rem); }
  .hero__texto{ max-width: 36rem; }
  /* EL VELO LATERAL DEL HERO (v4). Con una fotografía fija bastaba con el filo
     de arriba y el de abajo. Con sesenta fotogramas ya no: algunos son agua
     clara a plena luz y el titular blanco se perdía encima. El velo de la
     izquierda —el mismo que llevan los otros capítulos— le da al claim una
     base pareja en los sesenta, y deja limpia la mitad derecha del cuadro. */
  .cap--hero .velo{
    background:
      linear-gradient(to bottom, rgba(0,0,0,.62) 0%, rgba(0,0,0,.34) 7%, rgba(0,0,0,.10) 13%, rgba(0,0,0,0) 20%),
      linear-gradient(to top,    rgba(0,0,0,.70) 0%, rgba(0,0,0,.58) 22%, rgba(0,0,0,.34) 44%, rgba(0,0,0,0) 78%),
      linear-gradient(90deg,     rgba(0,0,0,.80) 0%, rgba(0,0,0,.66) 28%, rgba(0,0,0,.46) 46%, rgba(0,0,0,.16) 66%, rgba(0,0,0,0) 82%);
  }
  .cap__marco--pie{ display: grid; grid-template-columns: 1.25fr .75fr;
                    align-items: end; gap: clamp(2rem, 4vw, 4rem); }
  .hero__olas{ height: 56%; }

  .cap--ticket .cap__marco,
  .cap--zarpar .cap__marco,
  .cap--frio .cap__marco,
  .cap--encuentro .cap__marco,
  .cap--vecinos .cap__marco,
  .cap--familia .cap__marco,
  .cap--cierre .cap__marco{ display: grid; align-content: center; }

  /* El velo lateral: sobre foto a sangre, el texto vive a la izquierda. */
  .cap--ticket .velo, .cap--zarpar .velo, .cap--frio .velo, .cap--encuentro .velo,
  .cap--vecinos .velo, .cap--familia .velo, .cap--cierre .velo{
    background:
      linear-gradient(to top,  rgba(0,0,0,.52) 0%, rgba(0,0,0,0) 62%),
      linear-gradient(90deg,   rgba(0,0,0,.70) 0%, rgba(0,0,0,.34) 46%, rgba(0,0,0,0) 78%);
  }
  /* v7 · DEFECTO 1 en escritorio. El mismo párrafo cruza el pueblo y sigue
     sobre el mar claro, más allá de donde el velo lateral común se apaga. Su
     velo llega más lejos y suma el filo de abajo entero; la mitad derecha del
     cuadro —la poza y los botes— sigue limpia. */
  .cap--ticket .velo{
    background:
      linear-gradient(to top,  rgba(0,0,0,.58) 0%, rgba(0,0,0,.28) 34%, rgba(0,0,0,0) 70%),
      linear-gradient(90deg,   rgba(0,0,0,.82) 0%, rgba(0,0,0,.70) 30%, rgba(0,0,0,.48) 48%, rgba(0,0,0,.18) 68%, rgba(0,0,0,0) 84%);
  }
  /* El encuentro reparte tres fichas a lo ancho de la columna: su velo lateral
     alcanza más lejos para que la tercera no caiga sobre el lomo iluminado. */
  .cap--encuentro .velo{
    background:
      linear-gradient(to top,  rgba(0,0,0,.52) 0%, rgba(0,0,0,0) 62%),
      linear-gradient(90deg,   rgba(0,0,0,.72) 0%, rgba(0,0,0,.56) 34%, rgba(0,0,0,.24) 62%, rgba(0,0,0,0) 88%);
  }

  .capitan{ position: absolute; right: max(40px, 5vw); bottom: clamp(3rem, 9vh, 5rem);
            width: min(20vw, 240px); max-width: none; margin: 0; }
  .cap--zarpar .cap__marco{ position: relative; }

  .cap--frio .cap__col{ max-width: 32rem; }
  /* La placa del dron se posa a la derecha del pin, como la del capitán en el
     capítulo 2: el texto vive a la izquierda sobre el velo lateral y la
     fotografía ocupa el aire que le queda. */
  .cap--frio .agua{ filter: none; }    /* en escritorio manda el velo lateral */
  .cap--frio .cap__marco{ position: relative; }
  .dron{ max-width: min(32vw, 340px); }
  /* El agua de este capítulo es clara, y con sesenta fotogramas lo es de
     distintas maneras: al final del riel la cámara está dentro del enjambre,
     con los haces de luz encima, y ahí el titular blanco se caía del contraste.
     El velo lateral llega más lejos que en la v4 —medido, no estimado— y la
     mitad derecha del cuadro, donde vive la placa del dron, sigue limpia. */
  .cap--frio .velo{
    background:
      linear-gradient(to top,  rgba(0,0,0,.52) 0%, rgba(0,0,0,0) 62%),
      linear-gradient(90deg,   rgba(0,0,0,.84) 0%, rgba(0,0,0,.70) 26%, rgba(0,0,0,.52) 44%, rgba(0,0,0,.24) 62%, rgba(0,0,0,0) 80%);
  }
  /* v6 · EL VELO DEL CAPÍTULO 7. Con la fotografía sola bastaba el velo lateral
     común. Con sesenta fotogramas no: a mitad del riel la cola chorrea espuma
     blanca justo donde cae el titular, y al final quedan el mar quieto y la
     costa iluminada. El velo lateral llega más lejos —medido sobre los sesenta
     con `respaldo/contraste.mjs`, no estimado— y la mitad derecha del cuadro,
     donde la cola se hunde, sigue limpia. */
  .cap--familia .velo{
    background:
      linear-gradient(to top,  rgba(0,0,0,.52) 0%, rgba(0,0,0,0) 62%),
      linear-gradient(90deg,   rgba(0,0,0,.82) 0%, rgba(0,0,0,.68) 26%, rgba(0,0,0,.48) 46%, rgba(0,0,0,.18) 66%, rgba(0,0,0,0) 82%);
  }
  /* Sacarla del flujo es cosa del pin, así que vive en el BLOQUE B: bajo
     `reduced-motion` no hay pantalla pineada que la sostenga y la placa se
     queda donde el texto la dejó. */

  .cap--encuentro .cap__col{ max-width: 46rem; }
  /* La banda del encuentro va a una sola columna: la tira de las tres especies
     necesita el ancho entero para que las tres se lean del mismo tamaño. */
  .cap--encuentro .descarga{ grid-template-columns: minmax(0, 1fr); }
  .tira{ grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(.8rem, 1.6vw, 1.2rem); }
  .tira > :last-child:nth-child(odd){ grid-column: auto; }

  .especies{ grid-template-columns: repeat(3, minmax(0, 1fr));
             gap: clamp(1rem, 2.2vw, 2rem); }
  .especie{ align-content: start; }

  .muro{ grid-template-columns: repeat(5, minmax(0, 1fr));
         padding-block: clamp(2rem, 6vh, 3rem); }

  .meses{ grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .cap--calendario .cap__marco{ max-width: 68rem; margin-inline: auto; width: 100%; }
  .calendario{ max-width: none; }

  .preguntas .cap__marco{ grid-template-columns: repeat(2, minmax(0, 1fr));
                          column-gap: clamp(2rem, 4vw, 4rem); max-width: 72rem;
                          margin-inline: auto; width: 100%; }
  .preguntas .preguntas__cabeza{ grid-column: 1 / -1; }

  /* LAS RESEÑAS EN ESCRITORIO. La tira lateral es el gesto del teléfono; acá
     hay ancho para las seis y arrastrar sería trabajo regalado: rejilla de
     tres, dos filas, y las seis se leen sin tocar nada. */
  .resenas .cap__marco{ max-width: 72rem; margin-inline: auto; width: 100%; }
  .resenas__tira{
    margin-inline: 0; padding-inline: 0; overflow: visible;
    grid-auto-flow: row; grid-auto-columns: auto;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(.8rem, 1.6vw, 1.2rem);
  }

  /* El cierre en dos columnas: el camino a la izquierda, lo que hay que saber
     y los botones a la derecha. Con el bloque nuevo puesto, una sola columna
     no cabía en la pantalla pineada a 720 px de alto. */
  .cierre__caja{ max-width: 72rem; }
  .cierre__caja .cap__doble{ margin-top: clamp(1rem, 3vh, 1.6rem); }
  /* En escritorio los cuatro datos se reparten en dos por dos, con el rótulo
     encima de su línea. Es lo que hace que el cierre entero —titular, camino,
     precio, los cuatro datos y los tres botones— quepa en la pantalla pineada
     a 720 px de alto, que es el alto más apretado de la puerta. */
  .saber{ margin-top: 0; padding: clamp(.7rem, 1.8vh, .95rem) clamp(.8rem, 1.8vw, 1.1rem); }
  .precio{ margin-top: .25rem; }
  .precio b{ font-size: clamp(1.8rem, min(4.4vw, 4.6vh), 2.5rem); }
  .precio__pie{ margin-top: .15rem; }
  .saber__lista{ grid-template-columns: repeat(2, minmax(0, 1fr));
                 column-gap: clamp(1rem, 2vw, 1.6rem);
                 margin-top: clamp(.5rem, 1.6vh, .9rem); }
  .saber__lista li{ grid-template-columns: minmax(0, 1fr); gap: .05rem;
                    padding-block: clamp(.28rem, .9vh, .45rem); }
  .saber__lista span{ font-size: .88em; line-height: 1.45; }
  .botones{ grid-auto-flow: row; justify-items: stretch;
            margin-top: clamp(.7rem, 1.8vh, 1rem); gap: .45rem; }
  .botones .btn{ max-width: 34rem; padding-block: .6rem; }  /* los 48px de alto, intactos */

  .pie{ grid-template-columns: 1fr auto; align-items: end; column-gap: 3rem;
        padding-block: clamp(3rem, 8vh, 4.5rem); }
  .pie__logo, .pie__marca, .pie__linea, .pie__datos,
  .pie__idiomas, .pie__credito{ grid-column: 1; }
  .pie__enlaces{ grid-column: 2; grid-row: 1 / span 4; justify-content: end;
                 align-content: start; display: grid; gap: .5rem; }
  .pie__nota{ grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   7 · BLOQUE B — el mismo breakpoint, ancho + movimiento. Acá se pinean los
   ocho capítulos restantes y vive toda la coreografía que el guion pide.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1025px) and (prefers-reduced-motion: no-preference){

  /* --- el pin. Ningún sticky más alto que la pantalla: `100dvh`, exacto. --- */
  html.js .cap--riel .riel{ height: calc(100dvh + var(--pista, 100vh)); }
  html.js .cap--riel .cap__pin{
    position: sticky; top: 0; height: 100dvh; min-height: 0;
    display: grid; align-content: center; overflow: clip;
  }
  html.js .cap--riel .cap__marco{
    padding-block: calc(var(--tope) + clamp(1rem, 3vh, 2rem)) clamp(2.4rem, 7vh, 4rem);
  }
  html.js .cap--hero .cap__marco{
    padding-block: calc(var(--tope) + 2.5rem) clamp(2.2rem, 6vh, 3.2rem);
  }

  /* Las pistas del guion §1.3. Razón 1,3: plano, todos frenan parecido. */
  :root{ --riel-hero: 110vh; }
  .cap--hero      { --pista: 110vh; }
  .cap--ticket    { --pista: 100vh; }
  .cap--zarpar    { --pista: 100vh; }
  .cap--frio      { --pista: 130vh; }
  .cap--encuentro { --pista: 120vh; }
  .cap--vecinos   { --pista: 100vh; }
  .cap--calendario{ --pista: 110vh; }
  .cap--familia   { --pista: 100vh; }
  .cap--cierre    { --pista: 100vh; }

  /* ─── cap. 1 · la caleta se corre, y se detiene en el mesón ─── */
  html.js .cap--ticket .caleta{
    --e: clamp(0, calc((var(--p, 1) - .08) / .62), 1);
    transform: translate3d(calc(var(--paneo) * var(--e) * -1), 0, 0);
    will-change: transform;
  }
  html.js .cap--ticket .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .04) / .12), 1);
    opacity: var(--q);
  }
  html.js .cap--ticket .cap__entra > *{ transform: translate3d(0, calc(14px * (1 - var(--q))), 0); }
  html.js .cap--ticket .prosa{
    --q: clamp(0, calc((var(--p, 1) - .34) / .12), 1); opacity: var(--q);
  }
  html.js .cap--ticket .filas li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.52 + .05 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--ticket .tierra{ transform: scaleX(var(--q, 1)); }
  html.js .cap--ticket .pie-cap{
    --q: clamp(0, calc((var(--p, 1) - .70) / .09), 1); opacity: var(--q);
  }

  /* ─── cap. 2 · la estela suelta las cuatro cosas de a bordo ─── */
  html.js .cap--zarpar .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .10), 1); opacity: var(--q);
  }
  html.js .cap--zarpar .cap__entra > *{ transform: translate3d(0, calc(14px * (1 - var(--q))), 0); }
  html.js .cap--zarpar .estela{
    transform: scaleX(clamp(0, calc((var(--p, 1) - .10) / .58), 1));
  }
  html.js .cap--zarpar .abordo li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.18 + .15 * var(--t))) / .10), 1);
    opacity: var(--q);
  }
  /* El desplazamiento vive en el NIETO; el hijo solo lleva opacidad. */
  html.js .cap--zarpar .abordo__txt{ transform: translateY(calc(9px * (1 - var(--q)))); }
  html.js .cap--zarpar .capitan{
    --q: clamp(0, calc((var(--p, 1) - .74) / .10), 1);
    opacity: var(--q); transform: translate3d(0, calc(14px * (1 - var(--q))), 0);
  }

  /* ─── cap. 3 · el descenso, y la inversión ───────────────────
     `--d` va 0 → 1 → 0: baja hasta la mitad del riel y vuelve a subir. Lo
     escribe el JS (que ya lo tiene calculado para la sonda), así que el CSS
     solo lo consume y no depende de `abs()`. Con `--d: 0` por defecto la
     escena queda arriba, iluminada y legible sin JS. */
  /* Con el pin montado, el descenso lo hace el movimiento y la regla de los
     tres datos sobra. Se retira acá —en B— y no en A: bajo `reduced-motion`
     en escritorio tampoco hay descenso, así que la regla tiene que quedarse. */
  html.js .cap--frio .profundidades{ display: none; }
  html.js .cap--frio .agua      { transform: translate3d(0, calc(var(--d, 0) * -16vh), 0); }
  html.js .cap--frio .particulas{ transform: translate3d(0, calc(var(--d, 0) * -30vh), 0); }
  /* La placa del dron se posa a la derecha del pin, como la del capitán en el
     capítulo 2, y acompaña la inversión: sube tres centésimas de pantalla
     mientras sube el krill. Se mueve con la escena sin robarle el gesto. */
  html.js .cap--frio .dron{
    position: absolute; right: max(40px, 5vw); top: 50%;
    width: min(27vw, 340px); max-width: none; margin: 0;
    transform: translate3d(0, calc(-50% + (1 - var(--d, 0)) * 3vh), 0);
  }
  /* EL APAGÓN, CORREGIDO. La v2 bajaba TODO el lienzo un 22%: con la foto del
     dron dentro, la lancha desaparecía y la turbidez dejaba de ser velo para
     ser cortina. Ahora el apagón cae al 12% y toca SOLO el fondo —la columna
     de agua y las partículas—. La placa del dron queda fuera y se lee siempre.
     La profundidad la cuentan el color y la turbidez, no el apagón. */
  html.js .cap--frio .agua,
  html.js .cap--frio .particulas{ filter: brightness(calc(1 - .12 * var(--d, 0))); }
  html.js .cap--frio .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--frio .versos li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.22 + .12 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--frio .versos li > span{ transform: translateY(calc(9px * (1 - var(--q)))); }
  html.js .cap--frio .prosa{
    --q: clamp(0, calc((var(--p, 1) - .60) / .10), 1); opacity: var(--q);
  }
  html.js .cap--frio .cita,
  html.js .cap--frio .cita + .dato{
    --q: clamp(0, calc((var(--p, 1) - .70) / .10), 1); opacity: var(--q);
  }

  /* ─── cap. 4 · el cuadro sube y aparece el soplo ─────────────── */
  html.js .cap--encuentro .mar{
    --sube: clamp(0, calc((var(--p, 1) - .04) / .40), 1);
    transform: translate3d(0, calc((1 - var(--sube)) * 14vh), 0);
    will-change: transform;
  }
  /* El encuentro aparece UNA sola vez, entre 0.44 y 0.54, y ya no se va: la
     segunda fotografía se funde sobre la primera y el cuadro se queda quieto.
     Es lo que pasa de verdad cuando la ves. */
  html.js .cap--encuentro .revelado{
    --s: clamp(0, calc((var(--p, 1) - .44) / .10), 1);
    opacity: var(--s);
  }
  /* La ballena cruza DESPACIO: 150vw de recorrido —no los 174vw de la v1— en
     un riel de 1,20. Con `--ancho-ballena` en 62vw queda entera y centrada en
     el cuadro alrededor de `--e: 0.55`, que es el fotograma que hay que mirar. */
  html.js .cap--encuentro .ballena{
    --ancho-ballena: min(62vw, 940px);
    --e: clamp(0, calc((var(--p, .55) - .06) / .82), 1);
    left: 0;
    transform:
      translate3d(calc(100vw - var(--e) * 150vw), calc(-50% + (.5 - var(--e)) * 4vh), 0)
      rotate(calc((.5 - var(--e)) * 1.6deg));
    will-change: transform;
  }
  html.js .cap--encuentro .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--encuentro .lede{
    --q: clamp(0, calc((var(--p, 1) - .20) / .10), 1); opacity: var(--q);
  }
  html.js .cap--encuentro .dato-carga{
    --q: clamp(0, calc((var(--p, 1) - .58) / .08), 1); opacity: var(--q);
  }
  html.js .cap--encuentro .especie{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.64 + .05 * var(--t))) / .10), 1);
    opacity: var(--q);
  }
  html.js .cap--encuentro .especie__txt{ transform: translateY(calc(8px * (1 - var(--q)))); }
  /* Las distancias y el pre-avistamiento ya no viven en el pin: se descargaron
     a la banda en flujo de más abajo y entran con el observador, como todo lo
     que no está pineado. */

  /* ─── cap. 5 · el año se corrige hacia atrás ─────────────────── */
  html.js .cap--vecinos .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--vecinos .anio{
    --q: clamp(0, calc((var(--p, 1) - .14) / .10), 1); opacity: var(--q);
  }
  html.js .cap--vecinos .versos li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.40 + .06 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--vecinos .dato-carga{
    --q: clamp(0, calc((var(--p, 1) - .58) / .09), 1); opacity: var(--q);
  }
  html.js .cap--vecinos .empalme{
    --q: clamp(0, calc((var(--p, 1) - .70) / .09), 1); opacity: var(--q);
  }

  /* ─── cap. 6 · el año se llena ───────────────────────────────
     Cero JavaScript propio: `--a` sale de `--p` y todo lo demás es `calc()`. */
  html.js .cap--calendario .calendario{ --a: clamp(0, calc((var(--p, 1) - .12) / .58), 1); }
  html.js .cap--calendario .mes{
    --on: clamp(0, calc((var(--a) * 12 - var(--m)) / .6), 1);
    opacity: calc(.28 + .72 * var(--on));
  }
  html.js .cap--calendario .banda-mes{
    transform: scaleX(clamp(0, calc((var(--a) * 12 - var(--ini)) / var(--largo)), 1));
  }
  html.js .cap--calendario .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--calendario .versos li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.30 + .16 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--calendario .pie-cap{
    --q: clamp(0, calc((var(--p, 1) - .76) / .08), 1); opacity: var(--q);
  }

  /* ─── cap. 7 · la ficha se llena fila por fila ───────────────── */
  html.js .cap--familia .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--familia .ficha li{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.14 + .11 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--familia .fila__regla{ transform: scaleX(var(--q, 1)); }

  /* ─── cap. 8 · el camino baja y el botón se enciende ─────────── */
  html.js .cap--cierre .cap__entra{
    --q: clamp(0, calc((var(--p, 1) - .02) / .08), 1); opacity: var(--q);
  }
  html.js .cap--cierre .camino{
    transform: scaleY(clamp(0, calc((var(--p, 1) - .10) / .50), 1));
  }
  html.js .cap--cierre .tramo{
    --t: 0;
    --q: clamp(0, calc((var(--p, 1) - (.16 + .14 * var(--t))) / .09), 1);
    opacity: var(--q);
  }
  html.js .cap--cierre .tramo__txt{ transform: translateY(calc(8px * (1 - var(--q)))); }
  html.js .cap--cierre .salidas{
    --q: clamp(0, calc((var(--p, 1) - .58) / .09), 1); opacity: var(--q);
  }
  html.js .cap--cierre .btn{
    --b: clamp(0, calc((var(--p, 1) - .66) / .08), 1);
    background: color-mix(in oklab, var(--corriente) calc(var(--b) * 100%), transparent);
    border-color: color-mix(in oklab, var(--corriente) calc(40% + var(--b) * 60%), transparent);
    color: color-mix(in oklab, var(--espuma) calc(45% + var(--b) * 55%), transparent);
  }
  /* v7 · DEFECTO 4, su otra mitad. Acá el botón de línea perdía el relleno que
     la base le acaba de dar: lo que se enciende con `--b` es el borde, no la
     tinta de fondo, que tiene que estar puesta desde el primer fotograma
     —es lo que sostiene el texto sobre la foto aérea—. */
  html.js .cap--cierre .btn--linea{
    background: color-mix(in oklab, var(--abisal) 78%, transparent);
    border-color: color-mix(in oklab, var(--borde) calc(40% + var(--b) * 60%), transparent);
  }
  html.js .cap--cierre .btn:hover,
  html.js .cap--cierre .btn:focus-visible{ border-color: var(--corriente-claro); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   8 · QUIETO — lo poco que hay que decir bajo `prefers-reduced-motion: reduce`.
   Los bloques M y B no aplicaron: no hay pines, no hay océano fijo, no hay
   coreografía. La página queda apilada y sigue narrando el descenso por color.
   Acá solo se deja presentable, nunca se «deshace» una animación.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  .barra, .btn, .pildora, .pista, .sonda, .sonda__dato,
  .mes, .fila__regla{ transition: none; animation: none; }
  .pista{ opacity: .9; }
  .sonda{ display: none; }                    /* sin scrub no tiene qué medir */
  html.js .hero__video.listo{ display: none; }   /* queda la foto, que ya cargó */
  .cap--frio .agua, .cap--frio .particulas{ transform: none; }
}
