/* ═══════════════════════════════════════════════════════════════════════════════
   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)
       ⚠️ 2026-08-22 · ESTE TECHO YA NO DESCRIBE LA PÁGINA, y se deja escrito en
       vez de reescrito porque cambiar un límite declarado del estudio es
       decisión de un socio, no de una ronda. Medido hoy a 1440, dos piezas por
       encima:
         · `.tira__m--ancha` (§5, la barra) ......... 653 px — desde la r8, 21-08
         · `.cartel__rotulo` (§5, el rótulo) ........ 855 px — desde esta ronda
       Las dos son piezas APAISADAS cuyo sujeto llega a los dos cantos del
       fichero, así que estrecharlas a 480 no las encoge: las RECORTA, y en el
       rótulo se llevaría por delante «Ristorante» y «Pizzería». Ninguna de las
       dos corre por encima de su fichero (la barra 0,60×, el rótulo 0,79×), que
       es la regla que de verdad protege la nitidez. Queda como pregunta abierta:
       o el techo se redacta como «ninguna pieza por encima de 1,35× su nativo»,
       o se declara una excepción para la pieza apaisada de ancho completo.
       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);
  /* ⭐ r9 · 2026-08-22 · EL RÓTULO de §5. Vive pegado a `--cartel-h` por lo
     mismo que `--casa-h`: misma sección, misma familia de alturas de pieza. NO
     es un número inventado en el sitio donde hacía falta.
     `fachada-rotulo-noche` es 1.080 × 400 en disco ⇒ 2,70 de proporción, y su
     sujeto —las letras— llega a los DOS cantos del fichero, así que el recorte
     de `cover` sólo puede comerse ALTO: perder ancho sería perder letras. La
     caja se dimensiona por tanto a una razón de 3,0 fija, un 11 % más alargada
     que el fichero, y ese 11 % de alto se lo lleva `object-position:50% 40%`
     sobre todo del toldo de abajo.
     ⚠️ SON DOS CAJAS DISTINTAS Y POR ESO SON DOS DECLARACIONES: por debajo de
     900 el rótulo ocupa la sección entera, por encima sólo las DOS pistas de la
     derecha más su costura. Una sola fórmula daría dos encuadres distintos según
     la anchura, que es exactamente lo que se llama «salido de lugar».
     MEDIDO EN CHROME (`grid-template-rows` computado y pistas reales, NO el
     rectángulo pintado — `.cartel` lleva `data-reveal` y su rect sale un 2,5 %
     pequeño mientras la apertura corre):
        390 →  390 × 126,6 (3,08)   ·   900 → 568,2 × 184,8 (3,07)
       1440 →  855,2 × 277,7 (3,08) ·  1920 → 880,6 × 294 (3,00, con el techo de
                                              1.392 de `.sangra` ya mordiendo)
     El encuadre es por tanto EL MISMO a las cuatro anchuras: ninguna tiene un
     recorte propio. Y nunca corre por encima de su fichero: 855 sobre 1.080
     nativos = 0,79×, lejos del techo de 1,35×.                                 */
  --rotulo-h:clamp(126px,calc(28.1vw + 17px),272px);
  /* ⭐ r8 · LA TIRA de §5 (las tres fotografías nuevas de Diego, 2026-08-21).
     Vive PEGADO a `--cartel-h` porque es su hermano: la misma sección, la misma
     familia de alturas de tesela. No es un valor suelto inventado en el sitio
     donde hacía falta.
     La fila son CUATRO pistas y la barra ocupa las DOS DEL MEDIO, así que la
     altura se elige para que LA BARRA corra a su proporción nativa (1,333):
       1440 -> 518 · pista 339, la barra 690 => 690/518 = 1,332 ≈ NATIVO
        900 -> 324 · pista 205, la barra 422 => 422/324 = 1,302 (2 % de nada)
     Y a esa altura los dos retratos caen en celdas de razón 0,63-0,65 contra su
     0,750 nativo: se recortan 13-16 % DE ANCHO, nunca de alto. Un retrato que
     pierde alto pierde el sujeto; uno que pierde un poco de ancho, no.        */
  --casa-h:clamp(240px,36vw,520px);
  /* La celda del RETRATO por debajo de 900, donde la tira son 2 columnas: a 390
     la celda mide ~164 y esta altura ~242 (razón 0,68, casi el 0,75 nativo); a
     700 sale 0,75 EXACTO. Un retrato en una celda apaisada es lo que produce el
     recorte que Diego llama «salida de lugar».                                */
  --casa-hp:clamp(200px,62vw,430px);
  --ficha-h:clamp(260px,22vw,316px);
  /* ⚠️ 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` SE RETIRA EN LA r8. Era la pista del raíl fotográfico de §7, y
     esa foto la quitó Diego el 2026-08-21, así que ya no lo lee nadie: un token
     declarado que no lee nadie es una promesa falsa, no una paleta. Si algún día
     vuelve una fotografía a `#contacto`, vuelve el token con ella.            */
  --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-25 · SE RETIRA EL CUARTO PELDAÑO, «Ø sin foto», de 72 px.
     Existía para las filas sin fotografía nuestra; hoy las ocho familias
     publicadas llevan placa, así que no lo leía nadie, y un token que no lee
     nadie es una promesa falsa, no una paleta. El índice de las ocho suma
     3×132 + 1×112 + 4×92 = 876 px (r7: 2.640). Si algún día entra una familia
     sin foto, vuelve el peldaño con ella. */
  --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]`.                                                        */
/* ⭐ r9 · 2026-08-22 · `.cita--titular` SE BORRA. Era la cita que hacía de
   titular en §4, y §4 dejó de ser una cita (Pere: «pon "Fatta in casa" a
   secas»). `.cita`, `.cita__t` y `.cita__f` SIGUEN VIVAS — las usan §5 y §6.  */
#desde-0 .sec__in + .sangra{ margin-top:var(--seam) }

/* ── 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.          */
.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;
  }
}
/* 🔴 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 · ⭐ RONDA 5, 2026-08-18 ──
   Sólo Dénia: La Vila y Alicante siguen con el botón que rota ES→EN→IT→ES
   (Rotation-Log.md). El disparador SIGUE siendo `.nav__lang` — misma fila de
   52 px en el panel móvil, misma versión micro-uppercase en la barra de
   escritorio — y el marcador imita el de `.fuentes`: oculto de fábrica,
   sustituido por una flecha que gira al abrir.                               */
.idiomas{ position:relative }
.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);
}
.idiomas[open] > summary .idiomas__ind{ transform:rotate(180deg) }
/* El panel flota bajo el disparador, centrado sobre él — 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; top:calc(100% + 6px); left:50%; transform:translateX(-50%);
  z-index:5; min-width:8.5rem;
  display:grid; gap:2px; padding:6px;
  background:var(--plano-1); box-shadow:var(--filo),var(--sombra-2);
  border-radius:var(--r-control);
  list-style: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) }
}

/* ══ 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 DEL MISMO OFICIO, 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, así que el aparejo se ordena como el
   recorrido de una pizza por su propio horno: la masa (sin fuego) · el horno
   encendido · la pala entrando · la pizza en la solera · 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 ├────────┤
            │ pizza  │  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 · pizza │ 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 del horno 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--pizza{ 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){
  /* 🔴 2026-08-23 · LAS DOS FILAS SON `minmax(--apar-r, auto)` Y NO `--apar-r` A
     SECAS. Es EL MISMO FALLO que costó una ronda en `.cartel__servs` el
     2026-08-17, explicado arriba: una FILA DE ALTO FIJO + un hijo con
     `align-content:center` cuyo contenido NO CABE se derrama por LOS DOS
     EXTREMOS A LA VEZ. Aquí `.aparejo__txt` cruza las dos filas y lleva dentro
     `.horno__h` + `.horno__acc`; entre 900 y 1200 px su columna mide sólo
     260-370 px, el texto envuelve y pide 654 px donde la rejilla daba 392.
     Medido a 900: desborde 262 px ⇒ 131 por arriba y 131 por abajo, o sea el
     titular pintándose SOBRE el suelo de la sección por encima del plano y el
     botón «Ver la carta» cayendo FUERA del plano por debajo. Pere, 2026-08-23:
     «arregla para que esto este bien cuadrado ya que el texto se sale un poco
     por arriba».
     `minmax()` no cambia nada donde ya cabía —a 1440 el contenido pide 517 y la
     fila declarada da 545, así que la fila mide EXACTAMENTE `--apar-r` y el
     1440 aprobado no se mueve un píxel— y crece lo justo donde no cabía.
     ⚠️ NO se arregla invirtiendo filas (probado en el cartel: deja de recortar
     y pasa a SOLAPARSE con la media) ni con `overflow:hidden`, que no contiene
     el titular sino que lo recorta, y un texto cortado es peor que uno que se
     sale porque no se ve que está mal.                                        */
  .aparejo{
    grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr));
    grid-template-rows:repeat(2,minmax(var(--apar-r),auto));
  }
  .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--pizza{ 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) }
.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.                                        */
/* ⭐⭐ r8 · 2026-08-21 · EL PLIEGUE SUBE DE 700 A 1000, Y NO ES UN CAPRICHO:
   ES LO QUE IMPEDÍA QUE EL DIPLOMA SE LEYERA. Con la foto nueva (`premio-mundo-
   mesa`, 1.080 x 810 = 1,333) medí la caja ancho por ancho, y entre 700 y 1000
   la columna de texto se estira a 386 px —la fila «Salsas a elegir» y el botón
   parten en dos— mientras la pista de la media sigue en ~300. Resultado medido:
       700 -> 274x273 (1,004) · se ve el 75 % del ancho
       760 -> 299x386 (0,776) · se ve el 58 % ← EL PEOR
       820 -> 324x386 (0,840) · 63 %
       900 -> 360x386 (0,933) · 70 %
      1000 -> 407x322 (1,261) · 95 %
      1440 -> 462x322 (1,434) · 100 % del ancho, 93 % del alto
   Un 58 % del ancho en un DOCUMENTO corta por la mitad la frase «Record del
   Mundo de la Mesa de Restaurante más Largaaaaaaa». Un recorte que se come el
   marco de madera es encuadrar; uno que se come la letra es romper la foto.
   🔴 Y LA SALIDA NO ES `align-items:start` NI UN `aspect-ratio` DENTRO DE LA
   FILA. Las dos dejan la media más corta que su columna vecina y devuelven
   suelo desnudo dentro del bloque — «una columna corta declarada a la altura de
   una foto alta», que es literalmente el defecto que Standards manda arreglar
   POR LA CAUSA. La causa es que en esa banda no CABEN dos columnas. Así que en
   esa banda no hay dos columnas: la fila se apila, el diploma corre a lo ancho
   a su 4:3 nativo (recorte CERO) y los suplementos van debajo. Sin fila, no hay
   fila coja.
   ⚠️ `aspect-ratio` y `min-height` NO conviven en la misma caja: juntas hacen
   que la caja saque su ANCHO de su alto. Por eso el `min-height:220px` se muda
   al bloque de >=1000, que es el único donde la altura la manda la fila, y el
   `aspect-ratio` sólo existe por debajo.                                      */
.remate{
  display:grid; gap:var(--s4); min-width:0; align-items:stretch;
  grid-template-columns:minmax(0,1fr);
}
.remate__m{
  position:relative; overflow:hidden; min-width:0;
  border-radius:var(--r-pieza);
  aspect-ratio:4 / 3;
}
@media (min-width:1000px){
  .remate{ grid-template-columns:minmax(0,1fr) minmax(0,1.1fr); gap:var(--s5) }
  .remate__m{ aspect-ratio:auto; min-height:220px }
}
.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;
  }
  /* (r9 · la regla que alineaba la cita de esta cabecera se va con la cita.) */
  .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 «NUESTRA CASA» ═════════════════════════════════
   ⭐ RONDA 9 · 2026-08-22 · SE VA EL TRÍPTICO, ENTRA EL RÓTULO. Pere: «elimina
   las dos fotos de arriba y añade la primera foto adjuntada (gg-fachada) y
   reposiciona las 3 de abajo para que respeten simetría espaciado y jerarquía
   visual». La sección pasa de CINCO medias de peso parecido —que es exactamente
   no tener jerarquía— a UNA grande arriba (el rótulo, el plano de situación) y
   TRES iguales abajo (la tira, el detalle).
     >=900   fila 1 · palabras (1,15fr) | RÓTULO (2 pistas)
             fila 2 · palabras (cruza)  | SERVICIOS (2 pistas)
             fila 3 · TIRA, cuatro pistas iguales: retrato · barra(2) · retrato
     <900    rótulo / palabras / servicios / tira, cuatro bandas apiladas
   UNA sola costura en toda la sección: `--seam` = 12 px = `--s2`. Cero suelo de
   página suelto entre piezas, y la costura entre secciones (64-128 px) sigue
   siendo mayor que cualquier hueco de dentro.

   ── LO QUE SE CONSERVA DE LAS RONDAS ANTERIORES, PORQUE COSTÓ UNA RONDA CADA
      UNO Y SIGUE SIENDO VERDAD ────────────────────────────────────────────────
   🔴 2026-08-17 · UNA FILA DE ALTO FIJO RECORTA SU PROPIO CONTENIDO. La fila 1
   valía `var(--cartel-h)` a secas y el panel de servicios que colgaba debajo de
   la segunda media no cabía: «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. No era color: era una caja mintiendo sobre lo que le cabía dentro.
   Hoy el problema no puede repetirse por construcción, porque los servicios ya
   no viven dentro de la fila de la fotografía: tienen su propia fila `auto`.
   ⚠️ Y tampoco se arreglaba invirtiendo las filas de aquella columna — se probó
   y era peor: el panel dejaba de recortarse pero se SOLAPABA 93,7 px con la
   media, y como `.cartel__m` es `position:relative` la fotografía se pintaba
   ENCIMA del panel. Mismo texto ilegible, otro mecanismo.
   ⚠️ Un `aspect-ratio` sólo es seguro en una caja que NO lleve además una altura
   de fila ni un `min-height`: con las dos cosas la caja saca su ANCHO de su
   alto. Por eso el rótulo NO lleva `aspect-ratio` — su alto lo pone la fila
   (`--rotulo-h`) y rellena con `object-fit:cover`.
   ⚠️ Las piezas que comparten fila miden EXACTAMENTE lo mismo (`lopsided`).   */
.cartel{
  display:grid; gap:var(--seam);
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  /* <900 · CUATRO bandas apiladas, en el mismo orden que el DOM: rótulo ·
     palabras · servicios · tira. Una sola costura entre todas (`--seam`).     */
  grid-template-rows:var(--rotulo-h) auto auto auto;
  min-width:0;
}
.cartel__m{
  position:relative; overflow:hidden; grid-row:1; min-width:0;
  border-radius:var(--r-pieza);
}
/* 🔴 EL RÓTULO MANDA SU FILA, Y ES DELIBERADO. Su alto sale de `--rotulo-h`, no
   del texto que tiene al lado: una fotografía cuyo sujeto llega a los dos cantos
   no puede permitir que otra columna decida cuánto ancho se le recorta. El texto
   se acomoda (cruza las filas 1-2 a >=900), el rótulo no.                      */
.cartel__rotulo{ grid-column:1 / -1; grid-row:1 }
.cartel__m > img,.cartel__m > video{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}
/* ⭐ r9 · EL PANEL DE SERVICIOS ES AHORA UNA BANDA ANCHA, no una tarjeta.
   Hasta la r8 vivía en `.cartel__col`, debajo de `ig-pared-cuadros-italia`; esa
   columna se fue con la fotografía. Aquí ocupa el ancho entero del rótulo y toca
   a sus tres vecinos a 12 px —rótulo arriba, plano de texto a la izquierda, tira
   abajo—: nunca queda suelo alrededor.
   ⚠️ `flex-wrap` Y NO `repeat(n,1fr)`: son CINCO servicios, y cinco no es
   múltiplo de dos ni de tres, así que cualquier rejilla fija deja una celda
   vacía al final (la regla de la casa contra `auto-fit`). Envueltos en fila cada
   renglón queda lleno. Es el mismo patrón que `.pie .servs` ya resuelve en §7,
   copiado y no reinventado.                                                    */
.cartel__servs{
  /* <900 · fila 3, DEBAJO del texto y ENCIMA de la tira: el orden que se ve es
     el orden del DOM. Sin esta línea el panel se auto-colocaba en la fila 4, o
     sea después de la tira, y lo que se lee y lo que se ve dejaban de coincidir. */
  grid-column:1 / -1; grid-row:3; min-width:0; overflow:hidden;
  background:var(--plano-1); box-shadow:var(--filo);
  border-radius:var(--r-control);
  padding:var(--s3) var(--s4);
  display:grid; gap:var(--s2); align-content:center;
}
.cartel__servs .servs{
  display:flex; flex-wrap:wrap;
  gap:var(--s2) var(--s4);
}
.cartel__servs .serv{
  text-align:left;
  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);
}
/* ══ LA TIRA · §5 · ⭐ RONDA 8, 2026-08-21 ═══════════════════════════════════
   Las tres fotografías nuevas de Diego, en una fila propia DEBAJO del tríptico.
   El tríptico no se toca: el encargo era añadir, no rediseñar.
   🔴 «DEBEN DE VERSE SIMÉTRICAS» (Diego, 2026-08-21 — la SEXTA vez que un socio
   pide simetría en este repo). Lo que la hace simétrica, y es geometría, no
   gusto:
     · `repeat(3,minmax(0,1fr))` a >=900 ⇒ los tres anchos son el MISMO número,
       nunca «casi». `minmax(0,…)` y no `1fr` a secas, porque una pista implícita
       es `auto` y `auto` es «tan ancha como lo más ancho que lleve dentro».
     · UNA fila, UNA altura (`--casa-h`), y las tres teselas la llenan: la altura
       va en la FILA, jamás en cada tesela. Es la regla «cada par a través del
       pliegue es una fila con una altura», que es lo que `phone-fit` suspende
       como `lopsided` y como `deadspace`.
     · Ninguna corre a su proporción nativa: un ancho común + `object-fit:cover`
       + un `object-position` propio por foto. Proporción nativa a altura
       compartida = anchos distintos = la asimetría que ESENS r4 ya mató.
   🔴 Y POR DEBAJO DE 900, DOS COLUMNAS CON LA APAISADA CRUZANDO LAS DOS. Tres
   teselas en dos columnas dejan una huérfana con medio ancho de suelo al lado —
   el «parece salida de lugar» literal. Así hay dos filas llenas y ningún hueco.
   Además cada forma cae donde le toca: los dos retratos (0,750) en celdas
   estrechas de razón ~0,68-0,97, la barra apaisada a lo ancho.
   ⚠️ `aspect-ratio` en `.tira__m--ancha` es seguro porque esa caja NO lleva
   `min-height` ni altura de fila: su ancho lo fija la rejilla y el alto se
   deriva. Poner las dos cosas es lo que hace que una caja saque su ANCHO de su
   alto. Por eso a >=900, donde la fila SÍ impone altura, el `aspect-ratio` se
   apaga.                                                                      */
.tira{
  grid-column:1 / -1; grid-row:4; min-width:0;
  display:grid; gap:var(--seam);
  grid-template-columns:repeat(2,minmax(0,1fr));
  grid-template-rows:var(--casa-hp) auto;
}
.tira__m{
  position:relative; overflow:hidden; min-width:0;
  border-radius:var(--r-pieza);
}
/* <900 · las TRES 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 de la sección y no puede depender del algoritmo.  */
.tira__m--p1{ grid-column:1; grid-row:1 }
.tira__m--p2{ grid-column:2; grid-row:1 }
.tira__m--ancha{ grid-column:1 / -1; grid-row:2; aspect-ratio:16 / 9 }
.tira__m > img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}

@media (min-width:900px){
  /* ⭐ r9 · TRES FILAS Y NO DOS. El rótulo se lleva la 1 con su altura propia,
     los servicios la 2, y la tira la 3. La columna de palabras CRUZA las filas
     1-2, así que la mitad derecha y la izquierda empiezan y acaban en la misma
     línea: una fila, una altura, ninguna mitad flotando por su cuenta.
     `minmax(0,auto)` en la fila 2 para que el panel de servicios pueda crecer si
     el texto de al lado necesita más alto — nunca al revés.                    */
  .cartel{
    grid-template-columns:minmax(0,1.15fr) minmax(0,1fr) minmax(0,1fr);
    grid-template-rows:var(--rotulo-h) minmax(0,auto) auto;
  }
  /* Las dos pistas de la derecha ENTERAS, de la costura al canto: ni el rótulo
     ni la banda de servicios dejan un píxel de suelo contra el borde derecho. */
  /* La caja cambia de ancho al llegar aquí (de la sección entera a dos pistas),
     así que su alto cambia con ella: misma razón 3,0, otra fórmula. */
  .cartel{ --rotulo-h:clamp(184px,calc(17.2vw + 30px),294px) }
  .cartel__rotulo{ grid-column:2 / -1; grid-row:1 }
  .cartel__servs{ grid-column:2 / -1; grid-row:2 }
  /* ⭐ 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 / span 2;
    position:relative; z-index:2;
    margin-right:calc(-1 * var(--solape-2));
    padding:var(--s4);
  }
  /* ⚠️ Este bloque va DESPUÉS de las reglas base a propósito: un `@media` no
     suma especificidad, así que a igualdad de clase gana la que está más abajo
     en el fichero. Escrito arriba, esta rejilla no haría absolutamente nada. */
  /* 🔴 CUATRO PISTAS IGUALES Y LA BARRA EN LAS DOS DEL MEDIO — retrato · barra ·
     retrato. Es SIMÉTRICA POR EL EJE, no «tres cosas seguidas»: mismas teselas
     estrechas a izquierda y a derecha, la pieza ancha exactamente en el centro.
     Y de paso cada forma cae en la celda de su forma: los dos retratos en
     celdas verticales, la barra —que es un sujeto ancho, tres pizarras de punta
     a punta— en una apaisada.
     ⚠️ POR QUÉ CUATRO PISTAS Y NO TRES, que es lo que había aquí primero: con
     tres teselas iguales la tesela medía 455 px a 1440 = 32 % del ancho de
     página, y `variety-check [granularity]` lo suspendió (tope 27 %, mediana de
     la página 411). Con cuatro pistas la tesela baja a 339 = 23,5 % y la
     mediana de la página a 339. La salida es MÁS PIEZAS PEQUEÑAS QUE SE TOCAN,
     nunca menos y más grandes — y nunca estrechar la tira dejando suelo a los
     lados, que metería un tercer borde vertical en una sección que ya sangra.  */
  .tira{
    grid-row:3;
    grid-template-columns:repeat(4,minmax(0,1fr));
    grid-template-rows:var(--casa-h);
  }
  .tira__m--p1{ grid-column:1; grid-row:1 }
  /* La apaisada cruza las dos pistas centrales y pierde su proporción propia:
     en una fila de altura fija, `aspect-ratio` competiría con la altura de la
     fila y la caja acabaría sacando su ANCHO de su alto. */
  .tira__m--ancha{ grid-column:2 / span 2; grid-row:1; aspect-ratio:auto }
  .tira__m--p2{ grid-column:4; grid-row:1 }
}

/* ══ FORMA 6 · LA PILA · §6 RESEÑAS ══════════════════════════════════════════
   REESCRITA EN LA RONDA 5, 2026-08-18: hasta esa ronda la sección apilaba una
   cifra de recuento (86), tres citas de sellos de la carta y dos fotografías;
   la ronda 5 las quitó y dejó sólo la nota (4,8 ★ / 89, vía pos.do), porque no
   había ninguna reseña con nombre+texto verificados.
   ⭐ RONDA 7, 2026-08-19: `.pila__stack`/`.dice` VUELVEN — tres reseñas reales
   de la captura de Diego (Brief.md § Reputación), sin nombre ni fecha
   individual. Las dos fotografías de antes de la ronda 5 (`.pila__sala`/
   `.pila__pie`) NO vuelven: ninguna foto de este local ilustra «nuestra nota
   en Google», así que la sección sigue `data-no-image` para la imagen y suma
   sólo la cifra + las citas, centradas, sin rejilla que rellenar.
   ⭐ RONDA 8, 2026-08-21: SEIS citas, y por eso DOS COLUMNAS a partir de 900.
   La cifra pasa a 4,5 · 154 (ficha de Google, Diego 21/08) y `--pct` a 90 %.  */
.pila{
  display:grid; gap:var(--seam); min-width:0;
  grid-template-columns:minmax(0,1fr);
  justify-items:center;
}
.pila--nota{ padding-block:var(--s5); text-align:center }
.pila__cifra{
  display:grid; gap:2px; justify-items:center; text-align:center;
  width:min(720px,100% - 2 * var(--edge));
}
@media (min-width:900px){
  .pila--nota .pila__cab{ text-align:center; margin-inline:auto; max-width:640px }
}
/* ⭐ r7 · `.pila__stack`/`.dice` DE VUELTA — PORTADAS byte a byte de La Vila
   (`Clients/Ristorante-Da-Marc/Website/styles.css:1909-2081`), tal y como el
   comentario de la ronda 5 (más abajo) decía que había que hacer el día que
   volvieran citas reales. Única diferencia deliberada: aquí NO se porta la
   compensación `.dice:first-child{ padding-top:calc(var(--s4)+20px) }` de La
   Vila, porque esa regla existe allí para absorber el SOLAPE 3
   (`.pila__cifra{ margin-bottom:-20px }`) — un solape que Dénia no tiene (su
   `.pila__cifra` no lleva margen negativo). Portar el parche sin el problema
   que arregla habría dejado un hueco de 20 px sin motivo encima de la primera
   cita.
   ⭐⭐ r8 · 2026-08-21 · Y AHORA SÍ SE PORTA EL `grid-template-columns` A 900 px
   DE LA VILA. El comentario que estaba aquí decía que no se portaba «porque no
   hay raíl de fotografía que ponerle al lado» — y eso seguía siendo verdad con
   TRES citas, que en una columna se leen como una pila. Con SEIS, una columna
   son 6 planos apilados y ~1.100 px de sección estrecha con medio ancho de
   página vacío a cada lado. Se porta el idioma de La Vila
   (`styles.css:1960-1971`: un `@media (min-width:900px)` que reescribe
   `grid-template-columns` con pistas `minmax(0,1fr)`), no una rejilla nueva.
   🔴 SIMETRÍA, que es lo que Diego pidió el 2026-08-21 («deben de verse
   simétricas») y la SEXTA vez que un socio lo pide:
     · 6 citas ⁄ 2 columnas = 3 filas EXACTAS. Ninguna fila coja.
     · Las dos pistas son `minmax(0,1fr)`: mismo ancho, siempre.
     · La altura de cada fila la fija la rejilla y las DOS placas la llenan
       (`align-items` se queda en su `stretch` por defecto — NO se pone `start`
       aquí: `start` es lo que convierte una cita corta en un escalón). `.dice`
       ya trae `align-content:center`, así que el texto se centra dentro de una
       placa que mide lo mismo que su vecina aunque tenga la mitad de palabras.
       Es la regla «cada par a través del pliegue es UNA fila con UNA altura»
       resuelta por construcción, no ajustada a ojo.
     · `margin-inline:auto` se queda: la rejilla entera sigue centrada en la
       página, con la MISMA holgura a izquierda y a derecha.
   El tope sube de 720 a 1.040 px porque 720 partidos en dos son 354 por cita y
   ahí una reseña de 30 palabras se rompe en ocho líneas. 1.040 ⇒ 514 por
   columna, que es medida de lectura, no de tarjeta.
   ⚠️ EL ESCALONADO DE ENTRADA: `.dice` usa `animation-range:entry 4% cover 20%`
   —igual para las seis, sin `--i`—, así que en dos columnas las dos citas de
   una fila entran A LA VEZ y las filas se montan de arriba abajo. Se comprobó
   la alternativa (retrasar por `--i`) y se DESCARTA: en una rejilla de dos
   columnas un retardo por índice hace entrar la placa derecha después que la
   izquierda de su propia fila, que es precisamente la asimetría que Diego
   acaba de pedir que no haya. El `style="--i:N"` del marcado se conserva por
   fidelidad con el de La Vila; aquí no lo lee nadie, y queda dicho para que
   nadie lo tome por una promesa cableada.                                     */
.pila__stack{
  display:grid; gap:var(--seam); min-width:0;
  width:min(720px,100% - 2 * var(--edge));
  margin-inline:auto;
}
@media (min-width:900px){
  .pila__stack{
    grid-template-columns:repeat(2,minmax(0,1fr));
    width:min(1040px,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;
  text-align:left;
}
@media (max-width:559px){ .dice{ min-height:88px; padding:var(--s3) } }
/* ⚠️ `white-space: pre-line`: si algún día una cita trajera saltos de línea
   propios, no se reflowean ni se sustituyen por un <br> inyectado.            */
.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);
}

/* ── LAS CITAS ───────────────────────────────────────────────────────────────
   «Son solo bloques de texto, dales un poco de vida.» Lo que cambia: sus cinco
   estrellas arriba, 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 }
.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()){
    /* 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) }
}


/* ══ 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 PORCENTAJE EXACTO de la nota — en Dénia, 96,0 % =
   4,8 sobre 5 al píxel. Un redondeo a cinco estrellas llenas 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 }

/* ⭐ RONDA 7 · 2026-08-19 · `.dice`/`.dice__e`/`.dice__t`/`.dice__f` VOLVIERON A
   ESTA HOJA (ver «FORMA 6 · LA PILA» más arriba, donde vive el bloque
   portado). La ronda 5 (2026-08-18) los había retirado porque #dicen no tenía
   ninguna cita individual verificada; la ronda 7 sí las tiene (tres reseñas
   reales de la captura de Diego, Brief.md § Reputación) y el patrón vuelve
   byte a byte de `Clients/Ristorante-Da-Marc/Website/styles.css` (La Vila),
   sin su compensación de SOLAPE 3 —Dénia no tiene ese solape—. Lo que sigue
   aquí es SÓLO la animación de la NOTA (barrido de estrellas), que nunca se
   fue de esta hoja. */
@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) }
    }
  }
}

/* ══ FORMA 7 · LA FICHA · §8 VENIR ═══════════════════════════════════════════
   Un documento a sangre sobre el plano elevado, con paneles separados por 12 px:
   la fachada · 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.
   ⚠️ LA CAJA DE LA FACHADA NUNCA PUEDE SER MÁS ESTRECHA QUE 4:3. Medido sobre el
   fichero real: la «M» de «Marc» empieza en el 3 % del ancho, así que cualquier
   recorte horizontal se la come — es literalmente el defecto «1arc» de la r6.
   A ancho de móvil la caja es su 4:3 exacto y no recorta NADA.                  */
.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). `.ficha__m2` —el par de móvil de la r8c—
   se fue el 2026-08-23 por orden de Pere («quita estas dos imagenes…»): metía una
   foto apaisada y un fotograma vertical en dos cajas iguales. Con ella se va su
   `order:2` y el `order:1` que el mapa llevaba SÓLO para caer por encima de ella:
   con dos hijos, el orden del DOM (semana, mapa) ya es el orden pintado, y a
   ≥1000 px los dos van colocados a mano con `grid-column`/`grid-row`, donde
   `order` no gobierna nada. Comprobado en el render a 390, 500, 1000 y 1440. */
.ficha__cuerpo{ padding:var(--s4) var(--edge); display:grid; gap:var(--s3); align-content:start }
/* ⚠️ A partir de 1000 px la FILA declara la altura y la fachada la ocupa entera:
   ella no puede llevar `aspect-ratio` y estirarse a la vez, y si se estirase con
   la semana al lado (que mide ~500 px) la caja se volvería MÁS ESTRECHA que 4:3
   y volvería a comerse la «M». Con la altura en la fila 1 y la semana cruzando
   las dos filas, la fachada corre a 465 × 316 (1,47) a 1440 px: más apaisada que
   su nativo 4:3 = 1,33, nunca más estrecha. Y lo que sobra en la columna de la
   derecha cae DENTRO de un panel con su propio suelo, que es relleno, no un
   agujero en la página.
   ⭐ r7b · las columnas pasan de 1fr/1fr a 1fr/1,9fr y `--ficha-h` de
   clamp(300,28vw,400) a clamp(260,22vw,316): la fachada baja de 674 a 465 px.  */
@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 }

/* ══ 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.                                           */
/* ⭐⭐ RONDA 8 · 2026-08-21 · SE VA LA PUERTA Y LA SECCIÓN SE CENTRA ═════════
   Orden literal de Diego: «elimina la foto de la seccion de contacto, centralo y
   dejalo asi.»
   Todo lo de arriba —el raíl fotográfico, el eje único pegado a la izquierda, la
   pista `var(--puerta)`— se conserva ESCRITO porque explica por qué la sección
   tiene la forma que tiene, pero YA NO ES LO QUE HACE EL CÓDIGO. Con la foto
   fuera, una pista de 240 px vacía a la izquierda dejaba todo el contacto
   colgando a la derecha: eso es exactamente lo que él vio.
   🔴 «CENTRALO» SE RESUELVE CON GEOMETRÍA, NO CON UN `text-align` SUELTO. Son
   las dos cosas a la vez, y hacen falta las dos:
     (1) LA COLUMNA se centra en la página: un tope de medida y
         `margin-inline:auto` ⇒ holgura izquierda = holgura derecha a TODOS los
         anchos. Es lo único que `symmetry-check.py` sabe leer, y es lo que Diego
         está mirando.
     (2) EL CONTENIDO se centra dentro de esa columna. Si sólo se hiciera (1), la
         etiqueta, el número y los botones seguirían pegados al canto izquierdo
         de una caja centrada, y la sección se leería descentrada dentro de sí
         misma.
   ⚠️ EL EJE ÚNICO DE LA r6 NO SE PIERDE, CAMBIA DE SITIO. El defecto que aquella
   ronda midió era tener TRES ejes (etiqueta en x=132, teléfono en x=410, botones
   en x=515). Sigue habiendo UNO SOLO, y ahora es el centro:
       center(etiqueta) = center(teléfono) = center(botones) = center(datos).
   ⚠️ Y DESAPARECE LA MEDIA QUERY DE 560. Existía para bajar la puerta debajo del
   número cuando la columna de al lado se quedaba en 154 px. Sin puerta no hay
   dos columnas que repartir a ningún ancho: la maqueta es la MISMA de 320 a
   1440, que es la forma más barata de que no se rompa en medio.
   ⚠️ La lista de procedencias (`.fuentes__l`) NO se centra: son siete líneas
   largas con su fecha, y centrar un listado ragged por los dos lados se lee
   peor, no mejor. Se centra su `<summary>`, que es lo que se ve cerrado.
   Centrar por centrar es decoración; el objetivo es que la sección esté en
   medio.                                                                      */
.cierre{
  display:grid; min-width:0;
  gap:var(--s4);
  grid-template-columns:minmax(0,1fr);
  justify-items:center; text-align:center;
  width:min(720px,100%);
  margin-inline:auto;
}
.cierre__datos{
  display:grid; gap:var(--s4); align-content:start; min-width:0;
  justify-items:center; width:100%;
}
.cierre__tel{ display:grid; justify-items:center; 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;
}
.cierre__acc{ display:grid; grid-template-columns:minmax(0,1fr); gap:8px; width:100%; max-width:420px }
/* 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); width:100% }
@media (min-width:700px){ .pie__datos{ grid-template-columns:repeat(2,minmax(0,1fr)) } }
/* ⭐ r8 · el centrado de §7, ACOTADO A `.pie` para que no toque nada más de la
   web. `.servs` deja de ser una rejilla de una columna y pasa a ser una fila que
   envuelve y se centra: siete servicios apilados y centrados uno bajo otro se
   leerían como una lista descuadrada; en fila envuelta cada renglón queda
   centrado por sí solo y el bloque es simétrico a cualquier ancho.
   ⚠️ `.serv` conserva `text-align:left` dentro: lleva su bandita de 3 px en una
   columna propia, y centrar el texto contra la bandita la descuadra.          */
.pie .cierre__datos > div{ width:100%; display:grid; justify-items:center }
.pie .servs{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:var(--s2) var(--s4);
}
.pie .serv{ text-align:left }
.pie .fuentes{ width:100%; text-align:left }
.pie .fuentes__cab{ justify-content:center }
/* ⭐ 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) }
.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 ELIMINADA — corrección de Diego, 2026-08-19: la
   sección de reserva era redundante con el teléfono grande que ya está
   justo debajo. `.llamar`/`.llamar__num`/`.btn--grande`/`.btn__ico` no se
   usan en ningún otro punto de la página (comprobado con grep antes de
   borrar) y se retiran en el mismo paso que el HTML. El sistema n8n de
   reservas sigue vivo en `Clients/Ristorante-Da-Marc/Automation/`; si Dénia
   recupera un formulario propio, las ~170 líneas originales siguen en el
   histórico de git de este fichero y en `Clients/Ristorante-Da-Marc/Website/
   styles.css` (La Vila). */

/* ══ 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;
}
.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%;
    }
  }
}
.pie__legal{ 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]`
   sustituyó a `[data-lang-toggle]` en la ronda 5: sigue siendo un control que
   sin script no cambia nada (elegir un idioma reescribe el DOM), así que sigue
   la misma regla — oculto entero hasta que `.js` demuestra que hay script.   */
[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-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] .pila__m,
  .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 .pila__m,
  .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--pizza,
  .js-rev [data-reveal] .aparejo__t--corte{ clip-path:inset(100% 0 0 0) }
  /* ⭐ r9 · el cartel ya no tiene dos medias que se abran en espejo desde su
     costura vertical: tiene UNA, el rótulo, y se abre desde su canto izquierdo,
     que es el canto que toca el plano de texto. `.cartel__col` ya no existe.  */
  .js-rev [data-reveal] .cartel__rotulo{ clip-path:inset(0 0 0 100%) }
  .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,.pila__m,.cartel__m,.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,
  /* `.puerta` salió del marcado en la r8 (Diego quitó la foto de §7); su nombre
     se retira también de aquí, para que esta lista no prometa ocultar algo que
     ya no existe. */
  .ficha__m,.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 }
}
