/* ═══════════════════════════════════════════════════════════════════════════════
   Ristorante Da Marc · «AQUÍ SE COCINA A LA VISTA» · ronda 7 (la web entera)
   Process/design-direction-ronda-7.md · Process/copy-deck-ronda-7.md

   EL VEREDICTO QUE MANDA (Pere, 2026-08-02): «esto no puede ser una web genérica
   como la que has creado, SOLO ES UN FONDO DE UN COLOR Y TEXTO, la web tiene que
   estar completa, no quiero espacio en blanco (el menos posible), toma de
   referencia otras webs como essens y ozoa».

   La causa raíz estaba medida: CINCO de las siete secciones eran el mismo
   componente `.fila`. Esta hoja las borra. `.fila`, `.fila--2`, `.fila--3`,
   `.fila--foto` y `.franja` NO EXISTEN en este fichero.

   ⭐ RONDA 7b · «MÁS PIEZAS, MÁS PEQUEÑAS, QUE SE TOCAN»
   Process/design-direction-ronda-7b.md — DELTA sobre la r7, que NO se reabre.
   Pere, 2026-08-03: «sigue siendo muy básica… veo las fotos muy grandes…
   necesitan ser fotos más pequeñas, esto cansa la vista… que haya el mínimo de
   espacio vacío» · «el diseño es demasiado básico» · «más interactiva y visual».
   TRES QUEJAS, TRES CAUSAS DISTINTAS, y hay que contestarlas las tres:
     · «fotos grandes» ⇒ la escalera de pieza baja (techo duro 480 px CSS)
     · «básico»        ⇒ NO EXISTÍA LENGUAJE DE PROFUNDIDAD (0 sombras, 1
                         degradado, 1 radio en 1.357 líneas). Ahora: degradado
                         de 4 paradas, grano estático, 3 sombras, un filo, dos
                         radios y DOS solapes
     · «interactiva»   ⇒ casi todo pasaba solo. A10, A11 y A12 los CAUSA la mano
   🔴 UNA COSA QUE NO SE HACE, y se dice porque es la trampa de esta ronda: una
   pieza pequeña rodeada de fondo es EXACTAMENTE la «tarjeta con suelo alrededor»
   que Diego rechaza. La salida son PIEZAS PEQUEÑAS QUE SE TOCAN: costura de
   12 px (era 4 hasta el 2026-08-17), y el vecino de cada foto es otra foto, un
   plano o un filete, nunca el
   fondo. El héroe sigue a sangre por los cuatro lados.

   SIETE SECCIONES, SIETE FORMAS CON NOMBRE:
     1 FONDO   .hero     el fuego a sangre, contenido sobre un PLINTO que cruza
     2 APAREJO .aparejo  5 teselas del MISMO horno, 2 alturas, 1 que cruza filas
     3 ÍNDICE  .fams     10 filas, la altura la manda EL TEXTO, 2 filas sin raíl
     4 PISTA   .pista    4 pasos 9:16 con scroll-snap · LA FIRMA · INTOCABLE
     — regla   .regla    puntuación, no sección
     5 CARTEL  .cartel   tríptico 1.15fr/1fr/1fr, una altura, costura de 12 px
     6 FICHA   .ficha    documento de paneles sobre el plano elevado
     7 CIERRE  .cierre   la puerta como raíl y UN SOLO EJE de datos

   🔴 TODO `:hover` VA DENTRO DE `@media (hover:hover) and (pointer:fine)`, SIN
   EXCEPCIÓN. En un móvil el :hover se dispara al tocar y se queda pegado. Los
   dos que quedaban sueltos (`.nav__a`/`.nav__lang` y `.pie__social`/`.pie__legal`)
   están gateados desde la r7b.

   LAS DOS REGLAS QUE GOBIERNAN TODO, SIN CAMBIO DESDE LA r3:
     1 · un solo suelo grafito del primer píxel al último. `--grafito-2` existe
         SÓLO bajo documentos y controles, nunca como fondo de sección.
     2 · turquesa sobre crema = 1,04:1 ⇒ NO PUEDE HABER PLANOS CREMA.

   ANIMACIÓN — sólo `transform`, `opacity` y `clip-path` (y el clip-path nunca
   sobre una caja que vigile un observador: Ozoa r5 midió ratio 0,000 y doce
   fotos que no llegaron a pedirse). Jamás `transition: all`. Jamás `ease-in` en
   interfaz. Nunca desde `scale(0)`. La salida siempre más rápida que la entrada.
   CERO `will-change` (ESENS lo tenía en 23 elementos: era la presión de memoria
   detrás de «the computer lags»).

   Este fichero vive en la RAÍZ del sitio a propósito: menu-check.py lee
   site.glob("*.css") (no recursivo) y ahí busca `.pick` y las reglas de
   impresión. Lo mismo main.js.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Las dos caras, leídas de su rotulación ────────────────────────────────
   ⚠️ MEDIDO CON fontTools SOBRE ESTOS FICHEROS (2026-07-31) — se hereda:
     · Mulish NO trae `tnum`; la columna de precios NO se fía de la fuente: es
       una columna de ancho declarado (--col-precio) alineada a la derecha.
     · Vollkorn trae cifras ANTIGUAS por defecto y sí trae `lnum` ⇒ body fija
       `lining-nums`. NINGUNA cifra de esta web se compone en la display.
   ⭐ LA ITÁLICA ES NUEVA Y NO ES UN GUSTO: en los DOS sitios donde este negocio
   escribe su propio nombre lo escribe inclinado — la cursiva de «da MaRc» dentro
   del óvalo y la itálica caligráfica «Marc» del rótulo de la calle. Dos
   artefactos suyos independientes, la misma inclinación ⇒ la voz de display de
   esta web es la ITÁLICA de Vollkorn. No toca el cuerpo, ni la carta, ni un
   precio: sólo los seis <h2>.
   ⚠️ `-webkit-font-smoothing: antialiased` está PROHIBIDO por nombre.          */
@font-face{
  font-family:"Vollkorn";
  src:url("assets/fonts/vollkorn-latin-wght-normal.woff2") format("woff2");
  font-weight:400 700; font-style:normal; font-display:swap;
}
/* ⚠️ EL ÚNICO FICHERO NUEVO DE LA RONDA, y hay que COPIARLO a mano (esta sesión
   no tiene shell y un .woff2 es binario):
     cp Clients/Ristorante-Da-Marc/Website-rediseno/assets/fonts/vollkorn-latin-500-italic.woff2 \
        Clients/Ristorante-Da-Marc/Website/assets/fonts/
   La SEGUNDA fuente de este mismo @font-face es el roman variable: si el fichero
   itálico no está, el navegador compone los seis <h2> en Vollkorn recto en vez
   de caer a la itálica de Georgia. Degrada a la marca, nunca a otra letra.
   NO se precarga: la promesa está sobre el pliegue, pero el techo de carga
   inicial es 435 KB y la itálica pesa ~25 KB. `swap` la deja llegar tarde.     */
@font-face{
  font-family:"Vollkorn";
  src:url("assets/fonts/vollkorn-latin-500-italic.woff2") format("woff2"),
      url("assets/fonts/vollkorn-latin-wght-normal.woff2") format("woff2");
  font-weight:400 700; font-style:italic; font-display:swap;
}
@font-face{
  font-family:"Mulish";
  src:url("assets/fonts/mulish-latin-wght-normal.woff2") format("woff2");
  font-weight:400 700; font-style:normal; font-display:swap;
}

/* ── 2 · Tokens ────────────────────────────────────────────────────────────────
   PALETA MEDIDA EN SU PROPIO MATERIAL, con recuento de píxeles:
     --grafito  #1C1C1C  260.917 px de sus propios negros
     --crema    #F7E9DB  33.885 px: el lino de su mantel y su servilleta al sol
     --turquesa #87FCDC  391.328 px = 80,8 % de los saturados de su óvalo
   ⭐ --grafito-2 #26262A ES DERIVADO Y SE DICE: no es una medición.            */
:root{
  --grafito:#1C1C1C;
  --grafito-2:#26262A;
  --crema:#F7E9DB;
  --crema-2:#9C9186;
  --turquesa:#87FCDC;
  --linea:rgba(247,233,219,.16);
  --linea-2:rgba(247,233,219,.30);
  /* ⭐ r9 · EL ORO ES LA ÚNICA EXCEPCIÓN AL ACENTO ÚNICO, y sólo la merece por
     una razón: unas estrellas de puntuación que no son doradas no se leen como
     puntuación. Vive EXCLUSIVAMENTE dentro de `.estrella` — si aparece en
     cualquier otro sitio, la disciplina de un solo acento se ha roto.        */
  --oro:#EFB63C;

  --display:"Vollkorn","Hoefler Text","Iowan Old Style",Palatino,"Palatino Linotype",Georgia,serif;
  --texto:"Mulish","Avenir Next","Segoe UI",system-ui,-apple-system,"Helvetica Neue",sans-serif;

  /* Seis escalas publicadas. El hueco entre 34 y 17 px es deliberado: no existe
     tamaño intermedio, y por eso el nivel 3 no lleva titular.                   */
  --t-display:clamp(34px,9.2vw,68px);
  --t-h2:clamp(24px,5.4vw,34px);
  --t-figure:clamp(44px,12vw,96px);
  --t-tel:clamp(32px,9vw,64px);
  --t-body:17px;
  --t-meta:13px;
  --t-micro:11px;

  /* Rampa de tracking EN FUNCIÓN DEL TAMAÑO. Seis valores. */
  --tr-display:-.018em;
  --tr-h2:-.012em;
  --tr-figure:-.010em;
  --tr-body:.005em;      /* positivo: texto claro sobre grafito florece */
  --tr-meta:.02em;
  --tr-micro:.16em;

  /* ⭐ EL PRESUPUESTO DE VACÍO, REESCRITO A LA BAJA OTRA VEZ (r7 → r7b).
     Pere ha pedido «el mínimo de espacio vacío» DOS RONDAS SEGUIDAS, así que:
       --s6  se queda en 40   (el vacío que ve NO está dentro de las secciones)
             ⚠️ SUPERADO EL 2026-08-17: sube a 48 por la jerarquía. Ver la nota
             de la escalera, justo debajo, con la aritmética nueva.
       --pad-1 72→56/104→80 · --pad-2 56→44/84→64 · --pad-3 44→32/64→48   (−23 %)
     MONOTONÍA COMPROBADA EN LOS DOS EXTREMOS, que es donde falla siempre:
       a 320 px: hueco interno máx 40 · costura de suelo mín. 32+32 = 64  ✓
       a 1440 :  hueco interno máx 40 · costura de suelo mín. 48+48 = 96  ✓
       máximo posible 80+80 = 160, contra el umbral 400 de [deadspace].
     Acumulado desde la r6: la costura entre secciones baja de 176-336 px a
     64-160 px (−52 %).
     ⭐ REGLA NUEVA DE LA r7b, y cambia una norma del estudio: LA COSTURA ENTRE
     DOS SECCIONES ES O SUELO (≥ la suma de sus dos paddings) O CONTACTO
     (--seam). NO EXISTE VALOR INTERMEDIO. La banda muerta de ~150 px
     entre los botones de la portada y la primera foto era exactamente un valor
     intermedio: demasiado para ser una junta, demasiado poco para ser
     jerarquía. Contacto se usa en EXACTAMENTE DOS costuras de toda la web:
     portada → §2, y §5 media → plano de texto.                                */
  /* ⭐ 2026-08-17 · `--s6` SUBE DE 40 A 48, Y ARREGLA EL PELDAÑO ROTO DE ARRIBA.
     Pere pidió «mejor jerarquia visual, espaciado y tal» (2026-08-17). Medido
     sobre la escalera anterior, razón entre peldaños consecutivos:
       6→12 = 2,00 · 12→18 = 1,50 · 18→26 = 1,44 · 26→36 = 1,38 · 36→40 = 1,11
     El último peldaño era un 11 % más grande que el anterior: a ojo son el
     MISMO hueco, así que la escalera tenía cinco niveles y no seis. Con 48 la
     razón queda en 1,33 y la serie decrece limpia (2,00 · 1,50 · 1,44 · 1,38 ·
     1,33). El efecto concreto que se ve: `--vacio-max` (la costura entre la
     cabecera de una sección y su media a sangre) pasa de 40 a 48 contra el
     `--s5` = 36 de dentro de `.sec__in`, o sea de un 11 % de diferencia a un
     33 % — DOS niveles distinguibles donde antes había uno.
     MONOTONÍA RECOMPROBADA EN LOS DOS EXTREMOS, que es donde falla siempre:
       a 320 px: hueco interno máx 48 · costura de suelo mín. 32+32 = 64  ✓
       a 1440 :  hueco interno máx 48 · costura de suelo mín. 48+48 = 96  ✓
       máximo posible 80+80 = 160, contra el umbral 400 de [deadspace].       */
  --s1:6px; --s2:12px; --s3:18px; --s4:26px; --s5:36px; --s6:48px;
  --pad-1:clamp(56px,6vw,80px);     /* §3 LA CARTA — la protagonista */
  --pad-2:clamp(44px,4.8vw,64px);   /* §2 · §4 · §5 — apoyo */
  --pad-3:clamp(32px,3.6vw,48px);   /* §6 · §7 · la regla — servicio */
  /* ⭐ 2026-08-17 · LA COSTURA SUBE DE 4 A 12 px, Y ESTO SUSTITUYE A LA DECISIÓN
     DE LA r7 (`Playbook/Rotation-Log.md`), que la fijó en 4 px.
     Pere, 2026-08-17: «intenta que no se solapen las fotos y por ejemplo en la
     de denia en la seccion de nuestra casa esta la misma foto reptida dos veces
     una al lado de otra».
     MEDIDO ANTES DE TOCARLO, a 1366 / 1440 / 1680 / 1920 y descontando
     `clip-path`, `opacity:0` y `visibility:hidden`: en toda la web NO HAY un
     solo solape accidental entre dos fotografías —los únicos solapes reales son
     el logotipo sobre el fondo del héroe, que son deliberados, y los tres
     pósters apilados de §4, que llevan `clip-path:inset(0 0 0 100%)` porque son
     un secuenciador—. Lo que sí había, y es lo que se está viendo, son teselas
     a 4 px unas de otras en §2, §5, §6 y §8: dos fotografías a 4 px se leen como
     pegadas o como solapadas.
     12 px NO ES UN NÚMERO NUEVO: es `--s2`, el segundo peldaño de la escalera
     publicada, así que la costura entra en la jerarquía en vez de vivir fuera de
     ella. Y sigue siendo CONTACTO y no un valor intermedio: contra los 64–160 px
     de una costura de suelo, 12 px es una junta.
     LO QUE CUESTA EN ANCHO DE PIEZA, comprobado contra el techo duro de 480 px
     CSS y la regla del ×1,35 (a 1440, `.sangra` = 1.352 px):
       aparejo ≥900  (1352−3×12)/4,4  = 299,1 px/tesela   (antes 304,5)  ✅
       cartel  ≥900  (1352−2×12)/3,15 = 421,6 px/media    (antes 426,5)  ✅
       ficha   ≥1000 (1352−12)/2,9    = 462,4 px          (antes 465,5)  ✅
     Todas BAJAN, así que ninguna pierde proporción (van con `object-fit:cover`
     dentro de una caja de altura declarada) y ninguna se acerca más a su ancho
     nativo. El techo de 1.392 px de `.sangra` se recalcula abajo.             */
  --seam:12px;                      /* ⭐ la costura del aparejo, el cartel y la ficha */
  /* ⭐ EL ADJETIVO CONVERTIDO EN NÚMERO. Ninguna banda contigua de suelo
     desnudo —sin texto, sin media, sin filete, sin plano elevado— puede medir
     más de esto DENTRO de una sección. La r7 decía 120 px. Baja al mismo valor
     que el hueco interno máximo: no puede haber más aire suelto del que la
     escalera de espaciado autoriza.                                           */
  --vacio-max:var(--s6);            /* 48 px · el mismo número que el hueco interno máximo */
  /* `--solape` (SOLAPE 1, los 24 px que el plinto cruzaba hacia §2) SE BORRA en
     la r10: sin plinto no hay nada que cruzar. Queda un solo solape en la web. */
  --solape-2:32px;                  /* SOLAPE 2 · el texto del cartel monta su media */

  --edge:clamp(20px,5.2vw,44px);      /* el margen propio de la página */
  /* ⭐ UN SOLO EJE, EL DE LA VENTANA (Pere, r4). De aquí salen los DOS únicos
     bordes verticales de toda la web, y miden lo mismo:
       L = R = max(--edge, (ancho − --marco)/2 + --edge)                        */
  --marco:1120px;
  --gutter:max(var(--edge), calc((100% - var(--marco)) / 2 + var(--edge)));
  --medida-txt:44rem;

  /* ══ LA PROFUNDIDAD · la respuesta a «demasiado básico» ═══════════════════
     El recuento que lo motiva, hecho sobre esta misma hoja: 0 sombras, 1
     degradado y 1 border-radius en 1.357 líneas. Ozoa tiene 11 sombras y 32
     radios; la firma de Esens es literalmente una sombra de contacto bajo cada
     plato. Una página de rectángulos de canto vivo sobre un color plano se lee
     como una maqueta, por muchas fotos que lleve.
     En un suelo oscuro la elevación no la da sólo la sombra: la dan TRES cosas
     a la vez —el plano, el filo de luz del canto, y la sombra—, y las tres se
     declaran aquí.                                                            */
  --plano-0:var(--grafito);                      /* el suelo · lo visten la barra y la barra fija */
  --plano-1:var(--grafito-2);                    /* ⭐ --grafito-2, POR FIN CON TRABAJO */
  --filo:inset 0 1px 0 rgba(247,233,219,.06);    /* el filo de luz del canto superior */
  --sombra-1:0 2px 6px -2px rgba(0,0,0,.55);     /* controles */
  --sombra-2:0 18px 40px -24px rgba(0,0,0,.78);  /* planos elevados */
  --sombra-3:0 40px 90px -20px rgba(0,0,0,.60);  /* el tique de la comanda, flotando centrado */
  /* ⭐ DOS RADIOS, NI UNO MÁS. `--radius: 0` se borra.
     Por qué 3 px y no más: Ozoa r4 ya costó una queja de Diego («no me gusta
     que las fotos estén en un arco, demasiado espacio en blanco»). Un radio de
     3 px se come 1,9 px² por esquina: el 0,3 % de lo que se comía aquel arco.
     Es la diferencia entre «un rectángulo» y «una pieza», y no toca la foto.  */
  --r-pieza:3px;                       /* fotografías y vídeos */
  --r-control:8px;                     /* botones, chips, planos elevados, la hoja */

  /* Las tres curvas exactas (emil-design-eng). Nunca aproximadas. */
  --ease-out:cubic-bezier(.23,1,.32,1);
  --ease-in-out:cubic-bezier(.77,0,.175,1);
  --ease-drawer:cubic-bezier(.32,.72,0,1);

  --barra:52px;
  --ovalo:clamp(168px,52vw,200px);     /* ⭐ 160 → 200: «it needs to be big» */

  /* ══ RONDA 10 · EL UMBRAL SE BORRA ═══════════════════════════════════════
     La r8 metió delante del fuego una fila de tres —pieza A · plinto · pieza B—
     y el interruptor `--tira-h` para revertirla. Pere la retiró el 2026-08-03
     («quita los dos vídeos que hay a los lados»), así que el interruptor deja de
     tener sentido: lo que gobernaba ya no existe. Se borran `--tira-h`,
     `--pza-w`, `--pza`, `--pza-seam` y `--umbral-h`.
     Vuelve intacta la orden de Pere de la r4: el bucle de FONDO, a sangre por
     los cuatro lados, y su póster como LCP — pero ahora además SE VE, que era el
     punto entero del encargo.
     La columna de texto de escritorio es lo único que queda dimensionado aquí:
     30rem de medida sobre el tercio izquierdo, que es el tercio OSCURO del
     encuadre. Ver la aritmética junto a `.hero__velo`.                        */
  --hero-col:30rem;                         /* 480 px · la medida de la portada ≥900 */
  /* La promesa baja de 68 a 46 px SÓLO en escritorio: a 1440 competía con el
     óvalo y con el fuego. A 390 da 34 px, exactamente lo de hoy, así que la
     aritmética del pliegue en móvil NO se toca ni un píxel.                   */
  --t-promesa:clamp(34px,4.2vw,46px);

  /* ══ RONDA 8 · EL CAPÍTULO CREMA ═════════════════════════════════════════
     Tinta derivada para los metadatos sobre crema: `--crema-2` sobre `--crema`
     da 2,43:1 y no pasa. #6B6058 da 5,74:1. Se declara DERIVADO, no medido.   */
  --tinta-2:#6B6058;

  /* ALTURAS DE FILA DECLARADAS, una por partición. Ninguna mitad fluye por su
     cuenta ⇒ `deadspace`/`lopsided` imposibles por construcción. Cada número
     sale de la aritmética de nitidez de su propio metraje (dirección §4.2):
     un clip de 720 px no puede ir a sangre en un escritorio de 1440, y por eso
     el muro y el cartel SE PARTEN cuando la ventana crece.                     */
  /* ⭐ LA ESCALERA DE TAMAÑO DE PIEZA, REVISADA A LA BAJA (r7b).
       FONDO  100vw          sólo la portada
       PIEZA  168 – 480 px   ⭐ TECHO DURO: ninguna fotografía fija ni vídeo se
                             pinta por encima de 480 px CSS EN NINGUNA PARTE,
                             ni a 1440 ni a 2560                (r7: 193 – 759)
       PLACA   84 – 120 px   la miniatura del índice            (r7: 152 – 320)
       RAÍL   120 – 240 px   la puerta del cierre               (r7: 120 – 340)
     El diagnóstico en una línea: la pieza más pequeña de esta web (320 px) era
     más grande que la pieza MEDIA de Esens (284) y más del doble que la de Ozoa
     (141). Eso es «las fotos muy grandes». Y bajar el tamaño arregla de paso la
     nitidez: `horno-lena-encendido` es una foto de móvil que a 1.352 px se veía
     pastosa y a 448 corre a 0,22×.                                            */
  --apar-r1:clamp(120px,38vw,168px);   /* aparejo móvil · filas 1 y 3          */
  --apar-r2:clamp(170px,54vw,224px);   /* aparejo móvil · fila 2 (la que cruza)*/
  --apar-r:clamp(190px,18.6vw,268px);  /* aparejo ≥900 · 268 px a 1440         */
  --pista-t:54vw;                      /* 210 px a 390 ⇒ se ven 1,86 teselas   */
  /* ⚠️ La dirección publica clamp(300, 34vw, 480) ⇒ 480 px a 1440. Se construye
     a 374 y se dice por qué: los 480 salían de un par de medias que podían
     llenar 480 las dos, y `ig-pared-cuadros-italia` no puede —es una banda de
     720 × 382 cuyo recorte no puede crecer sin meter personas—. A 374 px la
     tercera columna queda EXACTAMENTE llena, y con la costura a 12 px
     (2026-08-17) la aritmética se recalcula: media 223,7 + costura 12 +
     panel 138,7 = 374,4. Sigue sin sobrar un plano elevado vacío. El cartel baja
     106 px más de lo presupuestado, no menos.                                 */
  --cartel-h:clamp(300px,26vw,380px);
  /* ⚠️ EL RAÍL DE LA PUERTA · el fichero mide 400 px de ancho en disco y ése es
     su techo. A 320 px de ventana la columna de datos que queda al lado no puede
     bajar de ~130 px, así que el raíl es fluido y no un número fijo.            */
  --puerta:clamp(120px,30vw,240px);
  --mapa:280px;

  /* ⭐ LA PLACA DE LA CARTA: LA FOTO DEJA DE MANDAR LA ALTURA DE LA FILA.
     El defecto medido sobre la captura de la r7: placa de 320 × ~310 ⇒ fila de
     ~345 px; el titular y la línea de platos ocupaban los primeros ~100 y el
     recuento quedaba clavado abajo ⇒ ~200 px de grafito liso a lo ancho de 700,
     DIEZ VECES SEGUIDAS. Estirar tres elementos sobre 345 px no llena 345 px:
     los separa. La inversión de la r7b: la placa se estira a la altura de la
     fila, y LA ALTURA LA ESCRIBE EL TEXTO.
       L ≥10 platos  3 líneas de avance   24+22+6+56,6+6+15 = 129,6 → 132
       M 5–9         2 líneas             24+22+6+37,7+6+15 = 110,7 → 112
       S ≤4 con foto 1 línea              24+22+6+18,9+6+15 =  91,9 →  92
     `--placa-L-h`, `--placa-M-h` y `--placa-S-h` SE BORRAN: sobran.
     ⚠️ 2026-08-24 · HABÍA UN CUARTO PELDAÑO, `--fila-O:72px` («Ø sin foto,
     1 línea, SIN RAÍL» = 24+22+6+18,9 = 70,9 → 72). Se retira con la variante:
     ya no queda familia sin fotografía. El registro está más abajo, donde
     vivían sus reglas.
     Índice de diez familias: 3×132 + 3×112 + 4×92 = 1.100 px (r7: 2.640).
     ⚠️ La suma que había escrita aquí —«2×92 + 2×72 = 1.060»— era la del
     2026-08-03 y llevaba desde el 22-08 sin recalcularse: aquel día Pescados
     pasó de Ø a S y el índice ya medía 1.080, no 1.060. */
  --placa-w:clamp(84px,26vw,120px);
  --fila-L:132px;
  --fila-M:112px;
  --fila-S:92px;

  /* La columna de precios, MEDIDA: «23,90 €» suma 65,2 px con los avances más
     desfavorables de Mulish 600 a 17 px. 4,8rem = 76,8 px deja 11 px.          */
  --col-precio:4.8rem;
  --col-canal:0px;
  --col-pick:0px;

  /* ⭐ r9 · EL RECORRIDO DEL REVEAL SE MULTIPLICA POR 2,4. Veredicto de Diego
     (2026-08-03), en mayúsculas: «Y TODAVÍA NO HE VISTO NI UNA PUTA ANIMACIÓN,
     DESPUÉS DE HABERLO DICHO 10 VECES». Fui a medirlo y era literal: las piezas
     subían 14 px repartidos a lo largo de media pantalla de scroll. Eso no es
     una animación discreta, es una animación invisible — que a efectos de quien
     mira la web es lo mismo que no tenerla.
     Ahora recorren 34 px y además entran desde 0,975 de escala, y el recorrido
     de scroll en el que lo hacen se ha acortado a la mitad (`entry 3% → cover
     12%`), que es lo que hace que se lea como un movimiento y no como una
     deriva. El tope de `emil-design-eng` se respeta: nada bloquea nunca la
     interacción y el retardo total sigue por debajo de 120 ms.               */
  --rev-y:34px; --rev-d:520ms;
}

/* ⭐ La placa ya NO cambia de tamaño por breakpoint: `clamp(84px, 26vw, 120px)`
   la resuelve entera —84 px a 320, 101 a 390, 120 desde 462— y las cuatro
   alturas de fila las escribe el TEXTO, no la ventana. Por eso el bloque que en
   la r7 redeclaraba seis variables de placa en tres breakpoints desaparece, y
   con él `--puerta:220/340`, que era lo que ponía la puerta en 340 px.         */
@media (min-width:900px){
  :root{
    --barra:64px;
    --ovalo:320px;
    --mapa:360px;
  }
}

/* ── 3 · Base ──────────────────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box }
/* ⚠️ EL DEGRADADO VA EN `html`, NO EN `body`, Y NO ES UN CAPRICHO DE ESTILO.
   `body::before` lleva `z-index:-3`, y una capa de z negativo se pinta en el
   paso 3 del orden de pintado: ANTES de los fondos de bloque de los
   descendientes (paso 4). Con el degradado en `body`, el grano quedaba DEBAJO
   del degradado y no se veía absolutamente nada. En `html` el fondo se propaga
   al lienzo, que se pinta el primero de todos, y el grano cae encima de él y
   debajo de todo el contenido — que es exactamente donde lo pone la dirección.
   `background-size: 100% 100%` resuelve contra la caja del elemento raíz, o
   sea contra la ALTURA DEL DOCUMENTO: las cuatro paradas se reparten por la
   página entera, no por una ventana.                                          */
html{
  background:linear-gradient(180deg,
    #1C1C1C   0%,      /* la portada y §2 */
    #212024  34%,      /* el índice */
    #1A1A1C  68%,      /* la pista y el cartel */
    #252429 100%);     /* la ficha y el cierre */
  background-size:100% 100%;
  background-repeat:no-repeat;
  -webkit-text-size-adjust:100%;
}
@media (prefers-reduced-motion: no-preference){ html{ scroll-behavior:smooth } }

/* ══ LA MATERIA DEL SUELO · dos capas, LAS DOS ESTÁTICAS ═════════════════════
   Hasta la r7 esto era #1C1C1C liso desde el píxel 0 hasta el 10.114.

   1 · EL DEGRADADO LARGUÍSIMO. Cuatro paradas sobre `body`, sin `fixed` (un
       `background-attachment: fixed` sobre 7.000 px repinta en cada scroll, y
       eso es exactamente el veredicto «el ordenador se ralentiza»). Δ máximo
       entre dos paradas contiguas = 7/255 repartido en ~2.300 px de página, es
       decir UN NIVEL CADA 330 px: no se puede señalar dónde cambia; sólo se
       nota que el suelo ya no mide lo mismo en todas las capturas.
   2 · EL GRANO (efecto 5.5 del catálogo). Tesela de 96 × 96 con
       `feTurbulence baseFrequency .9 numOctaves 3`, monocroma, repetida.
       🔴 ES ESTÁTICO: no respira, no se mueve, cero @keyframes. Una tesela de
       96 px en `fixed` es UNA CAPA COMPUESTA, no un re-raster de viewport — no
       es la malla desenfocada que causó el lag de Diego, y se dice
       explícitamente para que nadie lo confunda. Bonus real: difumina el
       bandeado del degradado de arriba, así que las dos capas se necesitan.
   El fichero lo entregó `media-agent` esta misma ronda: 96 × 96, 1,44 KB,
   monocromo, sin costura visible al repetir.                                   */
body{
  margin:0;
  background:transparent;             /* el degradado vive en `html` — ver arriba */
  color:var(--crema);
  font-family:var(--texto);
  font-size:var(--t-body);
  font-weight:400;
  line-height:1.62;
  letter-spacing:var(--tr-body);
  font-variant-numeric:lining-nums;
  overflow-x:hidden;                  /* red de seguridad, no sustituto de medir */
}
body::before{
  content:""; position:fixed; inset:0; z-index:-3; pointer-events:none;
  background:url("assets/img/grano-96.webp") repeat;
  background-size:96px 96px;
  opacity:.035;
}
@media (max-width:360px){ body{ font-size:16px } }

img{ display:block; max-width:100%; height:auto }
a{ color:inherit }
button{ font:inherit; color:inherit; background:none; border:0; margin:0 }
h1,h2,h3,p,ul,ol,figure,blockquote{ margin:0 }
ul{ padding:0; list-style:none }
[hidden]{ display:none !important }   /* [hidden] es regla de UA: cualquier display de autor la gana */

:focus-visible{ outline:2px solid var(--turquesa); outline-offset:3px }
.aparejo :focus-visible,.paso :focus-visible,.cartel :focus-visible{ outline-color:var(--crema) }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--crema); color:var(--grafito);
  padding:.75rem 1rem; font-size:var(--t-meta); font-weight:600;
}
.skip:focus{ left:0 }

/* ── 4 · Tipografía de la página ───────────────────────────────────────────── */
.h2{
  font-family:var(--display); font-weight:500; font-style:italic;
  font-size:var(--t-h2); line-height:1.14; letter-spacing:var(--tr-h2);
  color:var(--crema); text-wrap:balance;
}
/* ⭐ El ÚNICO <h2> display de la web es el de la carta: es la protagonista. */
.h2--display{
  font-size:var(--t-display); line-height:1.06; letter-spacing:var(--tr-display);
  max-width:16ch;
}
.deck{ color:var(--crema-2); max-width:40rem }
.fuente{
  display:block;
  font-size:var(--t-micro); line-height:1.35; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2); max-width:44rem;
}
.nota{ font-size:var(--t-meta); line-height:1.45; letter-spacing:var(--tr-meta); color:var(--crema-2) }

/* EL MOTIVO · «LA BANDA» — 3 × 14 px maciza, en su turquesa. Sale de las tres
   bandas verticales de la bandera dibujada dentro de su óvalo. Plana, sin radio,
   sin sombra, nunca girada. Se dibuja SÓLO donde la página dice «esto está
   encendido»: la etiqueta de sección, la familia abierta, el día elegido, el
   paso que suena, el hecho verificado.                                          */
.banda{
  display:block; flex:0 0 3px; width:3px; height:14px;
  background:var(--turquesa);
}

/* SUS PROPIAS PALABRAS · sus citas de Instagram, byte a byte.
   ⚠️ `white-space: pre-line`: si su frase se rompe se respetan LAS SUYAS; jamás
   se inyecta un <br> dentro de su texto. Las mayúsculas son suyas.             */
.cita{
  display:grid; gap:var(--s2);
  border-left:1px solid var(--linea); padding-left:var(--s3);
  max-width:38rem; min-width:0;
}
.cita__t{ font-size:var(--t-body); line-height:1.5; color:var(--crema); white-space:pre-line }
.cita__f{
  font-size:var(--t-micro); letter-spacing:var(--tr-micro); text-transform:uppercase;
  color:var(--crema-2);
}
/* La cita que ES el titular de §4: su frase, entera y con su fuente, compuesta
   al tamaño de un <h2>. Sin el filete de la izquierda —dentro de una cabecera
   centrada, un borde a un solo lado es justo la asimetría que el cliente lleva
   seis rondas pidiendo que no exista— y con la atribución debajo.              */
/* ⭐ r8d · LA CABECERA DE §4, y digo lo que este cambio hace y lo que NO hace.
   Era una cita centrada de 544 px en una caja de 1.032: ~244 px de suelo
   desnudo a cada lado, que es la definición de un objeto flotando. Ahora la
   frase corre 42rem y la pista sube a tocarla a 12 px en vez de a 40.
   🔴 ESTO NO AÑADE UN SOLO PÍXEL DE IMAGEN, y no voy a fingir que sí: aquí no
   cabe una pieza sin inventarse una forma nueva y sin un fichero más, y el peso
   está por encima del techo. Lo que arregla es la composición —el titular deja
   de ser una isla y el metraje que lo demuestra empieza justo debajo—, no el
   número de `[lleno]`.                                                        */
.cita--titular{
  border-left:0; padding-left:0; text-align:center; justify-items:center;
  max-width:42rem; margin-inline:auto;
}
#desde-0 .sec__in + .sangra{ margin-top:var(--seam) }
.cita--titular .cita__t{ font-size:var(--t-h2); line-height:1.2; letter-spacing:var(--tr-h2) }

/* ── 5 · La retícula y LOS TRES NIVELES ────────────────────────────────────── */
.sec{ scroll-margin-top:calc(var(--barra) + 8px) }
/* ⚠️ La carta abre con `--pad-1` y CIERRA con `--pad-2`. El pie de §3 y la
   cabecera de §4 sumaban 80 + 64 = 144 px de suelo desnudo, y aunque está dentro
   del rango publicado (96–160) se veía como una banda muerta en el render a
   1440. Con 64 + 64 = 128 la costura sigue siendo de SUELO —es exactamente la
   suma de los dos paddings que la delimitan— y sigue siendo monótona contra el
   hueco interno máximo de 40.                                                  */
.sec--n1{ padding-block:var(--pad-1) var(--pad-2); --rev-y:42px; --rev-d:600ms }
.sec--n2{ padding-block:var(--pad-2); --rev-y:34px; --rev-d:520ms }
.sec--n3{ padding-block:var(--pad-3); --rev-y:26px; --rev-d:460ms }
/* ⭐ COSTURA DE CONTACTO Nº 1 DE 2 · el fondo de fuego TOCA la primera fila del
   aparejo de piedra. Entre los botones de la portada y la primera foto había
   ~150 px de grafito sin nada: un valor intermedio, demasiado para ser una junta
   y demasiado poco para ser jerarquía. Aquí no queda hueco — y encima el plinto
   cruza 24 px hacia dentro de esta sección.
   (La costura de contacto nº 2 es §5 media → plano de texto, `--seam` en la
   rejilla del cartel. No hay ninguna más en toda la web.)                      */
#el-horno{ padding-top:var(--seam) }
/* Costura de contacto nº 3 y nº 4, las dos declaradas: el capítulo claro cierra
   y el oscuro abre CONTRA la cinta del desfile — contacto 4 + cinta 44 +
   contacto 4. Ahí es donde el render medía la banda negra muerta, y ya no cabe
   un valor intermedio ni por accidente.                                       */
.sec--carta{ padding-bottom:var(--seam) }
#desde-0{ padding-top:var(--seam) }

.sec__in{
  display:grid; grid-template-columns:minmax(0,1fr); gap:var(--s5);
  width:100%; max-width:var(--marco);
  margin-inline:auto; padding-inline:var(--edge);
}

/* ⭐ EL OBJETO A SANGRE. Una sola regla, y gobierna los DOS bordes a la vez:
   nunca uno solo. Por encima de 1408 px consume `--edge` como todo lo demás —
   que es lo que mantiene Δ = 0,0 px en symmetry-check.                          */
.sangra{ width:100%; min-width:0 }
/* ⭐ EL TECHO DE 1.392 px, Y SALE DE LA ARITMÉTICA DEL TECHO DE PIEZA (480 px).
   Sin él, a 2560 px de ventana el aparejo pintaría teselas de 821 px y la
   fachada 852: el techo duro de la r7b («ninguna pieza por encima de 480 px CSS
   ni a 1440 ni a 2560») se rompería justo donde nadie mira.
   ⭐ RECALCULADO EL 2026-08-17 con la costura a 12 px (antes 4). Todos BAJAN, así
   que el techo duro de 480 px sigue en pie con más margen que antes:
     aparejo (1,4fr+3×1fr, 3 costuras) (1392−36)/4,4 = 308 ✅  (antes 315)
     cartel  (1,15+1+1, 2 costuras)    (1392−24)/3,15 = 434 ✅  (antes 439)
     ficha   (1fr/1,9fr, 1 costura)     (1392−12)/2,9 = 476 ✅  (antes 479)
   A 1440 el ancho sigue siendo 100% − 2×--edge = 1.352, exactamente como en la
   r7 ⇒ `symmetry-check` no se mueve. El techo sólo muerde por encima de 1.568.  */
@media (min-width:1408px){
  .sangra,.carta{ width:min(calc(100% - 2 * var(--edge)),1392px); margin-inline:auto }
}
/* Las costuras INTERNAS de una sección miden `--vacio-max` (48 px desde el
   2026-08-17, antes 40 — ver la nota de la escalera arriba; es el hueco
   interno máximo publicado); la costura ENTRE dos secciones es la suma de sus
   dos paddings (64 px para arriba) o CONTACTO de 12 px. Ninguna interna puede
   alcanzar a la externa de suelo: ésa es la monotonía.                         */
.sec__in + .sangra,.sangra + .sec__in{ margin-top:var(--vacio-max) }

.sec__cab{
  display:grid; gap:var(--s2); justify-items:center; text-align:center;
  max-width:var(--medida-txt); margin-inline:auto; min-width:0;
}
.sec__cab .deck,.sec__cab .nota{ margin-inline:auto }
.sec__et{
  display:inline-flex; align-items:center; gap:var(--s2);
  font-size:var(--t-micro); font-weight:600; line-height:1.35;
  letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema-2);
}
.sec__et--h2{ font-family:var(--texto); font-style:normal }
.sec__cuerpo{ min-width:0; display:grid; gap:var(--s3) }

/* ── 6 · Botones ───────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  min-height:48px; padding:.7rem 1.1rem;
  border-radius:var(--r-control);
  box-shadow:var(--sombra-1);
  font-size:var(--t-meta); font-weight:600; line-height:1.2;
  letter-spacing:var(--tr-meta); text-align:center; text-decoration:none;
  cursor:pointer;
  transition:transform 200ms var(--ease-out), background-color 200ms var(--ease-out),
             color 200ms var(--ease-out), border-color 200ms var(--ease-out);
}
/* A2 · en un móvil no existe `:hover` y éste es el único feedback que hay.
   0 ms a la ida, 140 a la vuelta: la salida más rápida que la entrada.          */
.btn:active{ transform:scale(.97); transition-duration:140ms }
.btn--pri{
  position:relative; isolation:isolate;
  min-height:54px;
  background:var(--turquesa); color:var(--grafito);
  font-size:var(--t-body); font-weight:700; overflow:hidden;
}
.acc .btn--pri,.remate .btn--pri,.cierre__acc .btn,.accfija .btn{ width:100% }
/* A4 · el relleno se descubre de izquierda a derecha AL CARGAR. Estado base =
   descubierto: si el navegador no anima, el botón ya está lleno. El clip-path
   va sobre un ::before decorativo, NUNCA sobre una caja observada.              */
.btn--pri::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:var(--grafito); transform:scaleX(0); transform-origin:right;
}
.btn--sec{
  border:1px solid var(--linea-2); color:var(--crema); background:transparent;
}
/* Elevación sólo donde hay puntero fino. Sobre grafito una sombra no se ve, así
   que la elevación se hace con 3 px de subida y un filete más claro.            */
@media (hover:hover) and (pointer:fine){
  .btn--pri:hover{ transform:translateY(-3px) }
  .btn--sec:hover{ border-color:var(--crema); background:rgba(247,233,219,.06) }
}

/* ── 7 · La barra fija de arriba · CROMO ───────────────────────────────────── */
.bar{
  position:fixed; inset:0 0 auto 0; z-index:90;
  height:var(--barra);
  padding-inline:var(--edge);
  display:flex; align-items:center; justify-content:space-between; gap:var(--s3);
}
/* ESTADO BASE: SÓLIDA. Sin scroll-driven y sin JavaScript la barra se ve
   siempre, que es lo legible.                                                   */
.bar::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:var(--plano-0); opacity:1;
}
.bar__marca{ display:inline-flex; align-items:center; text-decoration:none; flex:0 0 auto }
.bar__logo{ width:auto; height:40px }
@media (min-width:900px){ .bar__logo{ height:48px } }
@supports (animation-timeline: scroll()){
  .bar::before{ animation:barSolida linear both; animation-timeline:scroll(root); animation-range:0 64px }
  @keyframes barSolida{ from{opacity:0} to{opacity:1} }
}
.js-bar .bar::before{ opacity:0; transition:opacity 300ms var(--ease-out) }
.js-bar .bar.is-solid::before{ opacity:1 }

/* ── 8 · La navegación · A7 ────────────────────────────────────────────────────
   UN solo <nav> con dos presentaciones: fila a ≥1024 px, panel a pantalla
   completa por debajo. Casilla + :checked, cero JavaScript para abrir y cerrar.
   280 ms, no los 650 del catálogo: un menú es interfaz y el techo es 300.
   ⚠️ El clip-path vive aquí porque el panel NO es una caja observada y no
   contiene ni una imagen diferida: nada se puede quedar sin descargar.

   🔴 EL PUNTO DE CORTE SIGUE EN 1024, Y LA HISTORIA DE POR QUÉ IMPORTA.
   El 2026-08-23 Pere mandó una captura de la barra INGLESA partida en dos filas,
   con «ITALIANO» colgando solo en la segunda. La primera respuesta fue subir el
   corte a 1.280 px, con la anchura mínima medida idioma a idioma (español 1.100,
   inglés 1.140, italiano 1.186) — y ESA RESPUESTA ERA UN PARCHE, porque tapaba
   la causa en vez de quitarla.
   La causa estaba prohibida por escrito desde el 2026-08-05, Diego: «the menu
   has too many sections. keep only the important ones» — LA BARRA ES PARA
   DECIDIR, NO PARA LISTAR. Nueve elementos en una fila es el patrón que esa
   regla rechaza; el problema no era de ANCHURA, era de RECUENTO.
   Así que la fila enseña cinco (ver `.nav__i--sec` más abajo), el panel de móvil
   sigue enseñando las nueve, el índice del pie también, y el corte vuelve a
   1.024 — donde estaba, y donde un portátil de 13" y un iPad en horizontal
   siguen viendo su fila.
   ⚠️ ESTE NÚMERO VIVE EN CUATRO SITIOS y los cuatro tienen que decir lo mismo:
   este bloque, el `@media` del `:hover` de aquí abajo, el del anclaje de
   `.idiomas__l`, y el `matchMedia` de `initNav()` en main.js. Más el
   `max-width:1023.98px` del arreglo del aviso de cookies, que es su negativo.  */
.nav{ display:flex; align-items:center; gap:var(--s3) }
.nav__sw{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none }
.nav__btn{
  display:inline-flex; align-items:center; gap:.5rem;
  min-height:44px; padding:.5rem .8rem;
  border:1px solid var(--linea-2);
  border-radius:var(--r-control);
  box-shadow:var(--sombra-1);
  background:var(--grafito);
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema); cursor:pointer;
  transition:border-color 200ms var(--ease-out), transform 140ms var(--ease-out);
}
.nav__btn:active{ transform:scale(.97) }
.nav__sw:focus-visible + .nav__btn{ outline:2px solid var(--turquesa); outline-offset:3px }
.nav__cerrar{ display:none }
.nav__panel{
  position:fixed; inset:var(--barra) 0 0 0; z-index:95;
  background:var(--plano-1);
  box-shadow:var(--filo),var(--sombra-2);
  border-top:1px solid var(--linea);
  padding:var(--s4) var(--edge) calc(var(--s5) + env(safe-area-inset-bottom));
  overflow:auto;
  clip-path:inset(0 0 100% 0);
  visibility:hidden;
  transition:clip-path 280ms var(--ease-drawer), visibility 0s linear 280ms;
}
.nav__sw:checked ~ .nav__panel{
  clip-path:inset(0 0 0 0); visibility:visible;
  transition:clip-path 280ms var(--ease-drawer), visibility 0s;
}
.nav__sw:checked ~ .nav__cerrar{
  display:block; position:fixed; inset:0; z-index:94; background:rgba(28,28,28,.6);
}
.nav__list{ display:grid; gap:0; max-width:var(--marco); margin-inline:auto; width:100% }
.nav__a,.nav__lang{
  display:flex; align-items:center; min-height:52px;
  border-bottom:1px solid var(--linea);
  font-size:var(--t-body); font-weight:600; letter-spacing:var(--tr-meta);
  color:var(--crema); text-decoration:none; width:100%; text-align:left;
  cursor:pointer;
}
.nav__lang{ color:var(--crema-2); border-bottom:0 }
.nav__a:active,.nav__lang:active{ transform:scale(.97) }
@media (min-width:1024px){
  .nav__btn,.nav__sw:checked ~ .nav__cerrar{ display:none }
  .nav__panel{
    position:static; inset:auto; background:transparent; border:0;
    padding:0; overflow:visible;
    clip-path:none; visibility:visible; transition:none;
  }
  .nav__list{
    display:flex; align-items:center; gap:var(--s2) var(--s3); flex-wrap:wrap;
    justify-content:flex-end; background:var(--grafito); padding:.3rem var(--s2);
    width:auto; border-radius:var(--r-control);
  }
  .nav__a,.nav__lang{
    min-height:0; border:0; width:auto;
    font-size:var(--t-micro); letter-spacing:var(--tr-micro); text-transform:uppercase;
    color:var(--crema-2); padding-block:.35rem;
  }
  /* 🔴 LA FILA ENSEÑA CINCO. EL PANEL SIGUE ENSEÑANDO LAS NUEVE.
     Regla de la casa, Diego 2026-08-05: «the menu has too many sections. keep
     only the important ones» — LA BARRA ES PARA DECIDIR, NO PARA LISTAR. Ocho
     enlaces más el selector es justo el patrón que esa regla rechaza, y era la
     causa de fondo de que la barra inglesa se partiera en dos filas: no era un
     problema de anchura, era de RECUENTO.
     Se quedan: La carta · Nuestra casa · Lo que dicen · Reservar · Venid.
     Se retiran DE LA FILA —y sólo de la fila— «Nuestra cocina», «Desde 0 cada
     día» y «Contacto».
     ⚠️ ES UNA SOLA LISTA, NO DOS. Los nueve `<li>` viven una única vez en el
     marcado; aquí se esconden tres, y sólo dentro de esta consulta. Dos listas
     paralelas discreparían la primera vez que alguien renombre una sección —
     que es exactamente lo que pasó esta misma noche con «Nuestra cocina».
     La condición que la regla exige se cumple: el índice del pie lista las
     NUEVE (con «Inicio»), así que ninguna sección se queda sin un solo enlace
     en toda la web. Dos superficies, dos trabajos.                             */
  .nav__i--sec{ display:none }
}
/* 🔴 GATEADO. Era uno de los dos `:hover` sueltos que quedaban en la hoja. En
   una pantalla táctil el :hover se dispara AL TOCAR y se queda pegado hasta que
   tocas otra cosa: el visitante ve un estado que no ha pedido y no sabe quitar.
   Se escribe como bloque propio en vez de anidarlo dentro del `min-width:1024`
   para no depender del anidamiento nativo de CSS.                              */
@media (min-width:1024px) and (hover:hover) and (pointer:fine){
  .nav__a:hover,.nav__lang:hover{ color:var(--crema) }
}

/* ── El selector de idioma · `<details>`, no ciclo · ⭐ 2026-08-23 ────────────
   COPIADO de `Ristorante-Da-Marc-Denia/styles.css:780-815`, que lo construyó el
   2026-08-18 a petición del dueño. El disparador SIGUE siendo `.nav__lang` —
   misma fila de 52 px en el panel de móvil, misma versión micro-uppercase en la
   barra de escritorio— y el marcador nativo se sustituye por una flecha que gira
   al abrir, igual que en `.fuentes`.

   🔴 TRES COSAS SE APARTAN DE DÉNIA. LAS TRES SON DEFECTOS MEDIDOS, no gustos,
   y las tres se resumen en una frase: **Dénia abre el panel SIEMPRE hacia abajo
   y SIEMPRE centrado sobre el disparador, y ninguna de las dos cosas cabe en los
   dos sitios donde vive el control.** Medido en Chrome real el 2026-08-23.

   1 · EL ANCLAJE. Centrado (`left:50%; translateX(-50%)`) el panel del PIE se
       sale por la derecha: en la web de Dénia llega a x=1.031 sobre una ventana
       de 1.024 px. Aquí el del pie se cuelga de `.pie__legal` — ver su nota.
   2 · LA DIRECCIÓN EN EL PIE. Abriendo hacia abajo, el borde inferior del panel
       cae en 7.736 px a 1024 y en 8.036 a 1440 en la web de Dénia, que es
       EXACTAMENTE el `scrollHeight` del documento: el menú ALARGA la página en
       vez de caber en ella.
   3 · LA DIRECCIÓN EN EL PANEL DE MÓVIL, que es la que casi se me escapa porque
       ningún comprobador la ve y sólo salió al AMPLIAR la captura. Por debajo
       del punto de corte el selector es la ÚLTIMA fila del panel a pantalla
       completa, así que debajo no hay nada — salvo el aviso de cookies, que es
       fijo. Medido a 390×844 con el aviso levantado: el panel ocupaba
       y 553-689 y la barra de cookies empieza en 676, o sea **«Italiano»
       cortado por la mitad**. Y es la PRIMERA visita, que es exactamente cuando
       alguien elige idioma.

   Así que la regla de esta hoja es «hacia donde haya sitio», y se lee sola:
   hacia arriba en el pie siempre, hacia arriba en el <nav> mientras sea un
   panel, hacia abajo en el <nav> cuando es una fila en la barra.
   El resto —clases, tamaños, colores, tiempos— es byte a byte lo de Dénia.     */
.idiomas{ position:relative; --ind:180deg }     /* 180 = la punta mira ARRIBA */
.idiomas > summary{ list-style:none }
.idiomas > summary::-webkit-details-marker{ display:none }
.idiomas__cod{ font-variant-numeric:lining-nums; letter-spacing:.04em }
.idiomas__ind{
  width:10px; height:7px; margin-left:.4rem; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform 140ms var(--ease-out);
}
/* La punta dice HACIA DÓNDE se abre, y gira media vuelta al abrir. Un solo
   token (`--ind`) gobierna las dos, así que la flecha no puede desmentir al
   panel: si cambias la dirección, la punta va detrás sola.                     */
.idiomas > summary .idiomas__ind{ transform:rotate(var(--ind)) }
.idiomas[open] > summary .idiomas__ind{ transform:rotate(calc(var(--ind) + 180deg)) }
/* El panel FLOTA — nunca empuja el resto de la barra ni del pie — y con
   `min-width:8,5rem` cabe «Italiano» entero incluso a 320 px. */
.idiomas__l{
  position:absolute; bottom:calc(100% + 6px); left:50%; transform:translateX(-50%);
  z-index:5; min-width:8.5rem;
  display:grid; gap:2px; padding:6px; margin:0;
  background:var(--plano-1); box-shadow:var(--filo),var(--sombra-2);
  border-radius:var(--r-control);
  list-style:none;
}
/* 🔴 EL DEL PIE NO SE COLGA DEL DISPARADOR, SE COLGA DE LA FILA LEGAL, y es la
   única forma que no se sale por ningún lado. Todo esto está medido en esta
   misma web, a doce anchuras y en los tres idiomas:
   · CENTRADO sobre el disparador —lo que hace Dénia— se sale por la DERECHA:
     7 px fuera a 1024 en español y en italiano, 14 px fuera a 390 en inglés.
     El disparador del pie es el último de una fila que ENVUELVE, así que su
     posición depende de lo largos que sean los tres enlaces legales, o sea del
     idioma.
   · ANCLADO por el canto derecho DEL DISPARADOR se arregla la derecha y se
     rompe la izquierda: cuando la fila envuelve y el disparador cae solo al
     principio de su renglón, el panel (136 px) empieza antes del margen —
     medido, 80 px fuera a 430 en español y 83 px fuera a 360 en inglés.
   · ANCLADO a `.pie__legal` no puede pasar ninguna de las dos cosas: su canto
     derecho ES el margen de la página, y la fila mide siempre más que el panel
     (280 px de contenido ya a 320 px de ventana, contra 136).
   `position:static` en el `<details>` es lo que hace que el bloque contenedor
   pase a ser la fila; sin eso el `right:0` seguiría midiendo desde el
   disparador.                                                                  */
.idiomas--arriba{ position:static }
.idiomas--arriba .idiomas__l{ left:auto; right:0; transform:none }
.idiomas__l li{ display:block }
.idiomas__op{
  display:block; width:100%; min-height:40px; padding:.5rem .7rem;
  border-radius:calc(var(--r-control) - 4px);
  background:transparent; border:0;
  font:inherit; font-size:var(--t-meta); font-weight:600; letter-spacing:var(--tr-meta);
  color:var(--crema-2); text-align:left; cursor:pointer;
}
/* 6,1:1 el turquesa sobre --plano-1 · AA de sobra para marcar «el idioma
   activo» sin depender sólo del color (lo dice también `aria-current`).      */
.idiomas__op[aria-current="true"]{ color:var(--turquesa); font-weight:700 }
@media (hover:hover) and (pointer:fine){
  .idiomas__op:hover{ background:rgba(247,233,219,.08); color:var(--crema) }
}
/* POR ENCIMA DEL PUNTO DE CORTE, y SÓLO el del <nav>, cambian las dos cosas a
   la vez, porque el control deja de ser una fila de un panel y pasa a ser un
   botón de 30 px pegado al margen derecho de la barra:
   · se ancla por SU canto derecho, que es el que toca el margen, así que no
     puede salirse de la ventana (ver el punto 1 de la nota de arriba);
   · abre hacia ABAJO, porque la barra está arriba del todo y encima no hay
     nada — y `--ind:0deg` hace que la punta se dé la vuelta sola.
   El del pie NO entra aquí: sigue subiendo a todas las anchuras.               */
@media (min-width:1024px){
  .nav .idiomas{ --ind:0deg }
  .nav .idiomas__l{
    top:calc(100% + 6px); bottom:auto;
    left:auto; right:0; transform:none;
  }
}

/* ══ FORMA 1 · EL FONDO · §1 INICIO ══════════════════════════════════════════
   La fotografía no es media portada: es EL FONDO ENTERO, a sangre por los cuatro
   lados y por debajo de la barra incluida, con el contenido en UNA columna
   centrada. Sin marco, sin pie, sin radio — «the way the video appears when you
   open the website is ugly, I dont like that its like a picture hanging on a
   wall» (Diego, Maestros r4).
   ⚠️ EL TOPE DE 780 px DEL BLOQUE DE MÓVIL NO ES DECORACIÓN: render-shots.py
   abre una ventana de 16.000 px de alto y sin `min()` la portada mediría
   dieciséis mil píxeles. En ESCRITORIO ese tope se retiró el 2026-08-17 (orden
   de Pere: la portada ocupa la pantalla entera) y de la cámara se encarga el
   `--hero-selector` del propio comprobador. Ver la nota junto al `@media`.     */
/* ⭐ RONDA 10 · LA PRIMERA PANTALLA ES EL BUCLE, Y NADA MÁS.
   Orden de Pere, 2026-08-03: «quita los dos vídeos que hay a los lados. El vídeo
   que hay de fondo ni siquiera se ve». Las dos frases son el mismo defecto: el
   tríptico de la r8 (pieza A · plinto opaco · pieza B) tapaba el bucle de 14 s
   por los tres sitios a la vez. Sólo asomaba una franja de arco por arriba.
     ≥900   el vídeo a sangre; el contenido en el TERCIO IZQUIERDO —columna de
            480 px que arranca en el mismo borde vertical que el aparejo de §2
            (--edge = 44 a 1440), así que no aparece un tercer eje— y la llama,
            que vive entre el 42 % y el 70 % del ancho del encuadre, entera al
            aire.
     <900   el vídeo a sangre; el contenido anclado abajo, centrado, sobre la
            parada pesada del velo. En un teléfono la relación 0,50 recorta el
            encuadre a su franja central y no hay refugio oscuro: manda la
            aritmética, y está escrita entera junto a `.hero__velo`.
   Se conserva de la r8 lo único que era verdad: el fuego cambia de papel, de
   sujeto a LUZ, y no afirma nada sobre quién es su dueño. Todo lo que SÍ afirma
   algo en esta pantalla —el óvalo, la nota, los cuatro botones— es material suyo.
   ⚠️ EL METRAJE DEL HÉROE NO SE ENMARCA (Diego, Maestros r4): ni radio, ni
   sombra, ni suelo alrededor. El vídeo ES el suelo.                            */
.hero{
  position:relative; isolation:isolate;
  /* Se conserva el `isolate` + z-index para que el velo y el contenido apilen
     dentro de la sección y ningún hermano posterior se cuele entre ellos. Ya no
     hay SOLAPE 1: sin plinto no hay nada que cruzar a §2, y la costura vuelve a
     ser exactamente lo que declara `#el-horno` — CONTACTO de 12 px.           */
  z-index:2;
  display:grid; align-content:end;
  min-height:min(100vh,780px);
  padding-block:calc(var(--barra) + var(--s3)) var(--s5);
}
@supports (height:1svh){ .hero{ min-height:min(100svh,780px) } }
/* ⭐ 2026-08-17 · EN ESCRITORIO LA PORTADA ES LA PANTALLA ENTERA.
   Orden de Pere, 2026-08-17: «quiero que el landing page ocupe toda la pantalla
   completa, es decir que no se vea el inicio de la siguiente seccion cuando lo
   abro desde el ordenador».
   LO QUE HABÍA, MEDIDO EN CHROME REAL antes de tocarlo (`--force-device-scale-
   factor=1`, ventana = alto útil exacto):
       ventana   alto del héroe   px de #el-horno a la vista
       768        658 (contenido)  110
       900        792 (el tope)    108
      1050        792 (el tope)    258
      1080        792 (el tope)    288
   Las dos causas eran el factor 88 % y el tope duro de 792 px: por encima de
   900 px de ventana el héroe se quedaba clavado en 792 y la siguiente sección
   asomaba más cuanto más grande era la pantalla. Los dos se van.
   ⚠️ SE QUEDA `min-height` Y NO `height`: si en una ventana muy baja el
   contenido (óvalo + promesa + h1 + sitio + prueba + cuatro botones) no cabe en
   100 svh, la caja CRECE y no recorta. Un `height` fijo cortaría letras.
   ⚠️ NO SE TOCA EL BLOQUE DE MENOS DE 900 px: en un teléfono una portada a
   pantalla completa es un antipatrón, y `min(100vh,780px)` está aprobado.
   ⚠️ EL TOPE DE 792 px TAMBIÉN PROTEGÍA DE LA CÁMARA: `render-shots.py` abre una
   ventana de 16.000 px y sin tope la portada mediría dieciséis mil píxeles. Ya
   no hace falta escribirlo aquí porque el clamp vive en el comprobador:
   `render-shots.py --hero-selector` (por omisión `.hero, [data-hero],
   header.hero`) y `contrast-check.py` / `site-audit.py` lo llaman con 860 px.
   Comprobado el 2026-08-17: los tres siguen midiendo bien.                    */
@media (min-width:900px){
  .hero{
    min-height:100vh;
    align-content:center;
    padding-block:calc(var(--barra) + var(--s5)) var(--s5);
  }
  @supports (height:1svh){ .hero{ min-height:100svh } }
  /* `dvh` == `svh` == `lvh` en un escritorio (no hay barra retráctil); se
     declara porque es la unidad correcta si algún día esta regla baja de 900. */
  @supports (height:1dvh){ .hero{ min-height:100dvh } }
}

.hero__fondo{ position:absolute; inset:0; z-index:-2; overflow:clip }
/* ⚠️ `<picture>` es INLINE y no tiene altura propia: la cadena de alturas tiene
   que ser continua (caja → picture → img).                                      */
.hero__fondo picture{ display:block; width:100%; height:100% }
.hero__fuego{ width:100%; height:100%; object-fit:cover }
/* El vídeo va ENCIMA del póster y empieza invisible. Se revela con el evento
   REAL `playing`, nunca de forma optimista: debajo siempre está el póster, que
   es el mismo fotograma 0.                                                      */
.hero__video{
  position:absolute; inset:0; z-index:1;
  width:100%; height:100%; object-fit:cover; object-position:50% 50%;
  opacity:0; transition:opacity 400ms var(--ease-out);
  pointer-events:none;
}
.hero__video.is-on{ opacity:1 }
/* ⭐⭐ EL VELO MEDIDO · r10. AQUÍ ESTÁ EL PUNTO ENTERO DEL ENCARGO.
   El plinto opaco se BORRA. Regla del estudio que lo obligaba a irse: el metraje
   del héroe no se enmarca, y una placa `rgba(38,38,42,.92)` de 798 px de ancho
   delante de un bucle de 14 s es exactamente por qué Pere escribió «el vídeo que
   hay de fondo ni siquiera se ve». El contraste pasa a darlo un VELO sobre el
   propio vídeo.
   ⚠️ El rulebook prohíbe poner texto sobre «un `linear-gradient` cuyo contraste
   es incognoscible en tiempo de construcción» (Diego, 2026-07-28). La objeción
   es correcta y se responde HACIÉNDOLO COGNOSCIBLE: los números de abajo no son
   una estimación, son una MEDIDA sobre los 70 fotogramas reales del bucle
   (`fuego-arco-loop-1600.webp` y `-640`), luminancia relativa sRGB por píxel,
   máximo por píxel a lo largo de todo el bucle — no el promedio.

   ── LO QUE DICE EL METRAJE ────────────────────────────────────────────────
   · L media de todo el encuadre .................................... 0,0363
   · L del píxel MÁS BRILLANTE de todo el bucle ..................... 1,0000
   · dónde vive ese píxel: la llama reventada, x 42–70 % · y 45–75 %
   · L máxima en el TERCIO IZQUIERDO (x 3–41 %, toda la altura) ..... 0,4223
   · L media en ese mismo tercio .................................... 0,0127
   De ahí sale la maqueta: en escritorio el texto se va al tercio izquierdo, que
   es donde el fuego NO está, y el velo sólo tiene que trabajar allí.

   ── LA ARITMÉTICA (crema #F7E9DB · L = 0,8317 · velo #1C1C1C · L = 0,0116) ──
   Composición α en espacio gamma, que es lo que hace el navegador:
     c_comp = α·0,1098 + (1−α)·c_vídeo   ⇒   contraste = 0,8817 / (L(c_comp)+0,05)
   ⚠️ NO es una estimación sobre un rectángulo a ojo. Se ha recorrido PÍXEL A
   PÍXEL cada caja de texto REAL (medida en el DOM vivo con cdp-shots), mapeando
   cada píxel de pantalla a su píxel de origen a través del `object-fit: cover`,
   leyendo ahí el MÁXIMO del bucle entero y componiéndolo con la α que el
   degradado vale exactamente en ese punto. El número que sale es el PEOR PÍXEL
   DEL PEOR FOTOGRAMA bajo cada elemento:

     ESCRITORIO 1440 × 792         peor L    α velo   contraste
       promesa                      0,2494    0,848    11,65:1  ✅
       h1                           0,1295    0,893    13,06:1  ✅
       sitio                        0,1162    0,896    13,19:1  ✅
       4,3 + «sobre 5 en Google»    0,0937    0,898    13,37:1  ✅
       fuente (Google · 30 jul)     0,3379    0,844    11,05:1  ✅
       botones secundarios          0,2796    0,910    12,63:1  ✅
     MÓVIL 390 × 688 (el caso apretado: barra de cookies abierta)
       promesa                      0,6653    0,758     7,23:1  ✅ ← el peor
       h1                           0,9898    0,888    10,27:1  ✅
       sitio                        1,0000    0,893    10,40:1  ✅
       4,3 + etiqueta               0,9907    0,905    10,87:1  ✅
       fuente                       0,6976    0,910    11,56:1  ✅
       botones secundarios          0,6824    0,931    12,23:1  ✅

   Mínimos exigidos: 7:1 para el <h1>, 4,5:1 para el cuerpo. El elemento MÁS
   AJUSTADO de toda la portada da 7,23:1, y es la promesa en un móvil con la
   barra de cookies abierta. El h1 va con 3,3 puntos de margen en móvil y 6,1 en
   escritorio. La parada del 36 % en móvil está en .58 y no en .50 justamente por
   ese 7,23: con .50 la promesa daba 6,50:1 y no llegaba.

   ── LO QUE SE GANA ────────────────────────────────────────────────────────
   A 1440 el fuego pasa de 0 px visibles (tapado por tres objetos) a los ~63 % de
   ancho que van del 37 % al 100 %, donde el velo no pasa de α 0,22. La llama
   entera, sin nada delante. Eso es lo que pidió Pere.                          */
.hero__velo{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  /* MÓVIL · cinco paradas. 0–18 % cierra bajo la barra fija; 18–36 % se abre
     para que respiren el arco y la leña; de 36 % a 52 % sube a la parada pesada,
     que es justo donde entra la primera línea de texto; y el último tramo cierra
     contra la costura de contacto con §2.                                      */
  background:linear-gradient(180deg,
    rgba(28,28,28,.62) 0%,
    rgba(28,28,28,.24) 18%,
    rgba(28,28,28,.58) 36%,
    rgba(28,28,28,.88) 52%,
    rgba(28,28,28,.95) 100%);
}
@media (min-width:900px){
  /* ESCRITORIO · dos capas que se multiplican. La HORIZONTAL es la que da el
     contraste (α 0,90 → 0,04 de izquierda a derecha, con la meseta de 0,80
     cubriendo entera la columna de texto); la VERTICAL sólo cierra los dos
     extremos —bajo la barra y contra la costura con §2— y deja el centro a cero,
     que es donde está la llama.                                                */
  .hero__velo{
    background:
      linear-gradient(180deg,
        rgba(28,28,28,.50) 0%,
        rgba(28,28,28,0) 18%,
        rgba(28,28,28,0) 66%,
        rgba(28,28,28,.62) 100%),
      linear-gradient(90deg,
        rgba(28,28,28,.90) 0%,
        rgba(28,28,28,.84) 26%,
        rgba(28,28,28,.80) 38%,
        rgba(28,28,28,.22) 58%,
        rgba(28,28,28,.04) 100%);
  }
}
/* EL CUERPO DE LA PORTADA · YA NO ES UNA SUPERFICIE.
   Sin `background`, sin `border-radius`, sin `box-shadow` y sin sombra de
   contacto: no queda una sola arista alrededor del texto. El óvalo vuelve a
   apoyarse en la escena y no en una placa — y el tamaño, que es lo único que
   Pere dejó ordenado (200 / 320), no se toca.
   Se conserva `z-index:3` para quedar por encima del velo, y `min-width:0` para
   que ninguna línea larga ensanche la columna.                                 */
.hero__cuerpo{
  position:relative; z-index:3;
  display:grid; gap:var(--s3); justify-items:center; text-align:center; align-content:end;
  width:100%; min-width:0;
  padding-inline:var(--edge);
}
/* 🔴 UN CONTROL QUE CAMBIA DE PLANO SE REVISA (Diego, r9e). `.btn--sec` está
   escrito para apoyarse en grafito o en el plinto; desde la r10 se apoya en un
   VÍDEO EN MOVIMIENTO. La tinta aguanta —12,63:1 medidos en escritorio y 12,23:1
   en móvil, arriba—, pero un filete transparente sobre metraje que se mueve deja
   de leerse como un botón. Se le da superficie propia: el mismo grafito del
   velo, translúcido. No es un marco alrededor del metraje, es la piel de un
   control, y sigue dejando ver el fuego a través.                              */
.hero .btn--sec{ background:rgba(28,28,28,.46) }
/* 🔴 GATEADO, y hace falta por especificidad: `.btn--sec:hover` puntúa 0,2,0 —
   igual que la línea de arriba— y la de arriba está MÁS ABAJO en el fichero, así
   que se comía el estado de hover. `.hero .btn--sec:hover` puntúa 0,3,0 y lo
   devuelve. El `@media (hover:hover) and (pointer:fine)` es obligatorio: en una
   pantalla táctil el :hover se dispara al tocar y se queda pegado.             */
@media (hover:hover) and (pointer:fine){
  .hero .btn--sec:hover{ background:rgba(247,233,219,.10); border-color:var(--crema) }
}
/* ⚠️ TODO EL TEXTO DE LA PORTADA VA EN --crema, NUNCA EN --crema-2: sobre el
   compuesto peor la crema da 7,23:1 y la crema-2 daría 2,44:1.                  */
.hero__cuerpo .prueba__lbl,.hero__cuerpo .prueba__src,.hero__sitio{ color:var(--crema) }
.hero__cuerpo .prueba{ width:100%; max-width:34rem; margin-inline:auto }
/* ⚠️ ESTE BLOQUE VA DESPUÉS DE LAS REGLAS BASE QUE CORRIGE, Y NO ES UN CAPRICHO
   DE ORDEN: un `@media` NO añade especificidad, así que `.hero__cuerpo .prueba`
   dentro y fuera de la consulta puntúan igual (0,2,0) y gana la que esté más
   abajo en el fichero. Escrito al revés, el `margin-inline:0` de escritorio no
   haría absolutamente nada.                                                    */
@media (min-width:900px){
  /* La columna arranca en el MISMO borde vertical que el aparejo de §2
     (`--edge` = 44 px a 1440) y mide `--hero-col`. No se usa `--gutter` a
     propósito: a 1440 el gutter vale 204 px y empujaría el texto encima de la
     llama, que empieza en el 42 % del ancho.                                   */
  .hero__cuerpo{
    justify-items:start; text-align:left;
    gap:var(--s2);
    max-width:calc(var(--edge) + var(--hero-col));
    padding-inline:var(--edge) 0;
  }
  .hero__cuerpo .prueba{ justify-content:flex-start; margin-inline:0 }
  .hero__cuerpo .hero__promesa{ margin-inline:0 }
  .hero__cuerpo .hero__id{ justify-items:start }
  .hero__cuerpo .acc{ margin-inline:0 }
}

.hero__logo{ width:var(--ovalo); height:auto }
.hero__id{ min-width:0; display:grid; gap:2px; justify-items:center }
.hero__h1{
  font-size:var(--t-meta); font-weight:600; line-height:1.35;
  letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema);
}
.hero__sitio{ font-size:var(--t-micro); letter-spacing:var(--tr-micro); text-transform:uppercase }
/* ⭐ ANCLAJE ÓPTICO: la promesa no puede ser más ancha que 1,9 × el óvalo. Marca
   y frase forman UN BLOQUE con dos bordes verticales compartidos, en vez de dos
   objetos flotando sobre una fotografía.                                        */
.hero__promesa{
  font-family:var(--display); font-weight:500; font-style:italic;
  font-size:var(--t-promesa); line-height:1.06; letter-spacing:var(--tr-display);
  color:var(--crema); max-width:calc(var(--ovalo) * 1.9);
  text-wrap:balance; hyphens:none; margin-inline:auto;
}
/* 🔴 La regla de decisión de la portada: lo que baja es el AIRE y el tamaño del
   óvalo, NUNCA el cuerpo de la promesa, ni las cifras, ni la altura del botón. */
/* ⚠️ VENTANAS CORTAS · ya no hay tira que revertir (la r10 la borró). Lo único
   que sigue haciendo falta en un móvil apaisado es apretar el aire y bajar el
   óvalo, porque manda la aritmética del pliegue: los cuatro botones tienen que
   caber sin scroll.                                                            */
@media (max-height:700px){
  .hero{ padding-top:calc(var(--barra) + var(--s2)) }
  .hero__cuerpo{ gap:var(--s2) }
}
@media (max-width:899px) and (max-height:700px){ :root{ --ovalo:clamp(140px,44vw,168px) } }
@media (min-width:900px) and (max-height:760px){ :root{ --ovalo:240px } }

.prueba{ display:flex; flex-wrap:wrap; align-items:baseline; justify-content:center; gap:.4rem .9rem }
.prueba__n{ font-size:22px; font-weight:700; letter-spacing:var(--tr-figure); font-variant-numeric:lining-nums tabular-nums }
.prueba__lbl{ font-size:var(--t-meta); letter-spacing:var(--tr-meta); color:var(--crema-2) }
.estrella{ fill:var(--turquesa); width:20px; height:20px; align-self:center }
.prueba__src{
  flex:1 0 100%; font-size:var(--t-micro); letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}
.acc{ display:grid; gap:var(--s2); width:100%; max-width:34rem; margin-inline:auto }
/* ⭐ 2026-08-17 · LA FILA SE MIDE POR SUS HIJOS, NO POR SU NOMBRE.
   Era `repeat(3,minmax(0,1fr))` cuando la fila tenía tres botones. Al caerse
   el botón de reparto (Pere, 2026-08-17) quedaban dos hijos en tres pistas, o sea
   una columna vacía y dos botones al 33 %. `grid-auto-flow:column` +
   `grid-auto-columns` reparte por el número real de hijos, así que la fila no
   puede volver a descuadrarse si mañana entra o sale otro botón. El nombre de
   la clase se queda: renombrarlo tocaría el marcado de las tres webs. */
.acc__tres{ display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:8px }
@media (min-width:900px){
  .acc .btn--pri{ width:auto; justify-self:center; padding-inline:2.4rem }
  /* En la portada la columna está alineada a la izquierda desde la r10, así que
     el botón primario se alinea con ella y no con su propio centro. Especificidad
     0,3,0 contra 0,2,0: gana esté donde esté en el fichero.                     */
  .hero .acc .btn--pri{ justify-self:start }
}

/* ══ LA CAPA DE VÍDEO, UNA SOLA REGLA PARA LOS DOCE ══════════════════════════
   Debajo de cada clip hay SIEMPRE un <img> real con su `alt` — el fotograma al
   45 % del propio clip—, y el vídeo se funde encima sólo cuando de verdad está
   reproduciendo. Sin JavaScript, con `prefers-reduced-motion`, con `saveData` o
   con 2g, lo que se ve es esa fotografía: ninguna caja se pinta vacía.
   El <video> NO lleva `poster=` a propósito: el atributo dispara una descarga
   ANSIOSA que duplicaría el peso inicial. El póster es el <img> de debajo.      */
.vid{
  position:absolute; inset:0; z-index:1;
  width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity 160ms var(--ease-out);   /* la salida, más rápida */
  pointer-events:none;
}
.vid.is-on{ opacity:1; transition-duration:240ms }       /* la entrada */

/* ══ FORMA 2 · EL APAREJO · §2 NUESTRO HORNO ═════════════════════════════════
   ⭐ LA ÚNICA SECCIÓN QUE CAMBIA DE COMPOSICIÓN EN LA r7b, y el motivo está
   medido: eran TRES piezas de 674–1.352 px. Es exactamente lo que Pere llama
   grande, y es donde estaba el defecto de nitidez (`horno-lena-encendido` es una
   foto de móvil de 2.048 px nativos: a 1.352 se le ve el ladrillo pastoso; a
   448 corre a 0,22× y es nítida).
   CINCO PLANOS DE SU COCINA, dos alturas de fila y una pieza que CRUZA LAS
   DOS FILAS. No es una rejilla uniforme —eso está rechazado 3× por Diego—: es
   un aparejo, con dos alturas distintas y una pieza a caballo.
   ⚠️ Y NO SON CINCO LLAMAS. La primera versión puso cinco planos de fuego
   seguidos debajo de una portada de fuego, y eso reabre la queja literal del
   dueño («el horno sale cuatro veces»). La regla de la r7 acota el fuego a DOS
   SECCIONES y a TRES vistas dentro de ésta; desde el 2026-08-22 son DOS aquí
   (leña y pala), porque la pizza en la solera dejó su sitio a un plato de
   carne: el horno encendido · la pala entrando · la carne en salsa (sin
   fuego) · la tabla de focaccia y quesos (sin fuego) · el corte en la mesa
   (sin fuego).

     ≥900   3 cols × 2 filas · fila 268 px · columna 448 px a 1440
            ┌────────┬────────┬────────┐
            │ pala   │  masa  │ leña   │  fila 1
            ├────────┤ (cruza ├────────┤
            │ carne  │  las 2)│ corte  │  fila 2
            └────────┴────────┴────────┘   alto = 268+4+268 = 540  (r7: 1.284)
     <900   2 cols × 3 filas · columna 193 px a 390
            fila 1 · leña, cruzando las dos columnas
            fila 2 · pala  │ masa
            fila 3 · carne │ corte           alto = 148+4+210+4+148 = 514

   ⚠️ LA PIEZA QUE CRUZA ES LA MÁS GRANDE DE LA SECCIÓN (448 × 540) Y POR ESO
   LLEVA EL FICHERO CON MÁS PÍXELES: `ig-masa-bolas-en-mano`, 1.080 × 1.500
   nativos ⇒ 0,41× a DPR1 y 0,83× a DPR2. El póster de un clip tope a 540 px de
   ancho, y ponerlo en esa caja lo dejaba en 0,83× / 1,66× — que es lo que se vio
   blando en el primer render. Los pósters se quedan en cajas de 448 × 268.

   ⚠️ La receta de la media sigue siendo la de Esens `.llegada__wall`: va
   `position:absolute; inset:0` PORQUE la altura intrínseca de un 720×1280
   dentro de una columna de 193 px son 343 px, la fila se inflaría, y el «too
   much blank space» de Diego reaparecería por otra ruta.
   ⚠️ Las dos teselas de cada fila miden EXACTAMENTE lo mismo (phone-fit
   `lopsided` falla dos medias de distinto ancho en la misma fila, ⚠️5×).
   ⚠️ NINGUNA PIEZA LLEVA SOMBRA NI MARGEN PROPIO: una foto con sombra es una
   foto que necesita suelo alrededor para que la sombra se vea. El vecino de
   cada pieza es otra pieza a 12 px, nunca el fondo.                            */
/* ⭐ r8b · EL TEXTO ENTRA DENTRO DEL APAREJO, y esto arregla el defecto medido
   más caro de la ronda: la franja de §2 —titular, dos líneas, tres servicios y
   el botón— vivía DEBAJO del bloque de fotos, a ancho completo sobre grafito
   liso, con 3,6 % de imagen. Era literalmente el defecto `[density]` que el
   estudio persigue desde la r1, sólo que `site-audit` no lo cazaba porque la
   SECCIÓN entera sí lleva imágenes.
   Ahora el texto es UNA CELDA MÁS del aparejo: su vecino por la derecha es una
   fotografía a 12 px y por la izquierda el margen de la página. Nunca el fondo.
   Y va sobre `--plano-1` con su filo, así que no es texto flotando: es un plano
   elevado que se toca con las piezas, que es la salida escrita en la §10 de la
   r7b para el conflicto Diego/Pere.
   ⇒ La banda de sólo texto DESAPARECE: no se rellena, deja de existir.         */
.aparejo{
  display:grid; gap:var(--seam);
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-template-rows:var(--apar-r1) var(--apar-r2) var(--apar-r1) auto;
  min-width:0;
}
.aparejo__txt{
  grid-column:1 / -1; grid-row:4; min-width:0;
  background:var(--plano-1); box-shadow:var(--filo);
  border-radius:var(--r-control);
  padding:var(--s4) var(--edge);
  display:grid; gap:var(--s4); align-content:center;
}
.aparejo__t{
  position:relative; overflow:hidden; margin:0; min-width:0;
  border-radius:var(--r-pieza);
}
/* Las cinco teselas van COLOCADAS A MANO: un item con fila definida y columna
   automática se coloca antes que los totalmente automáticos y da la vuelta a la
   fila. Aquí el orden es el retrato de su cocina y no puede depender del algoritmo. */
.aparejo__t--lena{ grid-column:1 / -1; grid-row:1 }
.aparejo__t--pala{ grid-column:1; grid-row:2 }
.aparejo__t--masa{ grid-column:2; grid-row:2 }
.aparejo__t--carne{ grid-column:1; grid-row:3 }
.aparejo__t--corte{ grid-column:2; grid-row:3 }
.aparejo__t > img,.aparejo__t > video{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}
/* ≥900 · CUATRO columnas: el texto ocupa la primera y cruza las dos filas, y las
   cinco piezas se reparten las otras tres. A 1440 la columna de texto mide 426
   px y cada pieza 304 —muy por debajo del techo de 480— y el bloque entero pasa
   de «media arriba, letra debajo» a UNA SOLA SUPERFICIE de 540 px de alto en la
   que el 76 % es fotografía.                                                   */
@media (min-width:900px){
  .aparejo{
    grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr));
    grid-template-rows:var(--apar-r) var(--apar-r);
  }
  .aparejo__txt{
    grid-column:1; grid-row:1 / span 2;
    padding:var(--s4);
    padding-left:var(--edge);
  }
  .aparejo__t--pala{ grid-column:2; grid-row:1 }
  .aparejo__t--carne{ grid-column:2; grid-row:2 }
  .aparejo__t--masa{ grid-column:3; grid-row:1 / span 2 }
  .aparejo__t--lena{ grid-column:4; grid-row:1 }
  .aparejo__t--corte{ grid-column:4; grid-row:2 }
}
/* `.horno__txt` SE BORRA con la banda que envolvía: el texto de §2 ya no es un
   bloque aparte, es la celda `.aparejo__txt` dentro del propio aparejo.        */
.horno__h{ display:grid; gap:var(--s2); min-width:0; align-content:start }
.hechos{ display:grid; gap:var(--s2); align-content:start }
.hecho{ display:grid; grid-template-columns:3px minmax(0,1fr); gap:var(--s2); align-items:start }
.hecho .banda{ margin-top:.45em }
.hecho__t{ font-size:var(--t-meta); font-weight:600; letter-spacing:var(--tr-meta); color:var(--crema) }
.hecho__s{ font-size:var(--t-meta); color:var(--crema-2) }
.horno__acc{ display:grid; justify-items:start; gap:var(--s3) }

/* ══ FORMA 3 · EL ÍNDICE · §3 LA CARTA ═══════════════════════════════════════
   Diez familias, los diez <details> CERRADOS al cargar y EXCLUSIVOS
   (name="carta", HTML nativo, cero JS): abrir una cierra la anterior, así que el
   índice nunca se pierde — y el navegador garantiza que sólo hay UN vídeo
   decodificando en toda la sección.
   ⭐ r7b · LA FOTO DEJA DE MANDAR LA ALTURA DE LA FILA, Y EL TEXTO PASA A
   MANDARLA. El defecto medido sobre la captura de la r7: foto de 320 × ~310 ⇒
   fila de ~345 px; el titular y la línea de platos ocupaban los primeros ~100 y
   el recuento quedaba clavado abajo ⇒ ~200 px de grafito liso a lo ancho de 700,
   diez veces seguidas. La solución de la r7 —«cuatro anclas repartidas sobre la
   altura de la placa»— REPARTIÓ EL TEXTO POR EL VACÍO EN VEZ DE QUITARLO:
   estirar tres elementos sobre 345 px no llena 345 px, los separa.
   Ahora: `align-content: space-between` SE BORRA, el bloque de texto va arriba y
   apretado con `gap: 6px`, y la placa se estira a la altura de la fila
   (`align-self: stretch`), no al revés. El sobrante vertical máximo de una fila
   L a 1440 es 2,4 px.
   Índice de diez familias: 2.640 px → 1.060.                                    */
/* ══════════════════════════════════════════════════════════════════════════
   ⭐ RONDA 8 · EL CAPÍTULO CREMA — UNA sola inversión en toda la página
   ══════════════════════════════════════════════════════════════════════════
   🔧🔧 EL INTERRUPTOR DE REVERSIÓN Nº 2:   .sec--carta{ --sw: 0 }
   Con 0, los seis `color-mix` de abajo devuelven EXACTAMENTE los colores del
   tema oscuro y vuelve el suelo único del primer píxel al último. Una línea.

   POR QUÉ ESTA SECCIÓN Y NO OTRA:
     1 · es literalmente un documento impreso — sobre crema deja de IMITAR un
         impreso y lo es;
     2 · es la más larga de la web (1.060 px cerrada, hasta 2.400 abierta) ⇒ el
         descanso es real, no decorativo;
     3 · cae justo después de la portada de fuego y del aparejo del horno, que es
         donde el propio dueño se quejó de repetición: el cambio de luz corta esa
         racha por ESTRUCTURA, no por recorte;
     4 · 100 filas de texto pequeño se leen mejor en negro sobre claro.

   🔴 Y POR QUÉ ESTO NO ES «BANDEAR LA PÁGINA» (rechazado por Diego 3×): una
   INVERSIÓN no es una ALTERNANCIA. La página tiene DOS capítulos, no ocho
   bandas: oscuro (§1–§2) · CLARO (§3) · oscuro (§4–§8).

   🔴 LA CONSECUENCIA DURA, y es la que hace que esto NO sea un segundo acento:
   `--turquesa` sobre `--crema` da **1,04:1** — sería invisible. Dentro del
   capítulo el motivo «LA BANDA» se compone en `--grafito` macizo, con sus mismas
   medidas (3 × 14 px). Sigue habiendo UN SOLO ACENTO en toda la web: el
   turquesa, sobre suelo oscuro. En el capítulo claro el motivo va en tinta,
   igual que en un impreso. Por lo mismo el botón primario pasa a tinta maciza:
   un relleno turquesa sobre crema no se vería como una forma (1,04:1).

   LA ARITMÉTICA, CALCULADA:
     grafito  sobre crema  = 14,31:1  ✅ AAA
     crema-2  sobre crema  =  2,43:1  🔴 ⇒ los metadatos van en `--tinta-2` (5,74:1)
     turquesa sobre crema  =  1,04:1  🔴 ⇒ ver arriba

   ⚠️ SI EL NAVEGADOR NO TIENE `color-mix`, las seis variables quedan inválidas
   en tiempo de cómputo, `background` cae a transparente y `color` hereda crema:
   es decir, DEGRADA AL ESTADO REVERTIDO, que es correcto. La caída es segura por
   construcción, no por suerte.                                                */
.sec--carta{
  --sw:1;
  --ch-suelo:color-mix(in srgb,var(--crema) calc(var(--sw) * 100%),var(--grafito));
  --ch-tinta:color-mix(in srgb,var(--grafito) calc(var(--sw) * 100%),var(--crema));
  --ch-meta:color-mix(in srgb,var(--tinta-2) calc(var(--sw) * 100%),var(--crema-2));
  --ch-linea:color-mix(in srgb,rgba(28,28,28,.18) calc(var(--sw) * 100%),var(--linea));
  --ch-linea-2:color-mix(in srgb,rgba(28,28,28,.32) calc(var(--sw) * 100%),var(--linea-2));
  --ch-acento:color-mix(in srgb,var(--grafito) calc(var(--sw) * 100%),var(--turquesa));
  --ch-plano:color-mix(in srgb,#EFDFCF calc(var(--sw) * 100%),var(--plano-1));
  /* ⚠️ El FONDO se mezcla contra `transparent`, no contra `--grafito`, y no es
     lo mismo: con `--sw:0` la sección queda transparente y vuelve a verse el
     degradado largo de `html` por debajo — o sea, el suelo único EXACTO de la
     r7b, no un parche de grafito plano encima de él. La reversión es limpia al
     píxel. (`--ch-suelo` sigue siendo un color opaco porque además hace de
     TINTA del botón primario, y un texto transparente no se lee.)             */
  --ch-fondo:color-mix(in srgb,var(--crema) calc(var(--sw) * 100%),transparent);
  --ch-filete:color-mix(in srgb,var(--linea-2) calc(var(--sw) * 100%),transparent);
  background:var(--ch-fondo);
  color:var(--ch-tinta);
  /* CORTE DURO de 0 px con un filete de 1 px. Nada de degradado de 120 px entre
     grafito y crema: un desvanecido lee como suciedad —y como la «banda» que
     Diego rechazó—; un corte lee como página nueva.                           */
  border-block:1px solid var(--ch-filete);
}
.sec--carta .sec__et,.sec--carta .nota,.sec--carta .fuente,
.sec--carta .fam__r,.sec--carta .fam__c,.sec--carta .fam__peek,
.sec--carta .carta__d,.sec--carta .sups__h,.sec--carta .carta__sup{ color:var(--ch-meta) }
.sec--carta .h2,.sec--carta .fam__n,.sec--carta .fam__ver,
.sec--carta .carta__n,.sec--carta .carta__p,.sec--carta .com__h{ color:var(--ch-tinta) }
.sec--carta .fams,.sec--carta .fam,.sec--carta .fam__cuerpo,
.sec--carta .com__caja,.sec--carta .fuentes{ border-color:var(--ch-linea) }
.sec--carta .carta__row{ border-bottom-color:var(--ch-linea-2) }
.sec--carta .fam__cuerpo,.sec--carta .com__caja{ background:var(--ch-plano); box-shadow:none }
/* El motivo, en tinta. Mismas medidas: 3 × 14 px, plano, sin radio, sin sombra. */
.sec--carta .banda,.sec--carta .banda--fila{ background:var(--ch-acento) }
.sec--carta .fam__ver svg,.sec--carta .fuentes__cab svg{ fill:var(--ch-acento) }
.sec--carta .btn--sec{ border-color:var(--ch-linea-2); color:var(--ch-tinta) }
.sec--carta .btn--pri{ background:var(--ch-acento); color:var(--ch-suelo) }
.sec--carta .btn--pri::before{ background:var(--ch-suelo) }
.sec--carta .pick{ border-color:var(--ch-linea-2); color:var(--ch-tinta) }
.sec--carta .pick.is-on{ background:var(--ch-acento); border-color:var(--ch-acento); color:var(--ch-suelo) }
/* 🔴 2026-08-17 · TEXTO INVISIBLE, MEDIDO EN 1,00:1. Esta regla conmutaba el
   FONDO del pie con `--sw` y dejaba atrás el `color`, que sigue siendo
   `var(--crema)` en la regla base (línea ~1452). Con `--sw:1` —que es lo que
   vale aquí— el fondo se vuelve crema y el texto crema se queda encima: cuatro
   bloques de letra que ocupan sitio y no se ven, diciendo justo lo que un
   cliente querría leer («No están en la carta de esta página: pregúntanos»).
   El arreglo usa el interruptor que ya existe y no inventa uno nuevo:
   `--ch-tinta` ES `color-mix(grafito · --sw · crema)`, o sea grafito sobre el
   plano claro y crema en cuanto alguien accione el interruptor de reversión
   nº 2 (`.sec--carta{--sw:0}`). El plano oscuro NO se toca: con `--sw:0` esta
   línea devuelve exactamente el `var(--crema)` de la regla base. Y sólo afecta
   a `.sec--carta`: cualquier `.remate__pie` fuera de la carta sigue igual. */
.sec--carta .remate__pie{
  background:color-mix(in srgb,rgba(247,233,219,.92) calc(var(--sw) * 100%),rgba(28,28,28,.86));
  color:var(--ch-tinta);
}
.sec--carta :focus-visible{ outline-color:var(--ch-acento) }
@media (hover:hover) and (pointer:fine){
  .sec--carta .fam__cab:hover{ background:rgba(28,28,28,.05) }
  .sec--carta .btn--sec:hover{ border-color:var(--ch-tinta); background:rgba(28,28,28,.05) }
  .sec--carta .pick:hover{ border-color:var(--ch-tinta) }
}

/* ⭐ r9 · LA CABECERA DE LA CARTA, SIN LAS DOS FOTOS ENORMES ════════════════
   Diego: «¿qué hacen esas dos fotos enormes ahí? nada de fotos grandes porque
   cansan la vista». Las dos piezas de 420 × 360 estaban ahí para tapar 700 px
   de crema vacía — o sea, para arreglar un problema de maqueta gastando la
   vista del visitante.
   El arreglo bueno es que no haya hueco: un mástil de dos columnas, titular a
   la izquierda y la comanda a la derecha, en vez de un titular solo a lo ancho
   de 1.440. La cabecera pasa de ocupar una pantalla a ocupar su altura, así que
   la primera fila de platos entra en la misma pantalla que el título.
   La fotografía de esta sección son las 12 placas de familia, a 120 px, cada
   una pegada a los platos que enseña. En una carta la foto va CON el plato.   */
.cartaCab{ display:grid; gap:var(--s5); min-width:0 }
.cartaCab__t{ display:grid; gap:var(--s5); min-width:0 }
.cartaCab__aparte{ display:grid; gap:var(--s3); align-content:center; min-width:0 }
@media (min-width:900px){
  .cartaCab{
    grid-template-columns:minmax(0,1fr) minmax(0,340px);
    gap:var(--s6); align-items:center;
  }
  /* Un titular centrado dentro de una columna, con una caja alineada a la
     izquierda al lado, se lee como dos maquetas distintas. En un mástil de dos
     columnas los dos bloques arrancan en el mismo tipo de eje.               */
  .cartaCab .sec__cab{ text-align:left; justify-items:start; margin-inline:0 }
}

.com__caja{
  border:1px solid var(--linea); border-radius:var(--r-control);
  background:var(--plano-1); box-shadow:var(--filo);
  padding:var(--s3);
  display:grid; gap:var(--s2); align-content:center; text-align:left;
}
.com__h{ font-size:var(--t-meta); font-weight:700; letter-spacing:var(--tr-meta); text-transform:uppercase }
.sec__cuerpo--centro{ justify-items:center; text-align:center }
.sec__cuerpo--centro > *{ width:100%; max-width:var(--medida-txt) }

.carta{ margin-block:var(--vacio-max); width:100%; min-width:0 }
.fams{ display:grid; gap:0; border-top:1px solid var(--linea) }
.fam{ border-bottom:1px solid var(--linea) }

/* ⚠️ EL PADDING VERTICAL VIVE EN `.fam__txt`, NO AQUÍ, y es lo que hace que la
   miniatura TOQUE LOS DOS FILETES de la fila (0 px de suelo arriba y abajo). Su
   vecino es texto por la derecha y una línea por arriba y por abajo: nunca
   grafito en tres lados.                                                        */
.fam__cab{
  position:relative;
  display:grid;
  grid-template-columns:var(--placa-w) minmax(0,1fr);
  column-gap:var(--s3);
  padding-inline:var(--gutter);
  min-height:var(--fila-h,var(--fila-S));
  cursor:pointer; list-style:none; align-items:stretch;
  border-radius:var(--r-control);
  transition:background-color 200ms var(--ease-out),transform 140ms var(--ease-out);
}
@media (max-width:399px){ .fam__cab{ column-gap:var(--s2) } }
.fam__cab::-webkit-details-marker{ display:none }
/* Las cuatro alturas de fila. Las escribe UN DATO DEL NEGOCIO —cuántos platos
   hay dentro—, no una decisión de gusto, y por eso las diez filas se ven
   distintas entre sí sin que nadie elija nada.                                  */
.fam--L{ --fila-h:var(--fila-L) }
.fam--M{ --fila-h:var(--fila-M) }
.fam--S{ --fila-h:var(--fila-S) }
/* ⭐ RETIRADA · AQUÍ VIVÍA LA FILA Ø (`fam--O`), 2026-08-03 → 2026-08-24.
   QUÉ ERA: la variante de fila de la carta para una familia de la que NO
   teníamos fotografía propia. Sin raíl de imagen (`grid-template-columns` de
   una sola pista), con el texto arrancando en el BORDE IZQUIERDO de la fila en
   vez de a 120 px, en dos líneas en vez de tres, y midiendo 72 px contra los
   92–132 de sus hermanas.
   POR QUÉ EXISTIÓ: porque la alternativa —la «placa-ÍNDICE» de la r7— dejaba un
   hueco de 320 × 310 px donde iba la foto, y un hueco no se lee como una
   decisión: se lee como una foto que no ha cargado. La fila Ø decía lo mismo
   siendo visiblemente otra clase de entrada, sin una sola palabra en pantalla
   —ni recuadro, ni cifra, ni «FOTO»—: aquí todavía no tenemos foto nuestra.
   POR QUÉ DESAPARECE: el 2026-08-24 SOPAS recibió su fotografía (Pere: «añade
   la foto de la sopa para la seccion de sopas de la carta para que se vea tal y
   como las otras fotos de la carta») y pasó a `fam--S`. Era la última que la
   usaba —Pescados la había dejado el 22-08—, así que las diez familias de la
   carta llevan ya fotografía del negocio y la variante se quedó sin dueño: CSS
   muerto, que es lo que `site-audit [css]` caza.
   ⚠️ NO SE REPONE «por si acaso». Si algún día entra una familia sin foto, se
   recupera de aquí (git) y se vuelve a leer este párrafo entero: lo que hacía
   que funcionara no eran las reglas, era que la fila se viera distinta a la
   primera. Mismo registro que `r8c`, `r9b` y `r9c` en este mismo fichero. */
.fam__placa{
  grid-column:1; grid-row:1;
  position:relative; display:block; overflow:hidden;
  width:var(--placa-w); align-self:stretch;
  border-radius:var(--r-pieza);
}
.fam__im{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  /* A11 · la placa se abre. Escala DENTRO de su propia caja: la caja no cambia
     de tamaño, así que hay CERO desplazamiento de maqueta. La salida (180 ms)
     más rápida que la entrada (280).                                           */
  transform-origin:50% 50%;
  transition:transform 180ms var(--ease-out),opacity 180ms var(--ease-out);
}
.fam[open] > .fam__cab .fam__im{ transform:scale(1.06); transition-duration:280ms }

/* ⭐ EL BLOQUE DE TEXTO VA ARRIBA Y APRETADO: tres filas `auto`, `gap: 6px`, y
   `align-content: start`. `align-content: space-between` DESAPARECE — era lo que
   repartía tres elementos por 345 px de vacío en vez de quitar el vacío.
   La aritmética publicada de la fila L: 24 (padding) + 22 (nombre 17/1,3) + 6 +
   56,6 (3 líneas de 13/1,45) + 6 + 15 (pie 11/1,35) = 129,6 ⇒ fila de 132.
   ⚠️ EL ORDEN DEL DOM NO ES EL ORDEN VISUAL, y va a propósito: menu-check.py lee
   el primer «· N » del texto del <summary> para cruzarlo con las filas que hay
   dentro, y la línea de avance de Pizzas contiene «· 4 Stagioni». Con el
   recuento ANTES en el DOM, lo primero que encuentra es «· 38 platos», que es la
   afirmación que la fila hace de verdad. Las tres cajas van colocadas a mano en
   su fila.                                                                      */
.fam__txt{
  grid-column:2; grid-row:1; min-width:0;
  display:grid; grid-template-rows:auto auto auto;
  align-content:start;
  row-gap:var(--s1);
  padding-block:var(--s2);
}
/* ⚠️ EN UN MÓVIL EL NOMBRE Y EL RANGO NO COMPARTEN LÍNEA, y está medido: a 390 px
   la columna de texto mide 179 px y «13,00 – 17,90 €» no se puede partir (88 px),
   así que a «Entrantes y tablas» le quedaban 91 px y se rompía en cuatro líneas
   — la fila crecía por encima de su placa y la escalera de tres alturas dejaba
   de existir. Apilados, el bloque de texto cabe dentro de la placa en las diez
   filas. Por la misma razón el recuento se calla por debajo de 560: el control
   ya dice el número, y decirlo dos veces costaba una línea entera.             */
.fam__alto{ grid-row:1; display:grid; gap:2px; min-width:0 }
.fam__bajo{ grid-row:3; display:flex; flex-wrap:wrap; align-items:center; gap:var(--s2) var(--s3); min-width:0 }
.fam__ver{ margin-left:auto }
@media (max-width:559px){ .fam__c{ display:none } }
@media (min-width:700px){
  .fam__alto{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--s3) }
}
/* ⚠️ 17 px / 1,3 = UNA CAJA DE LÍNEA DE 22 px, y ése es el número del que cuelga
   toda la escalera de filas de la r7b (132 / 112 / 92 / 72). Con los 30 px de la
   r7 la caja medía 34 y la fila L no podía bajar de 145. La jerarquía la sigue
   dando la ITÁLICA de Vollkorn contra el grotesco de todo lo demás, no el
   cuerpo. La cara no se reabre; el tamaño lo escribe la aritmética de la fila.  */
.fam__n{
  font-family:var(--display); font-weight:500; font-style:italic;
  font-size:17px; line-height:1.3;
  letter-spacing:var(--tr-h2); color:var(--crema); min-width:0;
  overflow-wrap:break-word;
}
@media (min-width:900px){ .fam__n{ font-size:19px; line-height:1.16 } }
.fam__r{
  font-size:var(--t-meta); font-weight:700; color:var(--crema-2);
  white-space:nowrap; font-variant-numeric:lining-nums tabular-nums;
}
.fam__c{ font-size:var(--t-meta); letter-spacing:var(--tr-meta); color:var(--crema-2); white-space:nowrap }
/* ⭐ LA LÍNEA DE AVANCE. Son sus nombres de plato, en su orden, generados desde
   el mismo carta.json que produce la lista y recortados con line-clamp. Es el
   contenido más persuasivo que existe en una web de restaurante, cuesta cero, y
   hace que las diez filas se vean distintas entre sí — lo contrario de un muro
   de teselas. `aria-hidden` porque el mismo texto está palabra por palabra
   dentro del cuerpo abierto, y menu-check.py no la ve porque cuenta
   `.carta__row`.                                                                */
/* ⭐ Y AHORA CORRE EL ANCHO ENTERO DE LA COLUMNA DE TEXTO — 894 px a 1440. Ése
   ERA el hueco de 700 × 200 px de la r7, y se llena con SUS PROPIOS NOMBRES DE
   PLATO. El recorte es 3 / 2 / 1 líneas a CUALQUIER ancho: es lo que fija las
   alturas 132 / 112 / 92 y lo que impide que la fila crezca en escritorio.      */
.fam__peek{
  grid-row:2;
  font-size:var(--t-meta); line-height:1.45; letter-spacing:var(--tr-meta);
  color:var(--crema-2); min-width:0;
  display:-webkit-box; -webkit-box-orient:vertical; overflow:hidden;
  -webkit-line-clamp:3;
}
.fam--M .fam__peek{ -webkit-line-clamp:2 }
.fam--S .fam__peek{ -webkit-line-clamp:1 }
/* ⭐ EL CONTROL QUE DICE QUE LA FILA SE ABRE. El defecto abierto de la r6 era
   que nada lo indicaba: un <details> sin afordancia es un callejón. Es texto de
   control —dice el gesto y el número a la vez—, con objetivo táctil ≥44 px, y
   el chevron gira 200/140 ms. La ALTURA del <details> no se anima jamás
   (::details-content mide 0 px en los dos estados y la carta se vuelve
   inalcanzable — el casi-fallo de ZAWA).                                        */
/* El objetivo táctil no es este texto: es el <summary> entero, que mide entre 72
   y 132 px de alto y ocupa el ancho de la página. Esto es la afordancia. */
.fam__ver{
  display:inline-flex; align-items:center; gap:.45rem;
  min-height:15px;
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  line-height:1.35;
  text-transform:uppercase; color:var(--crema); white-space:nowrap;
}
.fam__ver svg{ width:12px; height:12px; fill:var(--turquesa); transition:transform 140ms var(--ease-out) }
.fam[open] > .fam__cab .fam__ver svg{ transform:rotate(180deg); transition-duration:200ms }
/* A4 · «se enciende»: la banda sólo existe en la familia ABIERTA. */
.banda--fila{
  position:absolute; left:0; top:0; bottom:0; width:3px; height:auto;
  background:var(--turquesa);
  transform:scaleY(0); transform-origin:top;
  transition:transform 140ms var(--ease-out);
}
.fam[open] > .fam__cab .banda--fila{ transform:scaleY(1); transition-duration:200ms }
@media (hover:hover) and (pointer:fine){
  .fam__cab:hover{ background:rgba(247,233,219,.04) }
  .fam:hover{ border-bottom-color:var(--linea-2) }
}
/* A12 · PULSACIÓN DE FILA. `.97` sobre una fila de 1.032 px se ve como un salto;
   `.99` no. 0 ms a la ida, 140 a la vuelta. Y va sobre la FILA ENTERA, no sobre
   la placa: hasta ahora las diez filas reaccionaban igual y no había ninguna
   confirmación visible de cuál habías tocado.                                   */
.fam__cab:active{ transform:scale(.99); transition-duration:140ms }

/* EL CUERPO ABIERTO VA SOBRE EL PLANO ELEVADO: es un documento, no una banda.
   ⭐ A partir de 760 px se compone a DOS COLUMNAS: Pizzas pasa de 2.432 px de
   alto a 1.216. El contrato de fila no se toca y menu-check sigue contando 100. */
.fam__cuerpo{
  background:var(--plano-1);
  box-shadow:var(--filo);
  border-block:1px solid var(--linea);
  padding:var(--s4) var(--gutter);
}

/* 9.4 · SUBGRID: los precios forman UNA sola columna a cualquier ancho.
   ⚠️ CUATRO PISTAS, NO TRES: la tercera es el CANALÓN entre el precio y el «+». */
.carta__list{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(var(--col-precio),max-content) var(--col-canal) var(--col-pick);
  align-content:start;
}
.js .carta__list{ --col-pick:44px; --col-canal:var(--s2) }
@media (min-width:760px){
  .carta__list{
    grid-template-columns:
      minmax(0,1fr) minmax(var(--col-precio),max-content) var(--col-canal) var(--col-pick)
      var(--s5)
      minmax(0,1fr) minmax(var(--col-precio),max-content) var(--col-canal) var(--col-pick);
  }
  .carta__row:nth-child(odd){ grid-column:1 / span 4 }
  .carta__row:nth-child(even){ grid-column:6 / span 4 }
}
.carta__row{
  display:grid; grid-column:1 / span 4; grid-template-columns:subgrid;
  align-items:baseline; padding-block:.55rem; min-width:0;
  border-bottom:1px dotted var(--linea-2);
}
.carta__list > .carta__row:last-child{ border-bottom:0 }
@supports not (grid-template-columns: subgrid){
  .carta__row{ grid-template-columns:minmax(0,1fr) minmax(var(--col-precio),max-content) var(--col-canal) var(--col-pick) }
}
.carta__n{ display:block; min-width:0; padding-right:.6rem; color:var(--crema) }
.carta__d{
  display:block; margin-top:.1rem;
  font-size:var(--t-meta); line-height:1.45; letter-spacing:var(--tr-meta); color:var(--crema-2);
}
.carta__d:empty{ display:none }   /* 30 filas van vacías: su carta no dice más */
.carta__sup{
  display:inline-block; margin-left:.4rem;
  font-size:var(--t-micro); letter-spacing:var(--tr-micro); text-transform:uppercase;
  color:var(--crema-2); border:1px solid var(--linea); padding:.1rem .35rem;
  border-radius:var(--r-control);
}
.carta__p{
  font-size:var(--t-body); font-weight:600; text-align:right; white-space:nowrap;
  font-variant-numeric:lining-nums tabular-nums; color:var(--crema);
}
.sups{ display:grid; gap:var(--s2) }
.sups__h{ font-size:var(--t-meta); font-weight:700; letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema-2) }

/* ⭐ EL REMATE DE LA CARTA · una fila con UNA altura: la parrillada a la
   izquierda y, a su lado, los suplementos, la nota de precios y la acción.
   El pie de esta foto es el sitio donde la advertencia se sostiene sola —antes
   decía «esto TAMPOCO está en la carta de arriba» a 3.000 px de scroll de su
   antecedente— y de paso impide que el final de la sección sea medio kilómetro
   de tipografía sin una sola fotografía.                                        */
.remate{
  display:grid; gap:var(--s4); min-width:0; align-items:stretch;
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:700px){
  .remate{ grid-template-columns:minmax(0,1fr) minmax(0,1.1fr); gap:var(--s5) }
}
.remate__m{
  position:relative; overflow:hidden; min-height:220px; min-width:0;
  border-radius:var(--r-pieza);
}
.remate__m > img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover }
.remate__pie{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  background:rgba(28,28,28,.86);
  padding:var(--s2) var(--s3);
  font-size:var(--t-micro); line-height:1.4; letter-spacing:var(--tr-meta);
  color:var(--crema);
}
/* ⚠️ `align-content: start`, NUNCA `space-between`. Con `space-between` el
   sobrante de la fila —la foto declara 220 px de mínimo y esta columna suma
   ~184— se repartía entre los huecos y dejaba dos bandas de suelo desnudo
   dentro del propio bloque. Es el mismo defecto que el índice tenía a lo grande:
   repartir el texto por el vacío en vez de quitar el vacío.                    */
.remate__txt{ display:grid; gap:var(--s3); align-content:start; min-width:0 }

/* el «+» de cada fila — lo inyecta main.js sobre las filas que ya existen */
.pick{
  grid-column:4; justify-self:end; align-self:center;
  width:44px; height:44px;
  border:1px solid var(--linea-2); color:var(--crema); cursor:pointer;
  border-radius:var(--r-control); box-shadow:var(--sombra-1);
  display:flex; align-items:center; justify-content:center;
  font-size:16px; font-weight:700; font-variant-numeric:lining-nums;
  transition:transform 200ms var(--ease-out), border-color 200ms var(--ease-out),
             background-color 200ms var(--ease-out), color 200ms var(--ease-out);
}
.pick:active{ transform:scale(.97); transition-duration:140ms }
.pick.is-on{ background:var(--crema); border-color:var(--crema); color:var(--grafito) }
@media (hover:hover) and (pointer:fine){ .pick:hover{ border-color:var(--crema) } }

/* ══ P3 · EL DESFILE ═════════════════════════════════════════════════════════
   La cinta de 44 px que ocupa EXACTAMENTE la costura entre el capítulo claro y
   el oscuro — que es donde el render medía una banda negra muerta. La junta pasa
   a ser contacto (4) + cinta (44) + contacto (4) en vez de un valor intermedio.
   Lleva un DATO, no un adorno: sus cien nombres de plato, los mismos que están
   dentro de la carta. Contenido duplicado y `translateX(0 → −50%)` ⇒ el bucle no
   salta. 38 s, `linear`: es lentísimo a propósito, no persigue el ojo.
   ⚠️ NO es un contenedor con scroll: es un `transform`. Por eso NO pelea con el
   `scroll-snap` de la pista que tiene justo debajo — la combinación prohibida en
   `06-diversity-guardrails` §6 es «marquesina CON SCROLL + scroll-snap», y aquí
   no hay ni un píxel de scroll. `pointer-events:none`, `aria-hidden`.
   G5 · los dos degradados de 48 px impiden que los nombres se corten en seco.  */
.desfile{
  position:relative; overflow:hidden;
  height:44px; display:flex; align-items:center;
  border-block:1px solid var(--linea);
  pointer-events:none; user-select:none;
}
.desfile__t{
  display:flex; flex:0 0 auto; width:max-content;
  animation:desfile 38s linear infinite;
}
@keyframes desfile{ from{ transform:translateX(0) } to{ transform:translateX(-50%) } }
.desfile__g{
  flex:0 0 auto; padding-right:0;
  font-size:var(--t-micro); font-weight:600; line-height:1;
  letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema-2);
  white-space:nowrap;
}
.desfile::before,.desfile::after{
  content:""; position:absolute; top:0; bottom:0; width:48px; z-index:2;
  pointer-events:none;
}
.desfile::before{ left:0; background:linear-gradient(90deg,var(--grafito),transparent) }
.desfile::after{ right:0; background:linear-gradient(270deg,var(--grafito),transparent) }
@media (prefers-reduced-motion: reduce){
  /* No se apaga: se PARA. Lo que queda es una fila de nombres de plato legible,
     que es información, no movimiento (apple-design §14).                     */
  .desfile__t{ animation-play-state:paused }
}

/* ══ FORMA 4 · EL PASE · §4 DESDE 0 CADA DÍA · ⭐ LA FIRMA ════════════════════
   ⭐ r9 · UNA SECUENCIA, NO CUATRO MARCOS. Veredicto de Diego (2026-08-03):
   «qué cojones son esos 4 vídeos ahí tirados. como si fuesen marcos, odio eso,
   los vídeos deben de tener alguna animación para pasar entre ellos».
   La r8 pintaba cuatro teselas quietas, una al lado de otra. Ahora hay UNA
   escena y los cuatro pasos se relevan dentro de ella:

     · el que ENTRA barre de derecha a izquierda — clip-path 100% → 0 en 760 ms
     · y a la vez baja de escala 1,06 → 1 en 1.100 ms, así que el barrido
       destapa una imagen que además se está asentando: dos movimientos con
       distinta duración leen como un plano de cine, no como un carrusel
     · el que SALE se queda ENTERO debajo hasta que el barrido acaba. Nunca se
       ve el fondo entre dos clips — eso era exactamente lo que hacía que
       parecieran marcos pegados a un fondo
     · el rótulo entra por debajo con su número, 520 ms después

   🔴 UN SOLO DECODIFICADOR, la regla cara del expediente: el saliente se pausa
   ANTES de que arranque el entrante. La sensación es de cuatro vídeos; el coste
   es el de uno.
   El estado de reposo es VISIBLE: sin JavaScript se ve el primer paso a tamaño
   completo con su fotograma real, y el índice sigue siendo cuatro enlaces.     */
.pase{ min-width:0 }
.pase__escena{
  display:grid; gap:var(--s4); min-width:0; align-items:center;
}
/* ⚠️ 2026-08-03 · LA ESCENA SE SALÍA DEL MARCO Y DEJABA MEDIO PANEL MUERTO.
   Medido en la captura de 1.440: el vídeo empezaba en x=0 —sin margen de
   página, porque `.pase` no colgaba de `.sec__in`— y a la derecha, debajo de
   cuatro filas de 66 px, quedaban ~350 px de negro.
   Las dos cosas se arreglan con la misma decisión: el TITULAR de la sección se
   mete DENTRO de la escena, en la columna derecha, encima del índice. Así la
   columna se llena con lo que ya había que leer, y la sección se lee como una
   sola composición en vez de un título centrado con dos cosas debajo.        */
@media (min-width:900px){
  .pase__escena{
    grid-template-columns:minmax(0,440px) minmax(0,1fr);
    grid-template-rows:auto auto;
    column-gap:var(--s6); row-gap:var(--s5);
    align-content:center;
  }
  /* `.sec__cab` viene con `justify-items:center`, `text-align:center` y
     `margin-inline:auto`: dentro de una columna que además lleva un índice
     alineado a la izquierda, eso deja dos ejes distintos en el mismo panel.
     Aquí manda el eje del índice.                                            */
  .pase__cab{
    grid-column:2; grid-row:1; align-self:end;
    justify-items:start; text-align:left; margin-inline:0; max-width:none;
  }
  .pase__cab .cita,.pase__cab .cita__t,.pase__cab .cita__f{ text-align:left }
  .pase__vista{ grid-column:1; grid-row:1 / span 2 }
  .pase__idx{ grid-column:2; grid-row:2; align-self:start }
}
.pase__vista{
  position:relative; overflow:hidden; min-width:0;
  aspect-ratio:4 / 5;
  border-radius:var(--r-pieza);
  background:var(--plano-1);
  box-shadow:var(--filo),var(--sombra-2);
}
@media (min-width:560px){ .pase__vista{ aspect-ratio:1 / 1 } }
@media (min-width:900px){ .pase__vista{ aspect-ratio:9 / 13 } }

/* El estado de reposo de una capa que no está en pantalla NO lleva transición:
   así, cuando se le retira `.se-va`, desaparece de golpe por debajo del clip
   que ya la ha tapado, en vez de deshacer el barrido hacia atrás.              */
.pase__cap{
  position:absolute; inset:0; margin:0; z-index:1;
  clip-path:inset(0 0 0 100%);
  transform:scale(1.06);
}
.pase__cap.is-on{
  z-index:3; clip-path:inset(0); transform:scale(1);
  transition:clip-path 760ms var(--ease-out), transform 1100ms var(--ease-out);
}
.pase__cap.se-va{
  z-index:2; clip-path:inset(0); transform:scale(1.03);
  transition:transform 1100ms var(--ease-out);
}
.pase__cap > img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover }

.pase__rotulo{
  position:absolute; left:0; right:0; bottom:0; z-index:4;
  display:flex; align-items:baseline; gap:var(--s2);
  margin:0; padding:var(--s6) var(--s3) var(--s3);
  background:linear-gradient(180deg,rgba(20,20,22,0) 0%,rgba(20,20,22,.72) 62%,rgba(20,20,22,.88) 100%);
  font-size:var(--t-micro); font-weight:600; line-height:1.35;
  letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema);
}
.pase__rn{
  color:var(--turquesa); font-weight:700; flex:0 0 auto;
  font-variant-numeric:lining-nums tabular-nums;
}
.pase__rl{ min-width:0 }
.pase__rotulo.cambia{ animation:paseRotulo 520ms var(--ease-out) both }
@keyframes paseRotulo{
  from{ opacity:0; transform:translateY(12px) }
  to{ opacity:1; transform:none }
}

/* El índice. Cada fila es un paso y su barra se llena EN TIEMPO REAL mientras
   ese paso suena: es a la vez el reloj de la secuencia y la afordancia de que
   se puede saltar. Al salir de pantalla la barra se pausa, no se reinicia.     */
.pase__idx{ display:grid; gap:2px; list-style:none; margin:0; padding:0; min-width:0 }
.pasoB{
  width:100%; min-width:0;
  display:grid; grid-template-columns:auto minmax(0,1fr); gap:8px var(--s3);
  align-items:center; text-align:left;
  background:none; border:0; border-radius:var(--r-control);
  padding:var(--s3);
  color:var(--crema-2); font:inherit; cursor:pointer;
  transition:background-color 260ms var(--ease-out), color 260ms var(--ease-out);
}
.pasoB__n{
  font-size:var(--t-micro); font-weight:700; letter-spacing:var(--tr-micro);
  color:var(--turquesa); font-variant-numeric:lining-nums tabular-nums;
}
.pasoB__l{
  font-size:var(--t-micro); font-weight:600; line-height:1.35; min-width:0;
  letter-spacing:var(--tr-micro); text-transform:uppercase;
}
.pasoB__barra{
  grid-column:1 / -1; height:2px; border-radius:2px;
  background:var(--linea); overflow:hidden;
}
.pasoB__fill{
  display:block; height:100%; width:100%;
  background:var(--turquesa); transform:scaleX(0); transform-origin:left;
}
.pasoB.is-on{ background:var(--plano-1); color:var(--crema) }
.pasoB.ya .pasoB__fill{ transform:scaleX(1); opacity:.34 }
@media (hover:hover) and (pointer:fine){
  .pasoB:hover{ background:var(--plano-1); color:var(--crema) }
}
.pasoB:active{ transform:scale(.99); transition-duration:140ms }
@media (prefers-reduced-motion: no-preference){
  .pasoB.is-on .pasoB__fill{ animation:paseBarra var(--pase-t,5200ms) linear both }
  .pase__idx:not(.corre) .pasoB.is-on .pasoB__fill{ animation-play-state:paused }
  @keyframes paseBarra{ from{ transform:scaleX(0) } to{ transform:scaleX(1) } }
}
/* Con reduced-motion no hay avance automático (lo corta el JS), así que la
   barra del paso activo se queda llena: es estado, no cuenta atrás.            */
@media (prefers-reduced-motion: reduce){
  .pasoB.is-on .pasoB__fill{ transform:scaleX(1) }
}

/* ⭐ r9 · `.regla` (el filete del 772) SE HA IDO CON SU MARCADO. `.cifra__n` y
   `.cifra__lbl` se quedan: los usa la nota de la sección de reseñas.          */
.cifra__n{
  font-size:var(--t-figure); font-weight:700; line-height:1;
  letter-spacing:var(--tr-figure); color:var(--turquesa);
  font-variant-numeric:lining-nums tabular-nums; margin-block:-.06em;
}
.cifra__lbl{ font-size:var(--t-meta); letter-spacing:var(--tr-meta); color:var(--crema-2) }

/* ══ FORMA 5 · EL CARTEL · §5 ENTRA NEL MONDO DA MARC ════════════════════════
   ⭐ r7b · EL DÍPTICO PASA A TRÍPTICO: `1.15fr / 1fr / 1fr`. La media única de
   757 px —la más grande de la web después de la banda del horno, y la que corría
   a 1,05× de su fichero— se parte en DOS de 421,6 px que se tocan a 12 px: el clip
   de su comedor y la pared de cuadros italianos que hay dentro de ese mismo
   comedor. Dos vistas del mismo sitio, no dos fotos cualesquiera.
   `--cartel-h` baja de clamp(420,50vw,720) a clamp(300,34vw,480) ⇒ −240 px.
   Las palabras siguen sobre el plano elevado PEGADAS a la media: costura de 12 px,
   cero suelo de página entre ellas. Receta: Esens `.llevar__wall`.
   ⚠️ Las dos medias miden EXACTAMENTE lo mismo en la misma fila (`lopsided`).   */
/* 🔴 2026-08-17 · LA FILA NO CABÍA Y RECORTABA SU PROPIO TÍTULO.
   La fila valía `var(--cartel-h)` a secas — un alto FIJO. Dentro, la segunda
   columna es media + panel de servicios, y el panel es lo que sobra: a 820 px
   de ventana `--cartel-h` está pegada a su suelo de 300, la media se lleva 216,5
   por su `aspect-ratio` y al panel le quedaban 79,5 px para 177 de contenido.
   Con `align-content:center` + `overflow:hidden` eso recorta por los dos
   extremos: «En nuestra casa» se pintaba 31 px POR ENCIMA de la caja de su
   padre —o sea sobre la fotografía— y `contrast-check` lo leyó en 1,09:1. A
   1440 pasaba lo mismo en pequeño (374 de fila para 407,8 de contenido).
   NO era un problema de color: el panel es `--plano-1` OPACO. Era una caja que
   mentía sobre lo que le cabía dentro.
   ⚠️ Y tampoco se arregla invirtiendo las filas de `.cartel__col` — lo probé y
   es peor: el panel deja de recortarse pero se SOLAPA 93,7 px con la media, y
   como `.cartel__m` es `position:relative` la fotografía se pinta ENCIMA del
   panel. Mismo texto ilegible, otro mecanismo.
   El arreglo es que la fila pueda crecer cuando su contenido no cabe:
   `minmax(var(--cartel-h), auto)`. Cuando cabe —que es casi siempre— la fila
   mide exactamente `--cartel-h` y no cambia NADA: ni columnas, ni costura, ni
   solape, ni tipografía, ni el `aspect-ratio` que protege a la media del 1,35×.
   Cuando no cabe, crece lo justo y `.cartel__m--a`, que no lleva proporción,
   estira y recorta con su `object-fit:cover`. Es la misma regla que esta hoja
   ya aplica a `.pila`: «el alto de cada cita LO ESCRIBE SU TEXTO».            */
.cartel{
  display:grid; gap:var(--seam);
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-template-rows:minmax(var(--cartel-h),auto) auto;
  min-width:0;
}
.cartel__m{
  position:relative; overflow:hidden; grid-row:1; min-width:0;
  border-radius:var(--r-pieza);
}
.cartel__m--a{ grid-column:1; grid-row:1 }
.cartel__m > img,.cartel__m > video{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}
/* ⚠️ LA SEGUNDA COLUMNA NO ES UNA MEDIA SOLA: es una media con su propia
   proporción MÁS un plano elevado que ocupa exactamente el resto de la fila. La
   media (`ig-pared-cuadros-italia`, 720 × 382) no puede estirarse a 480 px de
   alto sin ampliarse a 1,88× —y su recorte no puede crecer, porque justo encima
   y debajo hay dos fotografías familiares—, así que la caja adopta SU
   proporción con `aspect-ratio` y el panel se come el sobrante.
   ⚠️ El `aspect-ratio` es seguro aquí porque esta caja NO lleva `min-height`:
   su ancho lo fija la pista de la rejilla y la altura se deriva de él. Poner
   las dos cosas es lo que hace que una caja saque su ANCHO de su alto.        */
.cartel__col{
  grid-column:2; grid-row:1; min-width:0;
  display:grid; grid-template-rows:auto minmax(0,1fr); gap:var(--seam);
}
.cartel__m--b{ grid-column:1; grid-row:1; aspect-ratio:720 / 382 }
.cartel__servs{
  grid-row:2; min-width:0; overflow:hidden;
  background:var(--plano-1); box-shadow:var(--filo);
  border-radius:var(--r-control);
  padding:var(--s3);
  display:grid; gap:var(--s2); align-content:center;
}
/* UNA columna siempre: dentro de un panel de 427 px, dos columnas parten
   «Accesible para personas con movilidad reducida» en cuatro líneas.          */
.cartel__servs .servs{ grid-template-columns:minmax(0,1fr) }
.cartel__servs .serv{ font-size:var(--t-micro); line-height:1.35; letter-spacing:var(--tr-meta) }
.cartel__txt{
  grid-column:1 / -1; grid-row:2; min-width:0;
  background:var(--plano-1);
  border-radius:var(--r-control);
  box-shadow:var(--filo),var(--sombra-2);
  display:grid; gap:var(--s3); align-content:center;
  padding:var(--s4) var(--edge);
}
.cartel__sub{
  font-family:var(--display); font-weight:500; font-style:italic;
  font-size:var(--t-body); line-height:1.3; color:var(--crema-2);
}
@media (min-width:900px){
  .cartel{
    grid-template-columns:minmax(0,1.15fr) minmax(0,1fr) minmax(0,1fr);
    /* mismo `minmax` que la regla base, y por el mismo motivo (2026-08-17) */
    grid-template-rows:minmax(var(--cartel-h),auto);
  }
  .cartel__m--a{ grid-column:2; grid-row:1 }
  .cartel__col{ grid-column:3; grid-row:1 }
  /* ⭐ SOLAPE 2 · las palabras se apoyan ENCIMA del canto de la fotografía en vez
     de al lado. Una declaración, y es el segundo y último solape de la web: dos
     son un sistema, cinco son un desorden.                                      */
  .cartel__txt{
    grid-column:1; grid-row:1;
    position:relative; z-index:2;
    margin-right:calc(-1 * var(--solape-2));
    padding:var(--s4);
  }
}

/* ══ FORMA 6 · LA PILA · §6 LO QUE DICEN ═════════════════════════════════════
   Una cifra grande con su fuente y su fecha · tres citas literales apiladas a
   12 px · y un pie que dice de dónde salieron y cuándo. Estructura calcada de
   `#dicen` de Ozoa, que es la web que Diego ha señalado con el dedo.
   🔴 2026-08-22 · ESTA SECCIÓN YA NO LLEVA NI UNA MEDIA, POR ORDEN DE PERE:
   «te he dicho que quitaras la foto de abajo de las reseñas no que pusieras un
   video, no quiero ni fotos ni imagenes ahi». Se fueron las dos piezas —la
   banda del comedor (`.pila__sala`) y el clip de la sartén (`.pila__m`)— con
   todas sus reglas, para que no quede ningún selector apuntando a una clase que
   ya no existe. La decisión está declarada en el marcado con `data-no-image`,
   que es el mecanismo de este repo para «sin imagen a propósito»: NO se
   «arregla» en una ronda futura reponiendo una foto.
   ⭐ NO SON TRES TARJETAS: son UNA PILA. La costura de 12 px y el hecho de que la
   cifra cruce el canto superior son lo que las convierte en un solo objeto.
   El alto de cada cita LO ESCRIBE SU TEXTO (mínimo 96 px): la tercera es larga
   porque la clienta escribió mucho, y recortarla para cuadrar una rejilla sería
   reescribirla.                                                                */
.pila{
  display:grid; gap:var(--seam); min-width:0;
  grid-template-columns:minmax(0,1fr);
  justify-items:center;
}
/* ⚠️ 2026-08-03 · ESTE BLOQUE ESTABA AQUÍ ARRIBA Y NO SERVÍA DE NADA. Un
   `@media` NO añade especificidad: `.pila__cifra` dentro de la consulta y
   `.pila__cifra` fuera valen lo mismo (0,1,0), así que ganaba EL ÚLTIMO del
   fichero — que eran las reglas base. Resultado medido en Chrome real: a 1.440
   la nota salía centrada en vez de a la izquierda, la pila medía 702 px en vez
   de 928, y la columna derecha entera se quedaba en negro.
   Llevaba así desde la r8 y ningún comprobador lo vio, porque ninguno mira si
   una foto se ve. Lo vi yo en la captura. Ahora el bloque va DESPUÉS de las
   reglas base, que es donde tenía que estar.                                 */
.pila__cifra{
  display:grid; gap:2px; justify-items:center; text-align:center;
  width:min(720px,100% - 2 * var(--edge));
  /* SOLAPE 3 · la cifra baja 20 px sobre el canto del primer plano. Es el
     tercero y último de la web: dos son un sistema, cinco son un desorden — y
     éste se lo gana porque es lo que ata la cifra a las citas.                 */
  margin-bottom:-20px; position:relative; z-index:2;
}
.pila__stack{
  display:grid; gap:var(--seam); min-width:0;
  width:min(720px,100% - 2 * var(--edge));
}
/* G6 · el plano de cada cita tiene canto: tres planos apilados se distinguen
   entre sí sin necesidad de una raya.                                          */
.dice{
  background:linear-gradient(180deg,#2A2A2E,#232327);
  box-shadow:var(--filo);
  border-radius:var(--r-control);
  padding:var(--s4) var(--s3);
  min-height:96px;
  display:grid; gap:var(--s2); align-content:center; min-width:0;
}
@media (max-width:559px){ .dice{ min-height:88px; padding:var(--s3) } }
.dice:first-child{ padding-top:calc(var(--s4) + 20px) }   /* sitio para la cifra */
/* ⚠️ `white-space: pre-line`: los saltos de línea de la tercera cita son SUYOS
   —dos republicadores independientes los conservan— y jamás se reflowean ni se
   sustituyen por un <br> inyectado en su texto.                                */
.dice__t{
  font-size:var(--t-body); line-height:1.55; color:var(--crema);
  white-space:pre-line; min-width:0;
}
.dice__f{
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}
/* 🔴 2026-08-22 · AQUÍ VIVÍAN `.pila__sala` (la banda del comedor) y, más
   abajo, `.pila__m` (el clip de la sartén). Las dos retiradas por orden de
   Pere; TODAS sus reglas se van con ellas —caja, alto, la media `absolute`,
   la colocación en la rejilla y las tres apariciones en el `reveal`— para que
   no quede ni un selector apuntando a una clase que ya no existe.        */
.pila__pie{
  display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap;
  width:min(720px,100% - 2 * var(--edge));
  font-size:var(--t-micro); line-height:1.45; letter-spacing:var(--tr-meta);
  color:var(--crema-2); margin-top:var(--s3);
}
/* ⭐ El único logotipo de esta sección es EL SUYO. La marca de Google no se
   dibuja nunca: no es nuestra y no la publicaríamos. La atribución es texto.  */
.pila__logo{ width:56px; height:auto; flex:0 0 auto }

/* ── LOS DOS ENLACES A GOOGLE · ⭐ 2026-08-26 ────────────────────────────────
   UNA sola clase para los dos, porque son el mismo objeto con dos destinos:
   arriba, junto a la cifra, VER la ficha (lo que hace comprobable el «4,3 ·
   772»); abajo, en la línea de atribución, ESCRIBIR una reseña.
   🔴 NI `.btn--pri` NI `.btn--sec`. El primario de esta web es «Reservar mesa»
   y un botón con caja aquí competiría con él a la misma altura visual. Es el
   patrón de enlace de texto que esta hoja ya usa en `.pie__social a` y en
   `.reserva__aparte a`: subrayado a 3 px, 44 px de alto de diana (WCAG 2.2
   AA · 2.5.8) y `:hover` GATEADO — sin la consulta se queda pegado al tocarlo
   en una pantalla táctil.
   `--crema` y no `--crema-2`: en el pie el texto de alrededor es `--crema-2` a
   11 px, así que el enlace tiene que separarse de él o no se lee como acción.
   ⚠️ `min-width:0` porque en `.pila__pie` es un hijo de flex y en `.pila__cifra`
   uno de grid: sin él su base es `auto` y a 320 px empuja la caja del padre.

   ⭐ MEDIDO EN CHROME REAL EL 2026-08-26, en reposo (reveals congelados: sin
   congelarlos se mide un 2,5 % de menos), con `Emulation.setDeviceMetricsOverride`
   y NO con `--window-size`, que Chrome recorta a 500 px de ancho mínimo. Doce
   anchuras — 320 · 390 · 500 · 820 · 900 · 914 · 960 · 1000 · 1024 · 1060 ·
   1200 · 1440 — y los TRES idiomas.

   🔴 LO QUE ESTA NOTA MIDE ES LA HOLGURA CONTRA EL CANTO DE LA VENTANA, que es
   donde estaba el fallo. La versión anterior de este comentario daba «9,9 px de
   holgura» a 900 px y era CIERTA —cadena italiana 206,1 px dentro de una pista
   de 216 px—, pero medía LA CADENA CONTRA LA PISTA y nunca LA PISTA CONTRA LA
   VENTANA: la pista nacía en x = 0,0 y cortaba glifos (el «4» del 4,3, la punta
   de la primera estrella, el «7» del 772, la inicial de los dos enlaces) con
   este comentario diciendo «medido» al lado. Canto izquierdo de tinta de la
   columna de la nota (`.pila__cifra` + `.pila__pie`), idéntico en es, en e it:
       320   20,0 ·  390   20,3 ·  500   26,0 ·  820   50,0   ← una sola columna
       900   44,0 ·  914   44,0 ·  960   44,0 · 1000   44,0
      1024   44,0 · 1060   44,0 · 1200  114,0 · 1440  234,0
   ANTES, en esas siete de 900 para arriba: 0,0 · 0,0 · 14,0 · 26,0 · 44,0 ·
   114,0 · 234,0. El canto DERECHO de la columna de las voces da los mismos
   44,0 px de 900 a 1060. Y 44 px es exactamente `--edge`: la rejilla dejó de
   tener un criterio de margen propio y obedece al de la página.

   ⚠️ LO QUE NO CUBRE, y hay que decirlo:
     1 · No mide el canto SUPERIOR ni el INFERIOR de nada, ni contraste.
     2 · Las cuatro cifras de ≤820 px no son un arreglo: son la maqueta de una
         sola columna, que no se ha tocado, y están aquí sólo como prueba de que
         no se movió (mismos números antes y después, en los tres idiomas).
     3 · NO PROMETE UNA LÍNEA. De 900 a ~978 px la pista de la nota vale 142 px
         y las cadenas largas —«Scrivi una recensione su Google» 206,1 px, «See
         the listing on Google» 160,5 px, «Escribir una reseña en Google»
         192,5 px— PASAN A DOS LÍNEAS ahí. Es aritmética forzada, no un descuido:
         con 44 px de margen a cada lado, 36 px de hueco y un titular que
         necesita ≥625 px para no partirse en tres, a 900 px no quedan 206 px
         para la nota. No mueve la maqueta porque `min-height:44px` ya reservaba
         ese alto — medido: 44 px con una línea y con dos.
   Los dos enlaces siguen sin caer NUNCA en la misma línea entre sí: viven en
   bloques distintos con las tres citas en medio.
   Si alguien toca `--edge`, `--s5`, `--nota-min`, `--medida-pila`, `--pista-nota`
   o `--t-meta`, es LA TABLA DE ARRIBA la que hay que volver a medir, y se mide
   con el override de métricas, nunca con `--window-size`.                      */
.dice__enl{
  display:inline-flex; align-items:center; min-height:44px; min-width:0;
  font-size:var(--t-meta); line-height:1.4; letter-spacing:var(--tr-meta);
  color:var(--crema); text-decoration:underline; text-underline-offset:3px;
}
@media (hover:hover) and (pointer:fine){
  .dice__enl:hover{ color:var(--turquesa) }
}
@media (min-width:900px){
  /* 🔴 2026-08-22 · DOS COLUMNAS, NO TRES. La tercera (420 px) existía SÓLO
     para el clip de la sartén; al retirarse la pieza, dejarla declarada habría
     abierto 420 px de columna vacía en todo el escritorio — que es literalmente
     el «espacio en blanco» que este estudio lleva nueve veredictos rechazando.
     La fila 1 sigue diciendo lo que dice la instrucción original de Diego
     (2026-08-03, «el título … entre el 4,3 y el borde»): la nota a su ancho y
     el titular a su derecha.
     La `auto` de la primera columna sigue siendo deliberada: la nota mide lo que
     mide su cifra, no una fracción arbitraria.

     🔴 2026-08-23 · Y AQUÍ SE ARREGLAN LAS DOS REGRESIONES QUE ABRIÓ AQUELLA
     BAJADA DE TRES COLUMNAS A DOS. Cerró el hueco del clip y abrió otros dos,
     porque `.pila__stack` seguía en `1 / -1` con `width:auto`: con tres pistas
     eso paraba en la segunda, con dos se comía la rejilla entera.
       1 · LA MEDIDA. `.dice__t` llegó a medir 1.316 px a 1440 y 1.356 a 1920 —
           **162 y 168 caracteres por línea**, contados carácter a carácter con
           un `Range` en Chrome real y con la animación de entrada CONGELADA
           (`citaEntra` deja la tarjeta a `scale(.985)` mientras corre, y sin
           congelarla se mide un 1,5 % de menos). A 17 px de cuerpo. La medida
           legible son 45–75, y esta sección ya fue rechazada por escrito («son
           solo bloques de texto», Diego 2026-08-03): una plancha de 1.300 px de
           texto es exactamente eso.
       2 · EL ESCALÓN. La fila 1 acababa en la tinta del titular (x=1.003 a 1440)
           y la fila 2 seguía hasta 1.396: **393 px** de suelo a la derecha del
           titular con las citas pasando por debajo (241 a 1200, 433 a 1920).
           Ningún comprobador lo caza —son 393 × 167 px y el umbral de
           `[void]`/`[deadspace]` son 400.

     EL ARREGLO ES UNO SOLO, y por eso está escrito como un token: `--medida-pila`
     es UNA pista, y de ella cuelgan LAS DOS FILAS. El titular y las citas nacen
     en la misma línea vertical y mueren en la misma, por construcción y no por
     coincidencia — que es la regla de las junturas verticales de `Standards.md`
     (⚠️ repetida 7×). `justify-content:center` centra las dos pistas dentro de
     la sangra en vez de anclarlas al canto izquierdo: anclarlas habría dejado
     ~360 px de suelo sólo a la derecha y `symmetry-check` habría cantado un
     tercer bloque descentrado.

     ⭐ POR QUÉ 648 px Y NO UN NÚMERO REDONDO. Es el único tramo donde las dos
     condiciones se cumplen a la vez, y las dos están MEDIDAS en Chrome real:
       · el titular entra en DOS líneas mientras la pista mida ≥ 625 px (a 624
         se parte en tres y su tinta cae de 625 a 422 px, o sea el escalón
         vuelve a abrirse a ~200 px);
       · `.dice__t` = pista − 2 × `--s4` = 596 px ⇒ **75 caracteres por línea**,
         justo el techo de la banda legible.
     648 deja 23 px de holgura por arriba de los 625: es el margen para que un
     cambio de fuente, de idioma o de redacción no tire el titular a tres líneas.
     Bajar la pista APRIETA la medida y a la vez ACERCA el corte de línea; son
     el mismo píxel, así que no hay un valor «mejor» — hay este equilibrio.

     ⚠️ El inset de la tarjeta sube de `--s3` a `--s4` DENTRO de esta consulta, y
     no es cosmética: es la mitad de la medida. Si alguien lo devuelve a 18 px,
     `.dice__t` se va a 612 px = 78 caracteres y la sección vuelve a estar fuera
     de banda sin que cambie una sola línea de la rejilla.

     ⚠️ SOLAPE 3 (la cifra cruzando el canto del primer plano) YA ERA INERTE aquí
     antes de este cambio, y sigue siéndolo: la fila 1 la marca el titular (144 px)
     y no la cifra (140 − 20), así que el `margin-bottom:-20px` no llegaba a
     cruzar nada por encima de 900. Donde sí vive es por debajo de 900, que es
     donde la cifra y la pila comparten columna. No es una pieza que este cambio
     retire; es una pieza que esta anchura nunca tuvo.                        */
  .pila{
    /* 🔴 2026-08-26 · EL MARGEN PROPIO DE LA PÁGINA, QUE ESTA REJILLA NO TENÍA.
       `.pila` es `.sangra`, y por debajo de 1408 px `.sangra` vale `width:100%`
       pelado: no aporta margen ninguno. Así que la aritmética de las pistas
       —216 + 36 de hueco + 648— sumaba EXACTAMENTE 900 px a 900 px de ventana y
       la primera columna nacía en x = 0,0, cortando glifos contra el canto: el
       «4» del 4,3, la punta de la primera estrella, el «7» del 772 y la inicial
       de los dos enlaces a Google, con su subrayado saliendo por el borde. En
       es, en e it, y de 900 a ~1060 px —la ventana de un portátil—, con las
       secciones vecinas (`.sec__in`) respetando `--edge` a su lado.
       El arreglo es `padding-inline`, y no un punto de corte más arriba ni un
       ancho a medida: así el `100%` de las dos pistas de abajo pasa a resolverse
       contra `100% − 2×--edge` —la caja de contenido— en vez de contra la
       ventana entera, de modo que la rejilla obedece AL MISMO TOKEN que ya
       obedece el resto de la página en lugar de tener un criterio de margen
       propio. Y no toca nada por debajo de 900: este bloque entero vive dentro
       de la consulta.                                                          */
    padding-inline:var(--edge);
    /* ⭐ LO QUE LA NOTA NO PUEDE CEDER. Es su contenido más ancho que no rompe:
       las cinco estrellas de `.estrellas--g`, 5×26 px + 4×3 px de hueco = 142 px
       medidos en Chrome real a 900 px. Por debajo de eso las estrellas se
       aplastan o desbordan el hueco, así que aquí se RESERVA antes de repartir.
       (A menos de 560 px la estrella baja a 22 px —122 px la fila—, pero eso
       queda fuera de esta consulta.)                                           */
    --nota-min:142px;
    /* ⚠️ LA MEDIDA CEDE, PERO SÓLO EN LOS 14 px MÁS APRETADOS. Con el margen ya
       descontado, a 900 px la caja de contenido son 812 px y 142 + 36 + 648 =
       826 no caben. Antes de este cambio no se notaba porque lo que se comía la
       diferencia era el margen de la página. `min()` deja que la medida baje de
       648 a 634 px entre 900 y 914 px de ventana —y ni un píxel más—, que sigue
       por encima de los 625 px que el titular necesita para no partirse en tres
       (comprobado: h2 en 2 líneas a 900 px en es, en e it) y deja `.dice__t` en
       582 px = 73 caracteres, dentro de la banda 45–75.                        */
    --medida-pila:min(648px, 100% - var(--s5) - var(--nota-min));
    --pista-nota:18rem;                     /* 288 px · lo que mide su recuento */
    /* ⚠️ EL `min()` DE LA PRIMERA PISTA NO ES ADORNO: DECIDE QUIÉN CEDE. Con dos
       `minmax(0,X)` sueltas, cuando no caben las dos, la rejilla reparte el
       hueco A PARTES IGUALES y las dos se quedan cortas — medido a 900 px: la
       nota se llevaba sus 288 y la medida caía a 584, o sea por debajo de los
       625 que necesita el titular para no partirse en tres. Escrito así, la
       pista de la nota nunca puede pasar de «lo que sobre después de la
       medida», de modo que la que cede SIEMPRE es la nota (su recuento pasa a
       dos líneas) y nunca la medida, que es lo que esta ronda defiende.       */
    grid-template-columns:
      minmax(0, min(var(--pista-nota), 100% - var(--s5) - var(--medida-pila)))
      minmax(0, var(--medida-pila));
    column-gap:var(--s5);
    justify-content:center;
    justify-items:stretch;
    align-items:start;
  }
  /* Sin `padding-left`: la separación con la nota la pone ahora `column-gap`, y
     así el canto izquierdo del titular ES el canto izquierdo de las citas. Con
     el padding, el titular entraba 36 px más adentro que las tarjetas de abajo —
     dos junturas verticales donde tiene que haber una.                        */
  .pila__cab{
    grid-column:2; grid-row:1; align-self:center;
    justify-items:start; text-align:left; margin-inline:0; max-width:none;
  }
  .pila__cifra{ grid-column:1; grid-row:1; width:auto; justify-items:start; text-align:left }
  .pila__stack{ grid-column:2; grid-row:2; width:auto }
  /* ⭐ EL PIE BAJA A LA PISTA DE LA NOTA, Y NO ES DECORACIÓN. Al topar la medida,
     la columna de la izquierda deja de tener nada debajo de la nota: ~700 px de
     suelo sin dibujar, que es la queja de «espacio en blanco» que este estudio
     lleva nueve veredictos escuchando —y que sería una plancha mayor que el
     hueco de 337 px que esta misma ronda viene a cerrar—. Con el pie abajo, la
     pista queda ANCLADA POR LOS DOS EXTREMOS y se lee como lo que es: la
     columna de la PROCEDENCIA (la nota, sus estrellas, su recuento; y al pie,
     su logotipo y la fecha de recogida), enfrente de la columna de las VOCES.
     `align-self:end` lo pega al canto inferior de la última cita: las dos
     pistas terminan a la misma altura, igual que terminan en la misma x.      */
  .pila__pie{
    grid-column:1; grid-row:2; width:auto;
    align-self:end; margin-top:0; align-items:flex-end;
  }
  .dice{ padding-inline:var(--s4) }
}


/* ══ LAS ESTRELLAS · ⭐ r9 ═══════════════════════════════════════════════════
   Veredicto de Diego (2026-08-03): «ponles lo de las estrellas de google o algo
   así que no sea solo texto».
   Dos capas exactas: cinco estrellas apagadas y, encima, las mismas cinco
   encendidas RECORTADAS AL 86 %. 86 % es 4,3 sobre 5 al píxel — la cuarta
   estrella se ve llena en un 30 %, que es literalmente la nota. Un redondeo a
   cuatro estrellas y media sería más bonito y sería falso.
   🔴 El <svg> del pictograma NO puede ir con `display:none`: Safari deja de
   resolver los <use> que apuntan dentro de él.                                */
.sprite{ position:absolute; width:0; height:0; overflow:hidden }
.estrellas{ position:relative; display:inline-flex; line-height:0 }
.estrellas__c,.estrellas__on{ display:inline-flex; gap:3px; line-height:0 }
.estrellas__c .estrella{ fill:var(--linea-2) }
.estrellas__on{
  position:absolute; inset:0;
  clip-path:inset(0 calc(100% - var(--pct,100%)) 0 0);
}
.estrellas__on .estrella{ fill:var(--oro) }
.estrellas--g .estrella{ width:26px; height:26px }
@media (max-width:559px){ .estrellas--g .estrella{ width:22px; height:22px } }

/* El recuento, que sube desde cero al entrar (lo cuenta `initCuentas`). El
   ancho se reserva con `ch` tabulares: si el número creciera de 1 a 3 cifras
   moviendo la línea, sería un salto de maqueta, no una animación.             */
.cifra__c{
  color:var(--crema); font-weight:700;
  font-variant-numeric:lining-nums tabular-nums;
}
.pila__cifra{ gap:6px }

/* ── LAS CITAS ───────────────────────────────────────────────────────────────
   «Son solo bloques de texto, dales un poco de vida.» Lo que cambia: sus cinco
   estrellas arriba, su fecha abajo, y una comilla de apertura enorme en la
   tipografía de display, al 14 % — la marca de que esto es una VOZ y no una
   descripción nuestra.                                                        */
.dice{ position:relative; overflow:hidden }
/* ⚠️ 2026-08-03 · a `top:-.24em` la comilla la cortaba el `overflow:hidden` de
   la tarjeta y sólo asomaba un pico raro. Medido en la captura. Ahora cae
   entera dentro, con `line-height:.86` para que el glifo no arrastre su
   interlínea.                                                                */
.dice::before{
  content:"\201C";
  position:absolute; top:8px; right:16px;
  font-family:var(--display); font-weight:500; font-style:italic;
  font-size:104px; line-height:.86;
  color:var(--turquesa); opacity:.13; pointer-events:none;
}
@media (max-width:559px){ .dice::before{ font-size:74px; right:12px } }
.dice__e{ display:inline-flex; gap:3px; line-height:0; position:relative; z-index:1 }
.dice__e .estrella{ width:15px; height:15px; fill:var(--oro) }
.dice__t,.dice__f{ position:relative; z-index:1 }

@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    /* El relleno de la nota BARRE de izquierda a derecha al entrar la sección:
       la nota no aparece, se gana.                                            */
    .estrellas--g .estrellas__on{
      animation:llenaEstrellas both;
      animation-timeline:view(); animation-range:entry 10% cover 22%;
    }
    @keyframes llenaEstrellas{
      from{ clip-path:inset(0 100% 0 0) }
      to{ clip-path:inset(0 calc(100% - var(--pct,100%)) 0 0) }
    }
    /* Cada estrella de una cita entra girando, 5 % de recorrido detrás de la
       anterior: cinco escalones, no un bloque.                                */
    .dice__e .estrella{
      animation:estrellaEntra both;
      animation-timeline:view();
      animation-range:entry calc(6% + var(--s,0) * 5%) entry calc(52% + var(--s,0) * 5%);
      transform-origin:50% 60%;
    }
    @keyframes estrellaEntra{
      from{ opacity:0; transform:scale(.3) rotate(-24deg) }
      to{ opacity:1; transform:none }
    }
    /* Y las tres citas entran escalonadas, cada una desde su propio punto del
       recorrido: se lee como una PILA que se monta, no como tres cajas.        */
    .dice{
      animation:citaEntra both;
      animation-timeline:view(); animation-range:entry 4% cover 20%;
    }
    @keyframes citaEntra{
      from{ opacity:0; transform:translateY(30px) scale(.985) }
      to{ opacity:1; transform:none }
    }
  }
}
@media (hover:hover) and (pointer:fine){
  .dice{ transition:transform 320ms var(--ease-out), box-shadow 320ms var(--ease-out) }
  .dice:hover{ transform:translateY(-3px); box-shadow:var(--filo),var(--sombra-2) }
}

/* ══ FORMA 7 · LA FICHA · §8 VENIR ═══════════════════════════════════════════
   Un documento a sangre sobre el plano elevado, con paneles separados por 12 px:
   DOS paneles — la semana · el mapa. Un mapa va AL LADO de la información que
   contesta (Diego, Ozoa r4), y horario + dirección + teléfono son UNA sola
   pregunta del visitante, no dos secciones.
   📁 REGISTRO · hubo un TERCER panel, la fachada con el rótulo «Marc» encima del
   mapa. Lo mandó quitar Diego el 2026-08-03: «quita la que se ve marc encima del
   google map». Con él se fueron `.ficha__m`, la fila de altura fija y su token
   `--ficha-h` (retirado del `:root` el 2026-08-23, cuando se comprobó que no lo
   leía ya ninguna regla).
   La condición que gobernaba aquella caja se conserva como nota sobre un FICHERO
   ARCHIVADO —`ig-fachada-rotulo-marc-*`, sin uso en la página— y NO sobre nada
   que se pinte hoy: su caja no podía ser más estrecha que 4:3, porque la «M» de
   «Marc» empieza en el 3 % del ancho del fichero y cualquier recorte horizontal
   se la comía; era el defecto «1arc» de la r6. Si esa foto vuelve algún día,
   vuelve con esa condición.                                                    */
.ficha{
  display:grid; gap:var(--seam); grid-template-columns:minmax(0,1fr); min-width:0;
}
.ficha__p{
  background:var(--plano-1); box-shadow:var(--filo);
  border-radius:var(--r-control);
  min-width:0; display:grid; align-content:start;
}
/* `.ficha__m` se fue con la fachada (r9c) y `.ficha__m2` —el par de fotos de
   móvil— con el veredicto de Pere del 2026-08-23. Aquí ya sólo hay paneles. */
.ficha__cuerpo{ padding:var(--s4) var(--edge); display:grid; gap:var(--s3); align-content:start }
/* ⭐ r8c · aquí vivía `.ficha__m2`, el par de fotos de móvil que cerraba la
   ficha (pizza en la barra + carne guisada). Retirado el 2026-08-23 por orden
   de Pere; el porqué, entero, está en el comentario `⭐ r8c` de `index.html`.
   Se va con él `.ficha__p--mapa{ order:1 }`: ese `order` sólo existía para
   adelantar el mapa por delante de un par que iba después en el DOM, y sin el
   par los dos paneles ya caen en orden de documento (semana, mapa).          */
/* 📁 REGISTRO · ASÍ FUNCIONÓ ESTA CONSULTA MIENTRAS HUBO FACHADA, HASTA LA r9c.
   A partir de 1000 px la FILA declaraba la altura y la fachada la ocupaba
   entera: no podía llevar `aspect-ratio` y estirarse a la vez, y estirada con la
   semana al lado (~500 px) su caja se habría vuelto MÁS ESTRECHA que 4:3 y se
   habría comido la «M». Con la altura en la fila 1 y la semana cruzando las dos
   filas, la fachada corría a 465 × 316 (1,47) a 1440 px: más apaisada que el 4:3
   = 1,33 de su fichero, nunca más estrecha; y lo que sobraba en la columna de la
   derecha caía DENTRO de un panel con su propio suelo, que es relleno y no un
   agujero. En la r7b las columnas pasaron de 1fr/1fr a 1fr/1,9fr y `--ficha-h`
   de clamp(300,28vw,400) a clamp(260,22vw,316), bajando la fachada de 674 a
   465 px.
   ⚠️ NADA DE ESTO RIGE YA. La foto la mandó quitar Diego el 2026-08-03 y con
   ella murieron la fila de altura fija y el token `--ficha-h`, borrado del
   `:root` el 2026-08-23. Las cifras de arriba son notas sobre un fichero
   archivado (`ig-fachada-rotulo-marc-*`), no medidas de nada que se pinte. Lo
   que hace HOY esta consulta está en la nota `⭐ r9c` de aquí debajo: dos
   paneles, una fila.                                                           */
@media (min-width:1000px){
  /* ⭐ r9c · DOS PANELES, UNA FILA. Al irse la fachada se va con ella el motivo
     de la fila de altura fija (`--ficha-h` existía para que la caja de esa foto
     no se estrechara por debajo de 4:3 y se comiera la «M» de «Marc»).
     Ahora: el mapa a la izquierda, la semana a la derecha, ambos en la fila 1.
     Y de paso desaparece el hueco de ~250 px que arrastraba esta sección desde
     la r8 — no por un truco de CSS, sino porque la columna que lo causaba ya no
     existe. Un defecto de composición se arregla quitando composición.        */
  .ficha{
    grid-template-columns:minmax(0,1fr) minmax(0,1.9fr);
    grid-template-rows:auto;
  }
  .ficha__p--mapa{ grid-column:1; grid-row:1 }
  .ficha__p--semana{ grid-column:2; grid-row:1 }
  /* El bloque del mapa es más corto que siete filas de horario, así que su
     contenido se centra en el panel: un panel con su contenido centrado se lee
     como un documento; el mismo contenido pegado arriba, como un hueco.       */
  .ficha__p--mapa{ align-content:stretch }
  .ficha__p--mapa .mapa{ height:100%; grid-template-rows:minmax(0,1fr) }
  .ficha__p--mapa .mapa__facha{ align-content:center }
  .ficha__cuerpo{ padding:var(--s4); align-content:space-between }
}

/* la semana · radio + :checked, cero JavaScript, teclado gratis */
.sem{ display:grid; grid-template-columns:3px minmax(min-content,1fr) minmax(0,max-content); column-gap:var(--s2) }
.sem__r{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none }
.sem__f{
  /* ⚠️ La columna del día lleva `minmax(min-content,1fr)`, la única excepción a
     `minmax(0,1fr)` de toda la hoja, y va por la razón contraria: aquí el 0
     CAUSA el desbordamiento (a 320 px «Miércoles» se saldría de su celda).      */
  display:grid; grid-column:1 / -1; grid-template-columns:subgrid;
  align-items:center;
  min-height:48px; padding-block:.35rem;
  border-bottom:1px solid var(--linea-2); cursor:pointer;
  color:var(--crema-2);
  transition:color 140ms var(--ease-out),transform 140ms var(--ease-out);
}
@supports not (grid-template-columns: subgrid){
  .sem__f{ grid-template-columns:3px minmax(min-content,1fr) minmax(0,max-content); column-gap:var(--s2) }
}
.sem__d{ font-size:var(--t-meta); font-weight:600; letter-spacing:var(--tr-meta) }
.sem__m{
  display:block; width:3px; height:34px; align-self:center;
  background:var(--linea-2);
  transform:scaleY(.41); transform-origin:center;
  transition:transform 140ms var(--ease-out), background-color 140ms var(--ease-out);
}
.sem__h{
  font-size:var(--t-meta); text-align:right; font-variant-numeric:lining-nums tabular-nums;
  line-height:1.35;
}
.sem__r:checked + .sem__f{ color:var(--crema); transition-duration:200ms }
.sem__r:checked + .sem__f .sem__m{
  transform:scaleY(1); background:var(--turquesa); transition-duration:200ms;
}
.sem__r:focus-visible + .sem__f{ outline:2px solid var(--turquesa); outline-offset:-2px }
/* A2 · auditoría de los `:active`: las SIETE FILAS DE DÍA estaban en la lista de
   lo pulsable y eran las únicas que no daban feedback al tacto. `.99` porque son
   filas anchas, no controles de ≤320 px. 0 ms a la ida, 140 a la vuelta.       */
.sem__f:active{ transform:scale(.99); transition-duration:140ms }
@media (hover:hover) and (pointer:fine){ .sem__f:hover{ color:var(--crema) } }
.sem__det{ grid-column:1 / -1; margin-top:var(--s3); min-height:calc(var(--t-h2) * 1.2) }
.sem__dia{ display:none }
#semLun:checked ~ .sem__det .sem__dia--lun,
#semMar:checked ~ .sem__det .sem__dia--mar,
#semMie:checked ~ .sem__det .sem__dia--mie,
#semJue:checked ~ .sem__det .sem__dia--jue,
#semVie:checked ~ .sem__det .sem__dia--vie,
#semSab:checked ~ .sem__det .sem__dia--sab,
#semDom:checked ~ .sem__det .sem__dia--dom{ display:grid; gap:var(--s1) }
.sem__diad{
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}
.sem__deth{
  font-family:var(--display); font-weight:500; font-size:var(--t-h2);
  line-height:1.14; letter-spacing:var(--tr-h2); color:var(--crema);
  font-variant-numeric:lining-nums;
}

/* el mapa, detrás del consentimiento. El panel NUNCA se pinta vacío: hasta que
   se acepte enseña la dirección entera, el enlace y el botón, y la fachada de
   consentimiento sólo se retira con el `load` REAL del iframe.                  */
/* ⭐ r8d · el panel de consentimiento es ahora FOTOGRAFÍA + BLOQUE DE DATOS, no
   una columna de texto. La pieza se retira sola al aceptar: el `<iframe>` va
   `position:absolute; inset:0` y cubre el panel entero, y además se oculta con
   `.is-mapa` para que no siga pidiendo píxeles debajo del mapa.
   ⚠️ El aviso NO se ha acortado. Ni una palabra.                              */
.mapa{ position:relative; display:grid; grid-template-rows:auto auto; min-width:0 }
/* ⭐ r9b · `.mapa__pza` SE HA IDO CON SU MARCADO: la foto que había encima del
   mapa la quitó Diego («deja solo el mapa, la foto no queda bien»). Estaba
   puesta para subir una banda de 5,6 % de imagen — el mismo error que las dos
   fotos de la carta y el ossobuco del contacto, tres veces en una ronda.       */
.mapa__facha{ display:grid; gap:var(--s2); align-content:start; padding:var(--s4) var(--edge) }
.mapa__p{ font-size:var(--t-meta); color:var(--crema-2); max-width:36rem }
.mapa__dir{ font-size:var(--t-body); font-weight:600; color:var(--crema) }
.mapa__acc{ display:flex; flex-wrap:wrap; gap:8px; margin-top:var(--s2) }
.mapa iframe{
  position:absolute; inset:0; width:100%; height:100%; border:0;
  opacity:0; transition:opacity 300ms var(--ease-out);
}
.mapa.is-mapa iframe{ opacity:1 }
.mapa.is-mapa .mapa__facha{ display:none }
.mapa.is-cargando{ min-height:var(--mapa) }
@media (min-width:1000px){
  .mapa__facha{ padding:var(--s4); grid-template-columns:minmax(0,1fr) auto; column-gap:var(--s5); align-items:start }
  .mapa__facha > *{ grid-column:1 }
  .mapa__facha > .mapa__acc{
    grid-column:2; grid-row:1 / span 3; align-self:center;
    flex-direction:column; align-items:stretch; margin-top:0;
  }
}

/* ⚠️ RECUENTO DE COLUMNAS DECLARADO, no flex-wrap ni auto-fit: los dos recuentos
   (4 servicios y 8) se dividen limpiamente por 1, 2 y 4, así que no hay celda
   huérfana a ningún ancho — y `auto-fit` se inventaría una.                     */
.servs{ display:grid; grid-template-columns:minmax(0,1fr); gap:var(--s2) var(--s4); align-items:start }
@media (min-width:640px){ .servs{ grid-template-columns:repeat(2,minmax(0,1fr)) } }
@media (min-width:1200px){ .servs{ grid-template-columns:repeat(4,minmax(0,1fr)) } }
.servs--casa{ grid-template-columns:minmax(0,1fr) }
@media (min-width:1200px){ .servs--casa{ grid-template-columns:repeat(2,minmax(0,1fr)) } }
.serv{
  display:grid; grid-template-columns:3px minmax(0,1fr); gap:var(--s2);
  align-items:start; font-size:var(--t-meta); color:var(--crema);
}
.serv .banda{ margin-top:.35em }
/* ⭐ 2026-08-25 · LA ÚNICA ETIQUETA DE SERVICIO QUE ES UN ENLACE, en §5 y en §7:
   «Eventos privados» lleva a §6c, que es la sección que la demuestra. Las otras
   diez etiquetas siguen siendo `<span>` porque no hay nada adonde ir.
   🔴 LA DIANA DE 44 px VA EN UN `::after` Y NO EN UN `min-height`, y el motivo es
   geométrico, no de gusto. `.serv` es una rejilla `3px + 1fr` con
   `align-items:start`, y su fila mide 17,40 px en §5 y 21,05 px en §7 (medido en
   Chrome a 390 y a 1440 antes de tocar nada). Un `min-height:44px` con el
   `margin-block:-13px` que compensa daría 18 px en las dos: +0,6 px en §5 y
   −3,05 px en §7, o sea la maqueta de las dos secciones movida por un enlace. El
   pseudo-elemento no entra en el flujo, así que el desplazamiento es CERO exacto
   —comprobado con el rect de los 1.399 elementos de la página antes y después— y
   la diana sigue siendo real: 44 px de alto por el ancho entero de la columna,
   verificada con `elementFromPoint` en los dos extremos.
   `phone-fit [tap]` lo apunta como nota y no como fallo, y su propio texto dice
   por qué: «an ::after hit-area may cover it — verify». Esto es la verificación.
   El subrayado es el patrón que la hoja ya tiene para un enlace en flujo
   (`.pie__social a`, `.reserva__aparte a`, `.pie__legal .nav__lang`): no se
   estrena una forma de enlace nueva.                                            */
.serv__a{
  position:relative; color:inherit;
  text-decoration:underline; text-underline-offset:3px;
}
.serv__a::after{ content:""; position:absolute; left:0; right:0; top:50%; height:44px; transform:translateY(-50%) }
@media (hover:hover) and (pointer:fine){
  .serv__a:hover{ color:var(--turquesa) }
}

/* ══ FORMA 7 · EL CIERRE · §7 LA PUERTA ══════════════════════════════════════
   ⭐ UNA COLUMNA ESTRECHA Y ALTA CON UN SOLO EJE DE DATOS. El defecto medido de
   la r6: a 820 px la etiqueta caía en x=132, el teléfono en x=410 y los botones
   en x=515 — tres ejes distintos en un pie de página. Aquí la puerta es un raíl
   fotográfico y ABSOLUTAMENTE TODO lo demás vive en una sola columna:
       left(etiqueta) = left(teléfono) = left(botones), ±0 px.
   La forma la eligió un número: `ig-entrada-comedor-desde-calle` mide 400 px de
   ancho, así que esa foto no puede ser una banda — y por eso el cierre es la
   única columna estrecha de la web.                                             */
/* ⭐ r7b · YA NO ES EL PIE DE LA PÁGINA: es la penúltima sección, porque Diego
   ordenó que la ubicación salga la última. Por eso lleva filete arriba Y abajo
   —tiene una sección detrás— y su propio `scroll-margin-top`, que antes le venía
   de `.sec` y ahora no.                                                        */
.pie{
  padding-block:var(--pad-3);
  border-block:1px solid var(--linea);
  scroll-margin-top:calc(var(--barra) + 8px);
  --rev-y:26px; --rev-d:460ms;
}
.pie .sec__in{ gap:var(--s5) }
/* ⭐ r9 · UNA SOLA PUERTA, Y CON ELLA SE VA LA BANDA ROTA DE TABLETA ═════════
   La r8c había puesto DOS raíles fotográficos de 240 px junto a la columna de
   datos para subir la superficie de imagen. Costó dos cosas: una foto de
   ossobuco con espaguetis que no pinta nada al lado de un teléfono (veredicto
   de Diego, 2026-08-03) y, a 820 px, 480 px fijos de raíl que dejaban ~250 para
   TODO el contacto — el teléfono partido en dos líneas, el botón de reparto que
   entonces había en tres, la dirección en cinco. (Ese botón ya no existe: el
   reparto salió el 2026-08-17. La medición se conserva porque es lo que
   justifica esta maqueta, pero no vayas a buscar el botón en el marcado.)
   Con una puerta la maqueta es la misma de 390 a 1440 y no hay banda que
   arreglar: fotografía a un lado, un solo eje de datos al otro.
       left(etiqueta) = left(teléfono) = left(botones), ±0 px.
   Regla que queda escrita: una columna de datos con un mínimo legible manda
   sobre una pieza de imagen de más.                                           */
.cierre{
  display:grid; align-items:stretch; min-width:0;
  gap:var(--s4); column-gap:var(--s5);
  grid-template-columns:var(--puerta) minmax(0,1fr);
}
.cierre > .cierre__tel{ grid-column:2; grid-row:1 }
.cierre > .cierre__acc{ grid-column:2; grid-row:2 }
.puerta{
  grid-column:1; grid-row:1 / span 3;
  position:relative; overflow:hidden; min-height:320px; min-width:0;
  border-radius:var(--r-pieza);
}
.puerta > img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover }
.cierre__datos{
  grid-column:2; grid-row:3;
  display:grid; gap:var(--s4); align-content:start; min-width:0;
}
/* Por debajo de 560 el número mide 192 px a --t-tel y la columna que queda
   junto a la puerta son 154: la puerta baja debajo y todo va a ancho completo.
   Lo que se mueve es la maqueta, nunca el tamaño del dato.                    */
@media (max-width:559px){
  .cierre{ grid-template-columns:minmax(0,1fr) }
  .cierre > .cierre__tel{ grid-column:1; grid-row:1 }
  .cierre > .cierre__acc{ grid-column:1; grid-row:2 }
  .puerta{ grid-column:1; grid-row:3; min-height:230px }
  .cierre__datos{ grid-column:1; grid-row:4 }
}
.cierre__tel{ display:grid; justify-items:start; gap:2px }
.pie__tel{
  font-size:var(--t-tel); font-weight:700; line-height:1;
  letter-spacing:var(--tr-figure); color:var(--crema); text-decoration:none;
  font-variant-numeric:lining-nums tabular-nums; display:inline-block; margin-block:-.06em;
}
/* ⭐ 2026-08-24 · EL FIJO. Es un segundo dato, no un segundo énfasis: el 644
   manda a --t-tel (32–64 px) y éste vive a la mitad larga, con su etiqueta
   propia encima. La caja de 44 px es obligatoria —es un enlace `tel:` y se toca
   con el pulgar—, y a 22–32 px el texto solo no la alcanza, así que la pone el
   `min-height` con el `inline-flex`. `margin-top` porque `.cierre__tel` tiene
   `gap:2px`, que es el aire entre una etiqueta y SU número, no entre dos pares. */
.cierre__tel .pie__lbl--fijo{ margin-top:var(--s2) }
.pie__tel--fijo{
  font-size:clamp(22px,5vw,30px);
  display:inline-flex; align-items:center; min-height:44px; margin-block:0;
}
.cierre__acc{ display:grid; grid-template-columns:minmax(0,1fr); gap:8px }
/* Misma corrección que `.acc__tres`, y por el mismo motivo (2026-08-17). */
.cierre__tres{ display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:8px }
.pie__lbl{
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2); margin-bottom:.25rem;
}
.pie__datos{ display:grid; gap:var(--s3); grid-template-columns:minmax(0,1fr) }
@media (min-width:700px){ .pie__datos{ grid-template-columns:repeat(2,minmax(0,1fr)) } }
/* ⭐ LAS OCHO NOTAS DE PROCEDENCIA, PLEGADAS. Eran 137 palabras repartidas en
   ocho interrupciones (el 19 % del texto de la web). Al primer vistazo
   desaparecen; a un clic siguen enteras, con su fecha.                          */
.fuentes{ border-top:1px solid var(--linea); padding-top:var(--s3) }
.fuentes__cab{
  display:flex; align-items:center; gap:.45rem; min-height:44px; cursor:pointer;
  list-style:none;
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}
.fuentes__cab::-webkit-details-marker{ display:none }
.fuentes__cab svg{ width:12px; height:12px; fill:var(--turquesa); transition:transform 140ms var(--ease-out) }
.fuentes[open] > .fuentes__cab svg{ transform:rotate(180deg); transition-duration:200ms }
.fuentes__cab:active{ transform:scale(.97); transition:transform 140ms var(--ease-out) }
.fuentes__l{ display:grid; gap:var(--s1); padding-top:var(--s2) }
.fuentes__l li{ font-size:var(--t-micro); line-height:1.5; letter-spacing:var(--tr-meta); color:var(--crema-2) }
/* 2026-08-24 · Facebook e Instagram, uno al lado del otro. Hasta hoy había un
   solo enlace aquí y el hueco no existía; con dos, sin esto se tocan.          */
.pie__redes{ display:flex; flex-wrap:wrap; gap:0 var(--s3) }
.pie__social a,.pie__legal a{
  display:inline-flex; align-items:center; min-height:44px;
  font-size:var(--t-meta); color:var(--crema-2); text-decoration:underline;
  text-underline-offset:3px;
}
/* 🔴 GATEADO. El segundo y último `:hover` suelto de la hoja. En una pantalla
   táctil se disparaba al tocar el enlace legal y se quedaba pegado.            */
@media (hover:hover) and (pointer:fine){
  .pie__social a:hover,.pie__legal a:hover{ color:var(--crema) }
}

/* ══ FORMA 9 · #reservar · EL FORMULARIO DE SOLICITUD ════════════════════════
   Encargo del 2026-08-17: el sistema de reservas de n8n está vivo y probado, y
   hasta hoy las tres webs de la marca tenían CERO `<form>`.

   ⭐ SU PROPIA FORMA, y por qué no se parece a ninguna otra sección: es UN SOLO
   plano elevado a sangre (`--plano-1` + `--filo` + `--sombra-2`), y todo lo que
   lleva dentro son controles. No es el documento de dos paneles de §8 (`.ficha`),
   no es el aparejo de teselas de §2, no es la columna estrecha de §7. La regla
   del estudio —«cada sección coloca su materia a su manera»— aquí se cumple con
   la retícula de campos, que no existe en ningún otro sitio de la web.

   ⭐ TRES COLUMNAS DE CAMPO A ≥1040, DOS A ≥560, UNA POR DEBAJO. No es
   decoración: a 1440 el plano mide 1.352 px y su interior 1.264, así que con dos
   columnas cada campo saldría a 620 px —un cuadro de texto de 620 px es
   ilegible de rellenar y deja la mitad del plano vacía—. Con tres, 404 px.
   MEDIDO en los tres escalones:
     1440 → 3 × 404 px · 1024 → 2 × 452 px · 390 → 1 × 302 px
   Y por eso NO hay columna de apoyo al lado: el hueco que habría que rellenar
   no existe, en vez de rellenarse con algo.

   ⚠️ SIN FOTOGRAFÍA, y está declarado en el marcado con `data-no-image`. Una
   foto aquí sería exactamente lo que Diego tachó cuatro veces en la r9 («¿por
   qué en el contacto hay una foto de unos spaghettis?»): materia puesta para
   subir la superficie de imagen de una banda. La sección tiene ~270 palabras,
   muy por debajo del umbral de 400 de `site-audit [density]`.

   🔴 NINGÚN `outline:0`. La regla `:focus-visible` de la línea 439 (0,1,0) es la
   que tiene que ganar, y un `input:focus{outline:0}` con especificidad 0,2,0 se
   la come — es cómo este estudio perdió el anillo de foco de un formulario
   entero (WCAG 2.4.7). Aquí sólo se AÑADE color de filete al foco.             */
.reserva{
  background:var(--plano-1); box-shadow:var(--filo),var(--sombra-2);
  border-radius:var(--r-control);
  padding:var(--s5) var(--edge);
  min-width:0;
  /* 🔴 NO ES DECORACIÓN: es lo que ancla la trampa (`.hp`, más abajo). Sin este
     `position`, su `top:0` se resuelve contra el bloque contenedor inicial, o
     sea contra el principio del DOCUMENTO — y `phone-fit` midió por eso una
     banda muerta de 7.691 px «dentro» de esta sección. La caja de un absoluto
     miente si no se le dice contra qué. */
  position:relative;
  /* Los controles nativos (fecha, hora, radio, casilla) se pintan según este
     esquema: sin él, el calendario de Chrome sale blanco sobre grafito. Va
     ACOTADO a esta sección — declararlo en :root cambiaría también las barras de
     desplazamiento de las tres webs, que nadie ha pedido. */
  color-scheme:dark;
  accent-color:var(--turquesa);
  /* El filete de un campo mide 3,46:1 contra el plano (rgba(247,233,219,.45)
     compuesto sobre --grafito = #7F7872, L=0,1916; --plano-1 L=0,0199).
     WCAG 1.4.11 pide 3:1 para el contorno de un control, y el relleno del campo
     NO lo da solo: #1C1C1C contra #26262A son 1,13:1. */
  --campo-linea:rgba(247,233,219,.45);
}
@media (min-width:1408px){ .reserva{ padding-inline:var(--s6) } }

.reserva__f{ display:grid; gap:var(--s4); min-width:0 }
.reserva__campos{ display:grid; gap:var(--s4); grid-template-columns:minmax(0,1fr); min-width:0 }
@media (min-width:560px){
  .reserva__campos{ grid-template-columns:repeat(2,minmax(0,1fr)); column-gap:var(--s4) }
}
@media (min-width:1040px){
  .reserva__campos{ grid-template-columns:repeat(3,minmax(0,1fr)) }
}
.reserva__ancho,.reserva__accion{ grid-column:1 / -1; min-width:0 }

.campo{ display:grid; gap:6px; min-width:0; align-content:start }
.campo__l{
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}
/* 4,87:1 contra --plano-1 · AA para texto normal. La misma pareja que .pie__lbl,
   recalculada aquí porque el suelo NO es el mismo: allí es --grafito.          */
.campo__ayuda{ font-size:var(--t-meta); line-height:1.4; color:var(--crema-2) }
.campo__i{
  width:100%; min-width:0; min-height:48px;
  padding:.62rem .8rem;
  font:inherit; font-size:var(--t-body); line-height:1.3;
  color:var(--crema); background:var(--grafito);
  border:1px solid var(--campo-linea); border-radius:var(--r-control);
  /* WCAG 2.4.11 «Focus Not Obscured»: la cabecera es pegajosa y mide --barra.
     Sin esto, tabular hasta un campo lo deja debajo de la barra.               */
  scroll-margin-top:calc(var(--barra) + var(--s3));
  transition:border-color 180ms var(--ease-out);
}
textarea.campo__i{ min-height:96px; resize:vertical }
.campo__i:focus-visible{ border-color:var(--turquesa) }
/* 🔴 MEDIDO CON UN TABULADOR DE VERDAD, y la primera corrección tampoco valía.
   En un `<input type="date">` y en un `<input type="time">` el foco real vive en
   un subcampo del shadow DOM de Chrome, así que el anfitrión NO casa
   `:focus-visible` **ni `:focus`** — medido: `:focus false · :focus-within true`
   con `Emulation.setFocusEmulationEnabled`, que hay que encender o una ventana
   headless dice que ningún campo tiene el foco y la medición entera miente.
   Sin esta regla, los dos únicos controles tabulables de toda la web sin anillo
   de foco eran justo el día y la hora (WCAG 2.4.7).
   ⚠️ En ningún sitio de esta hoja se escribe `outline:0`: aquí se AÑADE el mismo
   anillo, nunca se quita. Un `input:focus{outline:0}` con especificidad 0,2,0 se
   come al `:focus-visible` del sitio (0,1,0), y así perdió este estudio el
   anillo de un formulario entero. */
.campo__i[type="date"]:focus-within,.campo__i[type="time"]:focus-within{
  outline:2px solid var(--turquesa); outline-offset:3px;
  border-color:var(--turquesa);
}
.campo.is-mal .campo__i{ border-color:var(--crema) }
/* 12,65:1 contra --plano-1. El error NO se señala sólo por color (WCAG 1.4.1):
   lo dice la frase, y el campo lleva aria-invalid.                             */
.campo__err{ font-size:var(--t-meta); line-height:1.4; font-weight:600; color:var(--crema) }

/* Dos controles dentro de un mismo campo (día + hora). `flex-wrap` y no
   `auto-fit`: son dos piezas de anchos mínimos distintos y auto-fit inventa una
   celda vacía cuando no caben. */
.campo__par{ display:flex; flex-wrap:wrap; gap:var(--s2); min-width:0 }
.campo__par > .campo{ flex:1 1 9rem; min-width:0 }
.campo__par .campo__l{ font-size:var(--t-micro) }

/* Las leyendas de los dos <fieldset>, con la misma voz que .campo__l. */
.campo--grupo{ border:0; margin:0; padding:0; min-width:0 }
.campo--grupo > legend{
  padding:0; margin-bottom:6px;
  font-size:var(--t-micro); font-weight:600; letter-spacing:var(--tr-micro);
  text-transform:uppercase; color:var(--crema-2);
}

/* Los dos turnos y la casilla: control NATIVO dentro de una etiqueta de 44 px.
   No se reimplementa nada — el foco, el teclado y el rol llegan gratis.        */
.op{ display:flex; flex-wrap:wrap; gap:var(--s2); min-width:0 }
.op__l{
  flex:1 1 8rem; min-width:0;
  display:flex; align-items:center; gap:.55rem;
  min-height:48px; padding:.5rem .8rem;
  border:1px solid var(--campo-linea); border-radius:var(--r-control);
  background:var(--grafito); color:var(--crema);
  font-size:var(--t-body); cursor:pointer;
  transition:border-color 180ms var(--ease-out);
}
/* 24 px, que es el suelo duro de WCAG 2.5.8 «Target Size (Minimum)» — y no 20,
   aunque la etiqueta entera mida 48 y sea la que se pulsa: un contador que tiene
   que razonar sobre el área del padre para dar por buena una casilla acaba
   dándola por mala. Se mide lo que se ve.
   ⚠️ 26 y no 24: medido en Chrome real, un control de `width:24px` devuelve un
   rect de 23,x y cualquier sonda que redondee lo suspende por 1 px. */
.op__l input{ width:26px; height:26px; flex:0 0 auto; margin:0; scroll-margin-top:calc(var(--barra) + var(--s3)) }
.op__l:has(input:checked){ border-color:var(--turquesa) }
.campo.is-mal .op__l{ border-color:var(--crema) }
/* 38rem, no todo el ancho del plano: una etiqueta de 1.225 px hace que pulsar
   el vacío de la derecha marque la casilla sin querer. 48 px de alto, el mismo
   suelo que los demás controles. */
.casilla{ display:flex; align-items:flex-start; gap:.6rem; min-height:48px;
          max-width:38rem; cursor:pointer }
.casilla input{ width:26px; height:26px; flex:0 0 auto; margin-top:.5rem; scroll-margin-top:calc(var(--barra) + var(--s3)) }
.casilla span{ font-size:var(--t-meta); line-height:1.45; color:var(--crema) }

/* La trampa. Fuera de la pantalla como `.skip`, nunca `display:none` (un bot que
   salta lo oculto no cae) y nunca con etiqueta, aria-label ni placeholder: un
   nombre accesible la convertiría en una trampa para lectores de pantalla.
   ⚠️ La medida va también en el <input>, no sólo en el envoltorio: `overflow`
   recorta lo que se PINTA, no lo que devuelve `getBoundingClientRect()`, y un
   campo de 176 × 21 px escondido detrás de un recorte sigue siendo una caja de
   176 × 21 px para cualquier sonda. Con 1 px de alto, `phone-fit` lo descarta
   solo (`r.height < 4`).                                                       */
.hp{ position:absolute; left:-9999px; top:0; width:1px; height:1px; overflow:hidden }
.hp input{ width:1px; height:1px; min-height:0; padding:0; margin:0; border:0; font-size:1px }

.reserva__accion{ display:grid; gap:var(--s2); justify-items:stretch }
.reserva__accion .btn{ width:100% }
@media (min-width:560px){
  .reserva__accion{ justify-items:start }
  .reserva__accion .btn{ width:auto; min-width:16rem }
}
/* Sin JavaScript el envío no existe: el botón NO se pinta, y lo que queda es la
   vía que sí funciona —el teléfono de `.reserva__aparte`, que está siempre—.
   Un botón que no hace nada es «una etiqueta que promete un mecanismo que no
   ocurre», que es defecto registrado de este estudio.                          */
html:not(.js) .reserva__accion{ display:none }

.reserva__aparte{
  display:flex; flex-wrap:wrap; align-items:baseline;
  gap:var(--s2) var(--s4); min-width:0;
  padding-top:var(--s3); border-top:1px solid var(--linea);
}
.reserva__aparte .nota{ min-width:0 }
.reserva__via,.reserva__aparte a{
  display:inline-flex; align-items:center; min-height:44px;
  font-size:var(--t-meta); letter-spacing:var(--tr-meta);
  color:var(--crema); text-decoration:underline; text-underline-offset:3px;
}
@media (hover:hover) and (pointer:fine){
  .reserva__aparte a:hover{ color:var(--turquesa) }
  .op__l:hover{ border-color:var(--crema) }
}

/* El acuse. Región viva SIEMPRE presente (nunca `hidden`, o un lector de
   pantalla puede no anunciar lo que aparece dentro): en reposo mide 0 px porque
   sus cuatro bloques van con el atributo `hidden`, y `[hidden]` de la línea 437
   lleva `!important`, así que ningún `display` de autor de aquí lo puede pisar.
   ⚠️ Se comprueba ABRIENDO la página, nunca leyendo el marcado — Dharma r2 y Di
   Pizza costaron una ronda cada uno por esto.                                  */
.est{ display:grid; gap:var(--s2); min-width:0 }
.est__b{ display:grid; gap:var(--s2); justify-items:start; min-width:0 }
.est__b--ok{
  padding:var(--s4); border-radius:var(--r-control);
  background:var(--grafito); box-shadow:var(--filo);
  border-left:3px solid var(--turquesa);
}
.est__h{ font-family:var(--display); font-style:italic; font-size:var(--t-h2); line-height:1.15; color:var(--crema) }
.est__p{ font-size:var(--t-body); line-height:1.5; color:var(--crema) }
.est__t{ font-size:var(--t-body); line-height:1.5; color:var(--crema) }

/* ══ FORMA 10 · LA CALLE · §6c #eventos · ⭐ r10 ═══════════════════════════════
   LA NOVENA FORMA DE LA PÁGINA, y su frase de bloque: es la única banda de esta
   web hecha de UNA SOLA MEDIA SIN SUBDIVIDIR, cerrada por debajo por un raíl de
   control cuya altura la fija el botón y no el texto. La cabecera va ENCIMA de
   la media, que es el orden vertical contrario al del cartel (§5).

   🔴 LA PROPORCIÓN LA PONE EL FICHERO, Y NO ES UN CAPRICHO. La dirección de la
   r10 pedía `--calle-h: clamp(280px, 33.3vw, 480px)`, un ALTO. Medidos los
   derivados en disco (ffprobe + Pillow, 2026-08-25) resulta que el de escritorio
   es 1600×568 = 2,8169:1 y el de móvil 900×506 = 1,7787:1 — dos encuadres
   distintos, no dos tamaños del mismo —, así que cualquier alto declarado obliga
   a `object-fit:cover` a recortar por arriba y por abajo a casi todas las
   anchuras. Y arriba es justo donde está el rótulo de la fachada: el fichero de
   escritorio EXISTE porque el recorte centrado por CSS lo cortaba en los seis
   planos y lo perdía entero en dos (`Brief.md` l. 1645). Recortarlo otra vez con
   una altura sería deshacer a mano el trabajo por el que se recortó el fichero.
   Con `aspect-ratio` el recorte vertical es CERO a toda anchura y el alto sale
   solo — 480 px clavados a 1440, que es el techo de pieza de la r7b.
   El interruptor de tamaño, por si un socio la quiere más baja, es esta
   `aspect-ratio`: subir el primer número la achata Y EMPIEZA A COMERSE EL
   RÓTULO POR ARRIBA. No es una línea inocente, y por eso se dice.               */
.calle__cinta{
  position:relative; overflow:hidden; min-width:0;
  border-radius:0;                       /* toca los dos cantos de la ventana */
  aspect-ratio:900 / 506;                /* el fichero de móvil, entero */
}
.calle__cinta > picture{ position:absolute; inset:0; display:block }
.calle__cinta > picture > img,
.calle__cinta > video{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}
/* ⭐ EL FILETE DEL BUCLE · el motivo «LA BANDA», 3 px de turquesa, en su lectura
   más literal: corre exactamente mientras este clip es el que tiene el único
   decodificador de la página. Estado base `scaleX(0)` ⇒ sin JS, sin vídeo o con
   movimiento reducido no dice nada, que es lo correcto.                         */
.calle__filete{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  height:3px; background:var(--turquesa);
  transform:scaleX(0); transform-origin:left;
}
/* Hermano posterior, NO `:has()`: el combinador `~` lo entiende cualquier
   navegador, y si algún día `.is-on` no llega, el filete se queda a 0 en vez de
   quedarse corriendo sobre un vídeo parado. `.is-on` la pone `main.js` en el
   evento REAL `playing` y la quita `pausa()`, que no reinicia el `currentTime`:
   vídeo y filete se reanudan juntos y no pueden desincronizarse.                */
@media (prefers-reduced-motion: no-preference){
  .calle__cinta .vid.is-on ~ .calle__filete{
    animation:calleBucle 8.92s linear infinite;   /* la duración REAL del clip: 223 fotogramas a 25 fps, medidos con ffprobe sobre los cuatro derivados el 2026-08-25 (remontaje de media-agent: 9,16 → 8,92 s). Si el fichero se vuelve a cortar, este número LE SIGUE. */
  }
}
@keyframes calleBucle{ from{ transform:scaleX(0) } to{ transform:scaleX(1) } }

/* ⭐ EL ZÓCALO · un raíl de control, no un plano de texto (que es lo que sí es
   `.cartel__txt` en §5, cuya altura la fijan sus palabras). Contacto de 12 px
   con la cinta: `--seam`, el segundo peldaño de la escalera publicada, no un
   valor nuevo. Sin `border-radius`: comparte los dos cantos con la cinta, y un
   radio ahí abriría una junta que la costura de contacto existe para cerrar.    */
.calle__zocalo{
  min-width:0; margin-top:var(--seam);
  display:grid; gap:var(--s3); align-items:center;
  padding:var(--s3) var(--edge);
  background:var(--plano-1); box-shadow:var(--filo);
}
.calle__frase{ font-size:var(--t-body); line-height:1.5; color:var(--crema); min-width:0 }
.calle__cta{ width:100% }
/* Los `@media` van SIEMPRE después de las reglas base que corrigen: una consulta
   no añade especificidad y a igualdad gana la última del fichero. Esta casa lo
   ha pagado tres veces.                                                         */
@media (min-width:640px){
  .calle__zocalo{ grid-template-columns:minmax(0,1fr) auto; gap:var(--s4) }
  .calle__cta{ width:auto }
}
/* El MISMO umbral que el `media` del `<picture>` y que el `mm()` de `engancha()`
   en `main.js`. Si uno se mueve, el vídeo y el fotograma de debajo dejan de ser
   el mismo encuadre.                                                            */
@media (min-width:700px){
  .calle__cinta{
    aspect-ratio:1600 / 568;             /* el fichero de escritorio, entero */
    /* El techo de pieza de la r7b. Sólo muerde por encima de 1.352 px de banda
       —o sea a 1.353–1.407 y por encima de 1.568—, y lo que recorta entonces es
       HORIZONTAL y simétrico: ≤2,0 % por canto, contra un rótulo que empieza en
       el 14 % del ancho. Nunca toca el alto del fotograma.                      */
    max-height:480px;
  }
}

/* ══ FORMA 8 · EL PIE DE LA CASA · ⭐ r9 ══════════════════════════════════════
   Veredicto de Diego (2026-08-03): «al final de la web no has incluido la
   sección donde se ve el logo del restaurante, todas las secciones de la web,
   el teléfono, horario etc». No existía: la página terminaba en un mapa.
   Cuatro columnas a ≥1000 —marca · índice · teléfono y dirección · horario y
   redes— y una fila baja con el copyright y lo legal. Es el único sitio de la
   página donde el logotipo aparece a tamaño de firma.                        */
.pieF{
  border-top:1px solid var(--linea);
  background:var(--plano-0);
  padding-block:var(--pad-3) var(--s5);
  padding-bottom:calc(var(--s5) + env(safe-area-inset-bottom,0px));
}
.pieF__cuerpo{
  display:grid; gap:var(--s5); min-width:0;
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:640px){
  .pieF__cuerpo{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--s5) var(--s6) }
}
@media (min-width:1000px){
  .pieF__cuerpo{ grid-template-columns:auto repeat(3,minmax(0,1fr)); gap:var(--s6) }
}
.pieF__marca{ display:grid; gap:var(--s2); justify-items:start; align-content:start; min-width:0 }
.pieF__logo{ width:132px; height:auto }
.pieF__sitio{ font-size:var(--t-micro); letter-spacing:var(--tr-meta); color:var(--crema-2) }
.pieF__nav{ min-width:0 }
.pieF__nav ul{ list-style:none; margin:var(--s2) 0 0; padding:0; display:grid; gap:7px }
.pieF__col{ display:grid; gap:var(--s2); align-content:start; min-width:0 }
.pieF__col p{ min-width:0 }
.pieF__nav a{
  color:var(--crema-2); text-decoration:none;
  font-size:var(--t-meta); letter-spacing:var(--tr-meta);
  transition:color 180ms var(--ease-out);
}
.pieF__tel{
  font-size:26px; font-weight:700; line-height:1.1; color:var(--crema);
  text-decoration:none; letter-spacing:var(--tr-figure);
  font-variant-numeric:lining-nums tabular-nums; justify-self:start;
}
/* 2026-08-24 · el fijo en el pie: misma jerarquía que en #contacto, a escala de
   pie. `.pieF__col` ya reparte con `gap:var(--s2)`, así que aquí sólo cambia el
   tamaño y se asegura la caja de 44 px del enlace `tel:`.                      */
.pieF__tel--fijo{
  font-size:19px;
  display:inline-flex; align-items:center; min-height:44px;
}
.pieF__bajo{
  margin-top:var(--s5); padding-top:var(--s4);
  border-top:1px solid var(--linea);
  display:flex; flex-wrap:wrap; align-items:center;
  justify-content:space-between; gap:var(--s3) var(--s4);
}
.pieF__c{ font-size:var(--t-micro); letter-spacing:var(--tr-meta); color:var(--crema-2) }
/* ── LA FIRMA DEL ESTUDIO · pie ─────────────────────────────────────────────
   Pere, 2026-08-24, y REHECHA el mismo día tras su rechazo: «no me gusta como lo
   has puesto quiero, que este en medio y mas grande, ademas cuando la ves desde
   el movil no se ve». Centrada, grande, y sin la atenuación en reposo que nadie
   pidió. Sigue DENTRO del pie del cliente y por debajo de su copyright: «más
   grande» no reabre la franja aparte, que él descartó de entrada.

   🔴 POR QUÉ NO SE VEÍA EN EL MÓVIL — MEDIDO EN CHROME, no deducido. No era el
   tamaño ni el contraste: era OCLUSIÓN. `.accfija` —la barra fija de acciones
   del móvil, `position:fixed`, z-index 95 y fondo OPACO `--plano-0`— mide
   65 px a 390/430 y 80,2 px a 320 (y 80,2 también a 390 en italiano, en Dénia),
   mientras que `.pieF` sólo reservaba `--s5` = 36 px por debajo de su última
   fila. La firma, de 44 px, caía entera dentro de esa banda sin reservar:
     · 320 px → 43,9 de 44 px tapados (100 %) · `elementFromPoint` sobre el
       logotipo y sobre el texto devuelve el BOTÓN de la barra;
     · 390 px → 29,3 de 44 (67 %) · devuelve `DIV.accfija`;
     · 430 px → 29,4 de 44 (67 %) · devuelve `DIV.accfija`.
   Medido en los tres locales y en los dos estados del aviso de cookies.
   ⚠️ Y el defecto es ANTERIOR a la firma: en la versión sin ella los últimos
   28,7 px de `.pieF__bajo` —los descendentes de los enlaces legales— ya estaban
   debajo de la barra. Lo que hizo la firma fue caer entera en la banda.
   El arreglo es reservar la banda, abajo, y NO agrandar la firma: agrandarla
   sola la habría dejado igual de tapada.

   `flex-basis:100%` va en el ENVOLTORIO, no en el <a>: si fuera del enlace su
   caja mediría toda la fila y el `:hover` se encendería a 300 px de la firma,
   sobre nada. El envoltorio centra; el <a> mide lo que mide su contenido.

   🔵 2026-08-24 (tarde) · VUELVE EL LOGOTIPO, Y AHORA ES EL BUENO.
   Pere: «ahora mismo no se ve ningun logo en ninguna de las webs vendidas, sale
   web hecha por PDSites pero no sale logo, añadelo (el logo bueno)». El fichero
   es `pdsites-firma.webp` (320×253, WebP con alfa), derivado por `media-agent`
   de `PDSites/Website/assets/img/logo-pd.webp`, que Pere confirmó hoy que es la
   marca buena. Aquí NO lleva pastilla ni relleno de ningún tipo: se pinta
   directo sobre el grafito del pie, que es lo que pide la regla de «ni marco ni
   peana alrededor del logotipo».

   🔴 CONTRASTES MEDIDOS, no supuestos (el texto sube de 16 a 17 px — «más
   grande» es del conjunto, no sólo del dibujo):
   · texto  --crema #F7E9DB sobre el grafito #1C1C1C ......... 14,31:1 ✓ AA
   · logotipo, blanco 253,253,253 sobre ese mismo grafito .... 16,75:1 ✓
     (medido por `media-agent` sobre el propio fichero)

   🔴 LA RESERVA DE `.accfija` SE VOLVIÓ A MEDIR AL AGRANDAR LA FIRMA, porque el
   número de antes no vale cuando la pieza crece — `Standards.md` 2026-08-24. La
   firma pasó de 44 px de alto a 121,3 (320 px, donde envuelve en dos filas) y a
   94,9 (390 y 430, donde entra en una). Medido en Chrome sobre las TRES webs, a
   320/390/430, en castellano y en italiano, y en los dos estados del aviso de
   cookies — 36 combinaciones:
     · `.accfija` sigue midiendo lo mismo que entonces: 80,2 px es el peor caso
       (320 px en las dos lenguas, y 390 px en italiano en Dénia) y 65 px el
       resto. Es el alto de la BARRA, y la firma no lo toca.
     · El aire real entre el canto inferior de la firma y el canto superior de
       la barra va de **43,3 px** (el peor caso, 320 px) a 59,5 px.
     · `elementFromPoint` en NUEVE puntos repartidos por la caja de la firma
       devuelve un elemento de dentro de la propia firma en las 36 combinaciones:
       ni un solo punto tapado por nada fijo.
   Conclusión medida: **los 88 px se quedan como estaban**, y no por inercia —
   la reserva es función del alto de `.accfija`, no del de la firma, y el pie
   crece por dentro (`padding-bottom` total 124 px = 88 + `--s5`).
                                                                              */
.pieF__firma{
  flex-basis:100%; display:flex; justify-content:center;
  margin-top:var(--s4);
}
/* 🔴 LA ZONA PULSABLE TIENE QUE COINCIDIR CON LA TINTA, y con `flex-wrap` no
   coincide. Medido a 320 px: envolviendo, la caja del <a> medía 280 px —el
   ancho disponible— mientras su fila más ancha eran ~188, o sea ~46 px
   pulsables a cada lado que no dibujan nada. Un enlace NUESTRO que se traga
   dedos en el pie del cliente es exactamente lo que no toca hacer en casa
   ajena, y con el aviso de cookies en pie esa caja llega a 28-32 px del botón
   «Aceptar».
   `width:fit-content` sobre un contenedor `flex-wrap:wrap` NO lo arregla: al
   envolver, el contenido reclama todo el ancho disponible y `fit-content`
   devuelve ese mismo ancho. Lo que sí lo arregla es que el apilado sea
   EXPLÍCITO — `flex-direction:column` —, porque entonces el ancho de máximo
   contenido es el del hijo más ancho y la caja se ciñe sola. El resultado en
   pantalla es idéntico al de antes; lo único que cambia es dónde se puede
   pulsar. Y a partir del punto de corte vuelve a ser una fila, que es la forma
   «en línea» que eligió Pere.                                                 */
.firma{
  display:inline-flex; flex-direction:column;
  align-items:center; justify-content:center;
  gap:8px;
  width:fit-content; max-width:100%;
  min-height:44px;                             /* WCAG 2.5.8 · objetivo táctil */
  color:var(--crema); text-decoration:none;
  font-size:17px; line-height:1.2; letter-spacing:var(--tr-meta);
  text-align:center;
}
/* El punto de corte es MEDIDO, no elegido: la fila más larga es la italiana
   —«Sito realizzato da PDSites»— y con el dibujo a 160 px pide 160 + 16 + 212,8
   = 388,8 px, más los ~28-30 de canalón del pie. Por debajo de eso no cabe en
   una línea en NINGUNA de las tres lenguas, así que se apila.
   `flex-wrap:wrap` se conserva aquí arriba a propósito: si un día una lengua
   creciera, la fila envuelve en vez de desbordar. */
@media (min-width:480px){
  .firma{ flex-direction:row; flex-wrap:wrap; gap:6px 16px }
}
/* 🔵 EL LOGOTIPO. `width` es la anchura del DIBUJO, no de una caja: aquí no hay
   relleno ni pastilla porque el suelo del pie ya es el grafito y el perfil
   blanco se lee encima sin ayuda (16,75:1, medido por `media-agent` sobre el
   fichero, no supuesto). El `height:auto` deja que el 320×253 del atributo
   fije la proporción, así que la caja está reservada antes de que la imagen
   llegue y el pie no salta.
   🔴 LOS 160 px SALEN DE LA RESOLUCIÓN DEL FICHERO, NO DEL GUSTO — y es el
   ÚNICO techo que puede escribirse aquí, porque es aritmética y no criterio.
   `Standards.md` (f) del 2026-08-24 prohíbe expresamente poner en este sitio un
   límite en píxeles que Pere no haya dicho: se construye por lo alto y lo baja
   él. (Una versión anterior de este comentario, del mismo día, se inventó otro
   techo — «no más ancha que el logotipo del cliente» — y se retiró entero: era
   el mismo acto, disfrazado de prudencia.)
   La cuenta:
     · `PDSites/Website/assets/img/logo-pd.webp` mide 313 px de ancho y es la
       copia de MAYOR resolución que existe de la marca (`PDSites/Brief.md`
       §Assets: la de la tarjeta la trae a ~290 px y no es mejor).
     · el derivado `pdsites-firma.webp` son 320 px.
     · pintado a 160 css · dpr 2 → pide 320 px de fichero → EXACTO, sin ampliar.
     · pintado a 200 css · dpr 2 → pediría 400 px → AMPLÍA ×1,25, o sea blando.
   Mismo número en las cuatro webs firmadas.

   ⚠️ Y LO QUE ESTO NO ARREGLA, dicho como medida y no como excusa: el
   circuito-arbolito de dentro de la D —que es justamente lo que distingue el
   logotipo bueno del redibujo del favicon que Pere rechazó— tiene trazos de
   3 px de mediana sobre el fichero de 320 y de 1 px en su percentil 10. A
   120 px eso eran 0,75 px de pantalla a dpr 2: se perdía. A 160 px el trazo
   fino llega justo a 1,00 px y la mediana a 3,00. **Con el artwork que existe
   hoy, el circuito no va a quedar nítido a tamaño de firma por mucho CSS que
   se le ponga: hace falta el vectorial.** Es una decisión de marca, de Pere. */
.firma__l{ display:block; width:160px; height:auto }
.firma:focus-visible{ text-decoration:underline; text-underline-offset:4px }
@media (hover:hover) and (pointer:fine){
  .firma:hover{ text-decoration:underline; text-underline-offset:4px }
}
/* 🔴 LA RESERVA DE LA BANDA DE `.accfija`. Va DESPUÉS de la regla base de
   `.pieF`, porque un `@media` no añade especificidad y a igualdad gana la que
   está más abajo. Se acota a `max-width:899px` porque a partir de 900 px
   `.accfija` es `display:none` y no hay nada que reservar.
   88 px = los 80,2 px medidos como peor caso + 7,8 de holgura; `env()` sube con
   el mismo notch con el que sube la propia barra.
   ⭐ REMEDIDO el 2026-08-24 por la tarde, al agrandar la firma y meterle el
   logotipo: `.accfija` sigue en 80,2 px de peor caso y el canto inferior de la
   firma queda 43,3 px por encima de la barra en el peor de los 36 casos
   medidos (320 px). El número se queda; la comprobación no se dio por hecha. */
@media (max-width:899px){
  .pieF{ padding-bottom:calc(var(--s5) + 88px + env(safe-area-inset-bottom,0px)) }
}
@media (hover:hover) and (pointer:fine){
  .pieF__nav a:hover{ color:var(--crema) }
  .pieF__tel:hover{ color:var(--turquesa) }
}
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    .pieF__cuerpo{
      animation:revelar both;
      animation-timeline:view(); animation-range:entry 2% cover 18%;
    }
  }
}
/* `position:relative` desde el 2026-08-23: es el bloque contenedor del panel
   de idiomas del pie — ver la nota en `.idiomas--arriba`. */
.pie__legal{ position:relative; display:flex; flex-wrap:wrap; gap:var(--s2) var(--s3) }
.pie__legal .nav__lang{
  width:auto; min-height:44px; border-bottom:0; color:var(--crema-2);
  text-decoration:underline; text-underline-offset:3px; font-weight:400;
  font-size:var(--t-meta); letter-spacing:var(--tr-meta); text-transform:none;
}

/* ── La barra fija de acciones (móvil) ──────────────────────────────────────
   Aparece SÓLO tras pasar el pliegue, nunca lo tapa, y se retira mientras la
   comanda tiene contenido: nunca hay dos objetos fijos a la vez.
   env(safe-area-inset-bottom) + viewport-fit=cover en el <meta>: los dos.      */
.accfija{
  position:fixed; left:0; right:0; bottom:0; z-index:95;
  display:grid; grid-template-columns:minmax(0,1.4fr) minmax(0,1fr); gap:8px;
  padding:8px var(--edge) calc(8px + env(safe-area-inset-bottom));
  background:var(--plano-0); border-top:1px solid var(--linea);
  transform:translateY(110%);
  transition:transform 240ms var(--ease-drawer);
}
.accfija.is-on{ transform:none }
.accfija .btn--pri{ min-height:48px }
@media (min-width:900px){ .accfija{ display:none } }

/* ── La comanda: una línea fija y un tique. No es una tienda ─────────────────── */
.dock{
  position:fixed; left:0; right:0; bottom:0; z-index:96;
  background:var(--plano-1); border-top:1px solid var(--linea);
  box-shadow:var(--filo),var(--sombra-2);
  padding-bottom:env(safe-area-inset-bottom);
}
/* A10 · degradación bajo `prefers-reduced-motion` / saveData / 2g: el plato NO
   vuela; el número del dock cambia de color durante 180 ms, cero
   desplazamiento. Reduced motion no es cero movimiento: es una equivalencia más
   suave (apple-design §14).                                                    */
.dock__c b{ transition:color 180ms var(--ease-out) }
.dock.is-tick .dock__c b{ color:var(--turquesa) }
.dock__b{
  display:grid; grid-template-columns:auto auto minmax(0,1fr); align-items:center; gap:var(--s3);
  width:100%; min-height:52px; padding:0 var(--edge); cursor:pointer; text-align:left;
}
.dock__b:active{ transform:scale(.97); transition:transform 140ms var(--ease-out) }
.dock__c{ font-size:var(--t-meta); color:var(--crema-2); white-space:nowrap }
.dock__t{ font-size:var(--t-body); font-weight:700; font-variant-numeric:lining-nums tabular-nums; white-space:nowrap }
.dock__go{
  justify-self:end; font-size:var(--t-micro); font-weight:600;
  letter-spacing:var(--tr-micro); text-transform:uppercase; color:var(--crema);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* ── El tique ────────────────────────────────────────────────────────────
   El panel deja de ser una hoja que sube desde abajo y pasa a ser un TIQUE
   DE PAPEL, flotando centrado sobre el fondo — el mismo tique de Orno
   Benidorm (skill carta-y-comanda, actualizado 2026-08-03 por Diego): canto
   rasgado abajo, rayas de puntos entre líneas, precios en columna, y el
   óvalo del restaurante encabezando el papel. El papel usa --crema/--grafito
   TAL CUAL —el cremoso de su mantel, la tinta de su marca— como color, no
   como «texto sobre fondo oscuro»: ya hay un precedente de este mismo doble
   uso en --ch-plano, sobre .sec--carta. */
.ticket{ position:fixed; inset:0; z-index:120; display:grid; place-items:center; padding:var(--edge) }
.ticket__fondo{ position:absolute; inset:0; background:rgba(10,10,10,.78) }
.ticket__papel{
  position:relative; width:min(100%,440px); max-height:88vh; max-height:88svh;
  overflow:auto; background:var(--crema); color:var(--grafito);
  border-radius:var(--r-control);
  box-shadow:var(--sombra-3);
  padding:var(--s4) var(--edge) calc(var(--s5) + env(safe-area-inset-bottom));
  display:grid; gap:var(--s3); align-content:start; justify-items:center; text-align:center;
  /* el canto rasgado: una máscara radial repetida corta el papel por abajo */
  -webkit-mask:radial-gradient(7px 9px at 12px 100%,transparent 96%,#000 100%) 0 100%/24px 18px repeat-x,
               linear-gradient(#000,#000) 0 0/100% calc(100% - 9px) no-repeat;
  mask:radial-gradient(7px 9px at 12px 100%,transparent 96%,#000 100%) 0 100%/24px 18px repeat-x,
       linear-gradient(#000,#000) 0 0/100% calc(100% - 9px) no-repeat;
}
.ticket__x{
  position:absolute; top:var(--s2); right:var(--s2); width:44px; height:44px;
  border:0; background:transparent; cursor:pointer; font-size:20px; line-height:1;
  color:rgba(28,28,28,.5);
}
@media (hover:hover) and (pointer:fine){ .ticket__x:hover{ color:var(--grafito) } }
/* el óvalo, encabezando el papel — nunca un icono genérico */
.ticket__marca{ display:block; width:clamp(84px,22vw,112px); height:auto; margin:0 0 .2rem }
.ticket__h{ font-size:var(--t-meta); font-weight:700; letter-spacing:var(--tr-meta); text-transform:uppercase }
.ticket__nota{ font-size:var(--t-meta); color:rgba(28,28,28,.62); max-width:32ch }
.ticket__lista{ list-style:none; margin:0; padding:0; width:100%; border-top:1px dashed rgba(28,28,28,.28); text-align:left }
.ticket__it{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto; align-items:center; gap:var(--s2);
  padding:var(--s2) 0; border-bottom:1px dashed rgba(28,28,28,.28);
}
.ticket__it .nom{ min-width:0; font-size:var(--t-meta) }
.ticket__it .q{ display:flex; align-items:center; gap:.3rem }
.ticket__it .q button{
  width:32px; height:32px; border:1px solid rgba(28,28,28,.22); background:transparent;
  border-radius:var(--r-control); cursor:pointer; font-size:15px; font-weight:700; color:var(--grafito);
  transition:transform 140ms var(--ease-out), border-color 200ms var(--ease-out);
}
.ticket__it .q button:active{ transform:scale(.94) }
@media (hover:hover) and (pointer:fine){ .ticket__it .q button:hover{ border-color:var(--grafito) } }
.ticket__it .q output{ min-width:1.6rem; text-align:center; font-variant-numeric:lining-nums tabular-nums }
.ticket__it .pr{ font-size:var(--t-meta); font-weight:600; font-variant-numeric:lining-nums tabular-nums; white-space:nowrap; min-width:56px; text-align:right }
@media (max-width:400px){
  .ticket__it{ grid-template-columns:1fr auto; grid-template-areas:"n n" "q p"; row-gap:.35rem }
  .ticket__it .nom{ grid-area:n } .ticket__it .q{ grid-area:q } .ticket__it .pr{ grid-area:p }
}
.ticket__vacia{ font-size:var(--t-meta); color:rgba(28,28,28,.62) }
.ticket__total{
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--s3); width:100%;
  border-top:2px solid var(--grafito); padding-top:var(--s3);
  font-size:var(--t-body); font-weight:700; font-variant-numeric:lining-nums tabular-nums;
  letter-spacing:var(--tr-meta); text-transform:uppercase;
}
.ticket__pie{ font-size:var(--t-micro); color:rgba(28,28,28,.55) }
.ticket__acc{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; width:100% }
/* ⚠️ `.btn--sec` por defecto es tinta --crema (casi blanca) para leerse sobre
   --grafito. En el papel del tique el fondo YA es --crema: sin esto el botón
   era texto crema sobre papel crema, invisible — visto en el propio render. */
.ticket__acc .btn--sec{ color:var(--grafito); border-color:rgba(28,28,28,.28) }
@media (hover:hover) and (pointer:fine){
  .ticket__acc .btn--sec:hover{ border-color:var(--grafito); background:rgba(28,28,28,.05) }
}

/* ══ A10 · EL PLATO VUELA A LA COMANDA ═══════════════════════════════════════
   Al pulsar el «+» de una fila sale una ficha con el nombre del plato desde el
   punto pulsado y aterriza en el contador del dock. Mecanismo de Ozoa
   (`.chispa` / `volar()`), reescrito.
   El Gate de las cuatro preguntas, contestado:
     1 frecuencia · ocasional ✓
     2 propósito  · FEEDBACK: dice que la acción llegó y ADÓNDE ✓
     3 velocidad  · no es UI de espera, es confirmación posterior ⇒ >300 ms
                    permitido; 420 ms, con la opacidad cayendo en los últimos
                    140 (delay 280) ✓
     4 función    · AYUDA — el dock está fuera de la vista al pulsar y esto es
                    lo único que los conecta ✓
   ⚠️ NO es un rectángulo macizo de turquesa: el presupuesto del acento es «como
   máximo uno por altura de ventana» y el botón primario suele estar en
   pantalla. La ficha es un PLANO ELEVADO con el motivo —la banda de 3 px— en su
   canto: la banda se dibuja donde la página dice «esto está encendido», y un
   plato que se añade lo está.
   Es `transition` y no `@keyframes`: se puede pulsar diez veces seguidas y cada
   ficha es un nodo propio que se borra solo.                                   */
.vuela{
  position:fixed; z-index:130; pointer-events:none;
  max-width:min(60vw,220px); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  padding:.35rem .55rem;
  background:var(--plano-1); color:var(--crema);
  border-left:3px solid var(--turquesa);
  border-radius:var(--r-control);
  box-shadow:var(--filo),var(--sombra-2);
  font-size:var(--t-micro); font-weight:600;
  letter-spacing:var(--tr-micro); text-transform:uppercase; line-height:1.35;
  transform:translate(0,0) scale(1); opacity:1;
  transition:transform 420ms var(--ease-out),opacity 140ms linear 280ms;
}
.vuela.is-ida{ opacity:0 }

/* ── Los controles que SÓLO existen con JavaScript ──────────────────────────
   Un botón que no hace nada es un defecto, no un adorno.
   🔴 `[data-idiomas]` SUSTITUYE A `[data-lang-toggle]` el 2026-08-23, y el
   cambio de selector NO es cosmético: el atributo viejo desaparece con el
   marcado viejo, así que dejarlo escrito aquí habría pintado el control sin
   script. Y sin script el `<details>` SÍ se abre —es nativo— pero los tres
   botones no hacen nada: un control cuyo nombre accesible promete «abrir la
   lista de idiomas» y que abre una lista que no lleva a ningún sitio. Es la
   regla de «nunca entregues un control cuya etiqueta prometa un mecanismo que
   la plataforma no soporta», por la puerta de atrás. Oculto entero hasta que
   `.js` demuestra que hay script — mismo remate que Dénia.                     */
[data-map-btn],[data-idiomas]{ display:none }
.js [data-map-btn]{ display:inline-flex }
.js [data-idiomas]{ display:block }

/* ── EL AVISO DE COOKIES VIVE ABAJO ─────────────────────────────────────────
   lib/cookie-consent.js mide su propio alto, lo publica en `--ws-cb` y marca
   <html> con `.ws-cb-open`; esto es el otro lado del contrato.                 */
:root{
  --ws-cb:0px;
  --ws-cookiebar-bg:var(--plano-1);
  --ws-cookiebar-fg:var(--crema);
  --ws-cookiebar-font:var(--texto);
  --ws-cookiebar-line:var(--linea);
  --ws-cookiebar-btn:var(--linea-2);
  --ws-cookiebar-radius:0;
  --ws-cookiebar-z:97;
}
.ws-cb-open .dock{ bottom:var(--ws-cb,0px); padding-bottom:0 }
.ws-cb-open .accfija{
  bottom:var(--ws-cb,0px); padding-bottom:8px;
  transform:translateY(calc(110% + var(--ws-cb,0px)));
}
.ws-cb-open .accfija.is-on{ transform:none }
/* 🔴 2026-08-23 · EL PANEL DEL <nav> TAMBIÉN RESERVA SITIO PARA EL AVISO.
   Es UNA línea y se deshace en un segundo, pero sin ella el selector de idioma
   —que es la última fila del panel— no se puede ni ver en una pantalla corta.
   Medido a 320×568 con el aviso levantado: el aviso mide 193 px, el panel llega
   hasta 568 y su última fila ocupa y 495-547, o sea **entera por debajo del
   aviso**; y el panel sólo se puede desplazar 15 px (530 de contenido contra
   515 de hueco), que no despeja 193. La última sección —«Venir» cuando se
   midió, «Venid» desde esa misma noche— estaba igual de tapada.
   ⚠️ NO es un defecto que traiga esta ronda: medido byte a byte contra el commit
   7b815d4 (antes de tocar nada), la geometría era **idéntica** — el botón
   cíclico de idioma estaba tan escondido como lo está ahora el desplegable.
   Se arregla aquí porque el encargo de hoy dice que el control no puede quedar
   inalcanzable por debajo del punto de corte, y esta era la única anchura donde
   lo quedaba. Usa el contrato `--ws-cb` que ya existe (lo consumen `.dock` y
   `.accfija` justo aquí arriba); no inventa nada.

   🔴 Y VA ACOTADA POR `max-width`, que no es un detalle: por ENCIMA del punto de
   corte `.nav__panel` deja de ser un panel fijo y pasa a ser una caja ESTÁTICA
   dentro de los 64 px de la barra, con `padding:0`. Sin acotar, este
   `padding-bottom` la estiraba dentro de la barra y empujaba la fila entera
   hacia arriba: medido, el código del disparador se iba a **y = −31 px**, o sea
   fuera de la pantalla. Un `@media` NO añade especificidad, así que el
   `padding:0` del bloque `min-width:1024px` —que está más arriba en la hoja— no
   podía defenderse solo.                                                       */
@media (max-width:1023.98px){
  .ws-cb-open .nav__panel{
    padding-bottom:calc(var(--s5) + var(--ws-cb,0px) + env(safe-area-inset-bottom));
  }
}
/* 🔴 2026-08-17 · CAE EL `max-width:1199px`, Y ES CONSECUENCIA DIRECTA DE QUE LA
   PORTADA DE ESCRITORIO PASE A OCUPAR LA PANTALLA ENTERA.
   La reserva existía sólo por debajo de 1200 px porque hasta hoy el héroe de
   escritorio medía `min(88vh,792px)`: el tope dejaba suelo de sobra bajo el
   contenido y la barra de cookies caía en ese suelo. Con `100svh` ya no hay
   suelo, y está MEDIDO en Chrome real (ventana = alto útil exacto, barra de
   cookies abierta, que es el estado de la primera visita):
                       fila de botones      barra        holgura
     1366×768 antes     596 → 710         696 → 768      −14 px  (ya rozaba)
     1366×768 sin esto  607 → 721         696 → 768      −25 px
     1440×900 sin esto  673 → 787         828 → 900      +41 px
   O sea: a 1366 los dos botones secundarios quedaban 25 px POR DEBAJO del canto
   de la barra. No se recortaban —la caja se pinta entera— pero un control tapado
   por una superficie opaca es un control que el visitante no puede pulsar.
   Con la reserva, el héroe mide `100svh − barra` mientras la barra está abierta:
   los botones quedan libres y lo que se ve al pie de la pantalla es la barra
   —opaca, `--plano-1`— y NO el arranque de §2. En cuanto el visitante acepta o
   rechaza, `.ws-cb-open` se va y el héroe vuelve a medir la pantalla exacta.
   ⚠️ El `max-height:1000px` SE QUEDA: por encima de esa altura no hay colisión
   (a 1680×1050 la holgura medida es +102 px y a 1920×1080 +131 px), y ampliarlo
   encogería el héroe donde no hace falta.                                      */
@media (max-height:1000px){
  @supports (height:1svh){
    .ws-cb-open .hero{ min-height:calc(100svh - var(--ws-cb,0px)) }
  }
}

/* ── A1 · Reveals · nativo, con respaldo ────────────────────────────────────
   ESTADO POR DEFECTO: VISIBLE. Lo único que oculta algo es una clase que pone
   el propio JavaScript, y lleva un temporizador de 4 s que la retira pase lo
   que pase. Un main.js que falte no puede borrar la página (ESENS r3).
   ⭐ ESCALONADO POR NIVEL: nivel 1 sube 18 px, nivel 2 sube 14, nivel 3 sube 10.
   ⭐ r7b · 60 ms entre hermanos, GRUPOS DE TRES, retardo máximo 120 ms (r7:
   grupos de 4, 180 ms). `emil-design-eng`: el tope es el retardo TOTAL, no el
   escalón — y con 5 piezas en el aparejo y 8 filas de carta por pantalla, 240 ms
   acumulados se notan como lentitud. Nada bloquea la interacción en ningún
   momento.
   🔴 Sólo `opacity` y `transform`: un reveal con clip-path deja al observador
   informando ratio 0,000 y su imagen diferida no se descarga jamás (Ozoa r5).  */
@media (prefers-reduced-motion: no-preference){
  @supports (animation-timeline: view()){
    [data-reveal]{
      animation:revelar var(--rev-d,480ms) var(--ease-out) both;
      animation-timeline:view();
      animation-range:entry calc(3% + var(--i,0) * 5%) cover calc(12% + var(--i,0) * 5%);
    }
    @keyframes revelar{
      from{ opacity:0; transform:translateY(var(--rev-y,34px)) scale(.975) }
      to{ opacity:1; transform:none }
    }
  }
  .js-rev [data-reveal]{
    opacity:0; transform:translateY(var(--rev-y,34px)) scale(.975);
    transition:opacity var(--rev-d,480ms) var(--ease-out),
               transform var(--rev-d,480ms) var(--ease-out);
    transition-delay:calc(var(--i,0) * 60ms);
  }
  .js-rev [data-reveal].es-visible{ opacity:1; transform:none }

  /* ══ P1 · LA COSTURA QUE SE ABRE ═══════════════════════════════════════
     Cada pieza crece DESDE LA COSTURA QUE COMPARTE CON SU VECINA en vez de
     aparecer con un `fade` genérico. Eso es lo que dice que las piezas
     PERTENECEN A UNA MISMA SUPERFICIE, que es justo lo que hoy no se lee:
     «un fondo con fotos y vídeos pegados».
     620 ms · --ease-out · escalonado 90 ms en grupos de 3 (retardo total
     máximo 180 ms, que es el tope de `emil-design-eng`).

     🔴 LA TRAMPA QUE ESTO ESQUIVA, y costó doce fotos en Ozoa r5: un
     `clip-path` sobre un elemento OBSERVADO deja al IntersectionObserver
     informando ratio 0,000 para siempre y su imagen diferida no se pide
     jamás. Aquí el clip-path va sobre las PIEZAS, que no las observa nadie:
     lo observado es su contenedor (`[data-reveal]`), que sólo mueve
     `opacity`/`transform`. Y el `clip-path` no toca la maqueta, así que el
     `loading="lazy"` de cada imagen sigue disparando con normalidad.        */
  .js-rev [data-reveal] .aparejo__t,
  .js-rev [data-reveal] .cartel__m,
  .js-rev [data-reveal] .ficha__p{
    clip-path:inset(0 0 100% 0);
    transition:clip-path 620ms var(--ease-out);
    transition-delay:calc(var(--p,0) * 90ms);
  }
  .js-rev [data-reveal].es-visible .aparejo__t,
  .js-rev [data-reveal].es-visible .cartel__m,
  .js-rev [data-reveal].es-visible .ficha__p{ clip-path:inset(0) }
  /* El aparejo abre EN ESPEJO desde su costura horizontal: la fila de arriba
     crece hacia abajo, la de abajo hacia arriba. El cartel, desde la costura
     vertical que comparten sus dos medias.                                  */
  .js-rev [data-reveal] .aparejo__t--carne,
  .js-rev [data-reveal] .aparejo__t--corte{ clip-path:inset(100% 0 0 0) }
  .js-rev [data-reveal] .cartel__m--a{ clip-path:inset(0 0 0 100%) }
  .js-rev [data-reveal] .cartel__col{ clip-path:inset(0 100% 0 0);
    transition:clip-path 620ms var(--ease-out); transition-delay:90ms }
  .js-rev [data-reveal].es-visible .cartel__col{ clip-path:inset(0) }
  .aparejo__t--masa{ --p:1 }
  .aparejo__t--lena{ --p:2 }
  .ficha__p--semana{ --p:1 }
  .ficha__p--mapa{ --p:2 }

  /* La misma apertura, en el camino NATIVO (sin observador y sin `.js-rev`). */
  @supports (animation-timeline: view()){
    .aparejo__t,.cartel__m,.cartel__col,.ficha__p{
      animation:abre-costura 620ms var(--ease-out) both;
      animation-timeline:view();
      animation-range:entry 4% cover 22%;
    }
    @keyframes abre-costura{
      from{ clip-path:inset(0 0 100% 0) }
      to{ clip-path:inset(0) }
    }
  }

  /* La cabecera de la portada entra COMO UN SOLO OBJETO a los 140 ms, y 160 ms
     después —y sólo entonces— se enciende la luz: el relleno turquesa barre el
     botón de izquierda a derecha. Es la idea de la página en el primer segundo. */
  .hero__cuerpo{ animation:entrada .52s var(--ease-out) .14s both }
  @keyframes entrada{ from{ opacity:0; transform:translateY(14px) } to{ opacity:1; transform:none } }
  .hero .btn--pri::before{ animation:encender .22s var(--ease-out) .82s both }
  @keyframes encender{ from{ transform:scaleX(1) } to{ transform:scaleX(0) } }
}

/* Reduced motion NO es «cero animación»: es una equivalente más suave
   (apple-design §14). Los reveals se quedan visibles, la pista sigue
   deslizándose, los doce huecos enseñan su fotograma real, y el feedback al
   pulsar SE MANTIENE porque es respuesta, no movimiento vestibular.            */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:1ms !important; animation-delay:0ms !important;
    transition-duration:1ms !important;
  }
  .paso{ opacity:1; transform:none }
  .btn:active,.pick:active,.ticket__it .q button:active,.dock__b:active,
  .fam__cab:active,.sem__f:active{ transition-duration:140ms !important }
  /* A11 · la placa NO escala; cambia de opacidad .82 → 1. Misma información,
     cero movimiento. (A10 degrada en JS: la ficha no vuela y el número del dock
     cambia de color 180 ms.)                                                   */
  .fam__im{ transform:none !important; opacity:.82 }
  .fam[open] > .fam__cab .fam__im{ opacity:1 }
  .dock__c b{ transition-duration:180ms !important }
  /* 🔴 EL PLINTO Y EL GRANO NO SON MOVIMIENTO Y SE QUEDAN. Esta página se ha
     quedado en blanco DOS VECES por reglas de reduced-motion que apagaban
     contenido en vez de apagar animación. Aquí no se oculta nada: sólo se
     acortan duraciones.                                                        */
}

/* ── Impresión ─────────────────────────────────────────────────────────────
   Cmd+P con el tique cerrado imprime LA CARTA. Sólo el botón «Imprimir» de la
   comanda pone .imprimiendo, y entonces se imprime el tique.                   */
@media print{
  :root{
    --grafito:#fff; --grafito-2:#fff; --plano-0:#fff; --plano-1:#fff;
    --crema:#111; --crema-2:#555; --turquesa:#111;
    --linea:#ccc; --linea-2:#bbb;
    /* sombras transparentes, no `none`: `box-shadow: none, none` es sintaxis
       inválida y el resultado dependería de la recuperación del navegador.     */
    --filo:0 0 0 rgba(0,0,0,0);
    --sombra-1:0 0 0 rgba(0,0,0,0);
    --sombra-2:0 0 0 rgba(0,0,0,0);
    --sombra-3:0 0 0 rgba(0,0,0,0);
  }
  *,*::before,*::after{ animation:none !important; transition:none !important }
  body::before{ display:none !important }     /* el grano no se imprime */
  html,body{ background:#fff; color:#111 }
  .bar,.nav,.accfija,.dock,.skip,.hero__fondo,.hero__velo,.aparejo,.pista,.cartel__m,
  .ficha__m,.puerta,.mapa,.pick,.cierre__acc,.remate__m,.vuela,.ws-cookiebar{ display:none !important }
  .fam__placa{ display:none !important }
  .fam__cab{ min-height:0 !important }
  .hero{ min-height:0 !important; display:block; padding:0 }
  .hero__cuerpo{
    padding:0; width:auto; max-width:none; margin:0; text-align:left;
    background:none; box-shadow:none; border-radius:0;
  }
  body{ padding-bottom:0 !important }
  a{ text-decoration:none; color:#111 }
  details.fam::details-content{ content-visibility:visible !important; block-size:auto !important }
  .fam__cuerpo{ break-inside:auto; background:#fff; border-color:#ccc }
  .carta__row{ break-inside:avoid }
  .ticket{ display:none }
  body.imprimiendo > *{ display:none !important }
  body.imprimiendo .ticket{ display:grid !important; position:static; background:#fff; padding:0 }
  body.imprimiendo .ticket__fondo,body.imprimiendo .ticket__acc,
  body.imprimiendo .ticket__x,body.imprimiendo .ticket__it .q{ display:none !important }
  body.imprimiendo .ticket__papel{
    background:#fff; color:#111; max-height:none; overflow:visible; width:auto;
    box-shadow:none; mask:none; -webkit-mask:none;
  }

  /* 🔴 LA FIRMA DEL ESTUDIO NO SE IMPRIME — ES UNA DECISIÓN, NO UN OLVIDO.
     Y una carta de restaurante es exactamente lo que la gente imprime.
     ⭐ 2026-08-24 (tarde) · REVISADO AL VOLVER A ENTRAR EL LOGOTIPO, que es
     justo lo que esta regla tenía que volver a mirar. Nuestra marca es una P
     PERFILADA EN BLANCO: sobre el papel blanco de una impresora no existe —
     el mismo dibujo mide 1,09:1 sobre el papel claro de La Palmera—, y en una
     hoja impresa no hay un plano oscuro donde apoyarla. Así que la razón del
     contraste vuelve a estar viva y se suma a las dos de abajo: son tres.
     ⚠️ Y la respuesta NO es imprimir el dibujo con una pastilla oscura detrás:
     eso son 188×121 px de tinta negra maciza en cada hoja de una carta que un
     restaurante imprime a docenas. Se retira entera, logotipo y frase.
     Se retira entera por tres razones:
     1) Esta hoja YA retira todo lo que es afordancia de pantalla y no carta —
        la barra, el nav, la barra fija, la comanda, el mapa, el fondo del hero.
        Una firma cuya única función es un enlace no sobrevive al papel: en una
        hoja impresa no se puede pulsar, así que no entrega nada.
     2) El alcance que fijó Pere el 2026-08-24 es «en todas las WEBS que
        publiquemos». Una carta impresa no es una web: es papel del restaurante,
        y colgar nuestra marca ahí es más de lo que se ha decidido.
     El copyright del cliente y sus enlaces legales SIGUEN imprimiéndose.        */
  .pieF__firma{ display:none !important }
}
