/* Into The Wild remake - phase 2 visual foundation */

@font-face {
  font-family: "Andale Mono ITW";
  src: url("../fonts/ANDALEMO.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --color-bg: #000;
  --color-text: #fff;
  --color-muted: #fff;
  --color-soft: rgba(244, 241, 236, 0.42);
  --color-line: rgba(244, 241, 236, 0.14);
  --color-panel: #080808;
  --font-main: "Andale Mono ITW", "Andale Mono", "Courier New", monospace;
  --page-x: clamp(20px, 5vw, 72px);
  --section-y: clamp(96px, 16vw, 240px);
  --section-y-tight: clamp(56px, 9vw, 140px);
  --section-heading-gap: clamp(12px, 2vw, 30px);
  --video-batch-gap: 10px;
  /* Banda negra (letterbox de cine) arriba y abajo de los videos de seccion en
     DESKTOP. La caja sigue siendo 16:9 a todo el ancho; el video se mete en una
     franja central mas baja (object-fit: cover recorta un poco arriba/abajo) y
     este margen queda en negro. SUBIR el valor = mas banda negra y mas recorte;
     bajarlo = menos banda. Se anula en movil/tablet (<=900px). */
  --cine-band: clamp(23px, 5.6vw, 108px);
  --header-height: 82px;
  --hero-text-duration: 16s;
  /* Velocidad del auto-ocultado por inactividad (header y boton de sonido).
     Replica el .auto-hiding de dev: 1s con ease-in. */
  --ui-fade: 1s;
  --text-max: 980px;
  --brand-content-max: 980px;
  /* ===== SISTEMA TIPOGRAFICO =====================================================
     6 tamaños y UN solo tracking (0.12em) para TODO el sitio. Cada texto apunta a
     uno de estos tokens; no se usan tamaños sueltos. Los ajustes propios de movil/
     tablet viven en sus @media (unica excepcion puntual por espacio en pantalla).
       display  -> "stay wild"
       caption  -> overlays de texto sobre video (Language / ITW)
       hero     -> frases del intro (NO se tocan en tamaño: concepto del cliente)
       body     -> titulos de seccion, nombres de equipo, titulos de poster y parrafos
       small    -> info/meta de poster, cargos del equipo, footer
       micro    -> nav, logo, toggles, separador ES|EN
     Los line-heights se conservan tal cual estaban: el sistema unifica TAMAÑO y
     TRACKING, no toca el espaciado vertical ya ajustado. */
  --type-display: clamp(27px, 5.4vw, 83px);
  --type-caption: clamp(36px, 3.8vw, 60px);
  --type-hero:    clamp(17px, 2.4vw, 38px);
  --type-body:    clamp(10px, 1.1vw, 17px);
  --type-small:   clamp(12px, 1vw, 15px);
  --type-micro:   clamp(10px, 0.93vw, 13px);
  --tracking: 0.12em;
  /* Unico line-height que sigue como token (parrafos); el resto van inline. */
  --leading-body: 1.95;
}

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

html {
  background: var(--color-bg);
  font-family: var(--font-main);
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-height);
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  background: var(--color-bg);
  color: var(--color-text);
  letter-spacing: var(--tracking);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

button,
input,
textarea,
select {
  font: inherit;
}

h1,
h2,
h3,
h4 {
  font-weight: 400;
}

img,
svg {
  display: block;
  max-width: 100%;
  /* Acompaña a los width/height de las <img>: usa el aspect-ratio de los atributos
     en vez de aplicar la altura literal. Sin esto, una <img> con height="..." cuyo
     CSS solo fija el ancho (p. ej. el logo del footer) se estira a esa altura. */
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  border: 0;
  color: inherit;
}

:focus-visible {
  outline: 1px solid rgba(244, 241, 236, 0.72);
  outline-offset: 4px;
}

::selection {
  background: rgba(244, 241, 236, 0.22);
}

.site-header {
  position: fixed;
  z-index: 20;
  top: 0;
  left: 0;
  width: 100%;
  min-height: var(--header-height);
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: clamp(18px, 3vw, 42px);
  align-items: center;
  padding: 24px var(--page-x);
  /* Resto de la pagina: banda negra solida. */
  background: var(--color-bg);
  transform: translateY(0);
  /* Aparicion y ocultado por scroll: ease-out spring de dev; opacity 1s para
     el resalte al hover del efecto cine. */
  transition: transform 1.4s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 1s ease;
}

/* Arriba del todo (sobre el hero): efecto "cine" translucido con blur, como la
   web original. El JS anade .is-at-top solo en desktop y con scrollTop < 120;
   en el resto de la pagina el header es banda negra solida (regla base). */
.site-header.is-at-top {
  background: rgba(0, 0, 0, 0.04);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  opacity: 0.6;
}

.site-header.is-at-top:hover {
  opacity: 1;
}

.site-header.is-hidden {
  transform: translateY(-120%);
  opacity: 0;
  pointer-events: none;
}

/* El ease-in espeja el ease-out de la aparicion: el auto-ocultado por
   inactividad se siente tan gradual como el mostrar (replica .auto-hiding
   de dev). El ocultado por scroll usa la transicion base (mas rapida). */
.site-header.auto-hiding {
  transition: transform var(--ui-fade) cubic-bezier(0.16, 0, 0.84, 0),
              opacity var(--ui-fade) cubic-bezier(0.16, 0, 0.84, 0);
}

/* Banda negra fija DETRAS del header (header z-index 20, banda 19). Tapa el
   video del hero cuando, al hacer scroll, sube por debajo del header translucido
   (.is-at-top). Solo se muestra sobre el hero: en el resto de la pagina el header
   ya es banda negra solida, asi que se respetan las 3 intensidades del menu. */
.header-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--header-height);
  background: var(--color-bg);
  z-index: 19;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1s ease;
}

body:has(.site-header.is-at-top) .header-backdrop {
  opacity: 1;
}

.site-logo,
.site-nav a,
.language-switch button,
.menu-toggle {
  font-size: var(--type-micro);
  letter-spacing: var(--tracking);
  /* Menú/logo en su capitalización propia. El logo es "stay wild" (escrito en
     minúscula, se queda así); los enlaces del nav llevan su mayúscula inicial. */
  text-transform: none;
}

.site-logo {
  white-space: nowrap;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 14px 24px;
}

.site-nav a,
.language-switch button {
  opacity: 0.62;
  transition: opacity 500ms ease;
}

.site-nav a:hover,
.language-switch button:hover,
.language-switch button[aria-pressed="true"] {
  opacity: 1;
}

.language-switch {
  display: flex;
  gap: 10px;
}

.language-switch button {
  padding: 0;
  background: transparent;
  cursor: pointer;
  /* El selector de idioma va en MAYÚSCULAS (ES | EN), distinto del resto del nav. */
  text-transform: uppercase;
}

/* Separador "|" entre ES y EN. Decorativo (aria-hidden), no clicable. */
.lang-sep {
  font-size: var(--type-micro);
  line-height: 1;
  opacity: 0.32;
  user-select: none;
  pointer-events: none;
}

.menu-toggle {
  display: none;
  position: relative;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  cursor: pointer;
}

/* Estado CERRADO: el favicon (aro blanco sobre negro) hace de icono. En el header
   negro de tablet/móvil el fondo del icono se funde y solo se ve el aro. */
/* Botón del menú = círculo dibujado por CSS (sin imagen, no depende del favicon).
   Cerrado: aro con halo/glow difuso alrededor. Abierto: aro más fino concéntrico.
   Crossfade de opacidad entre ambos, alineado con el fade del overlay (500ms). */
/* Los dos círculos son IDÉNTICOS en tamaño y grosor (mismo inset/border); la única
   diferencia es el halo: el cerrado lo lleva, el abierto no. Crossfade entre ambos. */
.menu-toggle-ring,
.menu-toggle-close {
  position: absolute;
  inset: 4px;
  border: 2px solid currentColor;
  border-radius: 50%;
  transition: opacity 500ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Estado CERRADO: círculo con halo (glow blanco difuso alrededor; ajustable).
   Dos capas: una cercana e intensa + otra amplia y suave, para un halo marcado. */
.menu-toggle-ring {
  box-shadow: 0 0 8px 1px rgba(255, 255, 255, 0.7),
              0 0 18px 5px rgba(255, 255, 255, 0.45);
  opacity: 1;
}

/* Estado ABIERTO: mismo círculo, sin halo. */
.menu-toggle-close {
  opacity: 0;
}

.menu-toggle[aria-expanded="true"] .menu-toggle-ring {
  opacity: 0;
}

.menu-toggle[aria-expanded="true"] .menu-toggle-close {
  opacity: 1;
}

/* Fade del menú COMPLETO como bloque (estilo cross-fade del cambio de idioma):
   sin cascada, sin animación por enlace. Los links viven ya en su sitio y visibles
   dentro del overlay; solo el overlay entero hace fade.
   La apertura va por @keyframes (no transition) a propósito: en iPad/Safari una
   transition NO se dispara si el elemento pasa de visibility:hidden a visible en el
   mismo frame; una animation arranca su propia línea de tiempo y sí lo hace. */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 19;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 4vh, 36px);
  /* Negro sólido (sin backdrop-filter: blur). Con 0.97 de opacidad el blur apenas
     se veía, pero en iPad era caro de repintar durante el fade y lo entrecortaba.
     El menú es un takeover completo, así que el sólido queda igual y va fluido. */
  background: #000;
  padding: var(--header-height) var(--page-x) var(--page-x);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* SOLO se transiciona opacity. visibility/pointer-events los gobierna el JS en
     dos fases: (1) .is-mounted → visible; (2) tras doble rAF, .is-visible → opacity.
     Forzar el repintado del estado inicial (visible + opacity:0) ANTES de subir la
     opacidad es lo que hace que la transición se dispare de verdad en Safari/iOS
     (cambiar visibility y opacity en el mismo frame se saltaba el primer frame y
     pintaba opacity:1 "de golpe"). */
  transition: opacity 900ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Fase 1: montado (ocupa y es interactivo) pero aún invisible (opacity:0). */
.mobile-menu.is-mounted {
  visibility: visible;
  pointer-events: auto;
}

/* Fase 2: visible (fade de opacity). Al cerrar se quita esta clase (fade out) y,
   tras el fade, el JS quita .is-mounted para volver a visibility:hidden. */
.mobile-menu.is-visible {
  opacity: 1;
}

/* Links e idioma en su estado visible de reposo (sin animación ni desplazamiento):
   entran/salen con el fade del overlay completo. */
.mobile-menu a {
  font-size: clamp(17px, 4.2vw, 26px);
  letter-spacing: var(--tracking);
  text-transform: none;
  opacity: 0.62;
}

.mobile-menu .language-switch {
  opacity: 1;
}

.mobile-menu a:hover,
.mobile-menu .language-switch:focus-within {
  opacity: 1;
}

.mobile-menu .language-switch {
  margin-top: clamp(12px, 3vh, 24px);
}

/* En el menú hamburguesa el ES | EN se veía muy pequeño (heredaba los 11px del
   header). Lo subimos un pelo para que respire junto a los enlaces grandes. */
.mobile-menu .language-switch button,
.mobile-menu .lang-sep {
  font-size: 15px;
}

/* MÓVIL EN HORIZONTAL (poco alto): la columna única de enlaces no cabía y
   `justify-content:center` los recortaba arriba/abajo sin poder scrollear. En
   landscape sobra ancho y falta alto, así que reorganizamos en REJILLA de 2
   columnas (aprovecha el ancho) con enlaces más pequeños. `max-height:600px` con
   landscape = teléfonos (los iPad en horizontal miden ~810px de alto y no entran
   aquí). `overflow-y:auto` + `align-content: safe center` = red de seguridad: si
   aún no cupiera, no recorta y deja scrollear. */
@media (orientation: landscape) and (max-height: 600px) {
  .mobile-menu {
    display: grid;
    grid-template-columns: repeat(2, auto);
    justify-content: center;
    justify-items: center;
    align-content: safe center;
    column-gap: clamp(32px, 10vw, 90px);
    row-gap: clamp(6px, 2.5vh, 14px);
    padding-top: calc(var(--header-height) + 8px);
    padding-bottom: 8px;
    overflow-y: auto;
  }

  .mobile-menu a {
    font-size: clamp(14px, 4.6vh, 19px);
  }

  /* Los 6 primeros enlaces van en 2 columnas (3+3). Contact, el 7º (impar), se
     quedaba solo en la izquierda con un hueco a la derecha → lo centramos a todo
     lo ancho, en su propia fila, igual que el selector de idioma. */
  .mobile-menu a[href="#contact"] {
    grid-column: 1 / -1;
    justify-self: center;
  }

  /* El ES | EN ocupa toda la fila, centrado debajo de los enlaces. */
  .mobile-menu .language-switch {
    grid-column: 1 / -1;
    justify-self: center;
    margin-top: clamp(4px, 1.5vh, 12px);
  }

  .mobile-menu .language-switch button,
  .mobile-menu .lang-sep {
    font-size: 13px;
  }
}

.sound-toggle {
  position: fixed;
  right: var(--page-x);
  bottom: clamp(18px, 4vw, 40px);
  z-index: 18;
  padding: 10px 14px;
  border: 1px solid rgba(244, 241, 236, 0.24);
  /* Rectángulo (esquinas rectas), igual que las flechas del carrusel. */
  border-radius: 0;
  background: rgba(0, 0, 0, 0.38);
  color: #fff;
  font-size: var(--type-micro);
  letter-spacing: var(--tracking);
  /* Caja propia: "Sound on" / "Sound off" con la inicial en mayúscula (el texto ya
     viene así del HTML/JS; antes lo bajaba a minúscula). */
  text-transform: none;
  cursor: pointer;
  opacity: 1;
  /* Aparicion ease-out (como dev); el desvanecido usa la transicion de .hidden-ui. */
  transition: opacity 1.4s cubic-bezier(0.16, 1, 0.3, 1),
              color 180ms ease,
              border-color 180ms ease,
              background 180ms ease;
}

.sound-toggle:hover,
.sound-toggle[aria-pressed="true"] {
  border-color: rgba(244, 241, 236, 0.48);
  background: rgba(244, 241, 236, 0.08);
  color: var(--color-text);
}

.sound-toggle.hidden-ui {
  opacity: 0;
  pointer-events: none;
  /* Mismo desvanecido que el auto-ocultado del header (.auto-hiding). */
  transition: opacity var(--ui-fade) cubic-bezier(0.16, 0, 0.84, 0);
}

.video-loading-indicator {
  position: fixed;
  left: var(--page-x);
  bottom: clamp(18px, 4vw, 40px);
  z-index: 17;
  width: 22px;
  height: 22px;
  border: 1px solid rgba(244, 241, 236, 0.18);
  border-top-color: rgba(244, 241, 236, 0.84);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
  animation: video-loading-spin 900ms linear infinite;
}

body.has-video-loading .video-loading-indicator {
  opacity: 1;
}

.reveal {
  opacity: 0;
  filter: blur(10px);
  clip-path: inset(0 0 14% 0);
  transition: opacity 2.6s cubic-bezier(0.16, 1, 0.3, 1),
              filter 2.6s cubic-bezier(0.16, 1, 0.3, 1),
              clip-path 2.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.is-visible {
  opacity: 1;
  filter: blur(0);
  clip-path: inset(0);
}

/* Carrusel de pósters: fundido más largo que el reveal base. Se dispara con
   antelación (rootMargin '100px' en carousel.js), así que a 2.6s "llegaba casi
   terminado". Con transition-duration solo alargamos la duración, respetando el
   set de propiedades y el easing de cada breakpoint (desktop: opacity+blur+clip;
   móvil: opacity+transform). Sube también en móvil (sigue siendo barato: sin blur). */
.poster-list.reveal {
  transition-duration: 4s;
}

/* Cascada de los parrafos de un bloque de texto (manifiesto): reveal.js los hace
   visibles a la vez al entrar el bloque y este transition-delay por orden los
   escalona, asi aparecen "uno tras otro". Aplica a Existe (1 solo), Detener,
   Nuestro trabajo (work-text) y No acumulamos (itw-text). */
.manifesto > .reveal:nth-child(2) { transition-delay: 0.45s; }
.manifesto > .reveal:nth-child(3) { transition-delay: 0.9s; }
.manifesto > .reveal:nth-child(4) { transition-delay: 1.35s; }

.reveal--stay-wild {
  filter: blur(18px);
  transform: scale(0.985);
  text-shadow: 0 0 42px rgba(244, 241, 236, 0.18);
  transition: opacity 5s cubic-bezier(0.16, 1, 0.3, 1),
              filter 5s cubic-bezier(0.16, 1, 0.3, 1),
              clip-path 5s cubic-bezier(0.16, 1, 0.3, 1),
              transform 5s cubic-bezier(0.16, 1, 0.3, 1),
              text-shadow 5s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal--stay-wild.is-visible {
  transform: scale(1);
  text-shadow: 0 0 18px rgba(244, 241, 236, 0.08);
}

.reveal--language-caption {
  filter: blur(14px);
  transition: opacity 3.2s cubic-bezier(0.16, 1, 0.3, 1),
              filter 3.2s cubic-bezier(0.16, 1, 0.3, 1),
              clip-path 3.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.language-transition [data-i18n]:not(.no-lang-transition) {
  transition: opacity 500ms ease;
}

.language-transition .hero-sequence {
  transition: opacity 500ms ease;
}

.language-is-changing [data-i18n]:not(.no-lang-transition) {
  opacity: 0;
}

.language-is-changing .hero-sequence {
  opacity: 0;
}

main {
  min-height: 100vh;
}

.section {
  position: relative;
  width: 100%;
  padding: var(--section-y) var(--page-x);
  scroll-margin-top: var(--header-height);
}

.section > h1,
.section > h2,
.section > h3 {
  max-width: var(--text-max);
  margin: 0;
  font-weight: 400;
  line-height: 1.22;
  letter-spacing: var(--tracking);
  /* Títulos de sección en su capitalización propia (frase): "Stop the world",
     "On the road", "Into the wild"… Antes iban en minúscula (text-transform). */
  text-transform: none;
}

.section > h1 {
  font-size: clamp(22px, 4vw, 58px);
}

.section > h2 {
  font-size: var(--type-body);
}

/* Estas dos son FRASES (no títulos cortos de sección) y deben respetar siempre su
   capitalización ("There is still a wild Earth", "Stop the world so that life can
   speak."). Se deja explícito por si algún día volviera el text-transform a la base. */
#wild-earth-title,
#stop-manifesto-title {
  text-transform: none;
}

.section p {
  max-width: var(--text-max);
  margin: 0;
  color: var(--color-muted);
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

.section p + p,
.section h2 + p,
.section h3 + p {
  margin-top: clamp(24px, 4vw, 48px);
}

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  /* El vídeo y las frases viven dentro de .hero-media (anclada arriba, con la
     ALTURA del vídeo). Las frases se centran respecto a ESE contenedor, así que
     quedan en el centro del vídeo (donde sale "stay wild") para cualquier pantalla,
     en vez de en el centro de la ventana. overflow:hidden recorta el sobrante del
     vídeo (más alto que la pantalla); padding 0 para que vaya de extremo a extremo. */
  overflow: hidden;
  padding: 0;
  text-align: center;
}

.hero-media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  /* Sin altura explícita: la marca el vídeo en flujo normal que va dentro. */
}

.video-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  display: block;
}

.video-placeholder {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  background: var(--color-bg);
  color: transparent;
  font-size: 0;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}

@keyframes video-loading-spin {
  to {
    transform: rotate(360deg);
  }
}

.video-real {
  width: 100%;
  height: auto;
  object-fit: cover;
  background: var(--color-bg);
  opacity: 0;
  transition: opacity 1.8s ease;
}

.video-real.is-video-visible {
  opacity: 1;
}

.video-placeholder.is-hidden {
  opacity: 0;
  pointer-events: none;
}

.media-reference {
  position: relative;
}

/* Fondo de la caja: es lo que se ve en la banda de cine (arriba y abajo),
   ya que el video se mete en una franja central mas baja. (En modo debug se
   pinta de rojo; ver bloque TEMPORAL mas abajo.) */
.media-reference,
.language-item,
.final {
  background: var(--color-bg);
}

/* El video ocupa todo el ancho pero solo una franja central: inset vertical =
   --cine-band (banda negra de cine), inset horizontal = 0 (sangre completa).
   object-fit: cover llena esa franja recortando un poco el 16:9 arriba/abajo. */
.media-reference .video-real,
.language-item .video-real,
.final .video-real {
  position: absolute;
  z-index: 0;
  /* Letterbox de cine: el video es un elemento reemplazado, asi que NO se estira
     con top+bottom; hay que darle altura explicita. Ocupa todo el ancho y una
     altura = caja (16:9) menos las dos bandas; arrancando a --cine-band del borde
     superior, la banda inferior queda igual por simetria. object-fit: cover (de
     .video-real) llena esa franja recortando un poco el 16:9 arriba/abajo.
     aspect-ratio: auto anula el 16:9 que trae .video-frame. */
  aspect-ratio: auto;
  top: var(--cine-band);
  left: 0;
  width: 100%;
  height: calc(100% - 2 * var(--cine-band));
}

.video-placeholder--bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: unset;
  max-height: none;
  transform: none;
  opacity: 0.6;
}

/* El vídeo va en FLUJO NORMAL dentro de .hero-media: así su altura natural
   (a ancho completo) define la altura del contenedor, y las frases —centradas
   sobre ese mismo contenedor— quedan en el centro real del vídeo. La franja de
   arriba bajo el header la tapa la .header-backdrop. */
.hero .video-real {
  position: relative;
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: unset;
}

.stop-section h3,
.road-section h3 {
  display: none;
}

.hero h1 {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.hero-sequence {
  /* Cubre el contenedor del vídeo (.hero-media) y centra las frases en él:
     quedan SIEMPRE en el centro del vídeo, no en el de la pantalla. */
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-content: center;
  gap: clamp(2px, 0.6vw, 8px);
  justify-items: center;
}

.hero-sequence p {
  max-width: min(1100px, 92vw);
  color: #fff;
  font-size: var(--type-hero);
  line-height: 1.35;
  letter-spacing: var(--tracking);
  text-align: center;
}

/* Las frases del hero solo deben separarse por el `gap` del grid. La regla
   general `.section p + p` les anadia hasta 48px de margin-top que dominaba
   el gap (por eso reducirlo apenas se notaba en desktop). */
.hero-sequence p + p {
  margin-top: 0;
}

.hero-line {
  opacity: 0;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.5);
  animation-duration: var(--hero-text-duration);
  animation-iteration-count: 1;
  animation-fill-mode: both;
  animation-timing-function: ease;
}

.hero.is-hero-text-running .hero-line--one {
  animation-name: hero-line-one;
}

.hero.is-hero-text-running .hero-line--two {
  animation-name: hero-line-two;
}

.hero.is-hero-text-running .hero-line--three {
  animation-name: hero-line-three;
}

/* Si una pausa externa (tecla multimedia / Touch Bar de macOS) detiene el vídeo,
   congelamos la animación de las frases para que no se desincronice del vídeo.
   videos.js añade/quita .is-hero-paused según los eventos pause/play del vídeo. */
.hero.is-hero-paused .hero-line {
  animation-play-state: paused;
}

@keyframes hero-line-one {
  0% { opacity: 0; }
  6% { opacity: 1; }
  94% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes hero-line-two {
  0% { opacity: 0; }
  25% { opacity: 0; }
  31% { opacity: 1; }
  94% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes hero-line-three {
  0% { opacity: 0; }
  50% { opacity: 0; }
  56% { opacity: 1; }
  94% { opacity: 1; }
  100% { opacity: 0; }
}

.manifesto {
  min-height: 50vh;
  /* El aire arriba/abajo de los textos de contenido lo manda ESTE padding (no el
     min-height: con padding --section-y ≈240px el min-height no llega a bindear).
     Lo bajamos a --section-y-tight para quitar aire. "Existe…" (.manifesto--full)
     no se ve afectada: su min-height:100vh sí bindea y el texto sigue centrado. */
  padding-top: var(--section-y-tight);
  padding-bottom: var(--section-y-tight);
  display: grid;
  align-content: center;
  justify-items: center;
  text-align: center;
}

/* ===== TEMPORAL (depuracion de maquetacion) — QUITAR al terminar ============
   Los fondos de color SOLO se activan con la clase .debug-colors en <html>.
   Toggle: Ctrl+Alt+D (script inline en el <head> de index.html; estado recordado
   en localStorage). Sin la clase, el sitio se ve limpio (negro real); con ella,
   se encienden los colores para ensenar la maqueta al cliente.
   Correspondencia de colores:
     ROJO oscuro   #4a0000  -> bandas de cine (--cine-band), en las cajas de video
     VERDE oscuro  #003a1a  -> areas de video (huecos entre videos)
     MORADO oscuro #2e0a4a  -> GRUPO 1: titulos de seccion (stop/road/language/work/itw)
     AZUL oscuro   #001a4a  -> GRUPO 2: textos de contenido (Existe.../Detener.../Nuestro trabajo.../No acumulamos...)
     GRIS oscuro   #2a2a2a  -> carrusel (posters / equipo): su espacio propio arriba y abajo
     TEAL oscuro   #003a3a  -> stay wild (.final-tagline)
     OLIVA oscuro  #2a3a00  -> logos de marca (.partners)
     MAGENTA osc.  #3a002a  -> footer (.site-footer)
*/
.debug-colors .media-reference,
.debug-colors .language-item,
.debug-colors .final {
  background: #4a0000;
}
.debug-colors .section-content.media-sequence,
.debug-colors .section-content > .media-sequence,
.debug-colors .section-content > .language-list {
  background: #003a1a;
}
.debug-colors .section-heading {
  background: #2e0a4a;
}
.debug-colors .manifesto {
  background: #001a4a;
}
.debug-colors .carousel {
  background: #2a2a2a;
}
.debug-colors .final-tagline {
  background: #003a3a;
}
.debug-colors .partners {
  background: #2a3a00;
}
.debug-colors .site-footer {
  background: #3a002a;
}
/* ===== FIN TEMPORAL ===== */

/* ===== TEMPORAL 2 (depuracion TIPOGRAFICA) — QUITAR al terminar ==============
   Pinta un color de FONDO detras de cada texto segun su token del sistema
   tipografico (6 grupos), para ver de un vistazo que tamaño usa cada cosa.
   Independiente de .debug-colors: se activa aparte con la clase .debug-type en
   <html>. Toggle: Ctrl+Alt+T (script inline en el <head> de index.html; estado
   en localStorage). Fondos translucidos para que el texto siga legible.
   Leyenda de colores:
     ROSA     rgba(255,0,128)  -> --type-display  ("stay wild")
     CIAN     rgba(0,190,255)  -> --type-caption  (overlays de video)
     NARANJA  rgba(255,140,0)  -> --type-hero     (frases del intro)
     AZUL     rgba(60,110,255) -> --type-body     (titulos seccion, nombres, parrafos)
     VERDE    rgba(0,200,110)  -> --type-small    (info/meta poster, cargos, footer)
     AMARILLO rgba(225,205,0)  -> --type-micro    (nav, logo, toggles, separador)
*/
/* OJO con el ORDEN: varias de estas reglas tienen la MISMA especificidad (p. ej.
   `.section p` y `.hero-sequence p`, o `.section > h2` y `.final-tagline h2`), asi
   que decide el orden de fuente. Las genericas (body/small/micro) van PRIMERO y las
   especificas que deben ganar (caption/hero/display) van DESPUES, igual que en el
   CSS real de los font-size; si no, el body (azul) pisaba a hero y display. */
.debug-type .section > h2,
.debug-type .media-reference h3,
.debug-type .poster-card h3,
.debug-type .team-list h3,
.debug-type .section p,
.debug-type .manifesto h2,
.debug-type .manifesto p,
.debug-type .language-caption p {
  background: rgba(60, 110, 255, 0.32);
}
.debug-type .poster-info p,
.debug-type .poster-meta,
.debug-type .team-list p,
.debug-type .site-footer address,
.debug-type .copyright {
  background: rgba(0, 200, 110, 0.32);
}
.debug-type .site-logo,
.debug-type .site-nav a,
.debug-type .language-switch button,
.debug-type .menu-toggle,
.debug-type .lang-sep,
.debug-type .sound-toggle,
.debug-type .mobile-menu a {
  background: rgba(225, 205, 0, 0.32);
}
.debug-type .language-caption h3 {
  background: rgba(0, 190, 255, 0.34);
}
.debug-type .hero-sequence p {
  background: rgba(255, 140, 0, 0.38);
}
.debug-type .final-tagline h2 {
  background: rgba(255, 0, 128, 0.38);
}
/* Los textos con reveal/animacion arrancan en opacity:0 (y las frases del hero
   ADEMAS terminan su animacion en opacity:0), asi que su fondo de debug no se
   veria. En modo .debug-type los forzamos visibles para poder auditar TODO el
   texto de golpe, sin depender del scroll ni de la animacion del hero. */
.debug-type .reveal,
.debug-type .reveal--stay-wild,
.debug-type .reveal--language-caption,
.debug-type .hero-line {
  opacity: 1 !important;
  filter: none !important;
  clip-path: none !important;
  animation: none !important;
}
/* El transform SOLO se resetea en "stay wild" (su reveal usa scale). NO se toca en
   las captions: `.language-caption` lleva un `transform: translateY(12%)` POSICIONAL
   (las baja dentro del vídeo); resetearlo las subía de sitio al activar el debug. */
.debug-type .reveal--stay-wild {
  transform: none !important;
}
/* ===== FIN TEMPORAL 2 ===== */

/* La primera frase-manifiesto ("There is still a wild Earth") ocupa pantalla
   completa en TODOS los tamaños: la frase queda centrada vertical (align-content:
   center) con negro arriba y abajo. Doble clase para ganar al min-height de los
   media queries de .manifesto. (La 2ª, "Stop the world…", se revisa aparte.) */
.manifesto.manifesto--full {
  min-height: 100vh;
  /* lvh (no dvh): altura del viewport con la barra de URL oculta. Es un valor FIJO,
     así que no cambia mientras la barra se pliega/despliega al scrollear → no hay
     reflujo ni "salto" del contenido. Como a esta sección se llega scrolleando (la
     barra ya está oculta), lvh = pantalla real y llena exacto sin asomar vecinos.
     dvh daba la altura "viva" y por eso saltaba; svh se quedaba corta. */
  min-height: 100lvh;
}

/* Desktop: rebajar un poco el aire arriba/abajo de "Existe…" (no llena el 100%
   de pantalla). Solo desktop; movil/tablet mantienen el 100vh/lvh de arriba. */
@media (min-width: 901px) {
  .manifesto.manifesto--full {
    min-height: 80vh;
  }
}

.manifesto h2,
.manifesto p {
  max-width: var(--text-max);
  font-size: var(--type-body);
  line-height: var(--leading-body);
  color: var(--color-muted);
}

.manifesto h2 + p,
.manifesto p + p {
  margin-top: clamp(32px, 5vw, 64px);
}

/* GRUPO 2 — textos de contenido: cada texto es su propia seccion .manifesto
   (manifiestos + work-text + itw-text), todos con el mismo sistema tipografico
   (.manifesto h2/p usa los tokens --content-*). Las reglas ESPECIFICAS por texto
   (espaciado propio, etc.) se anaden luego apuntando a .work-text / .itw-text. */

/* Todos los titulos de seccion homogeneos: mismo padding arriba y abajo. (La
   antigua excepcion de .work-heading con mas padding-bottom ya no hace falta: el
   texto de Work es ahora su propia seccion .work-text y gestiona su espacio.) */
.section-heading {
  padding-top: clamp(56px, 7vw, 110px);
  padding-bottom: var(--section-heading-gap);
}

/* Desktop: el título cae al borde INFERIOR de su sección (la "morada" del debug)
   quitando solo el padding-bottom. El padding-top se queda en el valor base (no se
   añade aire arriba), así la sección se compacta por arriba y el contenido anterior
   queda más cerca. Móvil/tablet mantienen el padding-bottom (--section-heading-gap). */
@media (min-width: 901px) {
  .section-heading {
    padding-bottom: 0;
  }

  /* El título cuelga POR DEBAJO de su sección: lo bajamos su propia altura
     (translateY 100%) para que su borde superior caiga en el borde inferior de la
     morada. Restamos 0.2em para compensar el leading de line-height:1.22 y que sea
     el extremo de las MAYÚSCULAS lo que toque el borde (ajustable). El transform no
     ocupa espacio en el flujo: el título se mete en el hueco (padding-top) del
     contenido siguiente, que en desktop es ~140px, así que no pisa nada. */
  .section-heading h2 {
    transform: translateY(calc(100% - 0.2em));
    /* Al colgar bajo la sección, el título cae sobre la sección siguiente (vídeos
       que empiezan sin padding-top, manifiestos…), que se pinta después en el DOM y
       lo tapaba. position+z-index lo trae al frente (los vídeos están en z-index 0;
       el header fijo sigue por encima con z-index 20). */
    position: relative;
    z-index: 2;
  }

  /* Un poco más de aire encima del título de "Language" (separarlo de los vídeos de
     On the road). Solo desktop. */
  .language-heading {
    margin-top: clamp(32px, 4vw, 64px);
  }
}

/* Móvil: aire encima de "Language" (separarlo de los vídeos de On the road). Se
   iguala al hueco inferior Language->Work (.language-section padding-bottom =
   --section-y-tight * 2): como "Language" y "Work" comparten el mismo padding-top
   del .section-heading, con esto la distancia título->vídeo-de-arriba y la de
   última-frase->Work quedan idénticas. (Antes era 25vh, casi el doble.) */
@media (max-width: 900px) {
  .language-heading {
    margin-top: calc(var(--section-y-tight) * 2);
  }
}

.section-content {
  padding-top: 0;
}

.road-heading,
.language-heading,
.work-heading,
.itw-heading {
  text-align: left;
}

.media-sequence,
.language-list {
  display: grid;
  gap: var(--video-batch-gap);
  margin-top: clamp(40px, 8vw, 120px);
}

.poster-list,
.team-list {
  display: grid;
  gap: clamp(16px, 3vw, 42px);
  margin-top: clamp(40px, 8vw, 120px);
}

.media-sequence {
  padding-top: var(--section-y-tight);
  /* Sin colchon inferior: ningun grupo de videos lleva espacio extra debajo del
     ultimo video (homogeneo con .language-list y work, que no lo tenian). El
     espacio hasta la siguiente seccion lo da el padding propio de cada seccion. */
  padding-bottom: 0;
}

.section-content.media-sequence,
.section-content > .media-sequence,
.section-content > .language-list,
.section-content > .poster-list,
.section-content > .team-list,
.section-content > .carousel {
  margin-top: 0;
}

.work-section > .carousel {
  --carousel-top: clamp(72px, 10.5vw, 144px);
  --carousel-bottom: clamp(48px, 8vw, 120px);
}

/* Vídeo dentro de la sección Work: a sangre completa (rompe el padding lateral
   del section-content para ir de extremo a extremo, como los vídeos de las demás
   secciones) y con aire respecto al texto de arriba y a los pósters de abajo. */
.work-section > .media-sequence.work-video {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  /* Sin aire propio: el video va pegado al texto de Work. El aire inferior
     (video -> posters) lo da el padding-top del carrusel. */
  padding: 0;
}

.itw-section > .carousel {
  /* Arriba compacto; abajo bastante más aire (bajo el equipo, antes de la sección
     final). Original era clamp(90px,11vw,160px). */
  --carousel-top: clamp(45px, 5.5vw, 80px);
  --carousel-bottom: clamp(120px, 14vw, 200px);
}

.section-content.media-sequence,
.section-content > .media-sequence {
  padding-top: 0;
}

.stop-section,
.road-section,
.language-section,
.itw-video-section {
  padding-left: 0;
  padding-right: 0;
}

/* Las secciones de video no llevan padding inferior: el espacio hasta la
   siguiente seccion lo da el padding-top del titulo (o de la seccion) siguiente.
   (stop e itw-video ya lo tenian a 0 via .media-sequence; road/language no.) */
.road-section,
.language-section {
  padding-bottom: 0;
}

.media-reference h3,
.poster-card h3,
.team-list h3 {
  margin: 22px 0 0;
  font-weight: 400;
  font-size: var(--type-body);
  line-height: 1.45;
  letter-spacing: var(--tracking);
}

/* "Ingrid Fernandez de Castro" es el único nombre que se iba a 2 líneas, lo que
   bajaba su cargo una línea respecto al resto. Solo en SU tarjeta forzamos el nombre
   a UNA línea con tracking casi nulo (nowrap + 0.01em); el TAMAÑO es el mismo que el
   resto (--type-body), sin fuente menor. Única excepción al tracking del sistema, por
   necesidad de maquetación (sin el 0.01em el nombre no cabe). No afecta a nadie más. */
.team-list .team-card--long h3 {
  white-space: nowrap;
  letter-spacing: 0.01em;
}

.media-reference h3,
.poster-card h3 {
  text-transform: uppercase;
}

.language-item {
  position: relative;
}

.language-caption {
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  left: clamp(20px, 4vw, 52px);
  /* El copy se queda en la franja izquierda del video, no se mete hacia la
     derecha. (En movil esto se ignora: el caption pasa a display: contents.) */
  width: 65%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  /* Bajamos el bloque un % de la altura del vídeo (la caja va de top:0 a bottom:0,
     así que translateY(X%) = X% del alto del vídeo). A 13% para bajarlo un poco. Solo
     desktop (en móvil es display:contents y el transform no aplica). */
  transform: translateY(13%);
}

/* GRUPO 3 — overlay sobre los videos (DESKTOP; movil/tablet se fijan en el
   @media max-width:900px, que gana a estas reglas y no se ve afectado).
   Titulo: el doble de grande que antes (era clamp(18px,1.9vw,30px)).
   Subtitulo: mismas caracteristicas que el grupo 2 (tokens --content-*). */
.language-caption h3 {
  font-weight: 400;
  font-size: var(--type-caption);
  line-height: 1.15;
  letter-spacing: var(--tracking);
}

.language-caption p {
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

/* Desktop: acercar el subtítulo al título del overlay. La regla general
   `.section h3 + p` metía hasta 48px de margin-top entre ellos (además del gap del
   flex), por eso se veían muy separados. Lo anulamos para que queden juntos. Solo
   desktop: en móvil el subtítulo va debajo del vídeo con su propio margen. */
@media (min-width: 901px) {
  .language-caption h3 + p {
    margin-top: 0;
  }
}

/* Sobre el video el texto va en blanco puro, sin la transparencia de --color-muted
   que hereda de `.section p`. (Sin sombra: el cliente la quitó.) */
.language-caption h3,
.language-caption p {
  color: #fff;
}

/* El item "La precision de lo invisible" es el unico con DOS subtitulos (frase +
   specs "8K RAW..."). Cada subtitulo en UNA sola linea para que el bloque no
   crezca y el 2o no caiga en la banda inferior. En la fuente monospace, a anchos
   de desktop, ambas lineas caben en el 65% del caption. (En movil se resetea.) */
.language-item--specs .language-caption p {
  white-space: nowrap;
}

/* Entre la descripcion y la linea de specs ("8K RAW...") una separacion
   pequena: la regla general `.section p + p` metia hasta 48px (demasiado),
   pero a 0 quedaban pegadas y no parecian dos frases. */
.language-caption p + p {
  margin-top: 16px;
}


.work-section,
.itw-section {
  text-align: center;
  /* Sin padding inferior: el aire bajo el carrusel lo aporta el propio carrusel
     (--carousel-bottom), no la seccion, para que el carrusel sea autocontenido. */
  padding-bottom: 0;
}

/* El carrusel del equipo es el UNICO hijo de itw-section, asi que su aire de
   arriba lo controla SOLO --carousel-top (igual que el de abajo): quitamos el
   padding-top de .section (~--section-y) que se sumaba encima. Un unico mando
   arriba/abajo. (work-section NO: arriba lleva el work-video, no el carrusel.) */
.itw-section {
  padding-top: 0;
}

.carousel {
  position: relative;
  overflow: hidden;
  /* Cada carrusel es una "seccion" autocontenida: su espacio arriba/abajo es
     propio y configurable por instancia (--carousel-top / --carousel-bottom). */
  padding-top: var(--carousel-top, 0);
  padding-bottom: var(--carousel-bottom, 0);
  /* Al mantener el dedo para parar el carrusel, el navegador seleccionaba el texto
     o sacaba el menú de la imagen (guardar imagen…). Desactivamos selección y el
     callout de iOS dentro del carrusel (heredado por textos e imágenes). */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Evita el arrastre/menú "guardar imagen" de los pósters al mantener pulsado. */
.carousel img {
  -webkit-user-drag: none;
  user-drag: none;
}

.carousel-inner {
  display: flex;
  gap: 60px;
  will-change: transform;
}

.carousel > .poster-list,
.carousel > .team-list,
.carousel-inner > .poster-list,
.carousel-inner > .team-list {
  margin-top: 0;
}

.carousel-btn {
  position: absolute;
  /* Centrado en los POSTERS, no en la caja con padding: el carrusel mide
     padding-top + posters + padding-bottom, y esos paddings son asimetricos
     (--carousel-top != --carousel-bottom). Partimos del centro real (50%) y lo
     desplazamos media diferencia de paddings para caer en el centro de los
     posters. Las custom props se heredan desde .carousel. */
  top: calc(50% + (var(--carousel-top, 0px) - var(--carousel-bottom, 0px)) / 2);
  transform: translateY(-50%);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: rgba(10, 10, 10, 0.6);
  border: 1px solid rgba(244, 241, 236, 0.18);
  border-radius: 0;
  color: var(--color-text);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  /* Muy atenuadas por defecto; se acentúan al hover (mismo tempo: 500ms ease). */
  opacity: 0.4;
  transition: opacity 500ms ease, background 180ms ease;
}

.carousel-btn:hover {
  opacity: 1;
  background: rgba(40, 40, 40, 0.8);
}

.carousel-btn--prev { left: 0; }
.carousel-btn--next { right: 0; }

.poster-list {
  display: flex;
  gap: 30px;
  flex-shrink: 0;
  text-align: left;
}

.poster-card {
  width: min(620px, 80vw);
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}

.poster-card img {
  width: 100%;
  height: auto;
  display: block;
  transition: filter 4s cubic-bezier(0.16, 1, 0.3, 1);
}

.poster-card:hover img {
  filter: brightness(0.15);
}

.poster-info {
  position: absolute;
  bottom: clamp(24px, 3vw, 40px);
  left: clamp(24px, 3vw, 40px);
  right: clamp(24px, 3vw, 40px);
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 2.6s cubic-bezier(0.16, 1, 0.3, 1),
              transform 2.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.poster-card:hover .poster-info {
  opacity: 1;
  transform: none;
}

.poster-info h3 {
  margin: 0 0 10px;
}

/* Salto pequeño entre los bloques del póster (título → subtítulo → info técnica):
   las reglas genéricas .section h3+p / .section p+p metían un margin-top grande
   (clamp 24–48px) que los separaba demasiado. Aquí lo reducimos. */
.poster-info h3 + p,
.poster-info p + p {
  margin-top: 10px;
}

.poster-info p {
  font-size: var(--type-small);
  line-height: 1.4;
  color: var(--color-muted);
}

.poster-meta {
  font-size: var(--type-small);
  letter-spacing: var(--tracking);
  color: var(--color-muted);
}


.team-list {
  display: flex;
  gap: 70px;
  flex-shrink: 0;
  text-align: left;
}

.team-list article {
  width: min(320px, 70vw);
  flex-shrink: 0;
  min-height: 190px;
  padding-top: 22px;
}

.team-list p {
  font-size: var(--type-small);
  line-height: 1.85;
}

/* TRACKING del GRUPO BODY (el "azul" del debug tipográfico): el cliente pide
   0.15em en TODO el grupo —títulos de sección, nombres de equipo, títulos de
   póster, manifiestos y subtítulos de captions— en lugar del 0.12em general.
   SOLO DESKTOP (min-width:901px): en móvil/tablet el grupo azul se queda como
   estaba (títulos 0.12 por su `var(--tracking)`, párrafos 0.05 heredados del
   `body` de móvil), porque en pantalla estrecha 0.15 deja los párrafos demasiado
   aireados. Va después de las reglas que fijaban el tracking de esos elementos
   para ganarles por orden con la misma especificidad; la excepción de Ingrid
   (`.team-card--long h3`, 0.01em) tiene más especificidad y NO se ve afectada. */
@media (min-width: 901px) {
  .section > h2,
  .media-reference h3,
  .poster-card h3,
  .team-list h3,
  .section p,
  .manifesto h2,
  .manifesto p,
  .language-caption p {
    letter-spacing: 0.15em;
  }

  /* `.section p` (azul) también captura párrafos que NO son del grupo body: las
     frases del hero (naranja) y la info/meta de póster + cargos de equipo (verde).
     Los reafirmamos al tracking general 0.12 DESPUÉS, igual que el propio debug
     los repinta de su color con reglas posteriores. */
  .hero-sequence p,
  .poster-info p,
  .poster-meta,
  .team-list p {
    letter-spacing: var(--tracking);
  }
}

.final {
  padding: 0;
}

.final-tagline {
  /* Pantalla completa en TODAS las pantallas: "stay wild" centrado, sin que asome
     el video de arriba (.final) ni las marcas de abajo (.partners). lvh fija (no
     salta al plegarse la barra de URL; misma logica que .manifesto--full). */
  min-height: 100vh;
  min-height: 100lvh;
  display: grid;
  place-content: center;
  text-align: center;
}

.final-tagline h2 {
  margin: 0 auto;
  font-size: var(--type-display);
  text-align: center;
}

.partners {
  display: flex;
  /* Una sola línea en desktop: los 9 logos en fila, sin envolver. */
  flex-wrap: nowrap;
  --partners-gap: clamp(16px, 2.4vw, 40px);
  gap: var(--partners-gap);
  justify-content: center;
  align-items: center;
  /* Edge-to-edge como las secciones de texto / "stay wild": sin tope de 980px
     (ancho del footer) que la encajonaba. El ancho lo da la sección (viewport
     menos el padding de página), así las celdas son más anchas y los logos,
     limitados por el ancho de celda, se ven más grandes. */
  padding-top: var(--section-y-tight);
  padding-bottom: var(--section-y-tight);
}

.partners img {
  /* Los 9 logos en UNA línea: celdas iguales que se reparten el ancho (flex:1 1 0)
     y que PUEDEN encoger (min-width:0; sin él, una <img> no baja de su ancho
     intrínseco y los 9 desbordarían). max-height + object-fit mantienen cada logo
     contenido sin depender del ancho de su archivo. */
  flex: 1 1 0;
  min-width: 0;
  max-height: 60px;
  object-fit: contain;
  opacity: 0.7;
}

/* Un poco de aire lateral en desktop: edge-to-edge dejaba los logos demasiado
   abiertos a lo ancho. Mete algo más de margen que el padding de página normal
   (~72px máx) sin volver al encajonado de 980px. Solo desktop (en móvil es un
   grid de 3 columnas, no se sobreextiende). */
@media (min-width: 901px) {
  .partners {
    padding-inline: clamp(46px, 9.2vw, 150px);
  }
}

.site-footer {
  /* Full-width con los mismos márgenes laterales que la sección de marcas (ver
     @media desktop abajo). Antes estaba topado a 980px y quedaba estrecho. Destino
     de "Contact": ocupa toda la pantalla. lvh (no dvh): altura fija con la barra
     oculta → no salta al plegarse/desplegarse la barra. */
  width: 100%;
  min-height: 100vh;
  min-height: 100lvh;
  display: grid;
  /* 3 columnas: "stay wild" (izda) | logo (centro) | contactos (dcha). Los laterales
     son minmax(0,1fr) — EXACTAMENTE iguales aunque el email sea más ancho que "stay
     wild" — para que el logo quede centrado de verdad y cada lateral pegado a su
     extremo del contenedor. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  /* Todo alineado ABAJO: "stay wild" y el email quedan a la altura del borde
     inferior del logo. align-content centra el bloque entero en la pantalla. */
  align-items: end;
  align-content: center;
  padding: var(--section-y-tight) var(--page-x);
  border-top: 1px solid var(--color-line);
}

/* Mismos márgenes laterales que la sección de marcas (.partners) en desktop. */
@media (min-width: 901px) {
  .site-footer {
    padding-inline: clamp(46px, 9.2vw, 150px);
    /* Ancla para posicionar el copyright al fondo de la sección. */
    position: relative;
  }

  /* El archivo del logo (cuadrado 2000×2000) tiene ~28,25% de espacio transparente
     bajo el emblema (bbox alfa: bottom=1435/2000). Con align-items:end el texto se
     alineaba al borde de la IMAGEN, quedando muy por debajo del logo VISIBLE. Subimos
     el borde inferior de la caja del logo a su parte visible con un margin-bottom
     negativo = 28,25% de su alto (el alto = ancho, porque es cuadrado), así "stay
     wild" y el email caen justo al borde inferior del logo visible. */
  .site-footer img {
    margin-bottom: calc(min(360px, 60vw) * -0.2825);
  }

  /* Copyright al FONDO de la sección (no centrado con el bloque): lo sacamos del grid
     con position:absolute y lo anclamos abajo, dejando ~14px MENOS de aire que el
     padding inferior. El contenido principal (logo + textos) queda centrado solo. */
  .copyright {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(var(--section-y-tight) - 14px);
    margin: 0;
  }
}

.footer-tagline {
  margin: 0;
  justify-self: start;
  color: var(--color-muted);
  font-size: var(--type-small);
  line-height: 1.7;
}

.site-footer img {
  width: min(360px, 60vw);
}

.site-footer address {
  display: grid;
  gap: 14px;
  /* Contactos a la derecha (justify-self: end) y texto alineado a la derecha
     (justify-items: end). El orden del HTML es @instagram (arriba) y email (abajo);
     al estar el bloque alineado abajo, el email cae al borde inferior del logo,
     al mismo nivel que "stay wild", y el instagram queda justo encima. */
  justify-self: end;
  justify-items: end;
  color: var(--color-muted);
  font-style: normal;
  font-size: var(--type-small);
  line-height: 1.7;
}

.copyright {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--color-muted);
  font-size: var(--type-small);
}

@media (max-width: 1024px) {
  :root {
    --header-height: 78px;
    --page-x: clamp(20px, 4.5vw, 46px);
    --section-y: clamp(86px, 14vw, 170px);
  }

  .site-header {
    grid-template-columns: auto 1fr auto;
  }

  .site-nav {
    gap: 12px 16px;
  }

  /* Tablet/móvil (V y H): centramos el bloque vídeo+frases del hero en la PANTALLA
     (no pegado arriba como en desktop). .hero-media es absoluta; con top:50% +
     translateY(-50%) queda centrada en el .hero (100vh). Si el vídeo es más bajo
     que la pantalla → negro arriba y abajo; si es más alto (landscape) → recorte
     simétrico por overflow:hidden. Desktop (>1024px) NO se toca: sigue en top:0. */
  .hero-media {
    top: 50%;
    transform: translateY(-50%);
  }

}

@media (max-width: 900px) {
  :root {
    --header-height: 66px;
    --page-x: 22px;
    --section-y: clamp(76px, 18vw, 128px);
    --section-y-tight: clamp(48px, 12vw, 86px);
    /* Sin bandas de cine en móvil/tablet, el único separador entre vídeos apilados
       es este gap; lo subimos de 10px a 50px para que no queden pegados. */
    --video-batch-gap: 50px;
    /* Grupo azul MÁS GRANDE en móvil (en desktop es clamp(12px,1.3vw,19px), que en
       móvil se quedaba ~12px). Subimos el token para TODO el grupo a la vez, así
       manifiestos, títulos de sección, subtítulos de Language, nombres de equipo y
       títulos de póster son iguales y grandes. */
    --type-body: clamp(14px, 3.3vw, 20px);
  }

  /* EXCEPCIÓN de tracking en móvil/tablet: el tracking único del sistema es 0.12em
     (en `body`), pero en pantalla estrecha 0.12 deja los PÁRRAFOS demasiado aireados.
     Volvemos el tracking heredado a 0.05em (como estaba): afecta solo a los textos
     que NO fijan su propio letter-spacing (párrafos), porque títulos/nav/meta llevan
     `var(--tracking)` explícito y mantienen 0.12. Desktop no se toca. */
  body {
    letter-spacing: 0.05em;
  }

  /* Reveal barato en móvil: el efecto completo anima blur() y clip-path durante
     2,6–5s, que en móvil compite con la decodificación de vídeo y causa tirones.
     Quitamos blur/clip-path (caros de pintar) y dejamos opacity + transform: el
     transform va por el compositor (GPU), es barato, y conserva la entrada con
     escala del "stay wild" (.reveal--stay-wild). En desktop, intacto. (FIX 3.2) */
  .reveal,
  .reveal--stay-wild,
  .reveal--language-caption {
    filter: none;
    clip-path: none;
    transition: opacity 1.6s cubic-bezier(0.16, 1, 0.3, 1),
                transform 1.6s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .reveal.is-visible {
    filter: none;
    clip-path: none;
  }

  .site-header {
    grid-template-columns: auto auto;
    justify-content: space-between;
    padding: 18px var(--page-x);
  }

  .site-nav {
    display: none;
  }

  .menu-toggle {
    display: block;
  }

  /* En tablet ya aparece el menú hamburguesa, que YA incluye su propio selector
     de idioma. El selector del header se duplicaba con él. Lo ocultamos aquí
     (igual que en móvil) y el ES|EN queda solo dentro del menú. El switch de
     dentro de .mobile-menu no se ve afectado. */
  .site-header .language-switch {
    display: none;
  }

  .language-switch {
    gap: 8px;
  }

  .hero .video-placeholder--bg {
    width: 100%;
  }

  .hero-sequence p {
    font-size: clamp(14px, 4.2vw, 23px);
    letter-spacing: var(--tracking);
  }

  .manifesto {
    min-height: 58vh;
  }

  /* Manifiestos en móvil al tamaño del grupo azul (--type-body): se quita el override
     clamp(13px,3vw,18px) para que sean IGUALES al resto de textos azules (títulos de
     sección, etc.), no un tamaño aparte. */

  .media-sequence,
  .language-list,
  .poster-list,
  .team-list {
    margin-top: 42px;
  }

  .section-content.media-sequence,
  .section-content > .media-sequence,
  .section-content > .language-list,
  .section-content > .poster-list,
  .section-content > .team-list {
    margin-top: 0;
  }

  .section-content.media-sequence,
  .section-content > .media-sequence {
    padding-top: 0;
  }

  /* Doblar el hueco entre vídeos apilados de una misma secuencia (Stop the world,
     On the road). Language va aparte: sus vídeos están separados por su texto/overlay
     y ya se doblaron en .language-list. */
  .media-sequence {
    gap: calc(var(--video-batch-gap) * 2);
  }

  /* Aire entre el título de sección y el vídeo que va justo debajo (Stop the world,
     On the road, Language), que estaban demasiado juntos. */
  #stop,
  .road-heading,
  .language-heading {
    padding-bottom: clamp(48px, 12vw, 80px);
  }

  /* En movil/tablet no hay banda de cine: los videos de seccion ocupan su caja
     16:9 completa (la banda --cine-band es solo de desktop). */
  .media-reference .video-real,
  .final .video-real {
    top: 0;
    height: 100%;
  }

  .team-list article {
    min-height: auto;
  }

  .carousel-inner > .poster-list,
  .carousel-inner > .team-list {
    margin-top: 0;
  }

  .poster-card {
    overflow: visible;
    display: flex;
    flex-direction: column;
  }

  .poster-card img {
    filter: none;
    transition: none;
  }

  .poster-card:hover img {
    filter: none;
  }

  .poster-info {
    position: static;
    opacity: 1;
    transform: none;
    transition: none;
    /* Alineado a la izquierda, al ras del borde izquierdo del póster (antes centrado). */
    text-align: left;
    max-width: 100%;
    padding: 18px 0 0;
  }

  /* En móvil el caption es display:contents: sus hijos (h3, p) se colocan dentro del
     .language-item (flex column). El SUBTÍTULO (p) va debajo del vídeo (order 1). El
     TÍTULO (h3) va SUPERPUESTO en el cuarto inferior (centrado H) sobre el vídeo, mostrándose los primeros 6s
     de cada vuelta del loop (clase .is-title-on que pone videos.js). El vídeo es relative
     con su caja 16:9; el placeholder se oculta (el propio vídeo hace de marcador). */
  .language-item {
    display: flex;
    flex-direction: column;
    /* Como item del grid de Language, permitir que encoja por debajo de su
       min-content: si no, un texto largo (p. ej. la línea de specs) ensancha el
       track y arrastra TODOS los vídeos al overflow. */
    min-width: 0;
    /* Ancla para el título superpuesto. */
    position: relative;
  }

  .language-caption {
    display: contents;
  }

  .language-item .video-placeholder {
    display: none;
  }

  .language-item .video-real {
    position: relative;
    inset: auto;
    order: 0;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }

  /* Título superpuesto sobre el vídeo, centrado H y en el 25% inferior: caja
     absoluta que cubre la del vídeo (top:0, todo el ancho, mismo 16:9). Oculto por defecto; videos.js añade
     .is-title-on al .language-item los primeros 6s de cada vuelta del loop → fade in,
     y lo quita → fade out. pointer-events:none para no bloquear el vídeo. */
  .language-caption h3 {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
    /* Altura explícita (NO aspect-ratio): el vídeo es full-width 16:9 → alto = 100vw·9/16
       = 56.25vw. Safari/WebKit tiene un bug con aspect-ratio en absolute + left/right (sin
       height): encogía la caja a su contenido anclada a la izquierda, y el título salía
       descentrado en iPhone (en Chrome/Android salía bien). Con height fija se centra en todos. */
    height: 56.25vw;
    margin: 0;
    /* Flex centering (antes grid place-content, que descentraba con multilínea). */
    display: flex;
    /* Centrado horizontalmente pero NO verticalmente: apoyado en el 25% inferior del
       vídeo. flex-end lo pega al fondo de la caja (= fondo del vídeo) y el padding-bottom
       lo sube un poco para que quede en el cuarto inferior, no pegado al borde. */
    align-items: flex-end;
    justify-content: center;
    padding-inline: var(--page-x);
    padding-bottom: 6vw;
    /* Un pelo más grande que el subtítulo (--type-body +2px) y, además, +30% (el
     cliente lo quiere más grande en móvil). */
    font-size: calc((var(--type-body) + 2px) * 1.3);
    text-align: center;
    opacity: 0;
    pointer-events: none;
    /* Fade largo: el título va apareciendo gradualmente al acercarse el vídeo. */
    transition: opacity 2.5s ease;
  }

  .language-item.is-title-on .language-caption h3 {
    opacity: 1;
  }

  /* Doble separación entre los vídeos de Language (el doble del --video-batch-gap de
     móvil). Solo Language; el resto de secuencias mantienen su separación. */
  .language-list {
    gap: calc(var(--video-batch-gap) * 2);
  }

  .language-caption p {
    order: 1;
    margin: 14px 0 0;
    padding-inline: var(--page-x);
    /* Sin override de tamaño: hereda --type-body (grupo azul), igual que el resto de
       textos azules. (Antes 10px, que lo dejaba aparte del grupo.) */
    line-height: 1.7;
    text-align: center;
    /* En movil SI se permite envolver (el nowrap del item de specs es solo desktop;
       en pantalla estrecha una sola linea desbordaria). */
    white-space: normal;
  }

  /* El item de "specs" lleva white-space:nowrap en DESKTOP (cabe en el 65% del
     caption). En MOVIL ese nowrap NO debe aplicar: la linea "8K RAW, High Speed,
     ..." (~67 caracteres) mide ~400px y, al no envolver, ensanchaba el track del
     grid de Language -> TODOS los videos se estiraban a ese ancho y aparecia
     scroll lateral (y el header width:100% se descolocaba). OJO ESPECIFICIDAD:
     el reset generico de arriba (.language-caption p) NO basta porque pierde
     frente a .language-item--specs .language-caption p (0,2,1) de desktop. Esta
     regla iguala esa especificidad y va DESPUES (dentro del @media) -> gana. */
  .language-item--specs .language-caption p {
    white-space: normal;
  }

  .language-caption p + p {
    margin-top: 8px;
  }

  /* Espacio negro tras el último vídeo de Language (debajo de "…Time lapse"): la
     sección Language no llevaba padding inferior, así que el título "Work" quedaba
     casi tan cerca de Language como de su propio texto "Nuestro trabajo…" (que es un
     manifiesto con padding-top). Añadimos padding-bottom para separar Language de
     "Work" y que el título agrupe con su sección. Solo móvil. */
  .language-section {
    padding-bottom: calc(var(--section-y-tight) * 2);
  }

  /* Más aire DEBAJO del carrusel de pósters (antes de "Into the Wild"). Se iguala al
     espacio Language->WORK (ambos gaps comparten el padding-top del .section-heading
     siguiente, así que basta replicar su parte "extra": el calc(--section-y-tight * 2)
     de .language-section) y, además, se suma el alto de una línea del título
     ("Into the Wild", que en móvil usa --type-body). Solo móvil. */
  .work-section > .carousel {
    --carousel-bottom: calc(var(--section-y-tight) * 2 + var(--type-body) * 1.3);
  }

  .partners {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    justify-items: center;
  }

  .partners img {
    max-width: 86px;
    max-height: 34px;
  }

  .site-footer {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }

  /* En móvil el footer se simplifica: fuera el "stay wild" (quedan solo logo,
     enlaces de RRSS/contacto y copyright). */
  .footer-tagline {
    display: none;
  }

  /* Una sola columna centrada: anulamos el justify-self end de desktop. */
  .site-footer address {
    justify-self: center;
  }

  .site-footer address {
    justify-items: center;
  }
}

/* En vertical (móvil/tablet) el hero es alto y estrecho: con object-fit: cover
   un vídeo 16:9 se recorta a una franja central y se ve "en portrait". Con
   contain mostramos el plano completo centrado; el fondo del hero rellena las
   franjas de arriba y abajo. En horizontal mantenemos cover (ahí sí encaja). */
@media (max-width: 900px) and (orientation: portrait) {
  .hero .video-real {
    object-fit: contain;
  }
}

/* Bloques de texto-manifiesto a pantalla completa, centrados (negro arriba/abajo),
   en TABLET y MÓVIL. DESKTOP/portátil no se toca. El 1er manifiesto ("There is
   still a wild Earth") ya es full en todos los tamaños aparte.

   Los de 3 párrafos (2º manifiesto "Stop the world…" + itw-text "We do not
   accumulate time…"; solo el texto, el equipo de detrás no se toca) se centran:
   - en VERTICAL: tablet y móvil (≤1024px);
   - en HORIZONTAL: SOLO tablet, NO móvil. El iPad en horizontal mide 1080–1366px
     (supera 1024), así que la rama landscape NO usa max-width:1024 sino
     `pointer: coarse` (táctil → tablet/móvil, deja fuera portátiles que son `fine`)
     + `min-height: 600px` (excluye móviles en horizontal, que son más bajos; ahí
     3 párrafos no caben) + tope 1366px (iPad Pro 12,9"). */
@media (max-width: 1024px) and (orientation: portrait),
       (orientation: landscape) and (pointer: coarse) and (min-height: 600px) and (max-width: 1366px) {
  /* lvh (no dvh): altura fija con la barra oculta → no hay reflujo/salto al
     plegarse la barra de URL durante el scroll (dvh recalculaba y saltaba). */
  .manifesto {
    min-height: 100vh;
    min-height: 100lvh;
  }

  /* "Existe una Tierra…" (.manifesto--full) se queda full-screen (100vh): NO lleva
     override. "Nuestro trabajo…" (.work-text) baja a 50vh (contexto propio, sobre el
     work-video). La doble clase gana al min-height:100vh de arriba. */
  .manifesto.work-text {
    min-height: 50vh;
    min-height: 50lvh;
  }

  /* "Llevamos más de 25 años…" (.itw-intro, SOBRE el vídeo de ITW) y "No acumulamos
     tiempo…" (.itw-text, BAJO el mismo vídeo): distancia AL VÍDEO amplia e IDÉNTICA en
     los dos (como estaba "Llevamos…" con 50vh). Con min-height:fijo + centrado, textos
     de distinta altura (1 vs 3 párrafos) daban distancias distintas; con auto + padding
     grande SOLO en el lado del vídeo, la distancia es fija e igual. El lado exterior
     (hacia el título / hacia el equipo) mantiene el --section-y-tight. */
  .manifesto.itw-intro,
  .manifesto.itw-text {
    min-height: auto;
  }
  .manifesto.itw-intro {
    padding-bottom: clamp(96px, 22vw, 150px);
  }
  .manifesto.itw-text {
    padding-top: clamp(96px, 22vw, 150px);
  }
}

@media (max-width: 480px) {
  .site-logo,
  .site-nav a,
  .language-switch button,
  .menu-toggle {
    font-size: 10px;
  }

  /* El selector de idioma del header ya se oculta desde ≤900px (ver arriba); en
     móvil la cabecera queda en 2 columnas (logo + hamburguesa). */

  .partners {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* El selector universal `*` tiene especificidad (0,0,0) y perdía contra
   `.reveal`, `html { scroll-behavior: smooth }`, etc.: con movimiento reducido
   activado el CSS seguía animando (solo el JS lo respetaba). `!important` fuerza
   que gane. `scroll-behavior` se aplica al contenedor de scroll (`html`), no a `*`. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  html {
    scroll-behavior: auto !important;
  }

  .hero-line {
    opacity: 1;
    animation: none;
  }

  /* Excepción para el menú móvil: la regla `*` de arriba colapsaría su fade a
     ~0 → el menú saldría "de golpe". Un cross-fade de opacidad NO es movimiento
     (no hay desplazamiento), así que es accesible mantenerlo. Le devolvemos una
     transición de opacity suave; gana al `*` por especificidad. */
  .mobile-menu {
    transition: opacity 700ms ease !important;
  }
}
