/* ═══════════════════════════════════════════════════════════════════════════
   SANTA MEXICANA — LAYOUT

   Los tokens viven en tokens.css y no se redefinen aquí.

   Este archivo porta a CSS plano los componentes del design system que el deck
   de distribuidores ya usa (Watermark, Eyebrow, Logo, BrandPhrase, specs), con
   su geometría exacta, para que el sitio y el deck se vean como la misma marca.
   Los números no están a ojo: salen de components/core/*.jsx.

   Los cuatro recursos firma:
     1. .watermark   — la calavera DE LÍNEA, tono sobre tono, sangrando, al 4%
     2. .plate       — el producto real, con su sombra en capa aparte
     3. .specs       — mono, filas con filete
     4. aire         — una idea por pantalla
   ═══════════════════════════════════════════════════════════════════════════ */

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

html{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

body{
  margin:0;
  background:var(--surface-page);
  color:var(--text-body);
  font-family:var(--font-body);
  font-weight:var(--w-body);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  overflow-x:hidden;
}

/* Mientras el age gate está arriba, nada se mueve detrás. El estado lo pone el
   script síncrono del <head> sobre <html>, antes del primer pintado. */
html[data-gate="on"],
html[data-gate="on"] body{overflow:hidden;height:100%}
html[data-gate="off"] .gate{display:none}

img{max-width:100%;height:auto;display:block}

::selection{background:var(--gold);color:var(--ink)}

:focus-visible{outline:2px solid currentColor;outline-offset:3px}

a{color:inherit}


/* ── PRIMITIVAS ──────────────────────────────────────────────────────────── */

/* Eyebrow. Del componente del design system: flex, gap 12px, marca de 28×2px,
   mono con tracking .18em. La MARCA lleva el acento; la etiqueta NO. Medido:
   ningún acento pasa AA como texto sobre papel — coral 3.76:1, verde 2.20:1,
   oro 1.97:1. El color se ve igual, porque lo que registra el ojo es el filete. */
.eyebrow{
  display:flex;
  align-items:center;
  gap:12px;
  margin:0;
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-quiet);
}
.eyebrow::before{content:"";flex:none;width:28px;height:2px;background:var(--accent)}

.acc-pink {--accent:var(--pink)}
.acc-coral{--accent:var(--coral)}
.acc-green{--accent:var(--green)}
.acc-blue {--accent:var(--blue)}
.acc-gold {--accent:var(--gold)}

/* Titulares. Archivo 800, tracking cerrado, leading apretado.

   El tamaño está topado por el ancho disponible, no solo por vw. Cada titular
   declara --em: el ancho REAL de su renglón más largo, en em, MEDIDO en
   navegador sobre Archivo 800 con su tracking. No es número de caracteres por
   ancho promedio — eso falla: sirve para "AUTHENTICITY", que trae I y T
   angostas, y se queda corto con "REPOSADO", ocho letras anchas.

   La medida va en cqw, no en vw: 100vw incluye la barra de scroll, y en un
   sistema con barra visible el titular se desbordaba 15px.

   OJO al cambiar un titular: --em es el renglón MÁS LARGO, y no siempre es el
   que uno cree. En el hero el más largo es "should never be" (9.73em), no
   "industrialized." (9.02em). Para volver a medir, en consola:

     const p=document.createElement('span');
     p.style.cssText='position:absolute;left:-9999px;white-space:nowrap;'+
       'font:800 200px Archivo;letter-spacing:-.03em;text-transform:uppercase';
     document.body.append(p); p.textContent='TU FRASE';
     p.getBoundingClientRect().width/200                                    */
.colossal,
.display{
  --fit:calc(100cqw / var(--em));
  margin:0;
  font-family:var(--font-display);
  font-weight:var(--w-display);
  text-transform:uppercase;
  color:var(--text-display);
}
.colossal{
  font-size:min(var(--fs-colossal),var(--fit));
  line-height:var(--lh-colossal);
  letter-spacing:var(--track-colossal);
}
.display{
  font-size:min(var(--fs-display-2),var(--fit));
  line-height:var(--lh-display);
  letter-spacing:var(--track-display);
}
.colossal span,
.display span{display:block}

/* Frase de marca. Cormorant SOLO en itálica, máximo una por sección, nunca
   titular y nunca texto corrido. */
.brand-phrase{
  margin:0;
  max-width:30ch;
  font-family:var(--font-accent);
  font-style:italic;
  font-weight:400;
  font-size:var(--fs-subhead);
  line-height:1.25;
  color:var(--text-body);
}

.lead{max-width:var(--measure);margin:0;font-size:var(--fs-lead);font-weight:var(--w-body-light);line-height:1.55;color:var(--text-body)}
.body{max-width:56ch;margin:0;font-weight:var(--w-body-light);line-height:1.6;color:var(--text-body)}

/* Marca de agua: la calavera DE LÍNEA, gigante, tono sobre tono, sangrando.
   Geometría exacta del componente Watermark: alto 145–150% de la sección,
   corrida fuera por un borde, girada entre 4 y 12 grados.

   Va NÍTIDA. La primera versión usaba la calavera RELLENA con blur para
   disimular que se veía como mancha; la de línea al 4% se lee como dibujo, que
   es el efecto del deck. Medido contra el PDF: fondo #FAF8F4 y tinte #F1EFEB,
   o sea 3.9% de tinta — el mismo --watermark-opacity que ya estaba. */
.watermark{
  position:absolute;
  z-index:0;
  max-width:none;
  width:auto;
  opacity:var(--watermark-opacity);
  pointer-events:none;
  user-select:none;
  /* La sección recorta con overflow:hidden y la calavera se cortaba a filo
     recto justo en el borde. La máscara la disuelve antes de llegar ahí, así
     que de una sección a otra se lee como una sola marca de agua que pasa por
     detrás, no como un dibujo troquelado por sección. */
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 18%,#000 82%,transparent);
  mask-image:linear-gradient(to bottom,transparent,#000 18%,#000 82%,transparent);
}
.wm-left  {left:-20%;top:-28%;height:180%;transform:rotate(var(--wm-rot,-8deg))}
.wm-right {right:-22%;top:-22%;height:178%;transform:rotate(var(--wm-rot,8deg))}
.wm-center{left:50%;top:-26%;height:172%;transform:translateX(-50%) rotate(var(--wm-rot,5deg))}
/* Sobre tinta se invierte para que la línea quede clara. */
.sm-dark .watermark{filter:invert(1)}

/* Ficha de specs: mono, filas con filete, etiqueta a la izquierda en tinta
   suave y valor a la derecha en tinta. Del deck, lámina 05. */
.specs{margin:0;display:grid}
.specs > div{
  display:flex;
  justify-content:space-between;
  gap:var(--s-3);
  padding:10px 0;
  border-top:var(--border-hair);
  font-family:var(--font-mono);
  font-size:var(--fs-mono-sm);
  color:var(--text-body);
}
.specs > div:last-child{border-bottom:var(--border-hair)}
.specs dt{color:var(--text-quiet)}
.specs dd{margin:0;font-weight:var(--w-mono-strong);color:var(--text-display);text-align:right}

.mono-line{
  margin:0;
  font-family:var(--font-mono);
  font-size:var(--fs-mono-sm);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-quiet);
}

/* Placa de producto: la foto real con su sombra en capa aparte. La sombra NO es
   box-shadow ni filter — es un archivo, sintetizado de la silueta real por
   scripts/process_images.py.

   --ar es la proporción del archivo. La usan el aspect-ratio de la caja Y el
   inset negativo de la sombra: un solo número, no dos que se desincronicen
   cuando se regenere el recorte. */
.plate{position:relative;aspect-ratio:var(--ar)}
.plate__shadow,
.plate__product{position:absolute;width:100%;height:100%;object-fit:contain}
.plate__product{inset:0;z-index:1}

/* El archivo de sombra trae 15% del ancho de aire en cada lado para que el
   desenfoque no se corte contra el borde. El inset negativo devuelve ese aire. */
.plate__shadow{
  inset:calc(-15% * (var(--ar))) -15%;
  width:auto;height:auto;
  z-index:0;
  transform:translate(2%,1.5%);
}

/* Logo. Nunca invertido, nunca recoloreado. Sobre tinta va sobre placa crema,
   como manda el componente Logo. */
.logo{display:block;width:var(--logo-w,120px);height:auto}
.logo-plate{display:inline-block;background:var(--cream);padding:calc(var(--logo-w,120px) * .09)}


/* ── NAV ─────────────────────────────────────────────────────────────────── */

.nav{
  position:relative;
  z-index:20;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--s-5);
  min-height:64px;
  padding:var(--s-2) var(--margin-outer);
  border-bottom:var(--border-hair);
  background:var(--surface-page);
}
/* El logo se dimensiona por ALTO, no por ancho: el lockup es casi cuadrado
   (1367×1203) y sizarlo por ancho dejaba la barra en 123px. Con 64 de alto la
   barra queda en ~96, un poco arriba de la guía de 80 pero con el wordmark
   todavía legible, que en una marca de lujo importa más que 16 píxeles. */
.nav__logo{width:auto;height:clamp(48px,4.4vw,64px)}
.nav__list{display:flex;align-items:center;gap:clamp(var(--s-3),2.4vw,var(--s-5));list-style:none;margin:0;padding:0}
.nav__link{
  display:block;
  padding:var(--s-1) 0;
  border-bottom:2px solid transparent;
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  text-decoration:none;
  color:var(--text-quiet);
  white-space:nowrap;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.nav__link:hover{color:var(--text-display)}
.nav__link[aria-current="page"]{color:var(--text-display);border-bottom-color:var(--gold)}
.nav__toggle{display:none}


/* ── SECCIONES ───────────────────────────────────────────────────────────── */

.section{
  position:relative;
  container-type:inline-size;   /* contenedor de medida de los titulares */
  padding:var(--s-6) var(--margin-outer);
  overflow:hidden;
}
/* :not(.watermark) es obligatorio. `.section > *` pesa lo mismo que
   `.watermark` y viene después, así que le ganaría el position:absolute, la
   calavera se metería al flujo y la sección mediría el triple. Ya pasó. */
.section > :not(.watermark){position:relative;z-index:1}
.section__head{display:grid;gap:var(--s-3);margin-bottom:var(--s-4)}
.section__foot{
  display:flex;justify-content:space-between;gap:var(--s-4);
  margin-top:var(--s-6);padding-top:var(--s-3);
  border-top:var(--border-hair);
}


/* ── HERO ────────────────────────────────────────────────────────────────── */

.hero{
  position:relative;
  container-type:inline-size;
  min-height:max(calc(100svh - 96px),760px);
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:var(--s-5);
  padding:var(--s-7) var(--margin-outer);
  overflow:hidden;
}
.hero > :not(.watermark){position:relative;z-index:1}
.hero__title{max-width:none}

/* El titular YA NO se deja tapar por la botella: reserva su propio ancho de
   contenedor (64%, el resto para la botella + aire) y se vuelve container de
   sus propios hijos. La fórmula de --fit (min(cap, 100cqw/em)) no depende de
   que el contenedor sea el ancho completo del hero — encoge el texto para que
   quepa en LO QUE HAYA, así que basta con angostar la caja. Antes iba fuera del
   flujo a ancho completo a propósito para que la botella tapara la última
   palabra; ahora es al revés: nunca se tocan. */
.hero__row{position:relative;width:64%;container-type:inline-size}

/* Esta regla PIERDE contra `.hero > :not(.watermark){position:relative}` si se
   escribe como `.hero__plate` a secas: esa pesa (0,2,0) y una sola clase (0,1,0).
   Con el `>` delante empatan y gana esta por ir después. Sin esto la botella
   dejaba de ser absolute y el hero se descuadraba entero. */
.hero > .hero__plate{position:absolute}
/* La entrada NO se anima pisando este transform: el translateY(-50%) es lo que
   centra la botella y GSAP, al animar y/rotation, lo reemplazaría entero y la
   botella caería media altura. Se animan estas dos variables y el transform se
   queda donde debe estar, en CSS. */
.hero__plate{
  --ar:500 / 1666;
  --enter-y:0px;
  --enter-rot:5deg;
  position:absolute;
  /* Anclada por la IZQUIERDA, no por la derecha. Lo que tiene que quedar
     clavado es el filo izquierdo sobre la B de "be", y ese filo, anclando por
     right, es right + ancho — o sea se movía con cada cambio de alto. Anclando
     por left el filo no se mueve y la botella crece hacia afuera, sangrando por
     el canto derecho, que es justo el gesto que se quiere.
     78% no es a ojo: la B de "be" arranca en 78.5cqw y el recorte trae ~20px de
     transparente antes del vidrio. */
  left:78%;
  right:auto;
  /* Centrado por márgenes automáticos, no por top:50% + translateY(-50%).
     Con el translate, el transform tenía que cargar el -50% Y la rotación Y la
     entrada, y el resultado quedaba 35px arriba del centro real: a 840px de
     alto, eso bastaba para que el hero le cortara la calavera. Con inset 0 y
     margin auto el centrado lo hace el layout, exacto, y el transform queda
     libre para lo que es: girar y entrar. */
  top:0;
  bottom:0;
  margin-block:auto;
  height:min(88svh,880px);
  width:auto;
  transform:translateY(var(--enter-y)) rotate(var(--enter-rot));
}


/* ── BANDA OSCURA ────────────────────────────────────────────────────────────
   El único momento invertido del sitio, como la lámina 09 del deck. Aquí el oro
   SÍ es texto: medido, 9.01:1 sobre tinta. Sobre papel daría 1.97:1. */

.statement{
  position:relative;
  container-type:inline-size;
  background:var(--surface-page);
  padding:var(--s-7) var(--margin-outer);
  overflow:hidden;
}
.statement > :not(.watermark){position:relative;z-index:1}
.statement__lines{display:grid;gap:var(--s-2)}
.statement__gold{color:var(--gold)}


/* ── THE CRAFT ───────────────────────────────────────────────────────────── */

.philosophy__grid{display:grid;grid-template-columns:1.1fr .9fr;gap:var(--s-6);align-items:start}
.philosophy__copy{display:grid;gap:var(--s-4);align-content:start}
.philosophy__plate{width:min(100%,420px);justify-self:end}

/* Foto de grupo del teaser de Range en Home (recorte transparente, mismo
   patrón .plate que las botellas del hero/range). A diferencia del video y
   el chladni-still, llena toda su columna: es la pieza, no un adorno al lado
   del texto. */
.lineup{width:100%}

/* El video del tapón. Ancho de la columna y ALTO AUTOMÁTICO: el video pone su
   propia proporción, así que no hay caja que lo recorte ni letterbox que lo
   descentre. La primera versión lo metía en una caja con aspect-ratio fijo y
   object-fit, y con el recorte de alfa encima la pieza salía flotando fuera de
   centro y cortada. Sin caja no hay nada que cuadrar. */
.film-plate{width:min(100%,560px);margin-inline:auto}
.film{display:block;width:100%;height:auto}
/* `.film` pone display en una regla de AUTOR, y una regla de autor le gana
   siempre al [hidden] del user-agent, sin importar especificidad. Sin esta
   línea el canvas oculto se vería igual. Misma trampa que .lightbox en la
   galería. */
.film[hidden]{display:none}
/* El canvas ocupa el lugar del <img> mientras carga la secuencia, sin que la
   caja salte: los dos miden lo mismo y solo uno está visible a la vez. */
#seq-canvas{width:100%;height:auto}

/* Los cuatro hallmarks, 2×2, cada uno con filete arriba. Deck, lámina 03. */
.hallmarks{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-6)}
.hallmark{border-top:var(--border-hair);padding-top:var(--s-3);display:grid;gap:var(--s-2)}
.hallmark h3{
  margin:0;
  font-family:var(--font-display);
  font-weight:var(--w-subhead);
  font-size:clamp(19px,1.7vw,28px);
  letter-spacing:var(--track-head);
  text-transform:uppercase;
  color:var(--text-display);
}
.hallmark p{margin:0;font-weight:var(--w-body-light);line-height:1.6;color:var(--text-body)}

/* El momento quieto de la lámina 04. Ya no es solo texto: la foto de las tres
   botellas se subió aquí desde el muro del final. Un argumento —ninguna se
   repite— dicho una sola vez, con la frase al lado en vez de a media página de
   distancia. */
.wish{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:var(--s-6);align-items:center}
.wish__copy{display:grid;gap:var(--s-4);max-width:34ch}
/* En el deck esta frase va en oro sobre crema. En web NO pasa: medido, el
   --gold-d da 2.10:1 sobre papel y el mínimo para texto grande es 3. Es el
   único punto donde el sitio se separa del deck, y a propósito — la regla del
   propio sistema dice que el oro es filete y marca, nunca texto. La jerarquía
   se resuelve con peso de tinta, no con color. */
.wish__gold{color:var(--text-display)}

/* La foto va en placa: fondo crema y filete, para que se lea como pieza puesta
   sobre la página y no como imagen suelta al lado de un párrafo. El aire de
   adentro es lo que la hace cara. */
.trio-frame{
  margin:0;display:grid;gap:var(--s-3);justify-items:center;
  padding:var(--s-4);
  background:var(--surface-panel);
  border:var(--border-hair);
}
.trio{width:100%;height:auto}
.trio-frame figcaption{text-align:center}


/* Enlace de continuación. Mono con filete de oro, como el .mailto — el oro va
   de subrayado, nunca de texto: sobre papel da 1.97:1. */
.more{
  display:inline-block;
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  text-decoration:none;
  color:var(--text-display);
  border-bottom:2px solid var(--gold);
  padding-bottom:2px;
  transition:border-color var(--dur) var(--ease);
}
.more:hover{border-bottom-color:var(--text-display)}
.more::after{content:" \2192"}

/* La figura de Chladni del Home es una CAPTURA de la que dibuja frequency.html,
   no una segunda implementación: el patrón tiene que ser el mismo o son dos
   marcas. Se regenera desde la consola de esa página con canvas.toDataURL(). */
.chladni-still{width:min(100%,420px);height:auto;justify-self:end}


/* ── THE RANGE ───────────────────────────────────────────────────────────────
   Tres columnas: producto arriba, nombre, descriptor en Cormorant itálica y
   ficha. Es la lámina 05 del deck. */

.range{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-5)}
.expression{display:flex;flex-direction:column}
.expression__plate{height:min(74svh,720px);width:auto;margin:0 auto var(--s-5)}
.expression__name{
  margin:0;
  font-family:var(--font-display);
  font-weight:var(--w-display);
  font-size:clamp(28px,2.8vw,40px);
  letter-spacing:var(--track-head);
  text-transform:uppercase;
  color:var(--text-display);
}
/* En el Home las tres botellas son un adelanto, no la ficha: plato más chico y
   sin specs. La página del Range se queda con la versión completa. */
.range--teaser .expression__plate{height:min(52svh,460px)}

.expression__note{
  margin:6px 0 20px;
  font-family:var(--font-accent);
  font-style:italic;
  font-size:clamp(18px,1.5vw,22px);
  color:var(--text-body);
}


/* ── 963 HZ ──────────────────────────────────────────────────────────────── */

.frequency__number{margin-top:var(--s-2)}
.tone{
  display:grid;
  grid-template-columns:minmax(0,520px) minmax(0,1fr);
  gap:var(--s-6);
  align-items:center;
  margin-top:var(--s-7);
  padding-top:var(--s-5);
  border-top:var(--border-hair);
}
.tone__side{display:grid;gap:var(--s-4);align-content:center}
.tone__figure{width:100%;max-width:520px;aspect-ratio:1;display:block;background:transparent}
.tone__controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3)}
.tone__vol{display:flex;align-items:center;gap:var(--s-2)}
.tone__vol input{width:160px;accent-color:var(--ink)}
.tone__note{max-width:52ch;margin:0;font-family:var(--font-mono);font-size:var(--fs-mono-sm);line-height:1.7;color:var(--text-quiet)}


/* ── CONTACTO ────────────────────────────────────────────────────────────── */

.contact__grid{display:grid;grid-template-columns:1.2fr .8fr;gap:var(--s-8);align-items:center}
.contact__rows{width:min(440px,100%)}
/* Con formulario el lado ancho es el de los campos, y `start` en vez de `center`:
   centrar una columna de seis campos contra un párrafo deja el párrafo flotando
   a media altura. Mismo motivo que en .philosophy__grid. */
.contact__grid{grid-template-columns:.85fr 1.15fr;align-items:start}
.contact__aside{display:grid;gap:var(--s-5)}


/* ── FORMULARIO ───────────────────────────────────────────────────────────── */

.form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-3) var(--s-4)}
.field{margin:0;display:grid;gap:var(--u)}
.field--wide,.form__foot{grid-column:1 / -1}
.field label{
  font-family:var(--font-mono);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-quiet);
}
.field input,.field select,.field textarea{
  font-family:var(--font-body);
  font-size:var(--fs-body);
  color:var(--text-display);
  background:transparent;
  border:0;                                  /* solo la línea de abajo, como el resto del sitio */
  border-bottom:1px solid var(--line-strong);
  border-radius:0;                           /* iOS redondea los inputs por su cuenta */
  padding:calc(var(--u) * 1.25) 0;
  width:100%;
  min-height:44px;                           /* área de toque cómoda en móvil */
}
.field textarea{resize:vertical;line-height:1.55}
/* El select nativo trae su propia flecha del sistema; appearance:none la borraría
   y habría que dibujarla. Se deja la del sistema: es la que el usuario reconoce. */
.field select{appearance:auto}
.field input:focus,.field select:focus,.field textarea:focus{border-bottom-color:var(--gold)}
/* :user-invalid y no :invalid — :invalid marca en rojo un campo vacío que el
   usuario todavía no ha tocado, o sea el formulario abre ya regañando. */
.field input:user-invalid,.field select:user-invalid,.field textarea:user-invalid{
  border-bottom-color:#B3261E;
}
.field ::placeholder{color:var(--text-quiet);opacity:.7}

.form__foot{margin:var(--s-2) 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3)}
.form__note{color:var(--text-quiet)}

/* Honeypot. Fuera de pantalla, NO display:none — los bots que valen algo saltan
   lo que está en display:none, y esto tiene que parecer un campo real. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.mailto{
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  color:var(--text-display);
  text-decoration:none;
  border-bottom:1px solid var(--gold);
}
.mailto:hover{border-bottom-color:currentColor}


/* ── GALERÍA ─────────────────────────────────────────────────────────────── */

.gallery__filters{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-bottom:var(--s-5)}
.gallery__filters[hidden]{display:none}   /* misma trampa de [hidden] que .lightbox */
.gallery__filter{
  appearance:none;cursor:pointer;
  padding:var(--s-1) var(--s-3);
  border:var(--border-hair-strong);
  border-radius:var(--radius-0);
  background:transparent;
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  color:var(--text-quiet);
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.gallery__filter:hover{color:var(--text-display)}
.gallery__filter[aria-pressed="true"]{color:var(--text-display);border-color:var(--ink)}

/* Columnas tipo mampostería (CSS `columns`, no grid): el material real es una
   mezcla de video vertical de WhatsApp y fotos panorámicas del rack de
   producción — forzar los dos a una caja pareja con object-fit:cover recorta
   la mitad de una foto horizontal por los lados. Con `columns` cada tile
   conserva SU propio aspecto (alto y angosto, o ancho y bajo) y el navegador
   los acomoda en columnas sin dejar huecos, sin JS de layout. */
.gallery__grid{columns:240px 4;column-gap:var(--s-3)}
.gallery__item{
  position:relative;
  display:block;
  width:100%;
  margin-bottom:var(--s-3);
  break-inside:avoid;
  overflow:hidden;
  appearance:none;cursor:pointer;
  border:0;padding:0;
  background:var(--surface-panel);
}
/* width/height en el <img> (gallery.js los pone desde el manifiesto) ya le
   dan al navegador el aspect-ratio real ANTES de decodificar, así que no
   hace falta reservar la caja aparte — no hay salto de layout al cargar. */
.gallery__item img{display:block;width:100%;height:auto;transition:transform var(--dur-slow) var(--ease)}
.gallery__item:hover img{transform:scale(1.04)}
/* Video en el grid es SOLO poster + ícono: con un manifiesto grande, un grid
   de <video autoplay> sería un desastre de performance. Reproduce completo
   nada más que dentro del lightbox. */
.gallery__item--video::after{
  content:"";
  position:absolute;inset:0;margin:auto;
  width:0;height:0;
  border-style:solid;
  border-width:14px 0 14px 22px;
  border-color:transparent transparent transparent var(--paper);
  filter:drop-shadow(0 2px 6px rgba(20,17,13,.45));
}
.gallery__more{display:block;margin:var(--s-6) auto 0}
.gallery__more[hidden]{display:none}   /* misma trampa de [hidden] que .lightbox */
.gallery__empty{text-align:center;padding:var(--s-6) 0}

/* Overlay de página completa. rgba sobre --ink en vez de un token nuevo de
   color: es el mismo tono que ya usa la banda oscura del Home, solo con alfa. */
.lightbox{
  position:fixed;inset:0;z-index:50;
  display:flex;align-items:center;justify-content:center;
  padding:var(--s-4);
  background:rgba(20,17,13,.92);
}
/* El [hidden] que apaga el overlay vive en la hoja de estilo del navegador, y
   una regla de autor (el display:flex de arriba) SIEMPRE gana sobre una regla
   de user-agent, sin importar especificidad. Sin esto el lightbox se queda
   visible aunque tenga el atributo puesto. */
.lightbox[hidden]{display:none}
.lightbox__stage{max-width:92vw;max-height:88vh}
.lightbox__stage img,
.lightbox__stage video{display:block;max-width:92vw;max-height:88vh;width:auto;height:auto;object-fit:contain}
.lightbox__close,
.lightbox__prev,
.lightbox__next{
  position:absolute;
  appearance:none;cursor:pointer;border:0;background:none;
  color:var(--paper);
  font-family:var(--font-display);
  line-height:1;
}
.lightbox__close{top:var(--s-3);right:var(--s-3);font-size:32px}
.lightbox__prev,
.lightbox__next{top:50%;transform:translateY(-50%);font-size:28px;padding:var(--s-2)}
.lightbox__prev{left:var(--s-2)}
.lightbox__next{right:var(--s-2)}
.lightbox__close:hover,
.lightbox__prev:hover,
.lightbox__next:hover{color:var(--gold)}


/* ── BOTONES ─────────────────────────────────────────────────────────────── */

.btn{
  appearance:none;cursor:pointer;
  padding:calc(var(--u) * 1.75) var(--s-4);
  border:1px solid var(--ink);
  border-radius:var(--radius-0);
  background:var(--ink);
  color:var(--paper);
  font-family:var(--font-mono);
  font-weight:var(--w-mono-strong);
  font-size:var(--fs-label);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.btn:hover{background:transparent;color:var(--ink)}
.btn--quiet{background:transparent;color:var(--ink);border-color:var(--line-strong)}
.btn--quiet:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}


/* ── FOOTER ──────────────────────────────────────────────────────────────── */

.footer{border-top:var(--border-hair);padding:var(--s-6) var(--margin-outer) var(--s-5)}
.footer__top{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:var(--s-6) var(--s-5);align-items:start}
.footer__logo{--logo-w:clamp(110px,9vw,150px)}
.footer__sign{margin:var(--s-3) 0 0}
.footer__nav{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-4)}
.footer__nav a{
  font-family:var(--font-mono);
  font-size:var(--fs-mono-sm);
  letter-spacing:var(--track-label);
  text-transform:uppercase;
  text-decoration:none;
  color:var(--text-quiet);
}
.footer__nav a:hover{color:var(--text-display)}
.footer__legal{
  margin-top:var(--s-6);padding-top:var(--s-3);
  border-top:var(--border-hair);
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--s-2) var(--s-5);
}
.footer__legal p{margin:0}
.footer__legal a{color:var(--text-quiet);text-decoration:none;border-bottom:1px solid var(--line)}
.footer__legal a:hover{color:var(--text-display);border-color:var(--gold)}

/* Páginas legales: una columna de bloques .hallmark, que ya traen el filete
   superior y el ritmo interno. Esto es lo único que hace falta encima. */
.legal{display:grid;gap:var(--s-5);max-width:72ch}


/* ── AGE GATE ────────────────────────────────────────────────────────────── */

.gate{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:var(--s-4);background:var(--paper)}
.gate__panel{width:min(520px,100%);text-align:center;display:grid;justify-items:center;gap:var(--s-4)}
.gate__logo{--logo-w:min(220px,60vw)}
.gate__q{
  margin:0;
  font-family:var(--font-display);
  font-weight:var(--w-display);
  font-size:var(--fs-head);
  line-height:var(--lh-head);
  letter-spacing:var(--track-head);
  text-transform:uppercase;
  color:var(--text-display);
}
.gate__actions{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s-2)}
.gate__note{margin:0;max-width:38ch;font-family:var(--font-mono);font-size:var(--fs-mono-sm);line-height:1.7;color:var(--text-quiet)}


/* ── 1024 ────────────────────────────────────────────────────────────────── */

@media (max-width:1024px){
  .section{padding:var(--s-5) var(--margin-outer)}
  .philosophy__grid,
  .wish,
  .contact__grid{grid-template-columns:1fr;gap:var(--s-5)}
  .form{grid-template-columns:1fr}
  .hallmarks{gap:var(--s-5)}
  .tone{grid-template-columns:1fr;gap:var(--s-5)}
  .hero__plate{height:min(70svh,660px)}
  .expression__plate{height:min(52svh,480px)}
  .footer__top{grid-template-columns:1fr;gap:var(--s-5)}
}


/* ── 640 ─────────────────────────────────────────────────────────────────── */

@media (max-width:640px){
  /* El nav colapsa a un botón y la lista se abre debajo, a todo el ancho.
     Sin barra flotante de vidrio y sin blur. */
  .nav{flex-wrap:wrap}
  .nav__toggle{
    display:block;appearance:none;background:none;border:0;cursor:pointer;
    padding:var(--s-1) 0;
    font-family:var(--font-mono);font-weight:var(--w-mono-strong);
    font-size:var(--fs-label);letter-spacing:var(--track-label);
    text-transform:uppercase;color:var(--text-display);
  }
  .nav__list{display:none;width:100%;flex-direction:column;align-items:stretch;gap:0;padding-top:var(--s-3)}
  .nav[data-open="true"] .nav__list{display:flex}
  .nav__list li{width:100%;border-top:var(--border-hair)}
  .nav__link{padding:var(--s-3) 0;border-bottom:0}
  .nav__link[aria-current="page"]{border-bottom:0}

  .section{padding:var(--s-5) var(--margin-outer)}
  .hero{padding:var(--s-6) var(--margin-outer);min-height:0}
  /* En vertical la botella deja de tapar el titular: se apila debajo, entera.
     Encimada sobre un titular a este ancho no se lee como composición, se lee
     como error. */
  /* Mismo `>` que arriba, y por la misma razón: `.hero__plate` a secas pierde
     contra `.hero > .hero__plate`, y la botella se quedaba absolute dentro de
     un hero que en vertical mide 307px — se salía y quedaba cortada. */
  .hero__row{width:100%}
  .hero > .hero__plate{
    position:relative;
    left:auto;right:auto;top:auto;bottom:auto;
    margin:var(--s-5) auto 0;
    height:min(58svh,540px);
    --enter-rot:7deg;
    transform:translateY(var(--enter-y)) rotate(var(--enter-rot));
  }

  .hallmarks{grid-template-columns:1fr}
  .range{grid-template-columns:1fr;gap:var(--s-8)}
  .expression__plate{height:min(56svh,460px)}
  .tone{grid-template-columns:1fr;gap:var(--s-4)}
  .statement{padding:var(--s-6) var(--margin-outer)}
  .gallery__grid{columns:160px 4}
  .lightbox__prev,
  .lightbox__next{font-size:22px;padding:var(--s-1)}
  .footer__legal{flex-direction:column}
}


/* ── REDUCED MOTION ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}
