/* ═══════════════════════════════════════════════════════════════════════════
   MAISON ROUX — L'Arche.

   MUNDO PROPIO, y esto no es una nota de estilo: es la razon de que este
   fichero no sea el de Meridian con otros colores.

   · EL NEGRO ES VERDE. `--void` no es un gris neutro: sale del ciclorama de la
     propia pelicula, medido y llevado a valor de pagina. Un negro neutro
     detras de un plano verde deja una junta visible en cada `.breath`, que es
     justo donde la pelicula se queda sola.
   · UN SOLO CAMPO DISTINTO: `paper`. El nuancier se imprime, asi que se ve
     papel. Todo lo demas esta sobre la pelicula.
   · EL LATON ES EL UNICO ACENTO, y sale de los herrajes del bolso. Aparece en
     filetes de 1 px y en un boton. En cuanto se usa para un tercer sitio deja
     de ser el herraje y pasa a ser "el color de marca".
   · DOS FAMILIAS Y NINGUNA HABLA DOS VECES. Instrument Serif es la casa —
     titulares y nombres de cuero, siempre en romana, jamas en versalitas
     espaciadas. Public Sans es todo lo funcional. No hay una tercera para
     "los numeros": los numeros de la ficha son la sans en tabular, que es lo
     que hace una ficha de taller de verdad.

   ⛔ LO QUE NO PUEDE ENTRAR AQUI: versalitas con `letter-spacing` sobre un
      titular enorme (la forma de hero generado que cualquiera reconoce), una
      cuadricula de tarjetas con sombra, y cualquier `transition` que no sea
      `transform`/`opacity`/`color`.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* El ciclorama, medido sobre f-lo: el fondo cae entre #10160F y #1B241A en
     los tramos oscuros. La pagina se queda por debajo del mas oscuro para que
     la pelicula sea siempre lo mas claro que hay. */
  --void: #0B0F0C;
  --void-2: #121810;

  --ivory: #F2EFE7;
  --ivory-2: rgba(242, 239, 231, .74);
  --ivory-3: rgba(242, 239, 231, .54);

  /* Papel de tarjeta, no blanco. Un blanco puro contra el negro verde da un
     salto de 20 de contraste que se lee como una pagina distinta pegada. */
  --paper: #E8E2D4;
  --doc: #1A1712;
  --doc-2: rgba(26, 23, 18, .68);
  --doc-3: rgba(26, 23, 18, .46);

  /* Laton sin lacar, del herraje. Dos valores: el filete y el brillo. */
  --brass: #B08A4A;
  --brass-hi: #D8B778;

  --line: rgba(242, 239, 231, .13);
  --line-doc: rgba(26, 23, 18, .16);

  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --sans: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  --expo: cubic-bezier(.16, 1, .3, 1);
  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --w: min(1240px, calc(100% - var(--pad) * 2));
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* ⛔ `scroll-behavior: smooth` NO. Lo movia Lenis Y el navegador a la vez: dos
   suavizados sobre el mismo scroll, cada uno con su curva, y el segundo
   empezando a contar cuando el primero ya iba por la mitad. Medido en el 32:9 de
   Alex con un solo golpe de rueda (deltaY 120): 204 ms sin que se moviera UN
   pixel y 579 ms hasta asentar. Eso es el "exageradamente lagueado" del informe,
   y no era pintado — el contador iba a 240 fps clavados durante toda la medida.
   La regla del fichero ya estaba escrita para el film (L9, un solo lerp); esto
   es la misma ley aplicada al scroll: UN solo suavizado, y lo hace Lenis. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: auto; }
body {
  font-family: var(--sans);
  font-weight: 400;
  color: var(--ivory);
  background: var(--void);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  /* La pelicula es el fondo de TODO el documento; sin esto, el `background` del
     body se pinta encima del lienzo fijo en algunos navegadores. */
}
img { display: block; max-width: 100%; }
/* ⛔ EL LIENZO NO LLEVA `max-width: 100%`, Y NO ES UN DETALLE.
   Estuvo dentro de la regla de arriba junto a `img` y costo una pasada
   entenderlo. `geometry()` calcula un lienzo que CUBRE el escenario: a
   1440x900 son 1600x900 desbordando 80 px por cada lado. Con `max-width:100%`
   el navegador lo recortaba a 1440 — asi que (a) quedaba una franja negra de
   80 px a la derecha, que es la costura vertical que se veia, y (b) film.js
   dimensiona el backing store con la caja REAL del elemento, de modo que el
   fotograma 16:9 se dibujaba estirado dentro de 1,6:1 y el bolso salia
   ligeramente ancho. Un reencuadre y una deformacion por una linea heredada
   de la hoja de estilos. */
canvas { display: block; max-width: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

.wrap { width: var(--w); margin-inline: auto; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--paper); color: var(--doc);
  padding: .8rem 1.2rem; border-radius: 2px;
}
.skip:focus { left: var(--pad); top: .8rem; }

/* Foco visible y de la casa. `:focus-visible` y no `:focus`: con el segundo,
   cada clic de raton deja un anillo que nadie pidio. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--brass-hi);
  outline-offset: 3px;
}

/* ── LA PELICULA ───────────────────────────────────────────────────────────
   Fija detras del documento entero, de la primera seccion a la ultima. No es
   un hero con fondo: es la pagina. `100lvh` y no `100%` — la barra del
   navegador movil hace respirar una caja fija al 100%, y mientras el backing
   store no alcanza el navegador estira la pelicula dentro de la caja nueva. */
.filmbg {
  position: fixed; inset: 0;
  width: 100%; height: 100lvh;
  overflow: hidden;
  background: var(--void);
  z-index: 0;
  contain: strict;
}
/* ── LA JUNTA ENTRE LA PELICULA Y LA PAGINA ────────────────────────────────
   ⛔ ESTA MASCARA ESTUVO QUITADA Y HUBO QUE DEVOLVERLA. El comentario que la
   borraba decia «la bobina cubre el escenario entero, no hay junta que
   esconder». Era cierto — pero solo porque `geometry()` estaba AMPLIANDO el
   master hasta cubrir, que es justo lo que ponia la pagina borrosa en un
   monitor grande. Al arreglar aquello, la pelicula deja de cubrir y la junta
   vuelve a existir. Una decision de CSS que dependia de un fallo de JS.

   Que se funde y por que, medido sobre los 432 fotogramas:
     · IZQUIERDA — el borde del cuadro mide 3,7 (f1) y 17 (f300) de 255, y la
       pagina anda por 14. Casi el mismo negro, pero «casi» es lo que el ojo
       encuentra: un escalon de 3-5 niveles a lo largo de una vertical recta se
       lee como un borde. Rampa larga y suave.
     · ARRIBA y ABAJO — 39-48 de 255. Ahi el escalon es de 30 niveles y canta.
       Rampa mas corta y mas dura, porque hay mas que tapar en menos sitio.
     · DERECHA — no lleva. Se va de pantalla (el lienzo esta anclado a la
       derecha), asi que no hay junta; y si la hubiera, un degradado sobre el
       sujeto seria una vineta, no una union.

   Dos gradientes necesitan `mask-composite`, o se unen en vez de cortarse y
   las esquinas se quedan opacas. */
#film {
  position: absolute;
  --fadeL: 190px;
  --fadeY: 96px;
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, rgba(0,0,0,.02) calc(var(--fadeL) * .16),
      rgba(0,0,0,.10) calc(var(--fadeL) * .34), rgba(0,0,0,.30) calc(var(--fadeL) * .52),
      rgba(0,0,0,.60) calc(var(--fadeL) * .70), rgba(0,0,0,.88) calc(var(--fadeL) * .88),
      #000 var(--fadeL)),
    linear-gradient(to bottom, transparent 0, #000 var(--fadeY),
      #000 calc(100% - var(--fadeY)), transparent 100%);
  mask-image:
    linear-gradient(to right, transparent 0, rgba(0,0,0,.02) calc(var(--fadeL) * .16),
      rgba(0,0,0,.10) calc(var(--fadeL) * .34), rgba(0,0,0,.30) calc(var(--fadeL) * .52),
      rgba(0,0,0,.60) calc(var(--fadeL) * .70), rgba(0,0,0,.88) calc(var(--fadeL) * .88),
      #000 var(--fadeL)),
    linear-gradient(to bottom, transparent 0, #000 var(--fadeY),
      #000 calc(100% - var(--fadeY)), transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* Si la pelicula se sale por la izquierda (ventana estrecha), ese borde ya no
   esta en pantalla y difuminarlo solo comeria imagen util. */
body.band #film { --fadeL: 0px; --fadeY: 40px; }

main, footer { position: relative; z-index: 1; }

/* ── LA CAPSULA ───────────────────────────────────────────────────────────
   Una sola pieza: marca, filete, enlaces y accion, pegados. El logotipo va
   DENTRO con los enlaces y no en la otra punta de una barra de 1920 px. */
.nav {
  position: fixed; top: clamp(.7rem, 1.6vh, 1.3rem); left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex; align-items: center; gap: .2rem;
  padding: .42rem .42rem .42rem .95rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(11, 15, 12, .58);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  contain: paint;
}
.brand { display: flex; align-items: center; gap: .5rem; }
.brand-mark {
  font-family: var(--serif); font-size: 1.02rem; line-height: 1;
  color: var(--brass-hi);
  /* La "A" del monograma, la misma que va grabada en la solapa. */
}
.brand-name { font-size: .84rem; letter-spacing: .01em; white-space: nowrap; }
.nav-sep { width: 1px; height: 18px; background: var(--line); margin: 0 .75rem; }
.nav-links { display: flex; gap: .1rem; }
.nav-links a {
  font-size: .8rem; color: var(--ivory-2);
  padding: .45rem .7rem; border-radius: 999px;
  transition: color .3s var(--expo), background-color .3s var(--expo);
}
.nav-links a:hover { color: var(--ivory); background: rgba(242, 239, 231, .07); }
.nav-cta {
  margin-left: .55rem;
  font-size: .8rem; font-weight: 500;
  padding: .5rem 1.05rem; border-radius: 999px;
  background: var(--paper); color: var(--doc);
  transition: transform .35s var(--expo), background-color .3s var(--expo);
}
.nav-cta:hover { transform: translateY(-1px); background: #fff; }
.nav-burger { display: none; }

/* ── EL HERO ──────────────────────────────────────────────────────────────
   El hero NO mueve la pelicula: la mueve el documento entero. Esta altura solo
   decide cuanto corre la pelicula SOLA antes de que entre el nuancier — y no
   se escribe a mano, la despeja `fitHero()` por biseccion para que el traspaso
   caiga en HANDOFF en cualquier pantalla. El valor de aqui es solo el de
   partida, antes de que corra el JS. */
.hero { position: relative; height: 420lvh; }
.hero-pin {
  position: sticky; top: 0;
  height: 100lvh;
  overflow: hidden;
  pointer-events: none;
}
.hero-pin > * { pointer-events: auto; }

/* Las dos cajas ocupan EL MISMO sitio. `placeCopy()` les escribe `left` y
   `width`; lo de aqui es el respaldo y la posicion vertical. */
.hero-copy, .hero-relay {
  position: absolute;
  left: var(--pad);
  width: min(34%, 620px);
  top: 50%;
  translate: 0 -50%;
  /* `--rise` lo escribe el motor en cada fotograma: el bloque sube y se va, no
     se apaga en el sitio. */
  transform: translateY(calc(var(--rise, 0px) * -1));
  will-change: transform, opacity;
}
.hero-relay { opacity: 0; }

h1 {
  font-family: var(--serif); font-weight: 400;
  /* 9,5rem -> 11rem: Alex, 2026-08-03, *"el primer titulo tambien podria estar
     un poco mas grande"*. En el 32:9 el tope es lo que manda (11vw serian 563px),
     asi que el numero que se toca es el ultimo. A 176px "L'Arche" ocupa ~610 de
     los 1.178 px de la columna: sigue cabiendo en una linea, que es la condicion
     — partido en dos deja de ser un nombre y pasa a ser un parrafo. */
  font-size: clamp(3.9rem, 11.5vw, 11rem);
  line-height: .88;
  letter-spacing: -.025em;
  /* ⛔ Sin `text-transform` y sin `letter-spacing` positivo. El nombre es una
     palabra francesa con apostrofo: en versalitas espaciadas se lee como el
     rotulo de un hotel. */
}
/* EL RELEVO ES UN TITULAR, NO UN SUBTITULO. Estaba en 4,4rem contra los 9,5 del
   titular — medido en pantalla, 70px contra 152px, o sea MENOS DE LA MITAD — y
   por eso Alex lo leia como *"demasiado pequeño"*. Sube a 8,2rem (131px).
   ⛔ No iguala al titular a proposito: este va en DOS lineas ("Nobody's / first
      bag."), asi que a 176px ocuparia 352px de alto y el bloque entero — con su
      lede, su boton y su ficha — se saldria de la pantalla. A 131px son 252px y
      la caja queda del mismo alto que la del titular, que es lo que hace que el
      relevo se lea como un relevo y no como otra composicion. */
.hero-relay h2 {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(3.2rem, 8.5vw, 8.2rem);
  line-height: .94; letter-spacing: -.024em;
}
.lede {
  margin-top: 1.3rem;
  max-width: 44ch;
  font-size: clamp(.95rem, 1.05vw, 1.05rem);
  line-height: 1.68;
  color: var(--ivory-2);
}
.lede b { color: var(--ivory); font-weight: 500; font-family: var(--serif); }

.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem; margin-top: 2rem; }
.btn {
  display: inline-flex; align-items: center;
  padding: .82rem 1.5rem; border-radius: 999px;
  font-size: .9rem; font-weight: 500;
  background: var(--paper); color: var(--doc);
  transition: transform .4s var(--expo), background-color .3s var(--expo);
}
.btn:hover { transform: translateY(-2px); background: #fff; }
.btn-quiet {
  position: relative;
  font-size: .9rem; color: var(--ivory-2);
  padding-bottom: 3px;
  transition: color .3s var(--expo);
}
.btn-quiet::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--brass);
  transform-origin: left;
  transition: transform .45s var(--expo);
}
.btn-quiet:hover { color: var(--ivory); }
.btn-quiet:hover::after { transform: scaleX(.4); }

.hero-spec {
  margin-top: 2.2rem;
  font-size: .72rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ivory-3);
  font-variant-numeric: tabular-nums;
}
.hero-spec b { color: var(--brass); font-weight: 400; margin: 0 .35rem; }

.hero-cue {
  position: absolute; left: var(--pad); bottom: clamp(1.4rem, 4vh, 2.6rem);
  font-size: .64rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ivory-3);
}

/* ── EL RESPIRO ───────────────────────────────────────────────────────────
   La unica pieza de la pagina que existe para NO tener contenido. Poner la
   pelicula detras de todo no sirve de nada si delante no hay ningun hueco por
   el que se vea. */
/* 88lvh -> 26lvh. Alex, 2026-08-03: *"despues de esa parte de Nobody's first
   bag, haciendo scroll, hay demasiado tiempo sin salir nada"*. Medido: desde que
   el relevo se va (y=2280) hasta que entra el atelier (y=3899) habia **1.619 px
   = 1,12 pantallas** sin nada en pantalla. Sumaban dos cosas: la ultima pantalla
   del hero, que ya no tiene contenido porque el pin se ha soltado, y estos
   88lvh. Lo primero es estructural (lo despeja `fitHero()` desde la coreografia);
   lo segundo era un numero, y es el que se toca.
   El respiro NO se borra: sigue siendo el unico sitio donde la pelicula se queda
   sola, y esa pausa es la que hace que la seccion siguiente entre como un corte.
   Pero un respiro es una coma, no un parrafo en blanco. */
.breath { height: 26lvh; pointer-events: none; }

/* ── LOS CAMPOS ───────────────────────────────────────────────────────────
   `void` = la pelicula cruda. `paper` = una superficie opaca encima. */
[data-field] { position: relative; isolation: isolate; }
[data-field] > * { position: relative; z-index: 1; }
[data-field]::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
}
[data-field="void"]::after { background: none; }
[data-field="paper"] {
  background: var(--paper);
  color: var(--doc);
}
[data-field="paper"]::after { background: none; }

/* La costura del papel. Un corte recto entre la pelicula y una superficie
   opaca es correcto y es lo que se quiere — pero el borde superior necesita
   una linea de laton de 1 px, o el papel parece que flota sin apoyarse. */
.seam { position: relative; }
.seam::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px; z-index: 2;
  background: linear-gradient(to right, transparent, var(--brass) 22%, var(--brass) 78%, transparent);
  opacity: .5;
}

/* ── LA POZA ──────────────────────────────────────────────────────────────
   `.scrim` NO es opcional donde se usa. Las secciones `void` no llevan velo y
   la pelicula se ve cruda por detras — y esta bobina tiene tramos donde la
   mano iluminada y el traje llegan a 189 de 255. Sin la poza, un titular esta
   sobre negro en unas posiciones de scroll y sobre piel en otras. */
/* ⛔ LA POZA TIENE QUE LLEGAR A CERO DENTRO DE SU PROPIA CAJA.
   Este es el fallo que costo una pasada: la primera version era
   `radial-gradient(120% 100% at 22% 50%, ... transparent 78%)` sobre una caja
   con `inset: -2.5rem -3rem`. Con la forma final al 120% del ancho de la caja,
   el borde de la caja caia al 64% del radio — o sea que el degradado seguia
   con ~0,3 de alfa cuando el elemento se acababa, y ahi el navegador CORTA A
   PICO. Resultado medido en pantalla: una linea vertical recta a 582 px, justo
   donde acababa el `::before`, sobre un plano que en el fichero no tiene
   ningun borde (el gradiente maximo del fotograma es 5,9 de 255, y es el canto
   del bolso).

   Una poza que se ve NO es una poza: es un rectangulo oscuro encima de la
   fotografia, que es exactamente lo que el velo venia a evitar.

   ⇒ La forma final se queda POR DEBAJO del tamaño de la caja (78% x 62% contra
     una caja con 4-5 rem de margen), asi que el degradado ya vale cero mucho
     antes del borde y no hay nada que cortar. */
/* ⛔ `position: relative` AQUI PISABA EL `absolute` DE LOS DOS TITULARES DEL
   HERO, y ese es el bug que Alex describio como *"el segundo titulo no esta
   centrado"* (2026-08-03). Misma especificidad (una clase) y este bloque va
   ~130 lineas MAS ABAJO, asi que ganaba la cascada: `.hero-copy` y `.hero-relay`
   salian del posicionamiento absoluto, volvian al flujo normal y se APILABAN.
   Medido: el titular en y=543 y el relevo en y=1013 — 470 px mas abajo, cuando
   tenian que ocupar exactamente la misma caja.
   El velo solo necesita crear contexto de apilamiento para su `::before`, y
   `absolute` tambien lo crea. Asi que se excluyen los dos del hero por si algun
   dia se anade otro `.scrim` que si dependa de `relative`. */
.scrim, .scrim-wide { position: relative; }
.hero-copy.scrim, .hero-relay.scrim { position: absolute; }
.scrim::before, .scrim-wide::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: -4rem -5rem;
  background: radial-gradient(ellipse 78% 62% at 32% 50%,
    rgba(11, 15, 12, .90) 0%,
    rgba(11, 15, 12, .78) 38%,
    rgba(11, 15, 12, .44) 66%,
    rgba(11, 15, 12, .16) 84%,
    transparent 100%);
}
.scrim-wide::before {
  inset: -4rem -6rem;
  background: radial-gradient(ellipse 74% 64% at 50% 50%,
    rgba(11, 15, 12, .90) 0%,
    rgba(11, 15, 12, .80) 40%,
    rgba(11, 15, 12, .46) 68%,
    rgba(11, 15, 12, .17) 85%,
    transparent 100%);
}

/* ── TIPOGRAFIA DE SECCION ────────────────────────────────────────────────*/
.runhead {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding-bottom: .7rem;
  border-bottom: 1px solid var(--line);
  font-size: .66rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ivory-3);
}
[data-field="paper"] .runhead { color: var(--doc-3); border-bottom-color: var(--line-doc); }

.sec-head { margin-top: clamp(2.6rem, 7vh, 5rem); max-width: 62ch; }
.stmt {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.1rem, 5.2vw, 4rem);
  line-height: .98; letter-spacing: -.02em;
}
.stmt-note {
  margin-top: 1.4rem; max-width: 54ch;
  font-size: clamp(.95rem, 1.05vw, 1.04rem); line-height: 1.72;
  color: var(--ivory-2);
}
[data-field="paper"] .stmt-note { color: var(--doc-2); }

/* ── LE NUANCIER ──────────────────────────────────────────────────────────*/
/* ══ LES CUIRS — el catalogo ES el ultimo fotograma ═══════════════════════════
   No hay foto de producto en esta seccion, a proposito: el bolso que se ve es el
   lienzo `#film`, parado en su ultimo fotograma, y el selector cambia lo que ese
   lienzo pinta. Por eso aqui NO se pone fondo — cualquier `background` taparia
   justamente el producto.

   El alto es lo que le da al motor recorrido para llegar al ultimo fotograma
   virando el color (ver `CUIR_A/CUIR_B` en film.js). El bloque de texto se pega
   con `sticky` para que se quede quieto mientras eso pasa, y `placeCopy()` le
   escribe la MISMA columna que al titular del hero: el catalogo tiene que
   leerse como el ultimo acto de la pelicula, no como otra pagina. */
/* 190lvh -> 112lvh. Alex, 2026-08-03: *"despues de la parte del catalogo, tengo
   que hacer demasiado scroll para seguir bajando"*. Y era literal: el bloque va
   pinchado, asi que esos 190lvh eran 1,9 pantallas de rueda con la imagen y el
   texto CLAVADOS — nada cambiaba, solo se consumia scroll. Lo que tiene que
   durar es lo justo para que se lea el nombre del cuero, se pulse otro y se vea
   virar; 112lvh dan ese margen y devuelven casi una pantalla entera al recorrido.
   ⛔ No puede bajar de ~100lvh: el bloque esta pinchado a `100lvh` y por debajo
      de eso deja de haber recorrido para el sticky — el catalogo pasaria de
      largo sin llegar a quedarse quieto. */
.cueros { position: relative; height: 112lvh; }
.cueros-pin { position: sticky; top: 0; height: 100lvh; pointer-events: none; }
.cueros-pin > * { pointer-events: auto; }
.cueros-copy {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  left: var(--pad);                 /* respaldo: `placeCopy()` lo reescribe */
  width: min(30.5%, 1180px);
}
.cu-name { font-family: var(--serif); font-size: clamp(2rem, 3.4vw, 3.4rem); font-weight: 300; line-height: .98; }
.cu-note { margin-top: .6rem; font-size: .95rem; line-height: 1.6; color: var(--ivory-2); max-width: 34ch; }
.cu-chips { display: grid; grid-template-columns: repeat(5, 1fr); gap: .55rem; list-style: none; margin: 1.5rem 0 0; }
.cu-price { margin-top: 1.5rem; font-family: var(--serif); font-size: 1.5rem; font-weight: 300; }
.cu-lead { display: block; margin-top: .3rem; font-family: var(--sans); font-size: .68rem;
           letter-spacing: .1em; text-transform: uppercase; color: var(--ivory-3); }

.nuancier { padding: clamp(3.5rem, 9vh, 7rem) 0 clamp(3.5rem, 9vh, 6rem); }
.nu-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(320px, .85fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
  margin-top: clamp(2.4rem, 6vh, 4rem);
}
.nu-plate { position: relative; }
.nu-plate img {
  width: 100%; height: auto;
  aspect-ratio: 2400 / 1340;
  object-fit: cover;
  background: #C9C2B2;
  /* El cambio de cuero NO es un fundido cruzado ni un desplazamiento: la foto
     es la misma composicion al pixel (misma mujer, misma mano, mismo fondo —
     ver build_assets.py), asi que lo unico que cambia de verdad es el color del
     bolso. Un fundido de 180 ms lo cuenta; cualquier cosa mas larga lo
     convierte en una diapositiva. */
  transition: opacity .18s linear;
}
.nu-plate img.swap { opacity: 0; }
.nu-cap {
  display: flex; justify-content: space-between; gap: 1rem;
  margin-top: .8rem;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--doc-3);
  font-variant-numeric: tabular-nums;
}
.nu-cap .tab { color: var(--doc-2); }

.nu-name {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2rem, 3.4vw, 3rem); line-height: 1; letter-spacing: -.015em;
}
.nu-note { margin-top: .55rem; font-size: .92rem; line-height: 1.6; color: var(--doc-2); max-width: 34ch; }

/* Las pastillas. CUERO, no color plano: el `background-image` es un recorte
   real del cuerpo del bolso de esa variante. El `background-color` de debajo
   es el color medio, y solo se ve mientras la imagen carga. */
.nu-chips {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: .55rem;
  list-style: none; margin: 1.6rem 0 0;
}
.nu-chip {
  position: relative;
  width: 100%; aspect-ratio: 1;
  border-radius: 2px;
  background-size: cover; background-position: center;
  border: 1px solid rgba(26, 23, 18, .22);
  transition: transform .35s var(--expo), box-shadow .35s var(--expo);
}
.nu-chip:hover { transform: translateY(-2px); }
/* El elegido lleva un filete de laton POR FUERA, no un borde que empuje el
   contenido ni un tick encima que tape el cuero. */
/* El filete de separacion ya no es `--paper`: estas pastillas viven sobre la
   PELICULA, no sobre la carta impresa, asi que el halo que las separa del fondo
   tiene que ser el negro del film o el laton queda flotando sobre el cuero. */
.nu-chip[aria-checked="true"] {
  box-shadow: 0 0 0 2px var(--void), 0 0 0 3px var(--brass);
}
/* Cuero anunciado pero todavia sin imagen generada (mantequilla, hueso, blanco).
   Se marca en vez de dejar una pastilla que no hace nada al pulsarla. */
.nu-chip-soon { opacity: .38; }
.nu-chip-soon::after {
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(45deg, transparent 0 5px, rgba(0,0,0,.35) 5px 6px);
}
.nu-chip span {
  position: absolute; inset: auto 0 0 0;
  padding: .3rem .35rem;
  font-size: .58rem; letter-spacing: .07em; text-transform: uppercase;
  color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, .62), transparent);
  border-radius: 0 0 1px 1px;
  text-align: center;
}

.nu-spec {
  margin-top: 1.9rem;
  border-top: 1px solid var(--line-doc);
  font-variant-numeric: tabular-nums;
}
.nu-spec > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .62rem 0;
  border-bottom: 1px solid var(--line-doc);
  font-size: .84rem;
}
.nu-spec dt { color: var(--doc-3); }
.nu-spec dd { color: var(--doc); }
.nu-price {
  margin-top: 1.4rem;
  font-family: var(--serif); font-size: 2.1rem; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.btn-brass {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 1.2rem; padding: .85rem 1.5rem;
  border-radius: 999px;
  border: 1px solid var(--brass);
  color: var(--doc);
  font-size: .88rem; font-weight: 500;
  transition: background-color .35s var(--expo), color .35s var(--expo), transform .35s var(--expo);
}
.btn-brass:hover { background: var(--brass); color: var(--paper); transform: translateY(-2px); }
.btn-brass.big { width: 100%; margin-top: 1.5rem; padding: 1rem; }
[data-field="void"] .btn-brass { color: var(--ivory); }
[data-field="void"] .btn-brass:hover { background: var(--brass); color: var(--void); }

.nu-foot {
  margin-top: 2.4rem; padding-top: 1rem;
  border-top: 1px solid var(--line-doc);
  font-size: .78rem; line-height: 1.7; color: var(--doc-3);
}
.nu-foot b { color: var(--brass); font-weight: 400; margin: 0 .3rem; }

/* ── L'ATELIER — LA FICHA ─────────────────────────────────────────────────
   Una ficha de taller, no una tabla de especificaciones: numero, operacion y
   horas, en el orden en que ocurren. Las horas van en TABULAR y alineadas a la
   derecha porque es lo unico que se compara entre lineas. */
.atelier { padding: clamp(4rem, 10vh, 8rem) 0; }
.docket {
  list-style: none;
  margin-top: clamp(2.4rem, 6vh, 4rem);
  border-top: 1px solid var(--line);
}
.docket li {
  display: grid;
  grid-template-columns: 3.2rem minmax(0, 1fr) 5.5rem;
  gap: clamp(1rem, 2.4vw, 2.4rem);
  align-items: baseline;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--line);
}
.d-n {
  font-size: .72rem; letter-spacing: .1em;
  color: var(--ivory-3);
  font-variant-numeric: tabular-nums;
}
.d-op b {
  display: block;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.15rem, 1.9vw, 1.5rem); line-height: 1.15;
}
.d-op i {
  display: block; margin-top: .35rem;
  font-style: normal; font-size: .88rem; line-height: 1.6;
  color: var(--ivory-2); max-width: 62ch;
}
.d-h {
  text-align: right;
  font-size: 1.15rem;
  font-variant-numeric: tabular-nums;
  color: var(--ivory);
}
.d-h em { font-style: normal; font-size: .72em; color: var(--ivory-3); margin: 0 .04em; }

/* LA LINEA CORTA. Es el argumento entero de la seccion: ocho minutos, una vez,
   sin segunda oportunidad. Se marca con el laton — no se agranda, porque una
   linea mas grande dentro de una ficha deja de ser una ficha. */
.d-strike { background: linear-gradient(to right, rgba(176, 138, 74, .10), transparent 62%); }
.d-strike .d-n, .d-strike .d-h { color: var(--brass-hi); }
.d-strike .d-op b { color: var(--brass-hi); }

.d-sum { border-bottom: 0; padding-top: 1.6rem; }
.d-sum .d-op b { font-size: clamp(1rem, 1.5vw, 1.2rem); }
.d-sum .d-h { font-family: var(--serif); font-size: 1.9rem; }

/* ── LE CUIR ──────────────────────────────────────────────────────────────
   Corte duro a sangre. Sin caja, sin fundido y sin bordes redondeados: es lo
   que da contraste de verdad contra una pagina que por lo demas es una
   pelicula continua. */
.cuir { padding: 0; }
.cuir img { width: 100%; height: auto; }
.cuir-grid {
  padding: clamp(2.4rem, 6vh, 4rem) 0 clamp(3rem, 8vh, 5rem);
  max-width: 72ch;
}
.cuir-lead {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2.5rem); line-height: 1.18; letter-spacing: -.015em;
}
.cuir-cite {
  margin-top: 1.4rem;
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ivory-3);
}
.cuir-cite b { color: var(--brass); font-weight: 400; margin: 0 .35rem; }

/* ── LE REGISTRE ──────────────────────────────────────────────────────────*/
.registre { padding: clamp(4rem, 10vh, 8rem) 0 clamp(5rem, 12vh, 9rem); }
.reg-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 26rem);
  gap: clamp(2.4rem, 5vw, 5rem);
  margin-top: clamp(2.4rem, 6vh, 4rem);
}
.reg-lede { margin-top: 1.6rem; max-width: 46ch; font-size: 1rem; line-height: 1.72; color: var(--ivory-2); }
.reg-fine { margin-top: 1rem; max-width: 46ch; font-size: .84rem; line-height: 1.7; color: var(--ivory-3); }

.reg-form {
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: clamp(1.4rem, 2.4vw, 2rem);
  background: rgba(11, 15, 12, .55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.reg-form-h {
  font-family: var(--serif); font-size: 1.45rem; line-height: 1;
  padding-bottom: 1rem; margin-bottom: .4rem;
  border-bottom: 1px solid var(--line);
}
.fgrp { margin-top: 1.05rem; }
.fgrp label {
  display: block; margin-bottom: .35rem;
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ivory-3);
}
.fgrp input, .fgrp select, .fgrp textarea {
  width: 100%;
  font: inherit; font-size: .92rem;
  color: var(--ivory);
  background: transparent;
  border: 0; border-bottom: 1px solid var(--line);
  padding: .55rem 0;
  border-radius: 0;                 /* iOS redondea los inputs por su cuenta */
  transition: border-color .3s var(--expo);
}
.fgrp select {
  /* La flecha nativa en un fondo oscuro sale de otro mundo. */
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ivory-3) 50%),
                    linear-gradient(135deg, var(--ivory-3) 50%, transparent 50%);
  background-position: calc(100% - 10px) 1.15em, calc(100% - 5px) 1.15em;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 1.6rem;
}
.fgrp select option { background: var(--void-2); color: var(--ivory); }
.fgrp textarea { resize: vertical; min-height: 4.5rem; }
.fgrp input::placeholder, .fgrp textarea::placeholder { color: rgba(242, 239, 231, .3); }
.fgrp input:focus, .fgrp select:focus, .fgrp textarea:focus {
  outline: 0; border-bottom-color: var(--brass);
}
.fgrp input[aria-invalid="true"], .fgrp textarea[aria-invalid="true"] { border-bottom-color: #C97A5E; }

/* La trampa. Un visitante no la ve y no la rellena nunca; los bots rellenan
   hasta los campos ocultos. `tabindex=-1` para que el teclado no la pise.
   ⛔ `display:none` NO: bastantes bots lo detectan y saltan justo esos campos. */
.fpot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.fsend-busy { display: none; }
#fSend[data-busy] .fsend-idle { display: none; }
#fSend[data-busy] .fsend-busy { display: inline; }
#fSend[data-busy] { opacity: .6; pointer-events: none; }
.fmsg { margin-top: .9rem; font-size: .84rem; line-height: 1.6; min-height: 1.2rem; }
.fmsg.ok { color: var(--brass-hi); }
.fmsg.bad { color: #E09A80; }

/* ── EL PIE ───────────────────────────────────────────────────────────────*/
footer { border-top: 1px solid var(--line); padding: clamp(2.4rem, 6vh, 4rem) 0 3rem; background: var(--void); }
.demo-note { max-width: 68ch; font-size: .95rem; line-height: 1.72; color: var(--ivory-2); }
.demo-note b { color: var(--ivory); font-weight: 500; }
.demo-note a { color: var(--brass-hi); border-bottom: 1px solid rgba(176, 138, 74, .5); }
.foot {
  display: flex; flex-wrap: wrap; gap: 1.2rem 2.4rem; align-items: center;
  margin-top: 2.4rem; padding-top: 1.6rem;
  border-top: 1px solid var(--line);
}
.foot nav { display: flex; flex-wrap: wrap; gap: 1.2rem; }
.foot nav a { font-size: .82rem; color: var(--ivory-3); transition: color .3s var(--expo); }
.foot nav a:hover { color: var(--ivory); }
.foot nav[aria-label="Legal"] { margin-left: auto; }
.fine { margin-top: 1.6rem; font-size: .7rem; line-height: 1.8; color: var(--ivory-3); }

/* ── LAS PAGINAS LEGALES ──────────────────────────────────────────────────
   Sin pelicula: son documentos, y un documento sobre una pelicula en marcha no
   se lee. Se quedan con la tipografia y el laton de la casa, y nada mas. */
body.legal { background: var(--void); }
.legal-main { padding: clamp(7rem, 12vh, 9rem) 0 clamp(4rem, 9vh, 8rem); }
.legal-head { margin-bottom: clamp(2.4rem, 5vh, 4.4rem); }
.legal-head h1 {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.2rem, 4.4vw, 3.6rem); line-height: 1.02; letter-spacing: -.02em;
}
.legal-date {
  margin-top: .8rem;
  font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ivory-3);
}
.legal-body { max-width: 74ch; }
.legal-body h2 {
  font-family: var(--serif); font-weight: 400;
  margin: clamp(2.2rem, 5vh, 3.4rem) 0 .7rem;
  font-size: clamp(1.25rem, 1.9vw, 1.6rem); line-height: 1.2;
}
.legal-body p, .legal-body li { font-size: .95rem; line-height: 1.72; color: var(--ivory-2); }
.legal-body p + p { margin-top: .85rem; }
.legal-body ul { margin: .85rem 0 0; padding-left: 1.2rem; }
.legal-body li { margin-bottom: .6rem; }
.legal-body a { color: var(--ivory); text-decoration: underline; text-underline-offset: 3px; }
.legal-body a:hover { color: var(--brass-hi); }
.legal-body strong { color: var(--ivory); font-weight: 500; }
/* El aviso de que nada de esto existe va ARRIBA y con su propio filete: en unos
   terminos no es una salvedad, es el hecho que cambia el sentido de todo lo
   demas que se lea despues. */
.legal-flag {
  margin: 0 0 clamp(2rem, 4vh, 3.2rem);
  padding: 1.3rem 1.6rem;
  border: 1px solid rgba(176, 138, 74, .38);
  max-width: 74ch;
}
.legal-flag p { font-size: .92rem; line-height: 1.66; color: var(--ivory-2); }
.legal-flag b {
  display: block; padding-bottom: .45rem;
  font-size: .66rem; font-weight: 400; letter-spacing: .14em;
  text-transform: uppercase; color: var(--brass-hi);
}
.legal-back {
  display: inline-block; margin-top: clamp(2.6rem, 5vh, 4.4rem);
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ivory-2);
}
.legal-back:hover { color: var(--ivory); }

#dbg {
  position: fixed; left: 8px; bottom: 8px; z-index: 90;
  font: 11px ui-monospace, monospace; color: #7CFF9E;
  background: rgba(0, 0, 0, .7); padding: 6px 8px; white-space: pre;
  display: none;
}
#dbg:not(:empty) { display: block; }

/* ── LA ENTRADA ───────────────────────────────────────────────────────────
   14 px y opacidad, UNA vez por elemento, y solo `transform`/`opacity`. Detras
   hay una pelicula que ya se esta moviendo con la rueda: cualquier animacion
   con duracion propia va a su aire mientras el fotograma de debajo va al ritmo
   del scroll, y eso se ve como dos relojes. */
.rv, .rv-rows > * {
  opacity: 0; transform: translateY(14px);
  transition: opacity .75s var(--expo), transform .75s var(--expo);
}
.rv.in, .rv-rows.in > * { opacity: 1; transform: none; }
/* El escalonado de las filas es corto a proposito: 7 filas x 90 ms son 630 ms,
   y por encima de eso la ultima llega cuando ya has dejado de mirar. */
.rv-rows > *:nth-child(1) { transition-delay: 0ms; }
.rv-rows > *:nth-child(2) { transition-delay: 60ms; }
.rv-rows > *:nth-child(3) { transition-delay: 120ms; }
.rv-rows > *:nth-child(4) { transition-delay: 180ms; }
.rv-rows > *:nth-child(5) { transition-delay: 240ms; }
.rv-rows > *:nth-child(6) { transition-delay: 300ms; }
.rv-rows > *:nth-child(7) { transition-delay: 360ms; }
.rv-rows > *:nth-child(8) { transition-delay: 420ms; }

/* ── ANCHURAS ─────────────────────────────────────────────────────────────
   Un solo corte, y esta puesto donde la reja del nuancier deja de caber, no en
   un numero redondo de catalogo. Por debajo de 900 px esta pagina practicamente
   no se ve: la verja del `<head>` manda los telefonos al preview. Lo que queda
   aqui es para ventanas de escritorio estrechas y tabletas. */
@media (max-width: 1000px) {
  .nu-stage, .reg-grid { grid-template-columns: 1fr; }
  .hero-copy, .hero-relay { width: auto; right: var(--pad); }
  .nav-links, .nav-sep, .nav-cta { display: none; }
  .nav-burger {
    display: flex; flex-direction: column; justify-content: center; gap: 4px;
    width: 38px; height: 34px; padding: 0 9px; margin-left: .6rem;
  }
  .nav-burger span { display: block; height: 1px; background: var(--ivory); transition: transform .4s var(--expo), opacity .3s var(--expo); }
  .nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
  .nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
  .nav-panel {
    position: fixed; inset: 0; z-index: 49;
    display: grid; align-content: center; justify-items: center; gap: 1.6rem;
    background: rgba(11, 15, 12, .96);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
    opacity: 0; visibility: hidden;
    transition: opacity .4s var(--expo), visibility .4s;
  }
  .nav-panel.open { opacity: 1; visibility: visible; }
  .nav-panel a { font-family: var(--serif); font-size: 2rem; }
  .nav-panel-cta { color: var(--brass-hi); }
  .docket li { grid-template-columns: 2.4rem minmax(0, 1fr); }
  .d-h { grid-column: 2; text-align: left; margin-top: .5rem; }
  .foot nav[aria-label="Legal"] { margin-left: 0; }
}
@media (max-width: 620px) {
  .nu-chips { grid-template-columns: repeat(4, 1fr); }
}

/* La pelicula ES la pagina, asi que no se puede "apagar el movimiento" sin
   dejar la pagina vacia. Lo que si se apaga es todo lo que se mueve POR SU
   CUENTA: las entradas, los desplazamientos y el scroll suavizado (film.js no
   monta Lenis con esta preferencia). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
  .rv, .rv-rows > * { opacity: 1; transform: none; }
}
