/* ══════════════════════════════════════════════════════════════════════════
   LA FÁBRICA · web pública

   Dirección "Editorial". El diagnóstico que la originó: el problema no era el
   color, era la artesanía. Pacifico (script casual de Google) como tipografía
   de marca es lo que hacía ver barata la página; ninguna paleta arregla eso.
   Acá va una Didone de verdad, papel con grano, detalles de carta y movimiento
   ligado al scroll.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Tipografías autohospedadas ──
   Nada de CDN: en este repo ya hubo que vendorear React porque unpkg queda
   bloqueado en Brave y en redes con filtro, y una página cuyo diseño ES la
   tipografía no puede depender de que responda un tercero. Son los subconjuntos
   latin y latin-ext de Google Fonts, variables (el eje opsz de la Bodoni es lo
   que hace que el titular no se vea igual que el cuerpo). */
@font-face{
  font-family:'Bodoni Moda';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/assets/fuentes/bodoni-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Bodoni Moda';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/assets/fuentes/bodoni-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Bodoni Moda';font-style:italic;font-weight:400 500;font-display:swap;
  src:url('/assets/fuentes/bodoni-italic-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Bodoni Moda';font-style:italic;font-weight:400 500;font-display:swap;
  src:url('/assets/fuentes/bodoni-italic-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Instrument Sans';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/assets/fuentes/instrument-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Instrument Sans';font-style:normal;font-weight:400 600;font-display:swap;
  src:url('/assets/fuentes/instrument-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

:root{
  /* Papel y tinta. Sigue siendo la familia marrón + oro de la marca, en clave clara. */
  --papel:#F2EFE8;
  --papel-2:#EAE5DB;          /* bloques hundidos */
  --tinta:#221B15;
  --tinta-2:rgba(34,27,21,.66);
  --tinta-3:rgba(34,27,21,.42);
  --hilo:rgba(34,27,21,.16);
  --hilo-2:rgba(34,27,21,.09);
  /* #8A6B1F daba 4.35 sobre el papel y 3.98 sobre el bloque hundido: no llega
     al 4.5 de AA, y el oro se usa en las etiquetas, que son texto chico.
     Oscurecido hasta que pasa en las dos superficies. */
  --oro:#7C5E1D;
  --oro-claro:#C9A227;        /* sólo sobre la banda profunda */
  --hondo:#1A1410;            /* la banda oscura de contraste */
  --hondo-tinta:#F2EFE8;

  --dsp:"Bodoni Moda", "Bodoni MT", Didot, Georgia, serif;
  --txt:"Instrument Sans", system-ui, -apple-system, sans-serif;

  --e-out:cubic-bezier(.16,1,.3,1);
  --e-io:cubic-bezier(.65,0,.35,1);
  --maxw:1220px;
  --pad:clamp(20px,5vw,64px);
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
/* `clip` y NO `hidden`. Poner overflow-x:hidden hace que overflow-y compute a
   `auto`, y eso convierte al body en contenedor de scroll: ahí position:sticky
   deja de activarse por completo (ni el nav ni la sección anclada del proceso
   se pegaban). `clip` recorta igual sin crear scrollport. */
html,body{max-width:100%;overflow-x:clip;}
body{
  margin:0;background:var(--papel);color:var(--tinta);
  font-family:var(--txt);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
::selection{background:rgba(138,107,31,.22);}

/* Grano de papel. Va como SVG inline (feTurbulence): pesa ~400 bytes y no
   agrega una petición, a diferencia del paper.jpg de 200 KB que usa
   Santo Peccato. pointer-events:none o se come todos los clics. */
.grano{
  position:fixed;inset:0;z-index:9999;pointer-events:none;opacity:.05;
  mix-blend-mode:multiply;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad);}

/* ── Tipografía ── */
.dsp{
  font-family:var(--dsp);font-weight:400;line-height:1.02;letter-spacing:-.015em;
  margin:0;font-optical-sizing:auto;
}
.dsp em{font-style:italic;font-weight:400;}
h1.dsp{font-size:clamp(3.2rem,11vw,8.5rem);}
h2.dsp{font-size:clamp(2.3rem,6vw,4.6rem);}
h3.dsp{font-size:clamp(1.35rem,2.4vw,1.9rem);line-height:1.14;}

/* Etiqueta de sección: versalitas con hilo, el recurso editorial que le faltaba
   a la página anterior. */
.label{
  font-size:.72rem;font-weight:600;letter-spacing:.24em;text-transform:uppercase;
  color:var(--oro);margin:0 0 22px;display:flex;align-items:center;gap:16px;
}
.label::after{content:"";flex:1;height:1px;background:var(--hilo);max-width:120px;}
.lede{font-size:clamp(1.05rem,1.6vw,1.22rem);color:var(--tinta-2);max-width:52ch;}
.mini{font-size:.9rem;color:var(--tinta-3);}

/* ── Botones ── */
.btn{
  display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  font-family:var(--txt);font-weight:500;font-size:.95rem;letter-spacing:.01em;
  padding:15px 30px;border-radius:2px;border:1px solid transparent;
  transition:background-color .25s ease,color .25s ease,border-color .25s ease,scale 150ms var(--e-out);
}
.btn:active{scale:.975;}
.btn-solid{background:var(--tinta);color:var(--papel);}
.btn-solid:hover{background:var(--oro);}
.btn-linea{border-color:var(--hilo);color:var(--tinta);}
.btn-linea:hover{border-color:var(--tinta);}
.btn svg{width:14px;height:14px;transition:transform .3s var(--e-out);}
.btn:hover svg{transform:translateX(3px);}
:focus-visible{outline:2px solid var(--oro);outline-offset:3px;}

/* Subrayado que se dibuja. */
.sub{position:relative;}
.sub::after{
  content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:right;transition:transform .4s var(--e-out);
}
.sub:hover::after{transform:scaleX(1);transform-origin:left;}

/* ── Nav ── */
header.nav{
  position:sticky;top:0;z-index:60;background:rgba(242,239,232,.82);
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  border-bottom:1px solid var(--hilo-2);
}
.nav-in{display:flex;align-items:center;justify-content:space-between;height:74px;}
.marca{display:flex;align-items:center;gap:13px;}
/* El dibujo de Nene es un retrato vertical (relación ~0,70), no un monograma
   cuadrado: va con width:auto o se deforma. Y a 34px de alto el trazo se
   empasta, así que sube a 44. */
.marca img{height:44px;width:auto;}
footer .marca img{height:38px;}
/* El wordmark deja el script casual y pasa a la Didone en versalitas.
   Estaba fijo en 1.28rem con .11em de tracking y a 390px no entraba al lado del
   CTA: se partía en dos líneas y chocaba contra el botón. Con el cuerpo y el
   tracking fluidos entra en una sola línea hasta en 320px. */
.marca span{font-family:var(--dsp);font-size:clamp(.98rem,3.4vw,1.28rem);
  letter-spacing:clamp(.05em,.9vw,.11em);text-transform:uppercase;font-weight:500;
  white-space:nowrap;}
@media(max-width:520px){ header.nav .marca img{height:36px;} header.nav .marca{gap:9px;} }
.nav-links{display:flex;gap:34px;align-items:center;}
.nav-links a{font-size:.88rem;color:var(--tinta-2);font-weight:500;letter-spacing:.02em;transition:color .25s ease;}
.nav-links a:hover{color:var(--tinta);}
.nav-links .btn{padding:11px 22px;}
/* `.nav-links a` (0,1,1) le gana en especificidad a `.btn-solid` (0,1,0), así
   que el CTA salía con el color de texto del nav sobre su fondo oscuro: negro
   sobre negro, ilegible. Hay que igualar la especificidad, no subir !important. */
.nav-links a.btn-solid{color:var(--papel);}
.nav-links a.btn-solid:hover{color:var(--papel);background:var(--oro);}

/* ── Menú del teléfono ──
   El botón: dos rayas que al abrir se cruzan. Se anima `transform` y nada más
   (rotar y mover no repinta), y el área táctil es de 44px aunque el dibujo
   mida 22. */
.nav-btn{display:none;position:relative;width:44px;height:44px;flex:0 0 44px;
  margin-right:-10px;padding:0;background:none;border:0;cursor:pointer;}
.nav-btn-r{position:absolute;left:11px;width:22px;height:1.5px;background:var(--tinta);
  transition:transform .3s var(--e-out);}
.nav-btn-r:nth-child(1){top:18px;}
.nav-btn-r:nth-child(2){top:25px;}
[aria-expanded="true"] .nav-btn-r:nth-child(1){transform:translateY(3.5px) rotate(45deg);}
[aria-expanded="true"] .nav-btn-r:nth-child(2){transform:translateY(-3.5px) rotate(-45deg);}

/* El panel se oculta con `visibility` y no con `hidden`/`display:none` por dos
   razones: `visibility:hidden` ya lo saca del recorrido de teclado y del árbol
   de accesibilidad (así que no hace falta andar moviendo `aria-hidden`, que es
   donde se rompen estos menús), y deja que la entrada se pueda animar. */
html.js .menu{position:fixed;inset:74px 0 0;z-index:55;background:var(--papel);
  overflow-y:auto;overscroll-behavior:contain;
  visibility:hidden;opacity:0;transform:translateY(-8px);
  transition:opacity .24s var(--e-out),transform .24s var(--e-out),visibility 0s .24s;}
/* Nada aparece de la nada en el mundo real: entra desde -8px y con opacidad,
   nunca desde scale(0). */
html.js .menu.abierto{visibility:visible;opacity:1;transform:none;transition-delay:0s;}
.menu-in{display:flex;flex-direction:column;gap:6px;padding-block:clamp(26px,7vw,46px);}
/* El menú usa la Didone de la marca en cuerpo grande: es la tipografía que
   la página ya tiene y convierte un trámite en un momento de la marca. */
.menu-in > a{font-family:var(--dsp);font-size:clamp(1.9rem,8.4vw,2.7rem);line-height:1.28;
  letter-spacing:-.015em;color:var(--tinta);}
.menu-in > a:active{color:var(--oro);}
/* Lleva `.seguir` también, para heredar el estilo de las píldoras de redes.
   Con `.menu` adelante para ganarle a `.seguir{margin-top:18px}`, que está
   más abajo en la hoja y si no le pisa el margen. */
.menu .menu-redes{display:flex;gap:10px;flex-wrap:wrap;margin-top:clamp(22px,6vw,38px);
  padding-top:clamp(20px,5vw,30px);border-top:1px solid var(--hilo-2);}

/* El botón del nav: con texto arriba, sólo el ícono abajo.
   Los selectores llevan `.btn` adelante a propósito: `.btn svg` (0,1,1) le
   gana a `.nav-cta-icono` (0,1,0) y el ícono saldría de 14px. Se empata la
   especificidad, no se sube un !important. */
.btn .nav-cta-icono{display:none;}
.btn:hover .nav-cta-icono{transform:none;}
@media(max-width:560px){
  .nav-in{gap:12px;}
  .nav-cta-txt{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);}
  .btn .nav-cta-icono{display:block;width:19px;height:19px;}
  .nav-links .btn{padding:11px 13px;}
}

@media(max-width:860px){
  .nav-links a:not(.btn){display:none;}
  .nav-btn{display:block;}
  /* Sin JS el panel no se puede abrir, así que se muestra siempre: vale más
     una lista de enlaces bajo el encabezado que ninguna navegación. */
  html:not(.js) .menu{border-bottom:1px solid var(--hilo-2);background:var(--papel-2);}
  html:not(.js) .nav-btn{display:none;}
}
@media(min-width:861px){ .menu{display:none;} }

/* ── Hero ── */
.hero{position:relative;min-height:92svh;display:flex;align-items:flex-end;overflow:hidden;
  padding-block:clamp(90px,16vh,170px) clamp(48px,8vh,86px);}
/* Acá vivían `.hero-media` (el video) y `.hero-velo` (las tres capas oscuras que
   le devolvían contraste al titular por encima de la comida). Los dos se fueron
   con el video. El velo no se conserva "por las dudas": sin foto debajo, tres
   degradados oscuros sobre un fondo ya oscuro sólo ensucian el carbón, y el
   contraste que iban a rescatar ahora sale solo — #F2EFE8 sobre #1A1410 da 14:1,
   contra el 4,5 que pide AA. */
.hero .wrap{position:relative;z-index:2;}
/* Acá había un max-width:22ch. Trampa: `ch` se mide con la fuente DEL
   CONTENEDOR, que usa el cuerpo de 17px — o sea ~190px, y el H1 en Bodoni a
   158px no entra. Como .mask lleva overflow:hidden, "Fábrica" salía cortada
   en "Fábri". El ancho del titular lo define el propio titular. */
.hero-copy{max-width:none;}
.hero .label{color:#E6D9A8;}
.hero .label::after{background:rgba(242,239,232,.34);}
.hero h1{color:var(--hondo-tinta);}
.hero h1 em{color:#E9D9A5;}
/* El titular se dimensionaba SÓLO por ancho (11vw). En un portátil de 1366x650
   eso da 136px de tipografía dentro de una ventana de 650: dos líneas de Bodoni
   se comen la pantalla y los botones quedan abajo del pliegue. El min() le suma
   un techo por altura. En escritorio normal (900px de alto) no cambia nada. */
.hero h1{font-size:min(clamp(3.2rem,11vw,8.5rem), 17vh);}
.hero .lede{color:rgba(242,239,232,.84);max-width:44ch;margin:26px 0 34px;}
.hero .btn-solid{background:var(--papel);color:var(--tinta);}
.hero .btn-solid:hover{background:#E9D9A5;}
.hero .btn-linea{border-color:rgba(242,239,232,.34);color:var(--papel);}
.hero .btn-linea:hover{border-color:var(--papel);}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;}
/* Los dos botones miden distinto por su texto (199 y 180px). Uno al lado del
   otro no se nota; apilados en un teléfono esa diferencia se ve como un
   escalón mal cortado. El grid con `width:max-content` toma el ancho del más
   ancho y estira los dos — quedan parejos SIN irse a ancho completo, que
   rompería el aire editorial de la página. */
@media(max-width:560px){
  .hero-cta{display:grid;grid-auto-flow:row;width:max-content;max-width:100%;gap:11px;}
  .hero-cta .btn{justify-content:center;}
}

/* Hero de marca: el carbón con su luz detrás, él adelante. */
.hero--marca{background:var(--hondo);align-items:center;}
.hero-in{display:grid;grid-template-columns:1fr auto;gap:clamp(28px,5vw,72px);align-items:center;}

/* La luz — el ambiente. Es lo que reemplaza al video: le saca al fondo la
   lectura de "rectángulo plano" y cierra la composición con una viñeta.
   Es pseudo-elemento y no un div: el fondo dejó de tener contenido, así que no
   necesita nodo propio.
   Ojo: acá va SÓLO lo que depende del viewport (el lavado tibio general y la
   viñeta de los bordes). El halo que rodea al retrato NO puede vivir acá, y esa
   fue una corrección medida: con el halo anclado al 72% del viewport, en un
   monitor de 2560 se le corría a la derecha del hombro — porque el retrato está
   topado por --maxw:1220px y la luz no lo estaba. Ese halo vive en
   .hero-marca::before, pegado a él, y así se acomoda solo a cualquier ancho.

   La ÚLTIMA capa es una textura generada (hero-textura.webp): papel ahumado,
   parejo, sin foco. Va al final porque las capas de background pintan la primera
   arriba, así que listada última queda abajo de todo.
   Dos decisiones que costaron tres intentos:
   - La textura NO tiene composición a propósito. Los dos primeros intentos eran
     humo y llamas dorados, con lindura de sobra, y los dos fracasaron por lo
     mismo: el hero tiene sólo dos zonas —el titular a la izquierda y él a la
     derecha— y cualquier imagen con dirección le cae encima a una de las dos.
     Espejarla sólo cambió a cuál. Lo que sirve acá es materia, no motivo.
   - Viene YA COMPUESTA sobre el carbón #1A1410 dentro del archivo, y no puesta a
     media opacidad por CSS, porque una capa de background no tiene opacidad
     propia. Además así se controla exacto: sobre un fondo casi negro un 10% de
     alfa NO es un 10% de efecto —la luminancia salta de 26 a 49, casi el doble—
     y a ojo se subestima siempre.
   Pesa 5,4 KB. Si algún día se regenera, ese número es el techo. */
.hero--marca::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(96% 108% at 62% 48%,
      rgba(150,112,42,.13) 0%, rgba(110,80,32,.07) 40%, transparent 74%),
    radial-gradient(120% 108% at 50% 42%,
      transparent 44%, rgba(10,7,5,.36) 80%, rgba(8,5,4,.66) 100%),
    url("/assets/hero-textura.webp") center / cover no-repeat;
}

/* La trama de semitono.
   El retrato es una ilustración de SEMITONO —puntos de trama, tipo serigrafía— y
   ese es el único lenguaje visual propio que tiene la marca. Vivía en un solo
   elemento; acá el fondo lo adopta, y por eso la trama se lee como parte del
   dibujo y no como una textura de plantilla.
   Tres números que no son estéticos sino técnicos:
   - PASO de 14px. Una grilla regular más fina tironea contra la grilla de
     píxeles y hace muaré, sobre todo en pantallas de dpr 2 y 3, donde el punto
     no cae en un píxel entero. Verificado mirando capturas a 1x, 2x y 3x.
   - El punto se dibuja con un `radial-gradient` cortado en dos paradas casi
     pegadas: es un círculo con borde suave, no un cuadrado antialiaseado.
   - `mask-image` para que la trama SE DENSIFIQUE HACIA ÉL y se disuelva hacia la
     izquierda. El titular vive a la izquierda: una trama pareja le compite al
     texto justo donde hay que leer.
   Estática. Se pinta una vez y se compone; no hay nada que animar acá. */
.hero--marca::after{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:radial-gradient(circle at center,
    rgba(201,162,39,.30) 0 1.1px, transparent 1.7px);
  background-size:14px 14px;
  -webkit-mask-image:radial-gradient(72% 86% at 68% 50%,
    #000 0%, rgba(0,0,0,.62) 34%, rgba(0,0,0,.16) 62%, transparent 82%);
  mask-image:radial-gradient(72% 86% at 68% 50%,
    #000 0%, rgba(0,0,0,.62) 34%, rgba(0,0,0,.16) 62%, transparent 82%);
}

/* ── LA LUZ QUE SE MUEVE ──
   El fondo del hero quedó sin movimiento al sacar el video y el dueño lo dijo
   así: "se ve muy estático". Esto lo resuelve SIN volver a la fotografía —que es
   lo que estaba roto de origen— porque la luz no necesita material en alta: se
   dibuja.
   Son dos focos cálidos, cada uno con su período: 23s y 31s. Que no sean
   múltiplos es el truco entero: como no vuelven a coincidir, la luz nunca repite
   la misma combinación y el ojo no encuentra el bucle. Con un solo foco, o con
   dos sincronizados, a los veinte segundos se ve el latido y queda peor que
   estático — queda mecánico.
   `alternate` y no un ciclo cerrado: un gradiente que vuelve al inicio de un
   salto tiene un corte, y en un degradado grande el corte se ve.
   Se anima SÓLO transform y opacity, que van al compositor. Animar el
   `background-position` de un radial a pantalla completa es repintar 1920x1080
   por cuadro. */
/* Fuera de pantalla no se anima nada. Lo pone y lo saca un IntersectionObserver
   (ver el comentario del script en index.html): en una máquina sin GPU, animar
   el hero mientras se scrollea el resto de la página costaba 24fps donde con la
   pausa hay 60. */
.hero-pausa .hero-luz i,
.hero-pausa .hero-brasas i,
.hero-pausa .hero-grano{animation-play-state:paused;}

.hero-luz{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;}
.hero-luz i{position:absolute;display:block;will-change:transform,opacity;}
.hero-luz i:nth-child(1){
  inset:-28% -14% -14% 16%;
  background:radial-gradient(closest-side,
    rgba(198,150,55,.17) 0%, rgba(150,108,38,.08) 46%, transparent 74%);
  animation:heroLuzA 23s ease-in-out infinite alternate;
}
.hero-luz i:nth-child(2){
  inset:-12% 2% -30% 34%;
  background:radial-gradient(closest-side,
    rgba(158,102,34,.15) 0%, rgba(112,74,26,.07) 48%, transparent 76%);
  animation:heroLuzB 31s ease-in-out infinite alternate;
}
/* La amplitud NO es libre: estos dos focos son también los que iluminan el fondo
   detrás del titular, y subirlos sube la luminancia contra la que se lee la
   Bodoni. Los valores de acá abajo están medidos en ocho momentos distintos del
   ciclo, y el PEOR de los ocho da 11,9:1 en el renglón más flojo (el label),
   contra el 4,5 que pide AA. Si alguien los sube más, hay que volver a medir —y
   medir sobre la TINTA, no sobre la caja del h1, que abarca los 1220px de la
   columna y toca el retrato, que es crema: eso ya dio un falso 1,1:1 una vez. */
@keyframes heroLuzA{
  from{transform:translate3d(-4%,4%,0) scale(.94);    opacity:.55;}
  to  {transform:translate3d(6%,-5%,0) scale(1.22);   opacity:1;}
}
@keyframes heroLuzB{
  from{transform:translate3d(5%,-3%,0) scale(1.18);   opacity:.38;}
  to  {transform:translate3d(-6%,5%,0) scale(.90);    opacity:1;}
}

/* ── LAS MOTAS QUE SUBEN ──
   Lo único que se mueve con un borde definido, y por eso es lo que hace que el
   fondo se lea como vivo y no como un degradado que late.
   Se leen como brasas o como polvo en un haz de luz según quién mire; las dos
   lecturas son ciertas en un centro de producción, y ninguna de las dos exige
   afirmar nada que no sea verdad. No hay figura, no hay motivo, no hay dirección
   que compita con la composición — que es exactamente lo que hizo fracasar a las
   dos primeras texturas generadas.
   La máscara las borra en el tercio izquierdo. No es estética: el titular vive
   ahí, y un punto brillante cruzando abajo de una Bodoni es lo que hace que se
   relea la línea. Lo que se mueve va del lado del retrato.
   Cuatro reglas que las salvan de parecer un demo de partículas:
   - POCAS (20). Con cuarenta ya no es aire, es nieve.
   - CHICAS pero VISIBLES: 3 a 7px. El primer intento fue de 1,5 a 4px y una
     sonda que las contaba las encontró a las 16 en pantalla, con su animación
     corriendo y su opacidad correcta — o sea "funcionando" — pero en la tira de
     contactos no se veía UNA. Sobre un fondo con textura y grano, un punto de
     2px al 40% no existe. Que un elemento esté en el DOM con los valores
     correctos no prueba que se vea; eso lo prueba mirar.
   - VELOCIDADES DISTINTAS, de 14s a 34s el recorrido. Todas iguales suben en
     formación y se lee la grilla.
   - Los delays son NEGATIVOS: así la primera pantalla ya tiene motas a media
     altura. Con delays positivos el hero arranca vacío y la mota más lenta
     tarda 34 segundos en aparecer — o sea que justo el que entra y mira dos
     segundos ve el fondo quieto, que es el problema que esto vino a resolver. */
.hero-brasas{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,
    transparent 0%, rgba(0,0,0,.22) 19%, rgba(0,0,0,.78) 33%, #000 46%);
  mask-image:linear-gradient(90deg,
    transparent 0%, rgba(0,0,0,.22) 19%, rgba(0,0,0,.78) 33%, #000 46%);
}
.hero-brasas i{position:absolute;display:block;top:100%;left:var(--x);
  width:var(--s);height:var(--s);border-radius:50%;
  background:rgba(244,214,132,.95);
  box-shadow:0 0 10px 2px rgba(214,170,58,.45), 0 0 22px 6px rgba(180,124,36,.22);
  opacity:0;                     /* con reduced-motion se queda acá: invisible */
  animation:heroBrasa var(--t) linear var(--d) infinite;
  will-change:transform,opacity;
}
/* El recorrido se mide en svh (no en %) porque el % de un elemento de 3px es
   3px. En un hero bajo las motas se pasan de largo y las recorta el overflow,
   que es el comportamiento correcto. */
@keyframes heroBrasa{
  0%  {transform:translate3d(0,0,0) scale(.5);             opacity:0;}
  10% {opacity:var(--o);}
  45% {transform:translate3d(16px,-48svh,0) scale(1);}
  76% {opacity:var(--o);}
  100%{transform:translate3d(-13px,-106svh,0) scale(.75);  opacity:0;}
}
.hero-brasas i:nth-child(1) {--x:38%;--s:5px;--t:20s;--d:-14s;--o:.72;}
.hero-brasas i:nth-child(2) {--x:57%;--s:3px;--t:28s;--d:-4s; --o:.50;}
.hero-brasas i:nth-child(3) {--x:71%;--s:7px;--t:16s;--d:-9s; --o:.88;}
.hero-brasas i:nth-child(4) {--x:49%;--s:3px;--t:31s;--d:-23s;--o:.44;}
.hero-brasas i:nth-child(5) {--x:83%;--s:5px;--t:22s;--d:-6s; --o:.68;}
.hero-brasas i:nth-child(6) {--x:64%;--s:3px;--t:29s;--d:-19s;--o:.42;}
.hero-brasas i:nth-child(7) {--x:44%;--s:4px;--t:18s;--d:-11s;--o:.60;}
.hero-brasas i:nth-child(8) {--x:92%;--s:3px;--t:26s;--d:-2s; --o:.48;}
.hero-brasas i:nth-child(9) {--x:76%;--s:6px;--t:19s;--d:-16s;--o:.80;}
.hero-brasas i:nth-child(10){--x:53%;--s:3px;--t:34s;--d:-28s;--o:.38;}
.hero-brasas i:nth-child(11){--x:87%;--s:4px;--t:21s;--d:-13s;--o:.58;}
.hero-brasas i:nth-child(12){--x:68%;--s:3px;--t:30s;--d:-5s; --o:.46;}
.hero-brasas i:nth-child(13){--x:41%;--s:5px;--t:24s;--d:-21s;--o:.64;}
.hero-brasas i:nth-child(14){--x:79%;--s:3px;--t:27s;--d:-10s;--o:.40;}
.hero-brasas i:nth-child(15){--x:60%;--s:4px;--t:23s;--d:-17s;--o:.56;}
.hero-brasas i:nth-child(16){--x:96%;--s:3px;--t:17s;--d:-7s; --o:.52;}
.hero-brasas i:nth-child(17){--x:34%;--s:4px;--t:25s;--d:-3s; --o:.54;}
.hero-brasas i:nth-child(18){--x:73%;--s:3px;--t:33s;--d:-26s;--o:.36;}
.hero-brasas i:nth-child(19){--x:89%;--s:6px;--t:14s;--d:-12s;--o:.76;}
.hero-brasas i:nth-child(20){--x:47%;--s:4px;--t:32s;--d:-30s;--o:.50;}

/* Grano.
   Un carbón liso a pantalla completa se lee como "div vacío"; con grano se lee
   como película. Antes este comentario decía que el grano estaba para tapar que
   las fotos de origen eran de 206px — esas fotos ya no están, y el grano se
   queda igual porque su trabajo verdadero es darle materia al fondo: además le
   rompe la regularidad a la trama de semitono, que es lo que la salva de leerse
   como un mosaico de plantilla.
   Va en CSS y no quemado en una imagen por dos razones que siguen valiendo: el
   ruido es lo más caro de comprimir, y acá queda nítido a cualquier resolución
   de pantalla. La turbulencia se dibuja una vez en un mosaico de 180px y se
   repite: pintar feTurbulence a pantalla completa es caro.

   El grano TIEMBLA, y esa es la mitad barata de que el fondo se lea como
   película: en cine el grano cambia cuadro a cuadro, y un grano quieto sobre una
   imagen quieta se lee como suciedad de la pantalla, no como material.
   `steps(4)` a 1.2s son ~3 cambios por segundo, no 60: el grano de película se
   ve a ~24, pero acá arriba corren las motas y la luz, y un tercer elemento a
   60fps sobre una capa `mix-blend-mode` a pantalla completa es justo lo que hace
   que un fondo bonito tironee. Se mueve el mosaico, no se redibuja: el
   `translate3d` va al compositor y el ruido ya está pintado.
   El `inset:-110px` NO es un descuido: se mueve el elemento entero, así que con
   `inset:0` un salto de 90px deja una franja vacía de 90px en un borde del hero.
   Sobra material por los cuatro lados y el salto nunca llega a destaparlo. */
.hero-grano{position:absolute;inset:-110px;z-index:1;pointer-events:none;opacity:.13;
  mix-blend-mode:overlay;
  animation:heroGrano 1.2s steps(4) infinite;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");}
@keyframes heroGrano{
  0%  {transform:translate3d(0,0,0);}
  25% {transform:translate3d(-90px,45px,0);}
  50% {transform:translate3d(45px,-90px,0);}
  75% {transform:translate3d(90px,90px,0);}
  100%{transform:translate3d(0,0,0);}
}

/* El retrato es una ilustración a partir de su foto real, recortada sobre
   transparente. Que sea DIBUJO y no fotografía es hoy la razón de que el hero se
   sostenga: un dibujo no tiene resolución que perder, así que aguanta cualquier
   tamaño de pantalla — es el único elemento del proyecto del que se puede decir
   eso. Por eso quedó él solo adelante cuando el fondo de fotos se fue.
   La sombra proyectada es lo que lo despega del fondo, y necesita el halo cálido
   de .hero--marca::before para que se vea: sombra negra sobre carbón, sola, no
   despega nada. */
.hero-marca{margin:0;flex-shrink:0;position:relative;}
/* El halo, pegado a él y no al viewport (ver la nota de .hero--marca::before).
   Se desborda a propósito: el gradiente tiene que empezar bastante antes del
   recorte para que se lea como luz de fondo y no como un aura recortada.
   z-index:-1 y no 0: un pseudo-elemento POSICIONADO con z-index auto se pinta
   ENCIMA del contenido en flujo — o sea taparía el retrato. Se queda dentro del
   contexto de apilado de .wrap, así que no se va detrás del grano. */
.hero-marca::before{
  content:"";position:absolute;z-index:-1;pointer-events:none;
  inset:-24% -34% -14%;
  background:radial-gradient(closest-side at 50% 46%,
    rgba(214,174,58,.26) 0%, rgba(168,126,44,.15) 40%,
    rgba(104,76,32,.06) 66%, transparent 84%);
}
.hero-marca img{height:clamp(190px,46vh,470px);width:auto;display:block;
  filter:drop-shadow(0 26px 42px rgba(0,0,0,.55));}

/* ESCRITORIO · el retrato se sale de la jaula.
   El problema medido: el contenido vive dentro de --maxw:1220px pero el fondo va
   a sangre, así que a 1920 quedaban 414px de carbón vacío de cada lado y a 2560
   quedaban 734 — el 43% del ancho sin nada. Y en vertical el hero mide 92svh
   para un contenido de 551px.
   Las dos cosas las arregla el mismo movimiento: el retrato deja la grilla, se
   ancla al HERO (no al wrap) y crece. Es el único elemento que puede crecer sin
   perder nitidez, porque es un dibujo.

   El texto NO se mueve: se queda en los 1220 alineado con el nav —que usa el
   mismo .wrap— y con todas las secciones de abajo. Romper esa alineación se lee
   como bug, no como decisión.

   El truco que lo hace posible: `.hero .wrap` era position:relative + z-index:2,
   y eso lo convertía en el bloque contenedor, o sea que un absolute adentro se
   anclaba a 1220px y no a la ventana. Acá pasa a `static` — y SIGUE APILANDO
   igual, porque `.hero--marca` es flex y un flex item respeta z-index sin
   necesidad de position. El retrato queda dentro de su contexto de apilado (o
   sea, por encima del grano) pero posicionado contra el borde de la pantalla.

   No sangra fuera del canto a propósito: es una persona ilustrada, y cortarla
   contra el borde se lee como error. Se acerca, no se va. */
@media(min-width:881px){
  .hero--marca .wrap{position:static;}
  .hero--marca .hero-in{grid-template-columns:1fr;}
  .hero--marca .hero-marca{position:absolute;right:clamp(40px,4vw,110px);
    top:50%;transform:translateY(-50%);}
  .hero--marca .hero-marca img{height:clamp(560px,68vh,900px);}
}
/* El piso. El recorte terminaba en una línea recta a la altura de la cadera
   (el 73% del ancho opaco en la última fila) y se leía "cortado con tijera".
   El degradado va en el alfa del archivo —así la sombra proyectada se desvanece
   con él— y esta elipse le da algo donde apoyarse en vez de flotar. */
.hero-marca::after{
  content:"";position:absolute;left:9%;right:9%;bottom:1%;height:8%;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(ellipse at 50% 50%,
    rgba(0,0,0,.52) 0%, rgba(0,0,0,.3) 42%, rgba(0,0,0,.1) 66%, transparent 78%);
}
/* Teléfono: el hero tiene que entrar CON los botones a la vista. Medido, sin el
   ajuste de acá los dos CTA caían fuera de pantalla en todos los tamaños —
   191px de más en un iPhone SE. Son la acción principal de la página: si hay que
   scrollear para descubrir que existen, no existen. Se recorta de donde sobra
   (aire y retrato), no del titular. */
@media(max-width:880px){
  .hero{padding-block:clamp(74px,11vh,112px) clamp(28px,5vh,54px);}
  .hero-in{grid-template-columns:1fr;justify-items:start;gap:clamp(12px,2.2vh,26px);}
  .hero .lede{margin:16px 0 24px;}
  .hero-marca{order:-1;}
  .hero-marca img{height:clamp(112px,19vh,180px);}
}
/* Pantallas bajas: el SE, y cualquier teléfono con las barras del navegador a la
   vista. Acá el retrato cede lo que haga falta. */
@media(max-width:880px) and (max-height:790px){
  .hero{padding-block:50px 20px;}
  .hero-in{gap:10px;}
  .hero-marca img{height:clamp(84px,12.5vh,112px);}
  .hero .lede{margin:10px 0 14px;font-size:1rem;}
  .hero .label{margin-bottom:12px;}
  .hero h1{font-size:min(clamp(2.95rem,10.5vw,8.5rem), 17vh);}
}
/* El SE de 320x568 se pasaba por siete píxeles. Dos trampas al arreglarlo, las
   dos medidas y ninguna evidente:
   1. Recortar el padding de ABAJO no sube el botón — va después de él.
   2. El hero es flex con `align-items:center` y `min-height:92svh`. Cuando el
      contenido es más alto que esa caja, el desborde se reparte arriba Y abajo,
      así que cada píxel que le sacás al contenido devuelve MEDIO píxel al botón.
   Por eso acá se suelta el min-height: sin caja mínima no hay desborde que
   centrar, y el hero mide lo que mide su contenido. */
@media(max-width:880px) and (max-height:620px){
  .hero{padding-block:38px 16px;min-height:auto;}
  .hero-marca img{height:clamp(56px,10vh,88px);}
  .hero .lede{font-size:.95rem;line-height:1.45;margin:8px 0 12px;}
  .hero .label{margin-bottom:9px;}
  .hero h1{font-size:min(clamp(2.7rem,10vw,8.5rem), 17vh);}
}
/* Teléfono ACOSTADO: ancho de sobra, alto casi ninguno. Este tamaño se había
   quedado afuera de la regla que el hero declara arriba, y no por poco: los dos
   CTA terminaban en 509px sobre una pantalla de 390. Medido igual en producción
   antes de tocar nada, así que venía de antes.
   La causa es apilar. De 880px para abajo el retrato se pone ENCIMA del texto, y
   acostado eso gasta en vertical lo único que no sobra. Acá vuelve al costado,
   que es justamente lo que hay de más. */
@media(max-width:880px) and (max-height:520px) and (orientation:landscape){
  .hero{padding-block:16px 12px;min-height:auto;}
  .hero-in{grid-template-columns:1fr auto;align-items:center;gap:clamp(14px,3vw,30px);}
  .hero-marca{order:0;}
  .hero-marca img{height:clamp(110px,44vh,180px);}
  .hero h1{font-size:min(clamp(2.2rem,7vw,8.5rem), 14vh);}
  .hero .lede{margin:6px 0 10px;}
  .hero .label{margin-bottom:6px;}
}
/* Escritorio BAJO — un portátil de 13" a 1366x650 es un tamaño real, y ahí el
   hero ancho no entraba por 106px. Va aparte de las reglas de teléfono: si se
   hiciera una sola regla por altura, en un teléfono bajo agrandaría el retrato
   en vez de achicarlo. */
@media(min-width:881px) and (max-height:780px){
  .hero{padding-block:clamp(50px,8vh,92px) clamp(20px,3.4vh,44px);}
  .hero .lede{margin:14px 0 20px;}
  .hero .label{margin-bottom:14px;}
  /* El selector lleva `.hero--marca` por delante y no es adorno: el bloque de
     escritorio de arriba usa `.hero--marca .hero-marca img`, que es MÁS
     ESPECÍFICO que `.hero-marca img`. La especificidad le gana al orden, así que
     con el selector corto esta regla no se aplicaba: medido a 1366x650, el
     retrato salía de 560px dentro de un hero de 598 y dejaba 19px de aire. */
  .hero--marca .hero-marca img{height:clamp(240px,58vh,460px);}
}
/* Acá había una regla aparte para monitores de 1600px+ que subía el tope del
   retrato a 620px. Quedó absorbida por el bloque de escritorio de más arriba,
   que ya topa en 900 y lo ancla al borde de la ventana. Dejarla habría sido
   peor que borrarla: al ser más específica por ancho ganaba, y en un monitor
   grande —justo donde el vacío era peor— habría ACHICADO el retrato. */

/* La barra de datos (Dónde · Horario · Pedidos) que iba acá se retiró: repetía
   lo que ya muestra la sección de contacto, y en una página de marca personal
   el lugar que sigue al hero le corresponde al alcance de Nene, no al horario
   del galpón. Ningún dato se perdió. */

/* ── Secciones ── */
/* 13vw daba 170px arriba y abajo en escritorio: 350px de aire para secciones
   que tienen 560 de contenido (locales, con UNA tarjeta, medía 913px). A 132
   sigue respirando —esta tipografía necesita aire— y la página baja medio
   scroll de largo. */
section{padding-block:clamp(62px,10vw,132px);}
.dos{display:grid;grid-template-columns:1fr 1fr;gap:clamp(34px,6vw,90px);align-items:center;}
@media(max-width:880px){ .dos{grid-template-columns:1fr;} }

/* Manifiesto */
#sobre .manif{font-family:var(--dsp);font-size:clamp(1.5rem,3.2vw,2.5rem);line-height:1.24;
  letter-spacing:-.012em;margin:0 0 30px;max-width:20ch;}
#sobre .manif em{color:var(--oro);}
.figura{position:relative;overflow:hidden;}
.figura img{width:100%;height:auto;}

/* Par de fotos. Dos chicas en vez de una grande, porque el material del cliente
   mide 206px: agrandarlo no lo mejora, sólo hace más grande lo inventado. A dos
   columnas cada tile queda en ~242 CSS y el archivo tiene 480 — se muestra a su
   tamaño o por debajo, que es lo único que lo deja nítido. El escalón de la
   segunda además llena el alto de la columna sin estirar nada. */
/* El max-width no es estético: abajo de 880px `.dos` se apila y el par pasa a
   ocupar TODO el ancho, así que en una tablet los tiles quedaban a 340 (1,42×
   del archivo) — más grandes que en escritorio. El tope los deja en ~243, el
   mismo tamaño que arriba. */
.par{display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,1.4vw,16px);
  align-items:start;max-width:500px;}
.par figure{margin:0;position:relative;overflow:hidden;background:var(--papel-2);}
.par figure:nth-child(2){margin-top:clamp(26px,4vw,52px);}
.par img{width:100%;height:auto;aspect-ratio:1;object-fit:cover;display:block;}

/* ── Proceso anclado ──
   El alto del riel es lo ÚNICO que decide cuánto dura esta sección, y estaba en
   330vh. Medido sobre producción: 2.972 px de una portada de 9.933, o sea 3,3
   pantallas de las 11 — el 30% de la página para contar cuatro pasos, y con eso
   los productos (lo único que se puede pedir) no aparecían hasta la pantalla 6,2.

   La cuenta que importa no es el alto sino el RECORRIDO: `.proc-fijo` mide
   100svh y se queda pegado, así que lo que se scrollea es `height - 100vh`. A
   330vh eso daba 230vh para 4 pasos = 57,5vh cada uno, más de media pantalla de
   scroll para que cambie un paso. A 220vh quedan 120vh, o sea 30vh por paso: se
   registra cada uno sin tener que insistir.

   Piso duro: el JS (`calcular()` en index.html) apaga el riel si mide menos de
   1,5 ventanas. Acá son 2,2. Por debajo de 150vh la sección deja de funcionar y
   no avisa.
   Y esto es sólo escritorio: los bloques de teléfono más abajo ponen
   `height:auto` + `position:static`, y al ser max-width:880px no los pisa. */
.proc{padding:0;background:var(--papel-2);border-block:1px solid var(--hilo);}
.proc-riel{height:220vh;}
.proc-fijo{position:sticky;top:0;height:100svh;display:flex;align-items:center;}
.proc-in{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,80px);align-items:center;width:100%;}
.proc-lista{list-style:none;margin:26px 0 0;padding:0;}
.proc-paso{display:flex;gap:20px;padding:16px 0;border-top:1px solid var(--hilo-2);
  opacity:.34;transition:opacity .5s var(--e-out);}
.proc-paso:last-child{border-bottom:1px solid var(--hilo-2);}
.proc-n{font-family:var(--dsp);font-size:.9rem;color:var(--oro);padding-top:4px;
  font-variant-numeric:tabular-nums;letter-spacing:.08em;}
.proc-paso h3{margin:0 0 3px;}
.proc-paso p{margin:0;font-size:.93rem;color:var(--tinta-2);}
.proc[data-paso="0"] .proc-paso:nth-child(1),
.proc[data-paso="1"] .proc-paso:nth-child(2),
.proc[data-paso="2"] .proc-paso:nth-child(3),
.proc[data-paso="3"] .proc-paso:nth-child(4){opacity:1;}
.proc-medios{position:relative;aspect-ratio:4/5;overflow:hidden;}
.proc-medios figure{position:absolute;inset:0;margin:0;opacity:0;
  transition:opacity .7s var(--e-out),transform .9s var(--e-out);transform:scale(1.06);}
.proc-medios img{width:100%;height:100%;object-fit:cover;filter:grayscale(1) contrast(1.06);}
/* Duotono: multiply hunde las sombras al marrón, screen levanta las luces al
   oro. Separa "cómo trabajamos" de "qué comprás", que va a todo color. */
.proc-medios figure::before,.proc-medios figure::after{content:"";position:absolute;inset:0;}
.proc-medios figure::before{background:#3B2E22;mix-blend-mode:multiply;}
.proc-medios figure::after{background:var(--oro);mix-blend-mode:screen;opacity:.26;}
.proc[data-paso="0"] .proc-medios figure:nth-child(1),
.proc[data-paso="1"] .proc-medios figure:nth-child(2),
.proc[data-paso="2"] .proc-medios figure:nth-child(3),
.proc[data-paso="3"] .proc-medios figure:nth-child(4){opacity:1;transform:none;}
.proc-marca{position:absolute;right:0;bottom:0;z-index:2;font-family:var(--dsp);
  font-size:clamp(4rem,9vw,8rem);line-height:.8;color:var(--papel-2);
  padding:0 .12em .06em 0;font-variant-numeric:tabular-nums;}
@media(max-width:880px){
  /* Anclar en un celular es incómodo: se desarma en una lista normal. */
  .proc-riel{height:auto;}
  .proc-fijo{position:static;height:auto;padding-block:clamp(70px,12vw,110px);}
  .proc-in{grid-template-columns:1fr;}
  .proc-paso{opacity:1;}
  .proc-medios{aspect-ratio:16/10;order:-1;}
  .proc-medios figure{opacity:0;}
  .proc-medios figure:nth-child(1){opacity:1;transform:none;}
  .proc-marca{display:none;}
}

/* ── Catálogo, en clave de carta ── */
.cat-cab{display:flex;justify-content:space-between;align-items:flex-end;gap:30px;flex-wrap:wrap;
  margin-bottom:clamp(36px,5vw,62px);}
/* Centrada, la Paella quedaba flotando en el medio de una foto de 5:4 con
   vacío arriba y abajo; anclada arriba, el vacío se juntaba todo abajo. La
   columna se estira al alto de la foto y reparte: nombre y acción contra el
   borde superior, descripción contra el inferior. El aire queda ENTRE dos
   cosas ancladas, que es espacio compuesto y no sobrante. */
.destacado{display:grid;grid-template-columns:1.06fr .94fr;gap:clamp(26px,4vw,64px);
  align-items:stretch;margin-bottom:clamp(40px,5vw,70px);}
@media(min-width:881px){
  .destacado > div:last-child{display:flex;flex-direction:column;
    justify-content:space-between;padding-block:clamp(2px,.8vw,12px);}
}
.destacado-cab{margin:0;}
.destacado .lede{margin:18px 0 0;}
@media(max-width:880px){ .destacado{grid-template-columns:1fr;} }
.destacado .figura img{aspect-ratio:5/4;object-fit:cover;}
.destacado h3{font-size:clamp(2rem,4.4vw,3.2rem);margin:0 0 14px;}
.rejilla{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,3vw,42px);}
@media(max-width:880px){ .rejilla{grid-template-columns:1fr;} }
/* Encabezado de rubro. Hoy Nene publica una sola categoría y no aparece; cuando
   cargue más, el catálogo se corta por rubro con la misma versalita de sección
   en vez de meter una barra de pestañas, que rompería el tono de carta. */
.grupo{margin:clamp(46px,6vw,80px) 0 26px;}
.plato .figura{margin-bottom:18px;}
.plato .figura img{aspect-ratio:4/3;object-fit:cover;transition:transform .8s var(--e-out);}
.plato:hover .figura img{transform:scale(1.045);}
.plato h3{margin:0 0 8px;}
.plato p{margin:0;font-size:.92rem;color:var(--tinta-2);}
/* La línea de puntos entre el nombre y el precio: el detalle de carta que le
   faltaba a la página. */
.precio-fila{display:flex;align-items:baseline;gap:10px;margin:10px 0 6px;}
.puntos{flex:1;border-bottom:1.5px dotted var(--hilo);transform:translateY(-4px);}
.precio{font-family:var(--dsp);font-size:1rem;white-space:nowrap;font-variant-numeric:tabular-nums;}
/* Lo que va cuando NO hay precio: una acción, no un hueco con puntitos.
   Cuando Nene cargue los números vuelve sola la línea de arriba. */
.consultar-cta{display:inline-flex;align-items:center;gap:7px;margin:11px 0 8px;
  font-size:.72rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--oro);transition:gap .3s var(--e-out),color .25s ease;}
.consultar-cta::after{content:"→";font-size:.86rem;letter-spacing:0;}
.consultar-cta:hover{gap:11px;color:var(--tinta);}
.marca-agua{display:flex;align-items:center;justify-content:center;background:var(--papel-2);
  font-family:var(--dsp);color:var(--tinta-3);font-size:1.1rem;letter-spacing:.1em;text-transform:uppercase;}
/* El pie del adelanto de la portada. Centrado a propósito: es la única salida
   del bloque y una sola acción centrada se lee como una puerta, no como un
   botón más de la fila. */
.adelanto-pie{display:flex;justify-content:center;margin-top:clamp(36px,5vw,58px);}

/* ── Banda profunda: restaurantes ── */
/* La columna de texto del B2B mide ~700px y la foto ~376: centrada dejaba 160px
   de vacío arriba y otros 160 abajo. Estirada, las dos columnas terminan
   juntas. Va sólo acá: es un flat-lay de 1100px que aguanta el recorte
   vertical, al revés del par de #sobre, que son 480 y estirarlos sería volver
   a ampliar material de 206. */
@media(min-width:881px){
  #restaurantes .dos{align-items:stretch;}
  #restaurantes .figura{height:100%;}
  #restaurantes .figura img{height:100%;object-fit:cover;}
}

.hondo{background:var(--hondo);color:var(--hondo-tinta);}
.hondo .label{color:var(--oro-claro);}
.hondo .label::after{background:rgba(242,239,232,.22);}
.hondo .lede{color:rgba(242,239,232,.76);}
.hondo .mini{color:rgba(242,239,232,.5);}
.hondo .btn-solid{background:var(--papel);color:var(--tinta);}
.hondo .btn-solid:hover{background:var(--oro-claro);}
.lista-b{margin:30px 0 34px;}
.item-b{display:flex;gap:20px;padding:15px 0;border-top:1px solid rgba(242,239,232,.14);align-items:baseline;}
.item-b:last-child{border-bottom:1px solid rgba(242,239,232,.14);}
.item-b .k{font-family:var(--dsp);font-size:1rem;flex:0 0 clamp(112px,15vw,170px);}
.item-b .v{font-size:.92rem;color:rgba(242,239,232,.7);}
@media(max-width:520px){ .item-b{flex-direction:column;gap:4px;} .item-b .k{flex:none;} }

/* ── Contacto y pie ── */
.contacto-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,80px);}
@media(max-width:880px){ .contacto-grid{grid-template-columns:1fr;} }
.fila{padding:17px 0;border-top:1px solid var(--hilo-2);}
.fila:last-child{border-bottom:1px solid var(--hilo-2);}
.fila .k{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--oro);
  font-weight:600;margin-bottom:5px;}
.fila .v{font-family:var(--dsp);font-size:1.1rem;}
/* ── Pie ──
   Cuatro columnas y una fila de base. La primera pesa más porque lleva la
   marca; las otras tres son iguales entre sí. */
footer{border-top:1px solid var(--hilo);padding-block:clamp(44px,6vw,68px) 34px;}
.pie{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:clamp(26px,4vw,54px);
  align-items:start;}
/* Dos columnas y NO una sola apilada: en una sola el pie se iba a 766px en un
   teléfono y pasaba a ser la quinta sección más alta de la página. La marca
   cruza las dos porque su línea de texto necesita el ancho. */
@media(max-width:880px){
  .pie{grid-template-columns:1fr 1fr;gap:30px 24px;}
  .pie-marca{grid-column:1 / -1;}
}
.pie-marca .marca{margin-bottom:14px;}
.pie-marca .mini{margin:0;max-width:32ch;}
.pie-t{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--oro);
  font-weight:600;margin:0 0 12px;}
.pie-d{margin:0;font-size:.9rem;color:var(--tinta-2);line-height:1.7;}
.pie-nav{display:flex;flex-direction:column;gap:7px;}
.pie-nav a{font-size:.9rem;color:var(--tinta-2);transition:color .25s ease;}
.pie-nav a:hover{color:var(--tinta);}
.pie-base{display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;
  margin-top:clamp(34px,5vw,52px);padding-top:26px;border-top:1px solid var(--hilo-2);}
.pie-base .seguir{margin-top:0;}

/* ── Alcance ──
   Va pegado al hero porque es el argumento más fuerte que tiene la marca: son
   ~91 mil personas sumadas. La cifra en Didone, la red en versalitas. */
.alcance{padding:0;border-bottom:1px solid var(--hilo);}
.alcance-grid{display:grid;grid-template-columns:repeat(4,1fr);}
.red{display:flex;flex-direction:column;gap:2px;padding:clamp(28px,3.4vw,42px) clamp(14px,2.4vw,32px);
  border-left:1px solid var(--hilo-2);transition:background-color .3s ease;}
.red:first-child{border-left:0;padding-left:0;}
.red:hover{background:rgba(34,27,21,.045);}
/* Son ~91 mil personas sumadas: el argumento más fuerte que tiene la marca,
   y estaba resuelto en el cuerpo de un subtítulo. */
.red-n{font-family:var(--dsp);font-size:clamp(1.9rem,4.4vw,3rem);line-height:1;
  font-variant-numeric:tabular-nums;}
.red-p{font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;color:var(--oro);
  font-weight:600;margin-top:6px;}
.red-h{font-size:.8rem;color:var(--tinta-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
@media(max-width:720px){
  .alcance-grid{grid-template-columns:1fr 1fr;}
  .red{padding:18px 0 18px clamp(14px,4vw,24px);}
  .red:nth-child(odd){border-left:0;padding-left:0;}
  .red:nth-child(n+3){border-top:1px solid var(--hilo-2);}
}

/* ── Sus locales ──
   Bandas alternadas, no una grilla: con uno o dos locales una grilla de
   tarjetas se ve vacía, y estos son las marcas del tipo — merecen el ancho. */
.local{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(30px,5vw,80px);
  align-items:center;margin-top:clamp(48px,7vw,96px);}
.local:first-of-type{margin-top:clamp(34px,4vw,56px);}
.local:nth-of-type(even) .local-fig{order:2;}
@media(max-width:880px){ .local{grid-template-columns:1fr;} .local:nth-of-type(even) .local-fig{order:0;} }
.local-fig{position:relative;overflow:hidden;margin:0;background:var(--papel-2);}
.local-fig img,.local-fig video{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block;}
.local-rubro{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--oro);
  font-weight:600;margin:0 0 10px;}
.local h3{margin:0 0 14px;font-size:clamp(2rem,4.2vw,3rem);}
.local-datos{margin:22px 0 26px;padding:0;}
.local-fila{display:flex;gap:16px;padding:12px 0;border-top:1px solid var(--hilo-2);align-items:baseline;}
.local-fila:last-child{border-bottom:1px solid var(--hilo-2);}
.local-fila dt{flex:0 0 clamp(76px,10vw,104px);font-size:.68rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--tinta-3);font-weight:600;}
.local-fila dd{margin:0;font-size:.95rem;}
.local-cta{display:flex;gap:12px;flex-wrap:wrap;}

/* ── Muro de contenido: cinta infinita ──
   Miniaturas propias, no embeds: el script de Instagram y el de TikTok son
   externos y en este repo los CDN se bloquean (por eso React está vendoreado).
   Un embed que no carga deja un hueco blanco; esto se ve siempre.

   Va como cinta y no como grilla por dos razones que empujan al mismo lado. La
   de forma: treinta cuadrados iguales y quietos son un contact sheet, no un
   feed — ver treinta cosas a la vez es ver ninguna. La de material: las fotos
   miden 412px de lado, y acá el tile tiene tope de 196 CSS (392 reales en una
   pantalla retina), o sea por debajo del archivo. Mostrar material de teléfono
   a su tamaño o menos es la única forma de que se vea nítido. */
.cinta{
  --tile:clamp(122px,13.5vw,196px);
  --sep:clamp(8px,1vw,14px);
  /* En px y no en %: un 5% son 72px en escritorio y 19 en un teléfono, o sea
     que justo donde la pantalla es angosta el desvanecido desaparece y la foto
     del borde se corta de golpe. */
  --velo:clamp(34px,8vw,120px);
  display:grid;gap:var(--sep);overflow:hidden;
  /* Sin la máscara la cinta termina en un corte recto contra el borde de la
     pantalla y se lee como una tabla recortada, no como algo que sigue. */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--velo),#000 calc(100% - var(--velo)),transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 var(--velo),#000 calc(100% - var(--velo)),transparent 100%);
}
.fila{overflow:hidden;min-width:0;}
.pista{display:flex;gap:var(--sep);width:max-content;
  animation:correr 62s linear infinite;animation-play-state:paused;}
/* Arranca recién cuando la sección se acerca: una cinta corriendo veinte
   pantallas más abajo es GPU quemada de gusto. */
.cinta.corre .pista{animation-play-state:running;}
/* Direcciones y velocidades distintas: dos filas en fase se leen como una
   tabla que se mueve, no como un flujo. */
.fila[data-dir="der"] .pista{animation-duration:74s;animation-direction:reverse;}
.fila:hover .pista,.fila:focus-within .pista{animation-play-state:paused;}
/* El medio gap no es un ajuste a ojo. La pista son 2N tiles con separación
   entre todos, así que mide 2N·T+(2N−1)·G, y el 50% cae medio gap ANTES del
   punto donde el segundo juego calza exactamente sobre el primero. Sin
   restarlo, cada vuelta pega un salto de ~7px: invisible el primer minuto y
   obvio el segundo, que es justo cuando lo mira el cliente. */
@keyframes correr{ to{ transform:translateX(calc(-50% - var(--sep)/2)); } }

.post{position:relative;display:block;overflow:hidden;background:var(--papel-2);
  flex:0 0 var(--tile);width:var(--tile);aspect-ratio:1;}
.post img{width:100%;height:100%;object-fit:cover;
  transition:transform .7s var(--e-out),filter .35s ease;}
.post:hover img{transform:scale(1.05);}
/* No hay velo con texto: no tenemos el pie de cada publicación, y ponerle uno
   inventado sería escribirle nosotros lo que él nunca posteó. La afordancia de
   que es un enlace la da el hover, y adónde va lo dice el enlace del encabezado. */
.post::after{content:"";position:absolute;inset:0;background:rgba(26,20,16,.16);
  opacity:0;transition:opacity .35s ease;}
.post:hover::after,.post:focus-visible::after{opacity:1;}

/* Las treinta fotos van todas a la misma cuenta (el snapshot que nos pasaron no
   trae permalinks), así que treinta paradas de teclado idénticas no le sirven a
   nadie: los tiles salen del tab order y el destino vive acá, a la vista. */
.cinta-cuenta{color:var(--oro);font-weight:500;text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;transition:color .25s ease;}
.cinta-cuenta:hover{color:var(--tinta);}

/* ── Fila de redes del contacto ── */
.seguir{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px;}
.seguir a{display:inline-flex;align-items:center;gap:9px;padding:10px 17px;border-radius:999px;
  border:1px solid var(--hilo);font-size:.86rem;font-weight:500;
  transition:border-color .25s ease,background-color .25s ease;}
.seguir a:hover{border-color:var(--tinta);background:rgba(34,27,21,.03);}
.seguir svg{width:15px;height:15px;flex-shrink:0;}

/* ══════════════════════════════════════════════════════════════════════════
   MOVIMIENTO
   Base en animaciones dirigidas por scroll de CSS: es scroll-linked de verdad,
   corre fuera del hilo principal y no necesita ninguna librería (que en este
   repo tampoco se puede: los CDN quedan bloqueados en Brave).
   Donde no hay soporte —Safari viejo— entra un IntersectionObserver.
   ══════════════════════════════════════════════════════════════════════════ */

@keyframes subir{from{opacity:0;transform:translateY(26px);}to{opacity:1;transform:none;}}
@keyframes destapar{from{clip-path:inset(0 0 100% 0);}to{clip-path:inset(0 0 0 0);}}
@keyframes linea{from{transform:translateY(112%);}to{transform:none;}}

/* El título del hero se revela línea por línea, cada una desde su propia máscara. */
.mask{display:block;overflow:hidden;padding-block:.1em;margin-block:-.08em;}
.mask > i{display:block;font-style:inherit;transform:translateY(112%);
  animation:linea 1.15s var(--e-out) both;}
.mask:nth-of-type(2) > i{animation-delay:.1s;}
.hero .lede,.hero-cta,.hero .label{animation:subir .9s var(--e-out) both;}
.hero .label{animation-delay:.05s;} .hero .lede{animation-delay:.42s;} .hero-cta{animation-delay:.54s;}

@supports (animation-timeline: view()){
  [data-sube]{animation:subir linear both;animation-timeline:view();
    animation-range:entry 4% cover 26%;}
  [data-destapa]{animation:destapar linear both;animation-timeline:view();
    animation-range:entry 6% cover 34%;}
  /* Acá el fondo del hero se alejaba al scrollear (scale 1.13 sobre el video).
     Sin foto no queda nada que alejar: escalar un degradado no se ve, y encima
     ese 1.13 era un 13% MÁS de agrandamiento sobre un material que ya venía
     estirado. Se borra en vez de dejarlo apuntando a un selector que no existe. */
}
/* Sin soporte, lo maneja el observer. El estado inicial sólo se aplica si hay
   JS (html.js), así que si el script falla se ve todo. */
@supports not (animation-timeline: view()){
  html.js [data-sube]{opacity:0;transform:translateY(26px);}
  html.js [data-sube].vista{opacity:1;transform:none;
    transition:opacity .7s var(--e-out),transform .7s var(--e-out);}
  html.js [data-destapa]{clip-path:inset(0 0 100% 0);}
  html.js [data-destapa].vista{clip-path:inset(0 0 0 0);transition:clip-path 1s var(--e-io);}
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{animation:none!important;transition:none!important;}
  html.js [data-sube],html.js [data-destapa]{opacity:1!important;transform:none!important;
    clip-path:none!important;}
  .mask > i{transform:none!important;}
  .proc-riel{height:auto;}
  .proc-fijo{position:static;height:auto;padding-block:90px;}
  .proc-paso{opacity:1;}
  .proc-medios figure{opacity:0;} .proc-medios figure:nth-child(1){opacity:1;transform:none;}
  /* La cinta deja de correr sola (lo apaga el `animation:none` de arriba) y
     pasa a ser un carril que se arrastra. Sin esto quedaría una fila congelada
     mostrando cinco fotos y las otras diez inalcanzables. */
  .fila{overflow-x:auto;scroll-snap-type:x proximity;}
  .cinta .post{scroll-snap-align:start;}
  /* Los bordes difuminados sin nada moviéndose se leen como una foto rota. */
  .cinta{-webkit-mask-image:none;mask-image:none;}
  /* Y sin animación los clones sólo harían pasar dos veces por las mismas. */
  .pista [data-clon]{display:none;}
}


/* ══════════════════════════════════════════════════════════════════════════
   LA CARTA (/carta) + EL PEDIDO

   Vive acá y no en un archivo aparte a propósito: es la misma hoja para las dos
   páginas del sitio. Lo que cambia es cuánto de ella usa cada una.

   La regla que gobierna todo este bloque: MIENTRAS EL CATÁLOGO ESTÉ EN Bs 0 NO
   SE MUESTRA UN SOLO NÚMERO DE PLATA. El pedido junta cantidades y se manda a
   cotizar. El día que Nene cargue los precios, los subtotales y el total
   aparecen solos — el JS decide por `precio > 0`, igual que la línea de puntos
   del catálogo.
   ══════════════════════════════════════════════════════════════════════════ */

/* Encabezado de la carta: es una página, no una sección, así que el título va
   en el cuerpo grande de un h1 pero acotado — "La carta" a 8.5rem taparía la
   primera fila de productos en un portátil. */
.carta-cab{padding-block:clamp(34px,5vw,58px) clamp(30px,4vw,50px);}
.carta-cab h1.dsp{font-size:clamp(2.6rem,7vw,5.2rem);}
.carta-cab .lede{margin:20px 0 0;}
.carta-volver{display:inline-flex;align-items:center;gap:8px;margin-bottom:20px;
  font-size:.72rem;font-weight:600;letter-spacing:.18em;text-transform:uppercase;
  color:var(--tinta-3);transition:color .25s ease,gap .3s var(--e-out);}
.carta-volver::before{content:"←";letter-spacing:0;font-size:.9rem;}
.carta-volver:hover{color:var(--tinta);gap:12px;}

/* El aviso de que faltan precios. Se pinta sólo si de verdad falta alguno: el
   día que estén todos cargados, desaparece sin tocar nada. */
.carta-aviso{display:flex;gap:14px;align-items:flex-start;margin-top:26px;padding:16px 20px;
  background:var(--papel-2);border-left:2px solid var(--oro);}
.carta-aviso p{margin:0;font-size:.92rem;color:var(--tinta-2);max-width:60ch;}
.carta-aviso strong{color:var(--tinta);font-weight:600;}

#carta-lista{padding-bottom:clamp(70px,9vw,120px);}
/* En la carta las tarjetas van a 3 columnas como en la portada, pero acá cada
   una lleva un control: abajo de 620px una sola columna deja el paso a paso
   con área táctil de sobra. */
@media(max-width:880px) and (min-width:621px){
  #carta-lista .rejilla{grid-template-columns:1fr 1fr;}
}
.plato-cuerpo{display:flex;flex-direction:column;gap:8px;}

/* ── El paso a paso ──
   Un botón que dice "Agregar" y no cuánto llevás obliga a abrir el cajón para
   saberlo. Con el paso a paso, la cantidad está donde la decidís. */
.paso{margin-top:14px;}
.paso-add{display:inline-flex;align-items:center;gap:9px;cursor:pointer;
  font-family:var(--txt);font-size:.8rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--tinta);
  padding:11px 20px;border:1px solid var(--hilo);border-radius:999px;background:none;
  transition:border-color .25s ease,background-color .25s ease,scale 150ms var(--e-out);}
.paso-add::after{content:"+";font-size:1rem;letter-spacing:0;line-height:1;color:var(--oro);}
.paso-add:hover{border-color:var(--tinta);background:rgba(34,27,21,.03);}
.paso-add:active{scale:.97;}

/* Botón secundario del cajón: la misma píldora, SIN el "+". Volver al pedido no
   agrega nada, y el signo heredado lo hacía leer como si sí. */
.pedido-sec{display:flex;align-items:center;justify-content:center;gap:9px;width:100%;
  margin-top:12px;cursor:pointer;
  font-family:var(--txt);font-size:.8rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--tinta-2);
  padding:13px 20px;border:1px solid var(--hilo);border-radius:999px;background:none;
  transition:border-color .25s ease,color .25s ease,scale 150ms var(--e-out);}
.pedido-sec:hover{border-color:var(--tinta);color:var(--tinta);}
.pedido-sec:active{scale:.97;}

/* Los productos de la carta llevan un control, y un control tiene que estar
   SIEMPRE a la misma altura en toda la fila. Con la descripción de la paella en
   dos líneas y las otras en una, los botones quedaban escalonados 23px. */
#carta-lista .plato{display:flex;flex-direction:column;}
#carta-lista .plato-cuerpo{flex:1;display:flex;flex-direction:column;}
#carta-lista .paso{margin-top:auto;padding-top:14px;}

.paso-cuenta{display:inline-flex;align-items:center;gap:4px;
  border:1px solid var(--tinta);border-radius:999px;padding:5px 6px;background:var(--papel);}
.paso-btn{width:34px;height:34px;flex:0 0 34px;display:grid;place-items:center;cursor:pointer;
  border:none;border-radius:50%;background:none;color:var(--tinta);
  font-family:var(--txt);font-size:1.15rem;line-height:1;
  transition:background-color .2s ease,scale 150ms var(--e-out);}
.paso-btn:hover{background:rgba(34,27,21,.07);}
.paso-btn:active{scale:.9;}
.paso-n{min-width:5.4ch;text-align:center;font-family:var(--dsp);font-size:1.05rem;
  font-variant-numeric:tabular-nums;}
/* "para 8 personas" / "unidades": el sustantivo cambia por producto, no es
   decoración. La paella se hace para la gente que pidas (regla de Nene). */
.paso-u{font-size:.74rem;letter-spacing:.1em;text-transform:uppercase;color:var(--tinta-3);
  margin-left:6px;}

/* ── Botón flotante del pedido ── */
.pedido-fab{position:fixed;right:clamp(16px,3vw,32px);bottom:clamp(16px,3vw,32px);z-index:56;
  display:inline-flex;align-items:center;gap:12px;cursor:pointer;
  font-family:var(--txt);font-size:.9rem;font-weight:500;letter-spacing:.02em;
  padding:15px 26px;border:none;border-radius:999px;
  background:var(--tinta);color:var(--papel);box-shadow:0 10px 34px rgba(26,20,16,.28);
  opacity:0;transform:translateY(140%);pointer-events:none;
  transition:opacity .24s var(--e-out),transform .24s var(--e-out),background-color .25s ease;}
.pedido-fab.hay{opacity:1;transform:none;pointer-events:auto;}
/* Con el cajón abierto el botón queda DEBAJO del panel (el cajón mide 430px y
   arranca pegado a la derecha, justo encima). Un botón que se ve a medias y no
   se puede tocar es peor que ninguno: se va mientras el cajón está abierto.
   Para cerrar quedan los otros tres caminos: la ×, Escape y tocar fuera. */
.pedido-abierto .pedido-fab{opacity:0;transform:translateY(140%);pointer-events:none;}
.pedido-fab:hover{background:var(--oro);}
.pedido-fab:active{transform:scale(.97);}
.pedido-fab-n{display:grid;place-items:center;min-width:24px;height:24px;padding:0 7px;
  border-radius:999px;background:var(--oro-claro);color:var(--hondo);
  font-family:var(--dsp);font-size:.92rem;font-variant-numeric:tabular-nums;}

/* ── El cajón ──
   Mismas reglas de interacción que el menú del teléfono, que ya está probado:
   se oculta con `visibility` (sale del tab order y del árbol de accesibilidad
   sin andar moviendo aria-hidden, y encima se puede animar), cierra por cuatro
   caminos y bloquea el scroll en <html>, nunca en <body>. */
.pedido-velo{position:fixed;inset:0;z-index:70;background:rgba(26,20,16,.55);
  visibility:hidden;opacity:0;
  transition:opacity .24s var(--e-out),visibility 0s .24s;}
.pedido-cajon{position:fixed;top:0;right:0;bottom:0;z-index:71;width:min(430px,100%);
  display:flex;flex-direction:column;background:var(--papel);
  box-shadow:-18px 0 60px rgba(26,20,16,.2);
  visibility:hidden;transform:translateX(100%);
  transition:transform .3s var(--e-out),visibility 0s .3s;}
.pedido-abierto .pedido-velo{visibility:visible;opacity:1;transition-delay:0s;}
.pedido-abierto .pedido-cajon{visibility:visible;transform:none;transition-delay:0s;}

.pedido-cab{display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:22px 24px 18px;border-bottom:1px solid var(--hilo-2);}
.pedido-cab h2{margin:0;font-family:var(--dsp);font-size:1.5rem;font-weight:400;}
.pedido-x{width:38px;height:38px;flex:0 0 38px;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--hilo);border-radius:50%;background:none;color:var(--tinta);
  transition:border-color .25s ease,scale 150ms var(--e-out);}
.pedido-x:hover{border-color:var(--tinta);}
.pedido-x:active{scale:.92;}
.pedido-x svg{width:15px;height:15px;}

.pedido-cuerpo{flex:1;overflow-y:auto;overscroll-behavior:contain;padding:20px 24px;}
.pedido-vacio{margin:56px 0;text-align:center;color:var(--tinta-3);font-size:.94rem;}

.pedido-linea{display:flex;gap:14px;align-items:flex-start;
  padding:15px 0;border-bottom:1px solid var(--hilo-2);}
.pedido-linea:first-child{padding-top:0;}
.pedido-linea-txt{flex:1;min-width:0;}
.pedido-linea-n{font-family:var(--dsp);font-size:1.06rem;line-height:1.25;margin:0;}
.pedido-linea-d{margin:3px 0 0;font-size:.78rem;letter-spacing:.06em;color:var(--tinta-3);}
.pedido-linea-sub{font-family:var(--dsp);font-size:1rem;white-space:nowrap;
  font-variant-numeric:tabular-nums;margin-left:auto;}
.pedido-linea .paso-cuenta{padding:3px 4px;}
.pedido-linea .paso-btn{width:29px;height:29px;flex-basis:29px;font-size:1rem;}
.pedido-linea .paso-n{min-width:2.4ch;font-size:.98rem;}

.pedido-pie{border-top:1px solid var(--hilo);padding:18px 24px calc(18px + env(safe-area-inset-bottom));}
.pedido-total{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  margin-bottom:14px;}
.pedido-total .k{font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:var(--oro);}
.pedido-total .v{font-family:var(--dsp);font-size:1.5rem;font-variant-numeric:tabular-nums;
  text-align:right;}
/* Cuando falta algún precio el total no es una cifra: decirlo con palabras es
   más honesto que un "Bs 0" que nadie querría creer. */
.pedido-total .v.cotizar{font-size:1.05rem;letter-spacing:.02em;color:var(--tinta-2);}
.pedido-pie .btn{width:100%;justify-content:center;}
.pedido-pie .btn[disabled]{opacity:.42;cursor:not-allowed;}
.pedido-nota{margin:12px 0 0;font-size:.8rem;color:var(--tinta-3);line-height:1.5;}

/* ── Los datos del pedido ── */
.pedido-campo{margin-bottom:14px;}
.pedido-campo label{display:block;margin-bottom:6px;
  font-size:.68rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--oro);}
.pedido-campo input,.pedido-campo textarea{width:100%;box-sizing:border-box;
  font-family:var(--txt);font-size:.95rem;color:var(--tinta);background:var(--papel);
  border:1px solid var(--hilo);border-radius:2px;padding:12px 14px;
  transition:border-color .25s ease;}
.pedido-campo input:focus,.pedido-campo textarea:focus{border-color:var(--tinta);outline:none;}
.pedido-campo textarea{resize:vertical;min-height:74px;}
.pedido-modo{display:flex;gap:9px;margin-bottom:14px;}
.pedido-modo button{flex:1;cursor:pointer;font-family:var(--txt);font-size:.85rem;font-weight:500;
  padding:12px 10px;border:1px solid var(--hilo);border-radius:2px;
  background:none;color:var(--tinta-2);
  transition:border-color .25s ease,background-color .25s ease,color .25s ease;}
.pedido-modo button[aria-pressed="true"]{border-color:var(--tinta);background:var(--tinta);
  color:var(--papel);}
.pedido-error{margin:2px 0 12px;font-size:.85rem;color:#8C2F1D;min-height:1px;}

/* ── El acuse ── */
.pedido-listo{text-align:center;padding:26px 4px;}
.pedido-listo h3{font-family:var(--dsp);font-weight:400;font-size:1.9rem;margin:0 0 10px;}
.pedido-codigo{display:inline-block;margin:14px 0 6px;padding:9px 20px;
  border:1px solid var(--hilo);border-radius:999px;
  font-family:var(--dsp);font-size:1.3rem;letter-spacing:.08em;}
.pedido-listo p{color:var(--tinta-2);font-size:.94rem;margin:0;}

/* ── Pantallas BAJAS (el teléfono acostado, sobre todo) ──
   A 844×390 el encabezado y el pie del cajón se comían todo: quedaban 150px de
   lista y de tres ítems se veían dos. El aire de una pantalla alta es holgura;
   en una baja es contenido que no entra. Se mide por ALTURA, no por ancho: un
   iPad acostado tiene 1024 de ancho y el mismo problema no lo tiene. */
@media (max-height: 520px){
  .pedido-cab{padding:12px 18px 10px;}
  .pedido-cab h2{font-size:1.15rem;}
  .pedido-x{width:32px;height:32px;flex-basis:32px;}
  .pedido-cuerpo{padding:12px 18px;}
  .pedido-linea{padding:9px 0;}
  .pedido-pie{padding:12px 18px calc(12px + env(safe-area-inset-bottom));}
  .pedido-total{margin-bottom:9px;}
  .pedido-total .v{font-size:1.2rem;}
  .pedido-nota{margin-top:8px;}
  .pedido-campo{margin-bottom:10px;}
  .pedido-campo textarea{min-height:56px;}
  .pedido-listo{padding:14px 4px;}
  .pedido-listo h3{font-size:1.5rem;}
}

/* Con reduced-motion el cajón aparece y ya. Nada se oculta: sólo deja de
   deslizarse. */
@media(prefers-reduced-motion: reduce){
  .pedido-fab,.pedido-velo,.pedido-cajon{transition-duration:.01ms;}
  .pedido-fab{transform:none;}
  .pedido-cajon{transform:translateX(100%);}
  .pedido-abierto .pedido-cajon{transform:none;}
}

/* Sin JS la carta no se puede pintar (la trae /api/menu) y el pedido no existe.
   Se dice, con la salida a mano: el contacto de la portada. */
.carta-sinjs{margin:40px 0;padding:24px 26px;background:var(--papel-2);
  border-left:2px solid var(--oro);}
.carta-sinjs p{margin:0 0 14px;color:var(--tinta-2);}
.carta-sinjs p:last-child{margin-bottom:0;}
html.js .carta-sinjs{display:none;}
