/*
 * RestoOS · CSS del reproductor de vídeo de la carta pública.
 *
 * UN SOLO FICHERO FUENTE para las dos apps públicas, igual que su .js: vive en
 * `admin/public-compartido/` y `admin/vite.config.js` lo monta bajo las dos.
 * NO se copia a `public-carta/` ni a `public-web/` — eso sería el tercer espejo
 * de la issue 004, que es justo lo que este directorio existe para evitar.
 *
 * POR QUÉ ESTÁ AQUÍ Y NO DENTRO DEL .js (08/08/2026): vivía en un template
 * literal, y un backtick escrito en un comentario cierra la cadena y tumba la
 * suite entera con un error que apunta a una línea de prosa. Pasó dos veces en
 * la misma tarde. Sacarlo elimina el peligro en vez de vigilarlo, y de paso el
 * editor colorea esto como lo que es.
 *
 * LO QUE ESO CAMBIA, Y HAY QUE SABERLO: antes el módulo inyectaba su hoja solo
 * y la página no tenía que acordarse; ahora cada página que use el reproductor
 * debe enlazarla. Lo vigila `tools/mapa/css-del-reproductor.test.mjs`, que
 * descubre las páginas recorriendo los directorios en vez de enumerarlas.
 *
 * ORDEN DE CASCADA: el <link> va al FINAL del <head>, después del styles.css de
 * cada app. No es indiferente — es exactamente donde lo dejaba
 * `head.appendChild()`, así que el orden relativo es el de siempre.
 *
 * Las apps lo tematizan con variables: --medio-radio, --medio-fondo,
 * --medio-hueco, --medio-ancho, --medio-aspecto, --medio-tope, --rejilla-hueco,
 * --medio-vacio-fondo, --medio-vacio-texto.
 */
/* RESET COMPLETO DE APARIENCIA DE BOTON, y va en la clase COMPARTIDA.
 *
 * `.plato__medio` es un <button> siempre que la tarjeta se pueda abrir, y desde
 * el 08/08/2026 eso son los TRES eslabones: video, foto y sin medio. Un <button>
 * no hereda del documento: trae color, tipografia, fondo, alineacion, relleno y
 * borde propios del sistema operativo.
 *
 * Lo cazo Pedro en su movil: el nombre de la tarjeta sin medio salia AZUL --
 * el color de sistema que Safari en iOS le da al texto de un boton sin `color`
 * declarado. Lo introdujo el cambio de <div> a <button>, asi que lo trajo el
 * arreglo y no estaba antes; y afectaba tambien a la de foto y a la de video,
 * donde no se veia porque encima del medio no hay texto.
 *
 * `color: inherit` es la linea que arregla el sintoma; las demas estan porque
 * un boton hereda mas defaults de los que se ven en un simulador de escritorio
 * y no vamos a descubrirlos de uno en uno. */
.plato__medio{position:relative;
  border-radius:var(--medio-radio,10px);overflow:hidden;background:var(--medio-fondo,#00000010);
  cursor:default;padding:0;border:0;display:block;
  color:inherit;font:inherit;text-align:inherit;letter-spacing:inherit;
  -webkit-appearance:none;appearance:none;margin:0;
  -webkit-tap-highlight-color:transparent}
.plato__medio--pulsable{cursor:pointer}
/* CONTAIN, NUNCA COVER: cover recorta, y no se recorta nada. Cuando la caja
   tiene la relación del medio (el caso normal) contain y cover coinciden y no
   hay bandas; cuando el medio pasa del tope, la banda es la prueba visible de
   que no lo hemos mutilado. */
.plato__medio img,.plato__medio video{width:100%;height:100%;object-fit:contain;display:block}
.plato__medio video{position:absolute;inset:0}
/* Sin dimensiones conocidas (hoy: las fotos) la caja no puede reservar hueco y
   se deja dimensionar por la imagen. Con \`aspect-ratio: auto\` una imagen a
   \`height:100%\` colapsaría a 0, así que aquí manda su alto natural. */
/* Un selector de atributo mas clase pesa mas que una clase suelta, asi que sin
   el selector de modo delante la foto se quedaba forzada a 9:16 con bandas. */
[data-medio-modo] .plato__medio--sinmedidas{aspect-ratio:auto}
[data-medio-modo] .plato__medio--sinmedidas img{height:auto;position:static}

/* --- modo BLOQUE (el elegido): ancho completo, alto por aspecto propio ----- */
[data-medio-modo='bloque'] .plato--con-medio{display:block}
[data-medio-modo='bloque'] .plato__cuerpo{margin-top:var(--medio-hueco,12px)}
[data-medio-modo='bloque'] .plato__medio{width:100%;
  aspect-ratio:var(--medio-aspecto,var(--medio-tope,9/16))}

/* --- modo FILA: miniatura de ancho fijo al lado del texto ------------------ */
[data-medio-modo='fila'] .plato--con-medio{display:flex;gap:var(--medio-hueco,14px);
  align-items:flex-start}
[data-medio-modo='fila'] .plato__cuerpo{flex:1 1 auto;min-width:0}
[data-medio-modo='fila'] .plato__medio{flex:0 0 auto;width:var(--medio-ancho,84px);
  aspect-ratio:var(--medio-aspecto,3/4)}
.plato__medio-galon{position:absolute;right:4px;bottom:4px;font:600 .625rem/1 system-ui,sans-serif;
  color:#fff;background:#0009;border-radius:4px;padding:3px 5px;letter-spacing:.02em}
.medios__conmutador{appearance:none;border:1px solid var(--linea,#0002);background:transparent;
  color:inherit;font:inherit;font-size:.85em;border-radius:999px;padding:6px 12px;cursor:pointer}
.medios__conmutador:focus-visible{outline:2px solid currentColor;outline-offset:2px}
.visor{position:fixed;inset:0;z-index:9999;background:#000;display:flex;align-items:center;
  justify-content:center}
.visor video{max-width:100%;max-height:100%;width:auto;height:auto}
.visor__cerrar{position:absolute;top:max(12px,env(safe-area-inset-top));right:12px;
  width:44px;height:44px;border-radius:50%;border:0;background:#ffffff26;color:#fff;
  font:400 1.375rem/1 system-ui,sans-serif;cursor:pointer}
.visor__cerrar:focus-visible{outline:2px solid #fff;outline-offset:2px}
body.visor-abierto{overflow:hidden}

/* --- VISOR CON DATOS Y DESLIZAMIENTO (E4) ---------------------------------
   La pista es un scroll vertical con anclaje obligatorio: un plato por
   pantalla, en el orden de la carta. 'scroll-snap-stop: always' impide que un
   gesto largo se salte tres platos de golpe. */
.visor--pista{display:block}

/* ALTURA ABSOLUTA EN LA PISTA, NO HEREDADA (punto 10, 08/08/2026).
 *
 * Era `height:100%`, y con eso toda la cadena colgaba del viewport:
 * `.visor{inset:0}` -> pista -> diapositiva. Medido en el iPhone de Pedro, el
 * salto lleva la pista EXACTAMENTE al maximo de scroll -- partia de 2319 (3 x
 * 773) y acababa en 7730 (10 x 773, que es el maximo con 11 diapositivas) --
 * sin `resize`, sin `vv:resize`, sin `visibilitychange` y sin `focusin`. Eso no
 * es "se mueve": es un clamp, y un clamp solo ocurre si la geometria cambio y
 * nadie nos aviso. Una captura de iOS provoca un renderizado del que JS no se
 * entera.
 *
 * `svh` es el viewport PEQUENO: una unidad absoluta que NO cambia cuando la
 * barra del navegador aparece o se esconde. Al ponerla aqui, la altura de la
 * pista deja de depender de su contenedor, y con ella la de las diapositivas.
 * Si el contenedor colapsa un instante, esto no.
 *
 * VA EN LA PISTA Y NO EN LA DIAPOSITIVA a proposito: asi `.visor` sigue
 * cubriendo el viewport entero con su fondo negro, y cuando la barra se
 * esconde la franja que sobra por abajo queda NEGRA en vez de dejar ver la
 * rejilla de detras.
 *
 * El `100vh` de delante es el respaldo para navegadores sin `svh`, donde el
 * comportamiento es el de antes de este cambio. */
.visor__pista{height:100vh;height:100svh;
  overflow-y:scroll;scroll-snap-type:y mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.visor__pista::-webkit-scrollbar{display:none}
.visor__slide{position:relative;height:100%;scroll-snap-align:start;
  scroll-snap-stop:always;overflow:hidden;background:#000}
/* AQUI el medio SI llena la pantalla: la pantalla del movil ya es 9:16, asi que
   para el material vertical 'cover' y 'contain' coinciden y no se recorta nada.
   Se deja 'contain' de todas formas porque con un 16:9 la diferencia es real y
   la regla 2 manda en el visor: aqui se ve la obra. */
.visor__slide video,.visor__slide>img{position:absolute;inset:0;width:100%;
  height:100%;object-fit:contain;background:#000}
/* LA SOMBRA DERIVA SU ALTURA DEL TEXTO, NO DE UN PORCENTAJE (A4, 08/08/2026).
 *
 * Antes era un elemento aparte con `height:72%` y el degradado repartido en
 * porcentajes de esa altura. Medido sobre los ocho videos reales, el texto
 * pasaba WCAG por poco -- 4,9:1 en la descripcion -- y sobre todo **el margen
 * dependia de cuanto texto hubiera**: un titulo de dos lineas lo bajaba a 3,9 y
 * dejaba de cumplir. Un 9 % de holgura que se evapora con el contenido no es
 * una garantia, es una casualidad medida. Y subir el alfa movia el numero sin
 * cambiar eso.
 *
 * Ahora el degradado es el FONDO de la propia caja de datos, asi que su altura
 * ES la del contenido por construccion, y los tramos se miden en `em` y no en
 * porcentajes: el texto vive siempre sobre el tramo opaco y la transicion cae
 * entera dentro del `padding-top`, donde no hay nada escrito. Con el contenido
 * que sea. Deja de haber un numero que vigilar.
 *
 * `left/right:0` con el hueco lateral pasado a `padding`: asi el degradado
 * cubre todo el ancho mientras el texto sigue esquivando los botones. */
.visor__datos--fondo{
  background:linear-gradient(to top,
    #000000f2 0,
    #000000e0 calc(100% - var(--visor-transicion,3.5em)),
    #0000 100%)}

/* La ficha de un plato SIN MEDIO. Mismo lenguaje que `plato__medio--vacio` de
   la rejilla -- el degradado y el nombre centrado -- para que la ausencia de
   foto se lea igual en los dos sitios y no parezca un fallo en ninguno.
   El nombre va grande y apagado: es fondo, no dato. El dato esta abajo, en la
   capa de siempre, separado por la sombra. */
.visor__sinmedio{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;padding:32px;text-align:center;
  background:linear-gradient(160deg,#241d1a,#131010)}
.visor__sinmedio span{font:600 clamp(1.375rem,7vw,2.125rem)/1.25 inherit;color:#ffffff2e}
/* Sin medio no hay imagen que rescatar detras del texto, asi que la transicion
   puede ser mas corta y ensenar mas del fondo tipografico. */
.visor__slide--sinmedio .visor__datos{--visor-transicion:2em}
.visor__datos{position:absolute;left:0;right:0;bottom:0;color:#fff;
  padding:var(--visor-transicion,3.5em) 70px
    calc(22px + env(safe-area-inset-bottom,0px)) 16px}
.visor__datos h3{margin:0 0 5px;font:700 1.5625rem/1.15 inherit}
.visor__precio{font:700 1.25rem/1 inherit;margin-bottom:9px;font-variant-numeric:tabular-nums}
.visor__distintivo{display:inline-flex;align-items:center;background:#e8a02a;
  color:#241703;border-radius:99px;padding:4px 9px;font:700 .625rem/1 inherit;
  letter-spacing:.09em;margin-bottom:9px;text-transform:uppercase}
/* LA TRAMPA DEL SPRINT: un scroll vertical DENTRO de algo que tambien se
   desliza en vertical -- el mismo gesto para dos cosas. 'overscroll-behavior:
   contain' hace que la descripcion consuma el gesto y NO lo encadene a la
   pista, para que leer un texto largo no acabe saltando de plato sin querer.
   Se prueba con la descripcion mas larga que haya, no con una de dos lineas. */
/* EL TOPE SE MIDE EN LINEAS, NO EN PANTALLA (A3, 08/08/2026).
 *
 * Era `19vh`, y `vh` no escala con el texto: con el navegador en tamano grande
 * el texto crecia y el hueco no, asi que quedaban dos lineas visibles. Lo que
 * de verdad se quiere decir es "unas siete lineas", y eso se dice en `em`:
 * 1,5em por linea x 7 = 10,5em, que con el tamano base son los mismos ~147 px
 * de antes -- o sea, a tamano normal no cambia nada.
 *
 * El `min()` con 42vh es el techo que impide que se coma la pantalla: a 200%
 * el bloque crece, que es lo correcto porque quien amplia quiere LEER, pero
 * nunca pasa de dos quintos del alto. */
/* `also:` -- el calculo del apaisado en tablet (09/08/2026) destapo que con
   `left:0;right:0` la descripcion daba lineas de ~938 px en un iPad. No estaba
   roto, solo incomodo de leer. Un tope de medida en `em` lo acota sin tocar el
   degradado, que si tiene que cubrir todo el ancho. En movil no llega a
   aplicar. */
/* LA CAJA QUE SE DESPLAZA. Antes el tope vivia en `.visor__desc` porque la
   descripcion era lo unico que habia dentro; desde el 10/08/2026 comparte sitio
   con la lista de variantes, asi que el tope sube al contenedor.
   EL VALOR NO CAMBIA, y eso es deliberado: `10.5em` se resolvia contra los
   .875rem de la descripcion (=147px), asi que la caja declara el mismo
   `font-size` para que el tope no crezca en silencio al mudarse. */
.visor__scroll{max-width:42em;font-size:.875rem;
  max-height:min(10.5em,42vh);overflow-y:auto;overscroll-behavior:contain;
  margin:0 0 10px;padding-right:6px}
.visor__scroll::-webkit-scrollbar{width:3px}
.visor__scroll::-webkit-scrollbar-thumb{background:#ffffff40;border-radius:3px}
/* La descripcion ya no se desplaza sola: hereda el tamano de la caja. */
.visor__desc{font-size:1em;line-height:1.5;color:#fff;margin:0}
.visor__variantes + .visor__desc,
.visor__variantes-nota + .visor__desc{margin-top:10px}

/* LA LISTA DE VARIANTES DEL VISOR.
   Misma FORMA que la de la carta --nombre, puntos, precio-- pero regla propia y
   no la de `styles.css` de cada app: aquella esta escrita para fondo claro (el
   punteado es un gris calido casi invisible sobre negro) y ademas vive DUPLICADA
   en las dos apps, que es la issue 004. El visor es del modulo compartido y se
   estila aqui. */
.visor__variantes{list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:6px}
.visor__variante{display:flex;align-items:baseline;gap:10px}
.visor__variante-nombre{flex:0 1 auto;color:#ffffffde}
.visor__variante-puntos{flex:1 1 auto;min-width:14px;
  border-bottom:1px dotted #ffffff40;transform:translateY(-3px)}
.visor__variante-precio{flex:0 0 auto;font-weight:700;
  font-variant-numeric:tabular-nums}
/* UNA nota del bloque, no una coletilla por linea. Usa las mismas variables que
   el "IVA incl." del precio suelto para que las dos digan lo mismo igual. */
.visor__variantes-nota{margin:6px 0 0;
  font-size:var(--precio-nota-escala,.62em);
  opacity:var(--precio-nota-opacidad,.62)}

/* SEÑAL 2a -- QUE HAY MAS TEXTO. No es un cartel sobre el contenido: es el
   contenido diciendo que sigue. El texto se desvanece en el borde inferior
   SOLO cuando desborda, y la clase se retira sola al llegar al final, asi que
   la pista desaparece justo cuando deja de ser cierta.
   La mascara no ocupa sitio ni intercepta el gesto, que es la diferencia con
   poner un degradado encima. */
.visor__scroll--hay-mas{
  -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 2.2em),transparent);
  mask-image:linear-gradient(to bottom,#000 calc(100% - 2.2em),transparent)}
/* Los alergenos NUNCA se van con el scroll de la descripcion: son informacion
   de seguridad alimentaria y viven fuera de la caja que se desplaza. */
.visor__alergenos{display:flex;flex-wrap:wrap;gap:5px}
.visor__alergenos span{border:1px solid #ffffff30;color:#ffffffb0;font-size:.6875rem;
  padding:3px 9px;border-radius:99px}
.visor__lado{position:absolute;right:14px;
  bottom:calc(26px + env(safe-area-inset-bottom,0px));display:flex;
  flex-direction:column;gap:11px}
.visor__lado button{width:44px;height:44px;border-radius:50%;border:0;
  background:#ffffff26;color:#fff;cursor:pointer;font:400 1rem/1 system-ui,sans-serif}
.visor__lado button:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* SEÑAL 2b -- QUE HAY OTRO PLATO DEBAJO. Discreta, en la esquina izquierda, y
   se retira en cuanto el comensal desliza una vez: una pista que sigue ahi
   despues de aprenderla es ruido. */
.visor__pista-aviso{position:absolute;top:calc(16px + env(safe-area-inset-top,0px));
  left:16px;color:#ffffffa0;font-size:.719rem;letter-spacing:.1em;
  text-transform:uppercase;z-index:5;pointer-events:none;
  display:flex;align-items:center;gap:6px;
  transition:opacity .35s ease}
.visor__pista-aviso[hidden]{display:none}
.visor__pista-aviso--fuera{opacity:0}
.visor__pista-aviso i{font-style:normal;animation:restoos-sube 1.8s ease-in-out infinite}
@keyframes restoos-sube{
  0%,100%{transform:translateY(3px);opacity:.55}
  50%    {transform:translateY(-3px);opacity:1}}
/* Con movimiento reducido la señal EXISTE pero no se mueve: quien no tolera el
   movimiento necesita la pista igual, no menos. */
@media (prefers-reduced-motion: reduce){
  .visor__pista-aviso i{animation:none;opacity:1}
  .visor__pista-aviso{transition:none}}

/* La salida del final: un destino de anclaje mas, para que el mismo gesto que
   recorre los platos saque de la secuencia en vez de dejar al comensal
   rebotando contra el ultimo. */
.visor__fin{display:flex;align-items:center;justify-content:center;padding:24px}
.visor__fin-caja{text-align:center;max-width:16rem}
.visor__fin-texto{color:#ffffffb0;font-size:.9375rem;line-height:1.5;margin:0 0 18px}
/* Tres salidas en columna, de menos a mas compromiso: volver, repetir, avanzar.
   En columna y no en fila porque a 200 % tres botones en fila no caben, y
   porque el orden de lectura vertical coincide con el de compromiso. */
.visor__fin-acciones{display:flex;flex-direction:column;gap:10px;align-items:stretch}
.visor__fin-boton{background:#ffffff1f;border:1px solid #ffffff33;color:#fff;
  border-radius:99px;padding:11px 22px;font:inherit;font-size:.875rem;cursor:pointer}
.visor__fin-boton:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* La de avanzar destaca: es la que convierte el final en navegacion. */
.visor__fin-boton--principal{background:#fff;color:#111;border-color:#fff;font-weight:600}
@media (prefers-reduced-motion: reduce){.plato__medio video{display:none}}

/* --- modo REJILLA: dos columnas, molde uniforme 3:4 ------------------------
   Regla de render 2, mitad de la rejilla (acotada el 08/08/2026): aqui SI se
   recorta, porque lo de la rejilla es la MINIATURA y no la obra. La obra se ve
   entera en el visor, que sigue con 'contain' y su forma nativa.

   El molde tiene que ganarle al 'aspect-ratio' que montarMedio calcula desde
   las dimensiones reales del video: esa variable sirve al modo bloque, donde el
   alto lo marca el medio. Por eso el selector lleva el modo delante -- pesa mas
   que la clase suelta -- y por eso reescribe tambien 'object-fit'. Sin las dos
   cosas, un 9:16 seguiria midiendo 9:16 dentro de la rejilla. */
/* COLUMNAS POR ANCHO DISPONIBLE, NO POR DISPOSITIVO (punto 5, pieza 2).
 *
 * Eran dos fijas, y a 1400 px daban tarjetas de tamano cartel. Con `auto-fill`
 * + `minmax` no hay que nombrar ningun aparato: salen 2 columnas en movil, 3
 * hacia los 700 px y 4 hacia los 1000, y el dia que exista una pantalla que hoy
 * no imaginamos se reparte sola.
 *
 * El minimo de 9.5rem es lo que hace que en movil sigan siendo DOS y no tres
 * apretadas: con 390 px de ancho y el hueco, tres no caben.
 *
 * EL ANCHO MAXIMO CENTRADO no es estetica: una carta no gana nada por ocupar
 * 1400 px. Gana por que las fotos tengan tamano de plato y no de cartel, y por
 * que la vista no tenga que cruzar la pantalla entera para leer dos columnas. */
[data-medio-modo='rejilla'] .rejilla{display:grid;
  grid-template-columns:repeat(auto-fill,
    minmax(var(--rejilla-min,clamp(9.5rem,18vw,15rem)),1fr));
  gap:var(--rejilla-hueco,12px);align-items:start;
  max-width:var(--rejilla-max,1100px);margin-inline:auto}
/* ── LAS REGLAS DE ITEM VAN DENTRO DE `.rejilla`, Y ES UN ARREGLO ──────────
 *
 * Desde el E3 una CATEGORIA puede pedir su propio modo, asi que el <html> fija
 * el defecto (contrato del ADR 013: una plantilla es una fila de datos) y la
 * <section> lo sobreescribe. Con los selectores anteriores eso NO funcionaba, y
 * se calculo sobre esta misma hoja antes de tocarla: `[data-medio-modo='fila']
 * .plato__medio` y `[data-medio-modo='rejilla'] .plato__medio` tienen LA MISMA
 * especificidad (0,2,0), asi que con <html rejilla> y <section fila> los dos
 * ancestros casaban y decidia el orden de aparicion -- ganaba rejilla, que esta
 * mas abajo. Colisionaban `width` y `aspect-ratio`, y se colaba ademas el
 * `margin-top` de `.plato__cuerpo`, que rejilla pone y fila no.
 *
 * NO se arregla subiendo especificidad ni reordenando: con tres modos, cualquier
 * par puede ser el que choque y el orden no puede favorecerlos a todos. Se
 * arregla por ESTRUCTURA -- estas reglas solo tienen sentido dentro de la
 * rejilla, que es el contenedor que la app pinta unicamente en ese modo. Una
 * seccion en `fila` pinta `ol.platos`, asi que no hay `.rejilla` sobre ella y
 * estas reglas ni siquiera casan. No hay guerra de cascada que ganar.
 *
 * La regla del contenedor de arriba ya estaba asi; estas se le suman. */
[data-medio-modo='rejilla'] .rejilla .plato__medio{width:100%;aspect-ratio:3/4}
[data-medio-modo='rejilla'] .rejilla .plato__medio img,
[data-medio-modo='rejilla'] .rejilla .plato__medio video{object-fit:cover}
/* Una foto sin dimensiones conocidas tambien va al molde: en la rejilla el
   molde no depende del medio, asi que aqui no hay salto de maquetacion que
   declarar -- al reves que en el modo bloque. */
[data-medio-modo='rejilla'] .rejilla .plato__medio--sinmedidas{aspect-ratio:3/4}
[data-medio-modo='rejilla'] .rejilla .plato__medio--sinmedidas img{height:100%;position:absolute;inset:0}

/* La tarjeta SIN medio. No es un hueco vacio ni un placeholder: es el tercer
   eslabon de la cadena de respaldo, y tiene que poder estar al lado de una con
   video sin parecer que falta algo. Por eso el nombre va DENTRO del rectangulo
   y NO se repite debajo -- repetirlo es lo que lo convierte en un error visible. */
/* EL NOMBRE NO SE CORTA NUNCA (A3, 08/08/2026).
 *
 * `aspect-ratio: 3/4` + `overflow: hidden` + texto dentro es la combinacion que
 * pierde contenido: con `overflow:hidden`, `min-height:auto` resuelve a 0 y el
 * molde manda sobre el texto, asi que un nombre que no cabe se RECORTA. Eso es
 * incumplir WCAG 1.4.4, y el problema aparece justo ahora: mientras los tamanos
 * estaban en px el texto no crecia con el ajuste del navegador; al pasarlos a
 * `rem` si crece, y entonces se corta.
 *
 * Se arregla por el lado del texto y NO quitando el molde -- la rejilla depende
 * de que sea uniforme. Con `overflow:visible`, `min-height:auto` vuelve a valer
 * min-content: la caja MANTIENE el 3:4 mientras el nombre quepa, que es
 * siempre a tamano normal, y CEDE creciendo solo cuando cortar seria la
 * alternativa. El molde uniforme se conserva en el caso normal y se rompe justo
 * en el caso en que romperlo es lo correcto.
 *
 * La rejilla ya lo tolera: lleva `align-items:start` desde que se escribio. */
[data-medio-modo='rejilla'] .rejilla .plato__medio--vacio{display:flex;align-items:center;
  justify-content:center;padding:14px;text-align:center;
  overflow:visible;overflow-wrap:anywhere;
  background:var(--medio-vacio-fondo,#00000014)}
[data-medio-modo='rejilla'] .rejilla .plato__medio--vacio span{font:600 .9375rem/1.3 inherit;
  color:var(--medio-vacio-texto,inherit)}
[data-medio-modo='rejilla'] .rejilla .plato__cuerpo{margin-top:var(--medio-hueco,8px)}

/* El "IVA incl.": una NOTA sobre el precio, no un segundo precio. Competia con
   la cifra en el movil de Pedro (08/08/2026).
   Va por variables porque es exactamente lo que una plantilla del ADR 013 va a
   querer cambiar -- y porque un restaurante con precios sin IVA querra otra
   nota, u ninguna. */
.plato__precio-nota,.visor__precio .plato__precio-nota{
  font-size:var(--precio-nota-escala,.62em);
  font-weight:var(--precio-nota-peso,400);
  opacity:var(--precio-nota-opacidad,.62);
  letter-spacing:0;
  margin-left:var(--precio-nota-hueco,.4em);
  white-space:nowrap}

/* Panel de medida del punto 4. Solo aparece con `?medir=1` en la URL: sirve
   para leer las seis marcas en un movil real sin abrir herramientas de
   desarrollo, que es donde hay que medirlo. */
/* DOS paneles, con zonas separadas: el de ventana arriba y el de video abajo.
   No es estetica -- compartir sitio fue lo que hizo que el del punto 10 no
   registrara nada, porque el de video lo sobrescribia constantemente. */
.visor__medidor{position:absolute;left:8px;right:64px;z-index:6;margin:0;
  background:#000000cc;color:#9fe6a0;font:400 .6875rem/1.5 ui-monospace,monospace;
  padding:8px 10px;border-radius:8px;white-space:pre-wrap;pointer-events:none}
.visor__medidor--ventana{top:calc(56px + env(safe-area-inset-top,0px));color:#ffd28a}
.visor__medidor--video{bottom:calc(50% + 8px)}

/* ── AVISO DE APAISADO EN MOVIL (punto 5, pieza 1) ───────────────────────────
   Oculta, NO desmonta: el DOM de debajo sigue intacto, asi que al volver a
   vertical no hay nada que restaurar -- ni el plato, ni el scroll, ni el
   sonido. El requisito de "no perder el sitio" se cumple por construccion.

   El criterio es la FORMA Y EL TAMANO de la ventana, no el dispositivo:
   apaisado y alto <= 500 px. Un iPhone tumbado entra (390-430 px de alto); un
   iPad tumbado NO (768-820), asi que la tablet en apaisado sigue funcionando. */
/* LA DECIDE EL JS, NO UN MEDIA QUERY (corregido el 09/08/2026).
   El criterio son DOS condiciones -- apaisado Y modo con medios -- y la segunda
   el CSS no puede leerla: vive en `localStorage`. Con el media query aqui, la
   salida "Ver la carta en texto" no salia de nada, porque el aparato seguia
   apaisado y la capa volvia a taparlo todo.
   `display:none` en la regla base y no `opacity`/`visibility`: un elemento con
   display:none no genera caja y no puede interceptar ni un toque. */
.apaisado{display:none}
.apaisado.apaisado--puesta{display:flex;position:fixed;inset:0;z-index:10000;
  align-items:center;justify-content:center;padding:20px;
  background:var(--apaisado-fondo,#0f0c0b);color:var(--apaisado-texto,#f5efe9)}
/* El fondo se bloquea para que no se pueda desplazar a ciegas por detras. */
body.apaisado-tapado{overflow:hidden}
.apaisado__caja{text-align:center;max-width:22rem}
.apaisado__icono{font-size:2.5rem;line-height:1;margin-bottom:14px;
  display:inline-block;animation:restoos-gira 2.4s ease-in-out infinite}
.apaisado__texto{font-size:1rem;line-height:1.5;margin:0 0 18px}
/* LA SALIDA, y no es opcional: hay quien no puede girar el telefono -- bloqueo
   de rotacion, soporte de coche o de mesa, movilidad reducida. Sin esto la
   carta seria un muro, y es donde estan los alergenos. */
.apaisado__salida{background:transparent;border:1px solid currentColor;
  color:inherit;border-radius:99px;padding:11px 22px;font:inherit;
  font-size:.875rem;cursor:pointer}
.apaisado__salida:focus-visible{outline:2px solid currentColor;outline-offset:2px}
@keyframes restoos-gira{
  0%,45%,100%{transform:rotate(0deg)}
  60%,85%    {transform:rotate(-90deg)}}
/* Misma regla que la senal de deslizar: con movimiento reducido el icono
   EXISTE pero no se mueve. Quien no tolera el movimiento necesita la pista
   igual, no menos. */
@media (prefers-reduced-motion: reduce){
  .apaisado__icono{animation:none}}

/* NAVEGACION SIN DEDO (punto 5, pieza 3).
   Va en la capa del visor y NO dentro de la pista: el candidato principal al
   salto del punto 10 era un elemento enfocable dentro del contenedor
   desplazable arrastrandolo para revelarse. Resulto falso, pero el riesgo es
   real y evitarlo no cuesta nada.
   Solo aparece con puntero fino -- lo decide el JS -- porque en un movil
   sobraria y ocuparia pantalla. */
.visor__nav{position:absolute;right:14px;top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:10px;z-index:6}
.visor__nav-boton{width:44px;height:44px;border-radius:50%;border:0;
  background:#ffffff26;color:#fff;cursor:pointer;
  font:400 1.125rem/1 system-ui,sans-serif}
.visor__nav-boton:hover{background:#ffffff3d}
.visor__nav-boton:focus-visible{outline:2px solid #fff;outline-offset:2px}
