/* ============================================================
   footnote — PLANTILLA de despliegue de proyecto
   Usada por proyectos/virgin-voyage, project-4 y project-5.
   Es el layout de Lafayette (el más completo) con TODO el color en
   variables --proj-*: cada página sobrescribe solo la paleta en un
   <style> de su <head> (ver "PALETA DEL PROYECTO" en el HTML) y no
   toca este archivo.

   Para un proyecto nuevo: copiar la carpeta proyectos/virgin-voyage/,
   cambiar nombre, slug, paleta y contenido (ver proyectos/README.md).
   Cuando un proyecto necesite un dispositivo que los demás no tienen,
   se añade aquí como clase nueva — no se bifurca el archivo.

   Las fuentes se cargan con rutas relativas a ESTE archivo
   (assets/css → ../fonts).
   ============================================================ */

@font-face {
  font-family: "Sharp Grotesk Black 15";
  src: url("../fonts/sharp-grotesk-black15.woff2") format("woff2");
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: "Sharp Grotesk Medium 15";
  src: url("../fonts/sharp-grotesk-medium15.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
/* Corte que faltaba: el usuario dejó el .otf en fonts/ (no en assets/fonts/,
   por eso no se había convertido a woff2 hasta ahora) — es el que el
   wireframe usa de verdad para el cuerpo de texto (intro, setup, "our
   role"...), no el Black que se estaba usando ahí por error: el Black es
   SOLO para titulares gigantes (hero, statement), y a ese peso el cuerpo
   de párrafo se leía mucho más pesado de lo que el mockup muestra. */
@font-face {
  font-family: "Sharp Grotesk SemiBold 15";
  src: url("../fonts/sharp-grotesk-semibold15.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Anton";
  src: url("../fonts/anton.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("../fonts/geist-mono.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("../fonts/instrument-sans.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}

:root {
  /* — Paleta POR DEFECTO de la plantilla (neutra). Cada proyecto la
       sobrescribe en el <style> de su <head>; no se edita aquí. —
       --proj-ink        tinta: texto, hero, menú y círculo de transición
       --proj-ink-deep   la misma tinta, más profunda (fondo del hero al cargar)
       --proj-accent     acento de enlaces/foco (por defecto el naranja del estudio)
       --proj-paper      fondo de la página
       --proj-paper-dim  recuadros de imagen pendiente
       OJO: si cambias --proj-ink, cámbialo también en PROJECT_ACCENTS de
       assets/js/app.js (el círculo de transición del Home lo toma de ahí). */
  --proj-ink: #15171C;
  --proj-ink-deep: #0B0C0F;
  --proj-accent: #FF6022;
  --proj-paper: #FFFFFF;      /* fondo BLANCO (pedido 7-oct) */
  --proj-paper-dim: #EFEDF1;
  --proj-white: #FFFFFF;

  --white: #FFFFFF;
  --orange: #FF6022;   /* el punto del logo del estudio no cambia de proyecto a proyecto */

  --u: calc(min(calc(100vw / 1512), calc(1svh * 100 / 920)));
  --gutter: max(20px, calc(28 * var(--u)));
  --edge-top: calc(22 * var(--u));
  --edge-bottom: max(16px, calc(26 * var(--u)));

  --f-black: "Sharp Grotesk Black 15", "Anton", "Arial Narrow", Impact, sans-serif;
  --f-semibold: "Sharp Grotesk SemiBold 15", "Sharp Grotesk Medium 15", system-ui, sans-serif;
  --f-medium: "Sharp Grotesk Medium 15", "Instrument Sans", system-ui, sans-serif;
  --f-mono: "Geist Mono", ui-monospace, monospace;
  --f-ui: "Instrument Sans", system-ui, sans-serif;

  --t-ui: max(11px, calc(12 * var(--u)));
  --track-ui: 0.14em;
  --logo-w: calc(45 * var(--u));
  --logo-h: calc(41.3 * var(--u));
  --logo-f: calc(48 * var(--u));
  --logo-dot: calc(19.6 * var(--u));
  --menu-dot: calc(10 * var(--u));

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.76, 0, 0.24, 1);

  --z-chrome: 10;
  --z-nav: 20;
  --z-nav-chrome: 30;
  --z-cursor: 40;
  --z-reveal: 50;
}

/* Número animable de verdad (no solo un string interpolado a ojo): deja
   que `transition: --fill/--stroke` en .statement__title interpole con
   suavidad en vez de saltar en un solo paso — el mismo `--fill`/`--stroke`
   que ya usa el home por letra, aquí a nivel de bloque completo porque
   los titulares de proyecto son una afirmación fija, no el carrusel. */
@property --fill { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --stroke { syntax: '<number>'; inherits: true; initial-value: 1; }

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; background: var(--proj-paper); color: var(--proj-ink); }
body {
  font-family: var(--f-ui);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* NO overflow-x:hidden aquí: con overflow-y sin especificar, la propia
     spec de CSS lo convierte en overflow-y:auto — <body> pasa a ser SU
     PROPIO contenedor de scroll (sin alto fijo, así que no scrollea nada
     de verdad) y deja de coincidir con el scroll real del documento.
     Causaba una página en blanco: el texto existía, medía bien, tenía
     color correcto — pero pintaba en un contexto de scroll que ya no
     era el que la pantalla mostraba. Si algún elemento llega a desbordar
     en horizontal, se resuelve en ESE elemento (max-width, clamp), no
     apagando el overflow de la página entera. */
}
main { display: block; }
img { max-width: 100%; display: block; }
sup { font-size: 0.6em; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
:focus-visible { outline: 2px solid var(--proj-accent); outline-offset: 4px; }

/* ============================================================
   TRANSICIÓN CIRCULAR — el overlay que app.js del home escribe antes
   de navegar (guarda {x,y} del clic en sessionStorage) y esta página
   consume al cargar: arranca cubriendo TODO en el acento del proyecto
   y se ENCOGE (clip-path circle, no width/height) hasta desaparecer en
   el punto de origen. Si no hay dato (entrada directa por URL, o venir
   del propio menú), arranca desde el centro — nunca deja la página sin
   abrir. `pointer-events:none` desde el primer cuadro: nunca bloquea.
   ============================================================ */
.reveal-circle {
  position: fixed; inset: 0; z-index: var(--z-reveal);
  /* Verde de marca (el del hero), no el lima: el círculo se funde con el hero
     al abrirse — nada de parche de color distinto. */
  background: #FF6022;   /* naranja de la marca: el mismo color con que el Home abre la transición, a la ida y a la vuelta */
  pointer-events: none;
  /* Arranca cubriendo TODO y se encoge SOLO con una animación CSS que corre al
     cargar. Antes dependía de que imatana.js (diferido) añadiera `.reveal-open`;
     ese retraso dejaba un instante el círculo estático = el "parche verde". Al
     ser animación pura, se encoge desde el primer cuadro pintado, siempre fluido.
     El head-script ya fijó --rx/--ry antes de pintar, así que sale del punto del
     clic; sin dato (entrada directa) sale del centro. */
  clip-path: circle(150% at var(--rx, 50%) var(--ry, 50%));
  animation: reveal-shrink 0.95s var(--ease-io) forwards;
}
@keyframes reveal-shrink {
  from { clip-path: circle(150% at var(--rx, 50%) var(--ry, 50%)); }
  to   { clip-path: circle(0% at var(--rx, 50%) var(--ry, 50%)); }
}
/* Fallback si el JS marcó reveal-open igual (no rompe la animación). */
.reveal-open .reveal-circle { clip-path: circle(0% at var(--rx, 50%) var(--ry, 50%)); }

/* Salida: ahora CUALQUIER link interno de esta página (menú, "← All
   projects", logo) puede disparar navigateWithReveal (ver app.js), no solo
   el carrusel del home — así que este despliegue también necesita su propio
   círculo CRECIENDO antes de irse, igual que site.css. Cancela la animación
   de entrada (ya terminada a esta altura, pero por si acaso) para que la
   transición de salida parta del clip-path real, no compita con ella. */
.is-leaving .reveal-circle {
  animation: none;
  transition: clip-path 0.7s var(--ease-io);
  clip-path: circle(150% at var(--rx, 50%) var(--ry, 50%));
}
@media (prefers-reduced-motion: reduce) {
  .reveal-circle { animation: none; clip-path: circle(0% at 50% 50%); }
}

/* ============================================================
   CURSOR — el mismo punto naranja del home (initCursor de app.js ya
   generaliza el mecanismo, ver assets/js/app.js): coherencia de marca
   entre despliegues, "los botones deberían aparecer como el botón de
   ver en el home". Sin `.stage`, la zona activa es TODA la página
   (`body:has(...)` sin acotar a un contenedor), y la insignia se
   enciende sobre cualquier `[data-cursor-label]`. */
body:has(.cursor-dot.is-visible) { cursor: none; }
.cursor-dot {
  position: fixed; top: 0; left: 0; width: 0; height: 0;
  pointer-events: none; z-index: var(--z-cursor);
  opacity: 0; transition: opacity 0.2s ease; will-change: transform;
}
.cursor-dot.is-visible { opacity: 1; }
.cursor-dot__shape {
  position: absolute; top: 0; left: 0; width: 72px; height: 72px; margin: -36px 0 0 -36px;
  border-radius: 50%; background: var(--orange);
  display: flex; align-items: center; justify-content: center;
  /* Punto más grande (≈22px) — regla general en todo el sitio. */
  transform: scale(0.3);
  transition: transform 0.4s var(--ease-out);
}
.cursor-dot.is-label .cursor-dot__shape { transform: scale(1); }
.cursor-dot__label {
  font-family: var(--f-mono); font-weight: 600; font-size: 12px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--proj-ink); opacity: 0; transition: opacity 0.15s ease;
}
.cursor-dot.is-label .cursor-dot__label { opacity: 1; transition-delay: 0.12s; }

/* ============================================================
   CHROME — mismos nombres de clase que el home (.chrome, .ui-btn,
   .logo, .nav-panel) para heredar el comportamiento de app.js sin
   reescribirlo; solo cambia la paleta (tinta oscura sobre papel claro,
   en vez de blanco sobre negro).
   ============================================================ */
.chrome {
  position: fixed; left: var(--gutter); right: var(--gutter);
  z-index: var(--z-chrome);
  display: flex; align-items: center; gap: calc(20 * var(--u));
  text-transform: uppercase;
  pointer-events: none;
}
.chrome > * { pointer-events: auto; }
.chrome--top { top: var(--edge-top); z-index: var(--z-nav-chrome); }

/* El header es `position:fixed`: se queda SIEMPRE arriba, así que pasa
   por encima del verde oscuro del hero al cargar y del papel claro de
   las secciones de abajo en cuanto se hace scroll — un solo color de
   tinta no lee bien contra los dos. En vez de perseguir el fondo real
   (tendría que recalcularse con el scroll), texto siempre claro +
   sombra corta, mismo criterio que usa el home para su link/contador
   sobre una foto de contenido variable: funciona razonablemente sobre
   cualquier fondo sin tener que saber cuál es. */
/* Logo: la imagen real del estudio (misma que el home), no el F+punto viejo. */
.logo { position: relative; display: flex; align-items: center; flex: none; height: var(--logo-h); text-decoration: none; }
.logo__img { display: block; height: 100%; width: auto; transition: opacity 0.3s ease; filter: drop-shadow(0 1px 10px rgb(0 0 0 / 0.35)); }
.logo:hover .logo__img { opacity: 0.8; }

.ui-btn {
  appearance: none; background: none; border: 0; position: relative;
  display: inline-flex; align-items: center; gap: 0.5em;
  color: var(--white); text-decoration: none; cursor: pointer;
  font-family: var(--f-mono); font-weight: 500;
  font-size: var(--t-ui); letter-spacing: var(--track-ui); text-transform: uppercase;
  line-height: 1; padding: 12px 10px; margin: -12px -10px;
  text-shadow: 0 1px 10px rgb(0 0 0 / 0.35);
  transition: color 0.25s ease, opacity 0.25s ease;
}
.ui-btn::after { content: ""; position: absolute; left: 10px; right: calc(100% - 10px); bottom: 10px; height: 1px; background: currentColor; transition: right 0.5s var(--ease-out); }
.ui-btn:hover, .ui-btn:focus-visible { color: var(--proj-accent); opacity: 1; }
.ui-btn:hover::after, .ui-btn:focus-visible::after { right: 10px; }

/* La franja del header necesita ALGO de fondo propio detrás del texto
   claro para no perderse contra el papel claro más abajo cuando se
   hace scroll (el text-shadow por sí solo no basta ahí) — un degradado
   corto, no una barra sólida, para que siga sintiéndose parte de la
   escena y no un nav bar pegado. */
.chrome--top::before {
  content: "";
  position: fixed; top: 0; left: 0; right: 0;
  height: calc(120 * var(--u));
  background: linear-gradient(to bottom, rgb(from var(--proj-ink-deep) r g b / 0.45), transparent);
  pointer-events: none; z-index: -1;
}

.nav-slot { margin-left: auto; display: flex; align-items: center; gap: calc(20 * var(--u)); }
/* Menú grande + hamburguesa, igual que el home (no el punto naranja viejo). */
.nav-toggle { font-size: max(16px, calc(20 * var(--u))); }
.nav-toggle__hamburger { display: block; flex: none; width: 1.1em; height: 0.78em; transition: opacity 0.25s ease; }
.nav-toggle:hover .nav-toggle__hamburger { opacity: 0.7; }
/* Menú abierto → la hamburguesa se convierte en X (el botón ya cambia el texto
   a "CERRAR"). Las barras de arriba y abajo giran ±45° y se centran; la del
   medio se desvanece. transform-box: fill-box para girar alrededor del centro
   de cada barra. */
.nav-toggle__hamburger rect {
  transform-box: fill-box; transform-origin: center;
  transition: transform 0.34s ease, opacity 0.2s ease;
}
[data-nav-toggle][aria-expanded="true"] .nav-toggle__hamburger rect:nth-of-type(1) { transform: translateY(6.25px) rotate(45deg); }
[data-nav-toggle][aria-expanded="true"] .nav-toggle__hamburger rect:nth-of-type(2) { opacity: 0; }
[data-nav-toggle][aria-expanded="true"] .nav-toggle__hamburger rect:nth-of-type(3) { transform: translateY(-6.25px) rotate(-45deg); }
@media (prefers-reduced-motion: reduce) { .nav-toggle__hamburger rect { transition: none; } }

.nav-panel {
  position: fixed; inset: 0; z-index: var(--z-nav);
  background: var(--proj-ink);
  display: grid; align-content: center;
  padding: calc(120 * var(--u)) var(--gutter) calc(80 * var(--u));
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.75s var(--ease-io);
}
.nav-panel.is-open { clip-path: inset(0 0 0 0); }
.nav-panel[hidden] { display: none; }
.nav-panel ul { list-style: none; margin: 0; padding: 0; }
.nav-panel li { overflow: hidden; padding-top: 0.12em; }
.nav-panel a {
  /* Mismo cuerpo que el menú del home (110u, no 90u) — no había ninguna
     razón de contenido para que se viera más chico aquí, era deriva entre
     archivos, no una decisión. */
  display: block; font-family: var(--f-black); font-size: calc(110 * var(--u));
  line-height: 0.86; letter-spacing: 0.0219em; text-transform: uppercase; text-decoration: none;
  color: var(--proj-paper); opacity: 0.5; transition: opacity 0.3s ease, color 0.3s ease;
}
.nav-panel a span { display: block; transform: translate3d(0, 115%, 0); transition: transform 0.9s var(--ease-out) calc(0.2s + var(--i, 0) * 0.06s); }
.nav-panel.is-open a span { transform: none; }
.nav-panel a:hover, .nav-panel a:focus-visible { opacity: 1; color: var(--proj-accent); }
.nav-panel:has(a:hover) a:not(:hover) { opacity: 0.25; }

/* ============================================================
   HERO — video a pantalla completa (svh, no vh, por las barras del
   móvil), sin título ni etiquetas encima. Solo lleva la capa .hero__overlay
   para el logo de la marca (abajo) y la señal de scroll (más abajo en este
   archivo, fija en la pantalla).
   ============================================================ */
.hero {
  position: relative;
  min-height: 100svh;
  background: var(--proj-ink-deep);   /* solo se ve un instante, mientras carga el video */
  overflow: hidden;
}
.hero__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; display: block; }

/* OVERLAY — capa sobre el video para el logo de la marca, en el CENTRO exacto
   (ancho y alto). Hoy lleva un marcador; al llegar el logo, el <span> se
   cambia por <img class="hero__logo-img">. No intercepta el puntero. */
.hero__overlay {
  position: absolute; inset: 0; z-index: 1;
  display: flex; justify-content: center; align-items: center;
  padding: 0 var(--gutter);
  pointer-events: none;
}
.hero__logo { margin: 0; width: clamp(160px, 28vw, 460px); }
.hero__logo-img { display: block; width: 100%; height: auto; }
/* Marcador honesto (como los "pending asset" de la página): lleva su propio
   velo para leerse sobre cualquier cuadro del video, claro u oscuro. */
.hero__logo-ph {
  display: flex; align-items: center; justify-content: center; text-align: center;
  aspect-ratio: 3 / 1; padding: 0 1em;
  border: 1.5px dashed rgb(255 255 255 / 0.7);
  border-radius: max(10px, calc(16 * var(--u)));
  background: rgb(0 0 0 / 0.22);
  font-family: var(--f-mono); font-size: var(--t-ui); letter-spacing: var(--track-ui); text-transform: uppercase;
  color: var(--white);
}

/* ============================================================
   TEXTO — párrafos centrados de lectura (intro, setup) sobre papel
   claro; el patrón de notas al pie es real (no decorativo): una línea
   fina y dos columnas de texto pequeño, o dos notas al margen a los
   lados del párrafo, según el wireframe de cada bloque.
   ============================================================ */
/* Secciones de lectura estrecha: contenedor centrado. Ritmo vertical AMPLIO
   entre bloques para que cada animación (entintado, silkscreen, marquee) tenga
   aire y se aprecie al entrar/salir del viewport. */
.intro, .setup, .quote { padding: calc(64 * var(--u)) var(--gutter); max-width: 1400px; margin: 0 auto; }
/* Statement: ancho completo — el titular sangra de gutter a gutter como en el wireframe */
.statement { padding: calc(64 * var(--u)) var(--gutter); }
/* Black condensada, como el mockup. Columnas MÁS ESTRECHAS y centradas: el
   ancho del bloque de intro medido en el wireframe ≈ 925px (no a todo el
   contenedor). */
.intro__text, .setup__text {
  margin: 0 auto; text-align: center;
  /* Sharp Grotesk SemiBold 15 (no la Black): es la fuente correcta para el
     cuerpo de lectura de intro/setup. */
  font-family: var(--f-semibold); font-weight: 400;
  font-size: clamp(24px, calc(40 * var(--u)), 54px);
  line-height: 1.2; letter-spacing: 0.004em;
  color: var(--proj-ink);
}
.intro__text { max-width: calc(920 * var(--u)); }
.setup__text { max-width: calc(800 * var(--u)); }
.rule { border: 0; border-top: 1px solid rgb(from var(--proj-ink) r g b / 0.25); margin: calc(36 * var(--u)) auto calc(28 * var(--u)); width: min(100%, 900px); }
/* Las notas al pie usan la MISMA familia condensada que el resto del
   texto del wireframe, no la mono de UI del chrome (idioma/menú/contacto
   — esos sí son mono, son controles, no prosa de la marca). */
.footnotes {
  display: flex; flex-direction: column; justify-content: center; align-items: center; gap: clamp(14px, calc(22 * var(--u)), 28px);   /* una nota debajo de la otra, centradas */
  font-family: var(--f-semibold); font-size: clamp(16px, calc(19 * var(--u)), 23px);
  letter-spacing: 0.03em; line-height: 1.6;
  text-transform: uppercase; color: var(--proj-ink); opacity: 0.78; text-align: center;
}
.footnotes p { margin: 0; max-width: calc(640 * var(--u)); text-align: center; text-wrap: balance; }

.setup { position: relative; display: grid; grid-template-columns: 1fr; gap: calc(24 * var(--u)); }
.setup__note {
  font-family: var(--f-semibold); font-size: clamp(12px, calc(14 * var(--u)), 16px);
  letter-spacing: 0.03em; line-height: 1.6;
  text-transform: uppercase; color: var(--proj-ink); opacity: 0.74; max-width: calc(240 * var(--u));
}
/* Superíndices de referencia: pequeños, elevados y en el naranja de marca —
   se leen como marcas de nota, coherentes en todo el despliegue. */
.intro__text sup, .setup__text sup, .statement__body sup,
.footnotes sup, .setup__note sup, .footnote-badge sup {
  font-size: 0.6em; vertical-align: super; line-height: 0;
  color: var(--orange); font-feature-settings: "sups" 0; padding: 0 0.06em;
}
@media (min-width: 1000px) {
  .setup { grid-template-columns: 220px 1fr 220px; align-items: center; gap: calc(40 * var(--u)); }
  .setup__note--left { text-align: right; justify-self: end; }
  .setup__note--right { justify-self: start; }
}
/* Variante de UNA nota (.setup--single), debajo del párrafo y alineada a la izquierda —
   no dos flanqueando (eso es el dispositivo de Imatana). max-width
   contiene el párrafo mismo ancho que .intro para que quede centrado. */
.setup--single {
  display: block; max-width: calc(920 * var(--u)); margin: 0 auto;
}
.setup--single .setup__text { max-width: none; }
.setup--single .setup__note {
  text-align: left; margin-top: calc(28 * var(--u)); max-width: none;
}

/* Grilla de imágenes: los recuadros marcados como assets pendientes
   son honestos (misma filosofía que placeholder-hero.jpg del home):
   textura suave + una etiqueta pequeña, nunca una foto de relleno
   presentada como si fuera final. */
.media-grid { display: grid; gap: calc(40 * var(--u)); padding: calc(64 * var(--u)) var(--gutter); margin: 0 auto; }
.media-grid--2 { grid-template-columns: repeat(2, 1fr); }
.media-grid--3 { grid-template-columns: repeat(3, 1fr); }
.media-grid--1 { grid-template-columns: 1fr; }
/* Por debajo de esto la grilla va a ancho completo (borde a borde con el
   gutter); de ahí para arriba crece con el viewport en vez de quedar fija,
   igual que el referente (a 1920px de pantalla sus imágenes llegan a ~96%
   de ancho, no se quedan pegadas a un valor fijo). */
@media (min-width: 701px) {
  .media-grid { max-width: min(90vw, 1800px); }
}
.media-slot {
  aspect-ratio: 4 / 3; border-radius: 0;   /* borde RECTANGULAR en todas las fotos y recuadros (pedido 12-oct; antes 16 u) */
  background:
    repeating-linear-gradient(135deg, rgb(from var(--proj-ink) r g b / 0.06) 0 2px, transparent 2px 14px),
    var(--proj-paper-dim);
  display: flex; align-items: center; justify-content: center;
  color: var(--proj-ink); opacity: 0.55;
  font-family: var(--f-mono); font-size: clamp(10px, calc(12 * var(--u)), 13px); letter-spacing: 0.08em; text-transform: uppercase;
  position: relative;
  overflow: hidden;
}
/* Imágenes HORIZONTALES (media-grid--1): formato 1920×900. El arte puede llegar
   en 1920×1080 y se ajusta (cover) a esa caja. Van dentro de la columna de la
   grilla (≈ 86 % del ancho de la ventana: 90vw menos el gutter, igual que el
   wireframe de Imatana), no a borde. Para cambiar la proporción basta
   --wide-ratio; para el ancho, el max-width de .media-grid (más arriba). */
.media-grid--1 { --wide-ratio: 16 / 9; }
.media-grid--1 .media-slot { aspect-ratio: var(--wide-ratio); border-radius: 0; }   /* horizontales: borde recto (pedido 5-oct) */
/* Imágenes en grilla de 2/3: formato vertical, igual que el referente
   (más presencia por celda que un recuadro horizontal apretado). */
.media-grid--2 .media-slot, .media-grid--3 .media-slot { aspect-ratio: 4 / 5; }
/* Slot con imagen real: la foto llena la caja (mismo patrón que imatana.css,
   listo para cuando el proyecto reciba sus assets finales). */
.media-slot__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; transition: transform 0.3s ease-out; }
.media-slot:has(.media-slot__img) { opacity: 1; }
.media-slot:hover .media-slot__img { transform: scale(1.025); }
@media (hover: none) { .media-slot:hover .media-slot__img { transform: none; } }
@media (max-width: 700px) {
  .media-grid--2, .media-grid--3 { grid-template-columns: 1fr; }
}

/* ============================================================
   MARQUEE — corregido tras comparar de nuevo con tu wireframe: NO es una
   banda verde a todo el ancho — el "Salaaaaaaaaaaaaab" cortado por los
   dos bordes vive DENTRO de una celda normal de la grilla de 2 columnas,
   mismo tamaño y mismo fondo claro que su vecina (confirmado recortando
   esa zona exacta del JPG a resolución completa: caja clara, texto en
   movimiento recortado por SU PROPIO borde, no un fondo oscuro). Una
   cinta continua, contenida, congelada a mitad de recorrido en la
   captura original — de ahí las letras cortadas.
   ============================================================ */
.media-slot--marquee {
  background: var(--proj-paper-dim);   /* el mismo fondo claro que su vecina, no verde oscuro */
  overflow: hidden;
  justify-content: flex-start;
  padding: 0;
}
.media-slot--marquee .marquee__track {
  display: inline-flex; width: max-content; will-change: transform;
  animation: marquee-l 14s linear infinite;
}
.media-slot--marquee .marquee__track span {
  display: inline-block; flex: none; padding: 0 0.15em; white-space: nowrap;
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: clamp(40px, calc(64 * var(--u)), 88px); line-height: 1;
  background: linear-gradient(120deg, var(--proj-accent) 10%, #F2894A 55%, #F5C242 90%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
@keyframes marquee-l { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .media-slot--marquee .marquee__track { animation: none; }
}

/* ============================================================
   STATEMENT — los titulares grandes de sección (mismo cuerpo condensado
   que el home, esta vez fijo, no animado letra a letra: son afirmaciones
   de marca, no el carrusel). La onda SVG se dibuja una sola vez al
   entrar en vista (stroke-dashoffset, ver imatana.js).
   ============================================================ */
.statement__wave { width: min(100%, 520px); height: auto; margin: 0 auto calc(24 * var(--u)); display: block; overflow: hidden; }
/* La onda FLUYE en loop continuo: el grupo del waveform periódico se traslata
   −50% (un periodo exacto) de forma lineal e infinita → energía viajando por
   la onda, sin costura. transform-box: fill-box hace que −50% = mitad del
   bounding box del trazo (760 uds = 4 ciclos). */
.statement__wave .wave-flow {
  transform-box: fill-box;
  animation: wave-flow 5s linear infinite;
}
@keyframes wave-flow {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* Los titulares grandes arrancan en HUECO (solo contorno) y se llenan de
   color al entrar en vista — pedido explícito ("los textos más grandes
   deben aparecer de línea a relleno como en la referencia"), mismo
   mecanismo que usa el home por letra (`--fill`/`--stroke`, ver
   `.ch` en site.css) pero aquí sobre el bloque completo: un titular de
   marca es una afirmación fija, no algo que siga la distancia de un
   carrusel letra por letra. `@property` (arriba) es lo que permite que
   `transition: --fill` interpole de verdad en vez de saltar de golpe. */
/* Titular grande centrado (medido del wireframe: cap ≈ 95px ⇒ font ≈ 130px,
   centrado en la página). El relleno de línea→sólido lo maneja el scroll
   (imatana.js): --fill sube al bajar y baja al subir, así el visitante SIENTE
   el movimiento en ambas direcciones. Transición corta = sigue el scroll. */
.statement__title {
  margin: 0 auto calc(30 * var(--u)); text-align: center; text-transform: uppercase;
  /* max-width para que envuelva natural a ~3 líneas en desktop y a lo que
     quepa en móvil (nunca desborda: sin <br> fijos). */
  max-width: min(100%, calc(1120 * var(--u)));
  font-family: var(--f-black); font-weight: 400;
  font-size: clamp(48px, calc(128 * var(--u)), 240px);
  line-height: 0.95; letter-spacing: 0.03em; text-wrap: balance;
  --fill: 0; --stroke: 1;
  color: rgb(from var(--proj-ink) r g b / var(--fill));
  -webkit-text-stroke: 0.016em rgb(from var(--proj-ink) r g b / var(--stroke));
  paint-order: stroke fill;
  transition: none;   /* relleno en bloques: sin tonos intermedios (7-oct) */
}
/* Sección 3 en el wireframe NO es un titular gigante como las secciones 1
   y 2 — es un subtítulo chico, izquierda, sin el hueco→relleno (ya se lee
   sólido siempre): "SIX DAYS. ONE STREET. NO STUDIO." pesa poco al lado
   de la quote gigante que viene justo antes. */
.statement__title--sub {
  text-align: center; margin: 0 auto calc(18 * var(--u));
  max-width: calc(920 * var(--u));
  font-size: clamp(20px, calc(28 * var(--u)), 36px);
  --fill: 1; --stroke: 0; transition: none;
}

/* Remate "THEY EARNED IT." — gigante en gris tonal (del footnote 9), sangra
   por los bordes (overflow hidden en la banda), como en el mockup. Estático,
   no lleva el entintado letra por letra (es un watermark, no un statement). */
.earned-band { overflow: hidden; padding: calc(50 * var(--u)) var(--gutter) calc(70 * var(--u)); }
.earned-word {
  margin: 0; text-align: center; white-space: nowrap;
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: clamp(56px, calc(190 * var(--u)), 340px);
  line-height: 0.9; letter-spacing: 0.01em;
  color: rgb(from var(--proj-ink) r g b / 0.16);
}
/* Sin JS: se muestra relleno (no queda en contorno vacío). */
html:not(.js) .statement__title, .no-engine .statement__title { --fill: 1; --stroke: 0; }
@media (prefers-reduced-motion: reduce) {
  .statement__title { transition: none; --fill: 1; --stroke: 0; }
}
/* Warhol — revelado LETRA POR LETRA: cada letra cruza de contorno a relleno en
   cascada al hacer scroll (imatana.js escribe --fill por letra según avanza la
   posición; reversible al subir, como una placa de imprenta que entinta el
   texto de izquierda a derecha). */
/* Cada palabra agrupa sus letras y NO se rompe a mitad (el quiebre solo ocurre
   en los espacios entre palabras). */
.statement__title .word, .quote__text .word, .intro__text .word, .setup__text .word { white-space: nowrap; }
.statement__title .ch, .quote__text .ch, .intro__text .ch, .setup__text .ch {
  display: inline-block;
  --fill: 0; --stroke: 1;
  color: rgb(from var(--proj-ink) r g b / var(--fill));
  -webkit-text-stroke: 0.016em rgb(from var(--proj-ink) r g b / var(--stroke));
  paint-order: stroke fill;
  transition: none;
}
/* Cuerpos de lectura (quote, intro, setup): contorno más fino para no engordar
   las astas del SemiBold. */
.quote__text .ch, .intro__text .ch, .setup__text .ch { -webkit-text-stroke-width: 0.017em; }
html:not(.js) .statement__title .ch, .no-engine .statement__title .ch,
html:not(.js) .quote__text .ch, .no-engine .quote__text .ch,
html:not(.js) .intro__text .ch, .no-engine .intro__text .ch,
html:not(.js) .setup__text .ch, .no-engine .setup__text .ch { --fill: 1; --stroke: 0; }
@media (prefers-reduced-motion: reduce) {
  .statement__title .ch, .quote__text .ch, .intro__text .ch, .setup__text .ch { transition: none; --fill: 1; --stroke: 0; }
}

/* Warhol letterpress: cada palabra prensa desde abajo de su línea.
   El wrapper con overflow:hidden es la ranura de la imprenta; el inner
   es el bloque que sube. --wi (índice) lo escribe imatana.js. */
.word-print {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  margin-right: 0.16em;
}
.word-print:last-child { margin-right: 0; }
.word-print__inner {
  display: inline-block;
  transform: translateY(112%);
  transition: transform 0.72s var(--ease-out) calc(var(--wi, 0) * 48ms);
}
.is-in .word-print__inner { transform: none; }
html:not(.js) .word-print__inner,
.no-engine .word-print__inner { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .word-print__inner { transition: none; transform: none; }
}

/* El relleno lo maneja el scroll; el reveal genérico no debe reintroducir
   una transición larga que rompa el seguimiento del scroll. */
.statement__title[data-reveal-item] {
  opacity: 1;
  transform: none;
  transition: none;   /* relleno en bloques: sin tonos intermedios (7-oct) */
}

.statement__body {
  margin: 0 auto; max-width: calc(560 * var(--u)); text-align: center;
  font-family: var(--f-semibold); font-weight: 400;
  /* Cuerpo de lectura un poco más grande (pedido del usuario: se siente mejor):
     de 14–22 a 16–26, ~3px más en desktop, mismo estilo. */
  font-size: clamp(16px, calc(21 * var(--u)), 26px);
  line-height: 1.6; color: var(--proj-ink); opacity: 0.9;
}
.statement--tight .statement__row { display: grid; grid-template-columns: 1fr; gap: calc(24 * var(--u)); align-items: center; justify-items: center; }
@media (min-width: 1000px) {
  /* Cluster centrado: badge · texto · badge JUNTOS (no pegados a los bordes),
     así se ven/notan rápido en vez de quedar en las esquinas lejos del texto. */
  .statement--tight .statement__row {
    grid-template-columns: auto minmax(0, 460px) auto;
    justify-content: center;
    column-gap: clamp(24px, calc(52 * var(--u)), 72px);
  }
  .statement__body--narrow { max-width: 460px; }
}
/* Badge circular blanco (como la referencia): NÚMERO ARRIBA, texto en
   mayúsculas debajo, centrado en el círculo. */
.footnote-badge {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: calc(8 * var(--u));
  width: clamp(150px, calc(192 * var(--u)), 212px); aspect-ratio: 1;
  border-radius: 50%; background: var(--proj-white);
  box-shadow: 0 12px 34px rgb(from var(--proj-ink) r g b / 0.14);
  padding: calc(24 * var(--u)); color: var(--proj-ink);
}
.footnote-badge__num {
  font-family: var(--f-mono); font-weight: 500;
  font-size: clamp(12px, calc(14 * var(--u)), 16px); line-height: 1;
  color: var(--orange);
}
.footnote-badge__text {
  font-family: var(--f-semibold); font-weight: 400; text-transform: uppercase;
  font-size: clamp(10px, calc(11.5 * var(--u)), 13px); letter-spacing: 0.03em; line-height: 1.5;
  color: var(--proj-ink);
}
/* MÓVIL: sin círculos ni hover — los footnotes bajan como LISTA debajo del
   cuerpo (el body va primero con order:-1). */
@media (max-width: 760px) {
  .statement--tight .statement__row { display: flex; flex-direction: column; gap: calc(18 * var(--u)); align-items: stretch; }
  .statement__body--narrow { order: -1; max-width: none; }
  .footnote-badge {
    width: 100%; aspect-ratio: auto; border-radius: 0;
    background: none; box-shadow: none;
    flex-direction: row; align-items: baseline; justify-content: flex-start;
    text-align: left; gap: calc(10 * var(--u)); padding: calc(14 * var(--u)) 0 0;
    border-top: 1px solid rgb(from var(--proj-ink) r g b / 0.18);
  }
  .footnote-badge__text { text-transform: none; font-size: clamp(13px, calc(14 * var(--u)), 16px); }
}

/* ============================================================
   MARQUEE DE TITULAR — la frase "THE IDENTITY IS BUILT ON SOUND WAVES.
   NOT COFFEE BEANS." gira de derecha a izquierda de forma infinita,
   sangrando por ambos bordes (en el wireframe se ve cortada justamente por
   eso). Un punto naranja —el mismo del logo del estudio— separa cada
   repetición: marca dónde empieza y termina la frase.
   ============================================================ */
.marquee-statement { overflow: hidden; padding: calc(56 * var(--u)) 0; }
.marquee-band__track {
  display: flex; align-items: center; width: max-content;
  animation: marquee-band 34s linear infinite; will-change: transform;
}
.marquee-statement:hover .marquee-band__track { animation-play-state: paused; }
.marquee-band__phrase {
  flex: none; white-space: nowrap;
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: clamp(48px, calc(128 * var(--u)), 240px);
  line-height: 0.95; letter-spacing: 0.004em; color: var(--proj-ink);
  padding-right: 0.14em;
}
.marquee-band__dot {
  flex: none; align-self: center; border-radius: 50%;
  background: var(--orange);
  width: clamp(20px, calc(52 * var(--u)), 100px);
  height: clamp(20px, calc(52 * var(--u)), 100px);
  margin: 0 clamp(20px, calc(52 * var(--u)), 100px);
}
@keyframes marquee-band { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee-band__track { animation: none; }
}

/* La quote pesa tanto como un titular de sección en el wireframe real
   (no un párrafo itálico chico como se había puesto antes de revisarlo):
   misma familia y escala que .statement__title, con el mismo entintado
   letra por letra por scroll (.ch ya cubre .quote__text más abajo). */
.quote__text {
  margin: 0 auto; text-align: center;
  max-width: min(100%, calc(1040 * var(--u)));
  /* MAYÚSCULAS como el resto de textos display (mockup) — consistencia. */
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: clamp(32px, calc(74 * var(--u)), 120px);
  line-height: 1.05; letter-spacing: 0.002em; color: var(--proj-ink); text-wrap: balance;
}

/* Our Role: en el wireframe de Lafayette es UNA sola columna (no dos como
   en Imatana) — igual indent a la izquierda, misma familia media. */
/* Our Role: título centrado y, debajo, una tira a TODO el ancho que corre en loop
   infinito. Dos copias de la lista (.role__track) en fila; cada una se desplaza
   −100 % de su propio ancho, así que al terminar el ciclo la segunda ocupa el lugar
   de la primera y el salto es invisible. Se detiene con «reducir movimiento»
   (queda la lista envuelta y centrada). */
.role { --role-speed: 30s; padding: calc(60 * var(--u)) 0 calc(60 * var(--u)); }
/* Dos líneas finas a todo el ancho: una arriba del título y otra debajo de la tira (mismo trazo que .rule). */
.role::before, .role::after { content: ""; display: block; border-top: 1px solid rgb(from var(--proj-ink) r g b / 0.25); }
.role::before { margin-bottom: calc(60 * var(--u)); }
.role::after { margin-top: calc(48 * var(--u)); }
.role__heading {
  margin: 0 0 calc(34 * var(--u)); padding: 0 var(--gutter); text-align: center;
  font-family: var(--f-medium); font-weight: 400; text-transform: none;
  font-size: clamp(30px, calc(52 * var(--u)), 66px);
  line-height: 1; letter-spacing: 0.005em; color: var(--proj-ink); opacity: 1;
}
.role__marquee { display: flex; width: 100%; overflow: hidden; }
.role__track {
  flex: 0 0 auto; display: flex; align-items: center;
  list-style: none; margin: 0; padding: 0;
  animation: role-run var(--role-speed) linear infinite;
}
.role__track li {
  flex: none; white-space: nowrap;
  font-family: var(--f-medium); font-weight: 400; text-transform: none;
  font-size: clamp(16px, calc(23 * var(--u)), 30px); line-height: 1.3; letter-spacing: 0.005em;
  color: var(--proj-ink);
}
/* punto naranja de la marca entre servicios (y al cierre de cada lista, para que el empalme conserve el ritmo) */
.role__track li::after {
  content: ""; display: inline-block; width: 0.26em; height: 0.26em; border-radius: 50%;
  background: var(--orange); margin: 0 1.1em; vertical-align: 0.1em;
}
@keyframes role-run { to { transform: translate3d(-100%, 0, 0); } }
@media (prefers-reduced-motion: reduce) {
  .role__marquee { flex-wrap: wrap; justify-content: center; padding: 0 var(--gutter); }
  .role__track { animation: none; flex-wrap: wrap; justify-content: center; row-gap: 0.2em; }
  .role__track li[aria-hidden="true"] { display: none; }
  .role__track[aria-hidden="true"] { display: none; }
}


/* ============================================================
   BADGE SOBRE IMAGEN — a diferencia de Imatana (círculos flanqueando un
   párrafo), en Lafayette las notas de la sección 1 son círculos
   SUPERPUESTOS a la esquina de una imagen — confirmado en el wireframe:
   el círculo blanco se monta sobre el recuadro, no vive aparte.
   ============================================================ */
.media-slot { position: relative; }
.media-badge {
  position: absolute; z-index: 1;
  display: flex; align-items: center; justify-content: center; text-align: center;
  width: clamp(120px, calc(168 * var(--u)), 190px); aspect-ratio: 1;
  border-radius: 50%; background: var(--proj-white);
  box-shadow: 0 12px 30px rgb(from var(--proj-ink) r g b / 0.16);
  font-family: var(--f-semibold); font-weight: 400;
  font-size: clamp(10px, calc(11.5 * var(--u)), 13px); letter-spacing: 0.02em; line-height: 1.4;
  color: var(--proj-ink); padding: calc(18 * var(--u));
}
.media-badge sup { color: var(--orange); }
.media-badge--bl { left: calc(-24 * var(--u)); bottom: calc(-24 * var(--u)); }
.media-badge--br { right: calc(-24 * var(--u)); bottom: calc(-24 * var(--u)); }
@media (max-width: 760px) {
  .media-badge {
    position: static; width: 100%; aspect-ratio: auto; border-radius: 0;
    background: none; box-shadow: none; text-align: left;
    padding: calc(14 * var(--u)) 0 0; margin-top: calc(10 * var(--u));
    border-top: 1px solid rgb(from var(--proj-ink) r g b / 0.18);
  }
}

/* ============================================================
   CLOSE — el cierre firma con el wordmark gigante en outline, eco del
   referente de Warhol (tipografía condensada gigante como remate), pero
   con el color de Imatana en vez del rojo del referente.
   ============================================================ */
/* El footer necesita ALTURA: la fila de links/tagline vive ARRIBA y el
   wordmark gigante FOOTNOTE ocupa la parte baja, sangrando por el borde
   inferior (como el mockup). Antes el footer era muy bajo y el wordmark
   quedaba cortado a una franja que chocaba con los links. */
/* Footer sobre el MISMO fondo claro del resto de la página (no verde), con el
   wordmark FOOTNOTE RELLENO como marca de agua gris — igual que el mockup. */
.close {
  position: relative; background: var(--proj-paper); color: var(--proj-ink);
  padding: calc(56 * var(--u)) var(--gutter) 0;
  min-height: clamp(320px, 34vw, 560px);
  display: flex; align-items: flex-start; gap: calc(24 * var(--u)); flex-wrap: wrap;
  overflow: hidden;
}
.close .ui-btn { color: var(--proj-ink); position: relative; z-index: 1; }
.close .ui-btn:hover { color: var(--orange); opacity: 1; }
/* Tagline coherente con el home (mismo texto, misma familia, Instrument Sans
   Bold en "Designers with attitude"), centrada entre los dos links. */
.close__tagline {
  flex: 1 1 auto; text-align: center; position: relative; z-index: 1;
  margin: 0; color: var(--proj-ink);
  font-family: var(--f-medium); font-weight: 400;
  font-size: var(--t-ui); line-height: 1.6; letter-spacing: var(--track-ui);
  text-transform: uppercase; white-space: nowrap;
}
.close__tagline strong { font-family: var(--f-ui); font-weight: 700; letter-spacing: var(--track-ui); }
.close__place { opacity: 0.6; }
/* Wordmark COMPLETO y RELLENO: un gris tonal sutil sobre el fondo claro (marca
   de agua), no contorno ni verde. */
.close__word {
  position: absolute; left: 50%; bottom: calc(34 * var(--u));
  transform: translateX(-50%);
  margin: 0; width: 100%; text-align: center;
  font-family: var(--f-black); font-weight: 400;
  font-size: clamp(64px, 20.5vw, 400px);
  line-height: 0.9; letter-spacing: 0.01em; text-transform: uppercase;
  color: rgb(from var(--proj-ink) r g b / 0.08);
  pointer-events: none; user-select: none; white-space: nowrap;
}

/* ============================================================
   REVELADO AL HACER SCROLL — transform + opacity solamente (GPU-safe),
   con IntersectionObserver desde imatana.js. Cascada corta entre
   hermanos de un mismo grupo: nunca todo aparece de golpe.
   ============================================================ */
[data-reveal-item] {
  opacity: 0; transform: translate3d(0, calc(22 * var(--u)), 0);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
  transition-delay: calc(var(--ri, 0) * 90ms);
}
.is-in [data-reveal-item] { opacity: 1; transform: none; }
html:not(.js) [data-reveal-item], .no-engine [data-reveal-item] { opacity: 1; transform: none; }

/* Intro y setup animan letra por letra (contorno→relleno) como los titulares;
   el párrafo queda visible y el relleno de las letras hace el trabajo. */
.intro__text[data-reveal-item],
.setup__text[data-reveal-item] {
  opacity: 1;
  transform: none;
  clip-path: none;
  transition: none;
}

/* Las fotos aparecen ESTÁTICAS, igual que en proyectos/imatana: el usuario
   pidió quitar esta transición de entrada (el barrido "silkscreen") porque
   no se sentía bien — es una decisión sobre el MECANISMO, no algo pedido por
   el wireframe de Lafayette (a diferencia de las demás diferencias en este
   archivo, que sí vienen del wireframe real), así que se unifica con Imatana
   en vez de dejarla a medias en un solo despliegue. La caja queda visible
   desde el inicio, sin recorte ni tinta animada. */
.media-slot[data-reveal-item] {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal-item] { transition: opacity 0.4s ease; transform: none; }
  .intro__text[data-reveal-item], .setup__text[data-reveal-item] { transition: opacity 0.4s ease; clip-path: none; opacity: 0; }
  .is-in .intro__text[data-reveal-item], .is-in .setup__text[data-reveal-item] { opacity: 1; }
  .statement__wave .wave-flow { animation: none; }
}

/* ============================================================
   RESPONSIVE — mismo criterio que el home: marco propio de 390px con
   techo (no escritorio encogido, y sin la inflación sin freno que
   rompía el pie del home a anchos intermedios).
   ============================================================ */
@media (max-width: 768px) {
  :root {
    --u: min(calc(100vw / 390), 1.35px);
    --gutter: max(18px, calc(18 * var(--u)));
    /* Faltaban estos — el header se veía con la F notablemente más grande
       que en el home porque el logo y la posición del header seguían
       usando los tokens de ESCRITORIO, solo escalados por el techo de
       --u. Mismos valores que el bloque móvil de site.css, para que el
       header/logo se vea IGUAL en el home y en los despliegues. */
    --edge-top: calc(16 * var(--u));
    --edge-bottom: calc(16 * var(--u));
    --logo-w: calc(34 * var(--u));
    --logo-h: calc(31 * var(--u));
    --logo-f: calc(36 * var(--u));
    --logo-dot: calc(15 * var(--u));
  }
  /* Títulos display en vw: los múltiplos de --u estaban calibrados para 1512,
     así que en móvil (u≈1px) quedaban gigantes y DESBORDABAN. En vw escalan
     con el ancho real y nunca se salen. */
  .statement__title { font-size: clamp(30px, 12vw, 90px); }
  .marquee-band__phrase { font-size: clamp(38px, 14vw, 100px); }
  .marquee-band__dot {
    width: clamp(16px, 4.2vw, 40px); height: clamp(16px, 4.2vw, 40px);
    margin: 0 clamp(16px, 4.2vw, 40px);
  }
  .quote__text { font-size: clamp(22px, 7vw, 40px); }
  .intro__text, .setup__text { font-size: clamp(22px, 6.4vw, 34px); }
  .close { flex-direction: column; align-items: flex-start; padding-bottom: calc(160 * var(--u)); }
  .close__tagline { flex: none; white-space: normal; text-align: left; }
  .close__contact { margin-left: 0; }
  /* Mismo criterio que site.css: el cuerpo de escritorio (110u) escalado
     por el techo móvil se pasaba de grande — el menú también necesita su
     propio cuerpo aquí, no solo el header. */
  .nav-panel a { font-size: calc(52 * var(--u)); }

  /* Ritmo vertical UNIFORME en móvil (a pedido: "equilibra las cajas y
     elementos"): antes el texto iba a 64u y las imágenes a 56u, y el hero-media
     era asimétrico — se veía irregular. Ahora TODAS las secciones comparten el
     mismo aire arriba/abajo, más compacto para pantalla chica. */
  .intro, .setup, .statement, .quote, .role,
  .media-grid, .marquee-statement, .earned-band {
    padding-top: calc(48 * var(--u));
    padding-bottom: calc(48 * var(--u));
  }
}

/* ============================================================
   SEÑAL DE SCROLL (UX) — igual que en el home: el hero llena la pantalla,
   así que este cue ("Scroll" + punto naranja que baja) invita a desplazarse
   para ver el caso. Aparece con .is-live (app.js la pone al no haber carrusel)
   y el JS lo oculta al primer scroll. Decorativo (aria-hidden).
   ============================================================ */
.scroll-cue {
  position: fixed; left: 50%; bottom: calc(30 * var(--u));
  transform: translateX(-50%);
  z-index: var(--z-chrome);
  display: flex; flex-direction: column; align-items: center;
  gap: calc(9 * var(--u));
  color: var(--white);
  opacity: 0; visibility: hidden;
  transition: opacity 0.6s ease, visibility 0s linear 0.6s;
  pointer-events: none;
}
.is-live .scroll-cue { opacity: 0.72; visibility: visible; transition: opacity 0.7s ease 0.6s; }
.scroll-cue.is-hidden { opacity: 0; visibility: hidden; transition: opacity 0.5s ease, visibility 0s linear 0.5s; }
.scroll-cue__label {
  font-family: var(--f-mono); font-size: var(--t-ui);
  letter-spacing: var(--track-ui); text-transform: uppercase;
}
.scroll-cue__line {
  position: relative; width: 1.5px; height: calc(38 * var(--u));
  border-radius: 2px; background: rgb(255 255 255 / 0.28); overflow: hidden;
}
.scroll-cue__dot {
  position: absolute; left: 0; right: 0; top: 0; height: 40%;
  border-radius: 2px; background: var(--orange);
  animation: scroll-cue-travel 1.9s var(--ease-io) infinite;
}
@keyframes scroll-cue-travel {
  0%   { top: -40%; opacity: 0; }
  25%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue__dot { animation: none; top: 20%; }
}
/* El indicador de scroll también en móvil (a pedido del usuario). */

/* ============================================================
   AJUSTES DEL 7-oct (trasladados desde Imatana): móvil
   ============================================================ */
@media (max-width: 700px) {
  /* Titular: que «la última línea» quepa entera (antes quedaba una palabra sola). */
  .statement__title { font-size: clamp(26px, 10.6vw, 90px); }
  /* Notas al margen: centradas y un poco más legibles. */
  .setup__note { text-align: center; max-width: none; font-size: 13px; padding: 0 var(--gutter); }
  /* Pie: los tres bloques centrados sobre el mismo eje. */
  .close { align-items: center; text-align: center; gap: calc(18 * var(--u)); }
  .close__tagline { text-align: center; }
  .close__contact { margin-left: -10px; }
}
