/* ============================================================
   footnote — Despliegue de proyecto: IMATANA
   Plantilla pensada para reutilizarse en los próximos despliegues
   (Lafayette, etc.): las reglas de layout/tipografía/ritmo viven en
   clases genéricas (.hero, .statement, .media-grid, .role, .close...);
   lo único que cambia por cliente son los 4 tokens de --proj-* de
   abajo. Reusa el sistema tipográfico y las curvas de easing del home
   (site.css) para que el estudio se sienta consistente entre proyectos
   aunque cada uno tenga su propia paleta.
   ============================================================ */

@font-face {
  font-family: "Sharp Grotesk Black 15";
  src: url("../../assets/fonts/sharp-grotesk-black15.woff2") format("woff2");
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: "Sharp Grotesk Medium 15";
  src: url("../../assets/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("../../assets/fonts/sharp-grotesk-semibold15.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Anton";
  src: url("../../assets/fonts/anton.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("../../assets/fonts/geist-mono.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("../../assets/fonts/instrument-sans.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}

:root {
  /* — paleta del cliente (medida por pixel del wireframe, no a ojo):
       verde oscuro #003C14 dominante, lima #BEF046 de acento — la
       identidad de Imatana, deliberadamente distinta del naranja/lima
       de footnote (el estudio queda solo en el logo de la esquina). — */
  --proj-ink: #000000;        /* tinta de TODOS los textos sobre fondo claro: negro puro (pedido 8-oct; antes el verde #003C14) */
  --proj-green: #003C14;      /* el verde de la marca, solo para fondos (panel del menú): ya no se usa en textos */
  --proj-ink-deep: #002A0E;
  --proj-accent: #BEF046;
  --proj-paper: #FFFFFF;      /* fondo BLANCO (pedido 7-oct; antes crema #F4F1E7) */
  --proj-paper-dim: #E8E3D3;
  --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) para que se note bien. */
  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(0 20 8 / 0.35), 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-green);
  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; }

/* HERO EN SECUENCIA — 4 cuadros de la misma composición (wordmark + ondas en
   distintos colores) que se relevan en loop con un fundido (imatana.js, sección 6).
   El que entra aparece ENCIMA del que sale (.was-on lo sostiene opaco debajo),
   así el fundido nunca deja ver el fondo. El primer cuadro se ve sin JS.
   --hero-green es el verde plano del póster (#05471c, medido en los cuadros): el
   fondo del hero es el mismo, así no hay salto de color mientras carga la imagen. */
.hero--seq { --hero-green: #05471c; background: var(--hero-green); }
.hero__stage { position: absolute; inset: 0; overflow: hidden; }
.hero__seq { position: absolute; inset: 0; will-change: transform; }   /* parallax: imatana.js, sección 9 */
.hero__frame {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 50% 50%;
  opacity: 0; transition: opacity var(--seq-fade, 900ms) ease-in-out;
}
.hero__frame.is-on { opacity: 1; z-index: 2; }
.hero__frame.was-on { opacity: 1; z-index: 1; transition: none; }
/* TEXTO DEL HERO — lo que se trabajó (la misma lista de «Our Role») en UNA línea, un
   poco por debajo del centro y sin recuadro. Mismo estilo que las etiquetas de cada
   proyecto en el Home (.slide__tag-line, site.css): Sharp Grotesk Medium en
   mayúsculas, blanco y guiones largos entre ítems. El tamaño sigue el ancho de la
   ventana (1,15vw: la línea ocupa ≈ 46 % del ancho; el 8-oct se achicó un 20 % y bajó del 62 % al
   75 % del alto; el 12-oct subió 60 px: top = 75 % − 60 px, o sea ≈ 68 % a 900 px de alto). Sin sombra (pedido 7-oct): el
   blanco queda limpio, aunque sobre las crestas lima más claras tiene menos
   contraste que sobre el verde. Se mueve con el parallax (imatana.js,
   sección 9). */
.hero__info {
  position: absolute; left: 50%; top: calc(75% - 60px); translate: -50% -50%; z-index: 3;   /* 75 % del alto menos 60 px (pedido 12-oct: «50–70 px más arriba») */
  box-sizing: border-box; max-width: calc(100% - 2 * var(--gutter));
  margin: 0; padding: 0; list-style: none; text-align: center; white-space: nowrap;
  font-family: var(--f-medium); font-weight: 400; text-transform: uppercase;
  font-size: clamp(11px, 1.15vw, 22px); line-height: 1.3; letter-spacing: 0;
  color: var(--white);
  pointer-events: none; will-change: transform, opacity;   /* sin sombra (pedido 7-oct) */
}
.hero__info li { display: inline; white-space: nowrap; }
/* El guion largo va pegado al ítem que cierra (así nunca queda al inicio de una línea). */
.hero__info li:not(:last-child)::after { content: "\00a0\2014"; content: "\00a0\2014" / ""; }
/* Pantallas verticales: la composición completa (16:9) en vez de recortar el
   wordmark a pantalla completa, y el texto va DEBAJO de la imagen, sobre el mismo
   verde (en una tira tan baja taparía las ondas), en varias líneas centradas. */
@media (max-aspect-ratio: 1/1) {
  .hero--seq { min-height: 0; }
  .hero__stage { position: relative; inset: auto; aspect-ratio: 16 / 9; }
  .hero__info {
    position: relative; left: auto; top: auto; translate: none; z-index: auto;
    max-width: none; white-space: normal; text-wrap: balance;
    padding: calc(24 * var(--u)) var(--gutter) calc(30 * var(--u));
    font-size: calc(13.5 * var(--u)); line-height: 1.6; text-shadow: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero__seq, .hero__info { will-change: auto; transform: none !important; }
  .hero__info { opacity: 1 !important; }
}

/* 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(0 60 20 / 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; justify-content: center; align-items: flex-start; gap: clamp(28px, calc(56 * var(--u)), 72px); flex-wrap: wrap;   /* DOS COLUMNAS (12-oct: de vuelta a como estaban antes de apilarlas el 7-oct); donde no caben, bajan una debajo de la otra */
  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); text-align: center;
}
.footnotes p { margin: 0; max-width: max(calc(420 * var(--u)), 280px); text-align: center; text-wrap: balance; }   /* mínimo 280 px: en tableta las columnas no se vuelven angostísimas */

.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); 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; }
}

/* 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(32 * var(--u)); padding: calc(56 * 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(0 60 20 / 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 (del deck de marca): la foto llena la caja y el
   silkscreen la revela igual que a los placeholders. */
.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; } }
/* Empaque que ROTA: varias fotos apiladas en la misma celda; solo la .is-active
   se ve y van cruzándose en fundido (la gama de latas Imatana en su sitio). */
.media-slot--rotate .media-slot__img { opacity: 0; transition: opacity 0.9s ease; }
.media-slot--rotate .media-slot__img.is-active { opacity: 1; }
@media (max-width: 700px) {
  .media-grid--2, .media-grid--3 { grid-template-columns: 1fr; }
}

/* ============================================================
   ESTRUCTURA DEFINIDA — wireframe de Imatana (versión del 5-oct-2026)
   Posiciones y proporciones medidas sobre el wireframe que compartió el
   usuario. El ancho útil es el mismo de .media-grid (≈ 86 % de la ventana).
   Cada espacio de imagen lleva un número (01–25, en el orden de la página:
   el mismo que muestra la prueba ?prueba), su proporción y el tamaño de
   entrega, escritos en su rótulo «pending asset».

     .wf-block      grupo de espacios apilados con el hueco del wireframe
                    (≈ 22 px a 1512 px de ventana)
     .wf-pair       dos columnas: fotos 7:8 (arriba) · .wf-pair--tall 4:5 (abajo)
     .wf-collage    collage de 12 imágenes; cada una en % de su caja (--x --y
                    --w --h), así que escala con la pantalla
   ============================================================ */
.wf-block {
  --wf-gap: calc(40 * var(--u));
  grid-template-columns: 1fr;
  gap: var(--wf-gap);
  padding-top: calc(48 * var(--u)); padding-bottom: calc(48 * var(--u));
}
.wf-block .media-slot--wide { aspect-ratio: var(--wide-ratio, 16 / 9); border-radius: 0; }
.wf-pair { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--wf-gap, calc(22 * var(--u))); }
.wf-pair .media-slot { aspect-ratio: 7 / 8; }            /* pareja de fotos (arriba): 0,88 en el wireframe */
.wf-pair--tall .media-slot { aspect-ratio: 4 / 5; }      /* pareja de producto (abajo): 0,80 */
/* MITAD Y MITAD (14-oct, referencia del usuario): la pieza ancha de los empaques se parte en dos columnas PEGADAS
   (sin hueco): a la izquierda la imagen morada con el wordmark y a la derecha la rotación de empaques. Cada mitad es
   ≈ 8:9 (1000×1116 de un 2000×1116 ≈ 16:9, la misma proporción de la pieza ancha de antes). En celular (≤ 700 px) van
   una sobre otra con el hueco normal del bloque (--wf-gap). */
.wf-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.wf-duo .media-slot { aspect-ratio: 1000 / 1116; }
.wf-duo .media-slot:hover .media-slot__img { transform: none; }   /* sin el acercamiento del hover: las dos mitades se mueven igual (la derecha no lo tiene) */
@media (max-width: 700px) {
  .wf-duo { grid-template-columns: 1fr; gap: var(--wf-gap, calc(40 * var(--u))); }
}

/* Rótulo de un espacio vacío: número · descripción · tamaño de entrega */
.wf-label { display: grid; gap: 0.4em; padding: 0 1em; text-align: center; line-height: 1.4; }
.wf-label b { font-weight: 600; font-size: 1.15em; color: var(--proj-ink); }
.wf-label small { font-size: 0.92em; opacity: 0.85; letter-spacing: 0.06em; }

/* Collage: caja con la proporción medida (702 × 475) y ≈ 83 % del ancho útil,
   centrada. Las imágenes se superponen en el orden del HTML (la última, encima). */
.wf-collage { padding-top: calc(28 * var(--u)); padding-bottom: calc(28 * var(--u)); container-type: inline-size; }   /* contenedor: el título usa cqw, así sigue al collage y no a la ventana */
.wf-collage__stage { position: relative; width: 82.7%; margin: 0 auto; aspect-ratio: 702 / 475; }
.wf-c {
  position: absolute; aspect-ratio: auto;
  left: calc(var(--x) * 1%); top: calc(var(--y) * 1%);
  width: calc(var(--w) * 1%); height: calc(var(--h) * 1%);
  border-radius: 0;   /* fotos del collage con borde RECTANGULAR (pedido 12-oct; antes 6 u) */
  font-size: clamp(9px, calc(11 * var(--u)), 12px);
}
.wf-c .wf-label { padding: 0; }
.wf-c .wf-label small { display: none; }
/* Título del collage: «Natural sound waves» (8-oct; antes eran dos textos cortos en SemiBold). UNA línea en
   Sharp Grotesk Black, mayúsculas y negro puro (#000), como el pantallazo del diseño; interletrado 0,04 em
   (medido contra el pantallazo: huecos de 1,6–3,4 px entre letras y 14–14,5 px entre palabras con la «N» a
   38 px de alto). Va centrado en la franja libre del medio (entre la fila de fotos de arriba y la de abajo;
   el tramo libre mide ≈ 15 % del alto del collage) y DELANTE de todas las fotos en la capa 3D (translateZ
   mayor que el de la más cercana, 70 px) para que ninguna lo tape al flotar; un halo del color del papel lo
   mantiene legible si una foto oscura pasa por detrás. Tamaño: 5,4 cqw del collage (≈ 67 px a 1440): la
   línea ocupa ≈ 58 % del ancho del collage en cualquier pantalla, entre la foto alta de la izquierda y el
   borde derecho. (Con --u no servía: en tableta vertical --u se fija en 1,35 px y el título salía 55 %
   más ancho que el collage.) El tamaño en --u queda solo de respaldo para navegadores sin cqw. */
.wf-collage__title {
  position: absolute; left: 0; top: 44.5%; width: 100%; height: 14.5%;     /* centro del tramo libre ≈ 51 %; la caja da el eje, la «N» queda ≈ 0,6 % más arriba */
  display: grid; place-items: center;
  pointer-events: none;
  transform: translateZ(calc(100px * var(--k, 1)));   /* --k: la escala del collage (la escribe imatana.js) */
}
.wf-collage__title h2 {
  margin: 0; white-space: nowrap; text-align: center;
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: clamp(28px, calc(70 * var(--u)), 104px);          /* respaldo (sin cqw) */
  font-size: clamp(22px, 5.4cqw, 104px); letter-spacing: 0.04em; line-height: 0.95;
  color: #000;
  text-shadow: 0 0 calc(10 * var(--u)) var(--proj-paper), 0 0 calc(4 * var(--u)) var(--proj-paper);
}
/* COLLAGE QUE LEVITA (rompe la plantilla, solo Imatana). Cada foto tiene una
   profundidad --d (0 = lejos … 1 = cerca). imatana.js (sección 8) la mueve en loop
   —flota a su propio ritmo—, con el cursor (parallax e inclinación del conjunto)
   y con el scroll (lo cercano se desplaza más rápido). Aquí: perspectiva, capa 3D
   y sombra según la profundidad. */
.wf-collage[data-levitate] { perspective: 1600px; }
.wf-collage[data-levitate] .wf-collage__stage { transform-style: preserve-3d; will-change: transform; }
.wf-collage[data-levitate] .wf-c {
  will-change: transform;
  /* sin la transición del revelado ([data-reveal-item], 0,8 s con retraso por
     elemento): se reiniciaba en cada cuadro y dejaba quietas a las fotos con retraso */
  transition: none;
  box-shadow: 0 calc(6px + var(--d, 0.5) * 24px) calc(14px + var(--d, 0.5) * 40px) rgb(0 0 0 / calc(0.08 + var(--d, 0.5) * 0.16));
}
@media (max-width: 700px) {
  .wf-collage__stage { width: 100%; }
}

/* ============================================================
   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%, #5EE6A8 55%, #4FD2E8 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(0 0 0 / var(--fill));
  -webkit-text-stroke: 0.016em rgb(0 0 0 / var(--stroke));
  paint-order: stroke fill;
  transition: none;   /* cambio seco: sin tonos intermedios */
}
/* 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(0 0 0 / var(--fill));
  -webkit-text-stroke: 0.016em rgb(0 0 0 / var(--stroke));
  paint-order: stroke fill;
  /* Corta: la letra sigue al scroll. Con 0,22 s y un scroll rápido, el retraso de
     cada letra volvía a abrir un degradado en el tiempo (muchas letras a medias). */
  transition: none;   /* cambio seco: sin tonos intermedios */
}
/* 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;   /* cambio seco: sin tonos intermedios */
}

.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);
}
.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(0 60 20 / 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(0 60 20 / 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; }
}

.quote__text {
  margin: 0 auto; text-align: center;
  max-width: min(100%, calc(880 * var(--u)));
  /* Mismo estilo que intro/setup: Sharp Grotesk SemiBold 15 (sin itálica). */
  font-family: var(--f-semibold); font-weight: 400;
  font-size: clamp(22px, calc(38 * var(--u)), 54px);
  line-height: 1.3; color: var(--proj-ink); text-wrap: balance;
}

/* 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(0 60 20 / 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; }
}

/* ============================================================
   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); }
/* «Based in Bogotá»: negro pleno como el resto (8-oct; antes al 60 % de opacidad). */
/* 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(0 0 0 / 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 como los titulares: letra por letra (contorno→relleno)
   ligado al scroll (imatana.js los parte en .ch). El párrafo queda visible; el
   relleno de las letras hace el trabajo — sin recorte que compita. */
.intro__text[data-reveal-item],
.setup__text[data-reveal-item] {
  opacity: 1;
  transform: none;
  clip-path: none;
  transition: none;
}

/* Las fotos aparecen ESTÁTICAS: a pedido del usuario se quitó la transición de
   entrada (el barrido "silkscreen" lima) porque no se sentía bien. 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; }
  .media-slot[data-reveal-item] { transition: none; clip-path: none; }
  .media-slot[data-reveal-item]::after { display: none; animation: none; }
  .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 (39.7px vs 29.8px medido a 375 de ancho) 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 {
    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). */

/* ============================================================
   Banda parallax (.pband): medio de fondo + texto editable encima.
   El fondo (.pband__media) es más alto que la banda (--pb-ov arriba y abajo)
   y se desplaza dentro de ella; el texto se desplaza en sentido contrario.
   Las velocidades salen de data-media-speed / data-text-speed (imatana.js §10).
   ============================================================ */
.pband-wrap { padding-top: calc(96 * var(--u)); padding-bottom: calc(24 * var(--u)); }   /* aire entre el collage y la banda */
.pband {
  --pb-ov: 0.14;
  position: relative; overflow: hidden; background: #000;
  aspect-ratio: 16 / 9; container-type: inline-size;
  display: grid; place-items: center;
}
.pband__media { position: absolute; left: calc(var(--pb-ox, 0.05) * -100%); right: calc(var(--pb-ox, 0.05) * -100%); top: calc(var(--pb-ov) * -100%); bottom: calc(var(--pb-ov) * -100%); will-change: transform; }
.pband__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.pband__text {
  position: relative; z-index: 1; margin: 0; padding: 0 8%;
  max-width: 100%; text-align: center; text-wrap: balance;
  font-family: var(--f-black); font-weight: 400; text-transform: uppercase;
  font-size: max(20px, 5.4cqw); line-height: 1.05; letter-spacing: 0.04em;
  color: var(--white); text-shadow: 0 0 1.5cqw rgb(0 0 0 / 0.35);
  will-change: transform;
}

/* ============================================================
   Personalidad (.pers): onda verde (imagen aparte, con transparencia) + cuatro
   rasgos de texto real. La sección se queda fija (sticky) mientras dura el scroll
   y imatana.js (§11) escribe variables en .pers:
     --edge  hasta dónde se ha dibujado la onda (0 → 1, de izquierda a derecha)
     --c1…--c4  cuánto ha brotado cada rasgo (0 → 1): línea, punto, título, texto
     (el punto naranja de la onda se quitó el 8-oct)
   Sin JS (o con «reducir movimiento») todo queda a 1: se ve completo.
   Medidas del lienzo: 1410×788 (los --x/--y0/--y1 del HTML).
   ============================================================ */
.pers {
  --edge: 1; --c1: 1; --c2: 1; --c3: 1; --c4: 1;
  --pers-lime: #C9F848; --pers-bg: #04471C;
  position: relative; height: 230vh;
}
.pers__pin { position: sticky; top: 0; height: 100vh; height: 100svh; display: grid; place-items: center; }
/* mismo ancho que las fotos de la página: media-grid = min(90vw, 1800px) menos el gutter a cada lado */
.pers__view { width: min(calc(min(90vw, 1800px) - 2 * var(--gutter)), calc(92svh * 1410 / 788)); overflow: hidden; background: var(--pers-bg); }
.pers__canvas {
  position: relative; width: 100%; aspect-ratio: 1410 / 788; container-type: inline-size;
  background: var(--pers-bg);
  --fs-title: 1.7cqw; --fs-body: 0.9cqw; --w-body: 15cqw;
}
.pers__wave {
  position: absolute; left: 0; top: calc(300 / 788 * 100%); width: 100%; height: auto; display: block;   /* onda 1500×449: su borde superior queda a y=300 del lienzo */
  -webkit-mask-image: linear-gradient(90deg, #000 calc((var(--edge) * 1.25 - 0.25) * 100%), transparent calc(var(--edge) * 1.25 * 100%));
          mask-image: linear-gradient(90deg, #000 calc((var(--edge) * 1.25 - 0.25) * 100%), transparent calc(var(--edge) * 1.25 * 100%));
}
.pers__col {
  position: absolute; left: calc(var(--x) / 1410 * 100%); top: calc(var(--y0) / 788 * 100%);
  height: calc((var(--y1) - var(--y0)) / 788 * 100%); width: calc(var(--w-body) + 2cqw);
  --t: clamp(0, calc((var(--c) - 0.35) * 3), 1);     /* título */
  --b: clamp(0, calc((var(--c) - 0.6) * 3), 1);      /* texto */
}
/* la línea nace en la onda (abajo) y sube; el punto marca el contacto */
.pers__col::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: max(1px, 0.09cqw);
  background: var(--pers-lime); transform-origin: 50% 100%; transform: scaleY(var(--c));
}
.pers__col::after {
  content: ""; position: absolute; left: calc(max(1px, 0.09cqw) / 2 - 0.25cqw); bottom: -0.25cqw;
  width: 0.5cqw; height: 0.5cqw; border-radius: 50%; background: var(--pers-lime);
  transform: scale(clamp(0, calc(var(--c) * 8), 1));
}
.pers__title, .pers__body { margin: 0; padding-left: 1.14cqw; }
.pers__title {
  margin-top: 0.35cqw; font-family: var(--f-semibold); font-weight: 400; text-transform: uppercase;
  font-size: var(--fs-title); line-height: 1.12; letter-spacing: 0.02em; color: var(--pers-lime);
  opacity: var(--t); transform: translate3d(0, calc((1 - var(--t)) * 0.9cqw), 0);
}
.pers__body {
  margin-top: 1.1cqw; max-width: var(--w-body); box-sizing: content-box;
  font-family: var(--f-ui); font-size: var(--fs-body); line-height: 1.5; letter-spacing: 0.01em; color: rgb(255 255 255 / 0.9);
  opacity: var(--b); transform: translate3d(0, calc((1 - var(--b)) * 0.9cqw), 0);
}
/* Celular y tableta (≤ 1100 px): el lienzo es más ancho que la pantalla y se desplaza en
   horizontal (imatana.js lo mueve con transform según el scroll); textos proporcionalmente
   más grandes (en la composición de escritorio quedarían de 6–8 px). */
@media (max-width: 1100px) {
  .pers { height: 380vh; }
  .pers__pin { background: var(--pers-bg); }   /* verde a pantalla completa mientras está fija */
  .pers__view { width: 100vw; }
  .pers__canvas {
    width: max(170vw, min(230vw, calc(78svh * 1410 / 788)));
    --fs-title: 1.95cqw; --fs-body: 1.02cqw; --w-body: 15.5cqw;
    will-change: transform;   /* se desplaza en horizontal con el scroll */
  }
  .pers__col:nth-of-type(2) { --y0: 62 !important; }
}
@media (max-width: 700px) {
  .pers__canvas {
    width: max(240vw, min(320vw, calc(78svh * 1410 / 788)));
    --fs-title: 2.1cqw; --fs-body: 1.1cqw; --w-body: 15.5cqw;
  }
}
/* «Reducir movimiento»: sin pin ni animación; en celular el lienzo se recorre a mano. */
.pers--static { height: auto; }
.pers--static .pers__pin { position: static; height: auto; padding: calc(28 * var(--u)) 0; }
@media (max-width: 1100px) { .pers--static .pers__view { overflow-x: auto; } }

/* ============================================================
   Carrusel horizontal en loop (.hcar): los cuadros van en fila dentro de una
   pista que se desliza a la izquierda (imatana.js §12). El primer cuadro se
   repite al final para que el cierre del loop no tenga salto.
   ============================================================ */
.media-slot:has(.hcar) { opacity: 1; background: #000; }
.hcar { position: absolute; inset: 0; overflow: hidden; }
.hcar__track { display: flex; height: 100%; width: 100%; will-change: transform; }
.hcar__img { flex: 0 0 100%; width: 100%; height: 100%; object-fit: cover; display: block; }

/* <picture> dentro de un espacio de imagen (GIF con alternativa fija para «reducir movimiento»): la imagen sigue llenando la caja */
.media-slot picture { display: contents; }

/* ============================================================
   Cambio entre imágenes (.xfade): fundido en loop como la secuencia del hero (o corte seco con data-fade="0", como en los empaques).
   La que entra (.is-on) va encima; la que sale (.was-on) queda opaca debajo
   hasta terminar el fundido, así nunca se ve el fondo entre una y otra
   (imatana.js §13).
   ============================================================ */
.media-slot:has(.xfade) { opacity: 1; }
.xfade { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; }
.xfade__img {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 50% 50%;
  opacity: 0; transition: opacity var(--xf-fade, 350ms) ease-in-out;
}
.xfade__img.is-on { opacity: 1; z-index: 2; }
.xfade__img.was-on { opacity: 1; z-index: 1; transition: none; }

/* ============================================================
   MÓVIL (≤ 700 px) — ajustes de recortes, textos y espaciado
   (revisión del 7-oct con capturas a 390×844)
   ============================================================ */
@media (max-width: 700px) {
  /* Titular: «Most coffee doesn't.» cabe en UNA línea (antes «MOST» quedaba sola). */
  .statement__title { font-size: clamp(26px, 10.6vw, 90px); }

  /* Notas al margen del texto de Geoff y Catalina: centradas, un poco más legibles. */
  .setup__note { text-align: center; max-width: none; font-size: 13px; padding: 0 var(--gutter); }

  /* Banda de la onda negra: más alta (cuadrada) y con el texto más grande. */
  .pband { aspect-ratio: 1 / 1; }
  .pband__text { font-size: 7.4cqw; padding: 0 6%; }

  /* Empaque horizontal: 4:3 (la foto completa es 16:9; en celular se recortan los lados, centrada en la
     bolsa, para que no quede diminuta); las dos verticales van una debajo de la otra a todo el ancho. */
  .wf-block .media-slot--pack { aspect-ratio: 4 / 3; }
  .wf-pair--tall { grid-template-columns: 1fr; }

  /* COLLAGE: en vez de una composición miniatura (354×240 px, fotos de 60 px) se arma una
     rejilla de 2 columnas con las fotos a tamaño legible, sin superposición ni flotación;
     el título «Natural sound waves» va en medio (entre las 6 primeras fotos y las 6 últimas), a todo el
     ancho y en dos líneas. */
  .wf-collage__stage { aspect-ratio: auto; display: grid; grid-template-columns: 1fr 1fr; gap: calc(14 * var(--u)); align-items: start; width: 100%; transform: none !important; }
  .wf-collage[data-levitate] .wf-c {
    position: relative; left: auto; top: auto; width: 100%; height: auto;
    aspect-ratio: calc(var(--w) * 702 / (var(--h) * 475));
    transform: none !important; order: 1;
  }
  .wf-collage[data-levitate] .wf-c:nth-child(even) { margin-top: calc(26 * var(--u)); }   /* escalonado entre columnas */
  .wf-collage[data-levitate] .wf-c:nth-child(n+7) { order: 3; }
  .wf-collage__title {
    position: relative; left: auto; top: auto; width: auto; height: auto; transform: none;
    grid-column: 1 / -1; display: block; order: 2; padding: calc(34 * var(--u)) calc(4 * var(--u));
  }
  .wf-collage__title h2 { font-size: 15vw; line-height: 0.95; white-space: normal; text-wrap: balance; }   /* 2 líneas: «NATURAL» / «SOUND WAVES» */


  /* Pie: los tres bloques centrados y con el mismo eje (antes «Contact us» quedaba sangrado). */
  .close { align-items: center; text-align: center; gap: calc(18 * var(--u)); }
  .close__tagline { text-align: center; }
  .close__contact { margin-left: -10px; }
}
