/* ==========================================================================
   Menu interactivo · feed vertical
   La paleta sale del propio local: negro de la sala, ambar de las lamparas
   colgantes y magenta de los cerezos iluminados.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TIPOGRAFIA, SERVIDA DESDE AQUI
   --------------------------------------------------------------------------
   Antes esto venia de fonts.googleapis.com, y era el UNICO recurso de
   terceros de toda la PWA del comensal. Dos motivos para traerlo:

   1. Mandaba la IP y el navegador de cada comensal a Google en cada carga.
      El producto se vende sobre "cero terceros, cero cookies", asi que un
      enlace a Google en la cabecera era un agujero en el argumento.
   2. El service worker no cacheaba un dominio ajeno, asi que sin conexion
      la tipografia se caia y la carta se veia con la fuente de respaldo.

   Las dos son SIL Open Font License, asi que se pueden alojar.

   Son fuentes VARIABLES (wght como eje continuo), no una por peso. Importa
   porque el CSS usa 350, 460 y 470, que con archivos estaticos no existen.

   Solo se traen los subconjuntos latin y latin-ext: cubren ingles, espanol
   y frances. El navegador pide latin-ext unicamente si el texto lo necesita,
   asi que en la practica se descargan 94 KB, no 176 KB.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("fonts/fraunces-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("fonts/fraunces-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url("fonts/jost-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 300 500;
  font-display: swap;
  src: url("fonts/jost-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* Visible para el lector de pantalla, invisible para los ojos.
   No vale display:none ni visibility:hidden, que lo sacan tambien del arbol
   de accesibilidad. Tampoco vale un ancho de 0. La receta es un recorte de
   1x1 pixel con el texto fuera de vista pero renderizado. */
.solo-lector {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:root {
  /* Las curvas de toda la interfaz. Las de serie de CSS son demasiado
     flojas: no tienen el tiron que hace que una animacion parezca
     intencionada en vez de un retardo. */
  --sale: cubic-bezier(0.23, 1, 0.32, 1);          /* entra o sale */
  --mueve: cubic-bezier(0.77, 0, 0.175, 1);        /* se desplaza en pantalla */
  --cajon: cubic-bezier(0.32, 0.72, 0, 1);         /* hojas y cajones */

  --negro:        #0a0708;
  --negro-suave:  #161012;
  --negro-carta:  #1d1518;
  --ambar:        #f5a623;
  --ambar-claro:  #ffd089;
  --magenta:      #e0338c;
  --alerta:       #ff6b5e;
  /* Derivados del de alerta, con su variable propia y en rgba literal, que
     es como estan los demas translucidos de esta hoja (--hueso-tenue y
     compania). Se probo con color-mix y se deshizo: era el unico uso en
     3.100 lineas, y donde el resto degrada (una animacion que no se ve),
     un color-mix que el navegador no entiende TIRA la declaracion entera,
     asi que el recuadro del aviso desaparecia y se quedaba una linea roja
     suelta indistinguible del resto. */
  --alerta-borde: rgba(255, 107, 94, 0.55);
  --alerta-fondo: rgba(255, 107, 94, 0.12);
  --verde:        #6fcf8f;
  --hueso:        #f6efe7;
  --hueso-tenue:  rgba(246, 239, 231, 0.66);
  --hueso-debil:  rgba(246, 239, 231, 0.22);

  --tipo-titulo: "Fraunces", Georgia, serif;
  --tipo-texto:  "Jost", -apple-system, sans-serif;

  --cabecera: 7.6rem;     /* alto de la barra superior con sus dos filas */
  --foto-dura: 4.6s;      /* cuanto se ve cada toma, igual que FOTO_DURA */
  --fundido: 1300ms;      /* el cruce entre fotos, largo a proposito */
  /* El recorrido de la foto dura exactamente lo que la foto esta en
     pantalla: los 4,6 s que manda mas los 1,3 que tarda en irse. Ni un
     milisegundo mas, o al final del turno se quedaria parada, ni menos,
     o pararia antes de desaparecer. */
  --kb-dura: 5.9s;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { background: var(--negro); }

body {
  min-height: 100dvh;
  background: var(--negro);
  color: var(--hueso);
  font-family: var(--tipo-texto);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

:focus-visible { outline: 2px solid var(--ambar); outline-offset: 3px; }

/* ==========================================================================
   Barra superior
   ========================================================================== */

#cabecera {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 30;
  padding: max(0.7rem, env(safe-area-inset-top)) 0 0.55rem;
}

/* El velo y el desenfoque van en una capa aparte, no en el propio header.
   Si se le pone backdrop-filter al header, el desenfoque termina en seco
   justo donde el degradado ya es transparente y se ve una linea recta
   cruzando la foto. Aqui la mascara apaga el velo y el blur a la vez. */
#cabecera::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: rgba(10, 7, 8, 0.88);
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  mask-image: linear-gradient(
    #000 0%, #000 48%, rgba(0, 0, 0, 0.72) 68%,
    rgba(0, 0, 0, 0.3) 85%, transparent 100%);
  -webkit-mask-image: linear-gradient(
    #000 0%, #000 48%, rgba(0, 0, 0, 0.72) 68%,
    rgba(0, 0, 0, 0.3) 85%, transparent 100%);
}

.fila-marca {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(0.9rem, 4vw, 1.6rem) 0.5rem;
}

#marca {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: clamp(1rem, 4.4vw, 1.3rem);
  letter-spacing: -0.015em;
  line-height: 1.1;
}

#toggle-vista {
  display: grid;
  place-items: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  flex: none;
}

#toggle-vista svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.7; }

/* --- Pestanas de categoria ------------------------------------------------
   Son EXCLUYENTES: un plato pertenece a una sola. Van en su propia fila,
   separadas de los filtros, para que no se confundan.
------------------------------------------------------------------------- */

#categorias, #filtros {
  display: flex;
  gap: 0.45rem;
  overflow-x: auto;
  scroll-snap-type: x proximate;
  scrollbar-width: none;
  padding: 0 clamp(0.9rem, 4vw, 1.6rem);
}

#categorias::-webkit-scrollbar, #filtros::-webkit-scrollbar { display: none; }

/* El boton de filtros va debajo de las pestanas, en su propia linea y
   pegado a la izquierda. Los filtros se despliegan a su derecha, en esa
   misma linea, asi que abrirlos no empuja nada hacia abajo. */
.fila-filtros {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0 clamp(0.9rem, 4vw, 1.6rem);
  min-height: 1.9rem;
}

#btn-filtros {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 1.9rem;
  height: 1.9rem;
  color: var(--hueso-tenue);
  transition: color 200ms ease, transform 140ms var(--sale);
}

#btn-filtros svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
}

#btn-filtros:active { transform: scale(0.9); }
#btn-filtros[aria-expanded="true"] { color: var(--ambar); }

@media (hover: hover) and (pointer: fine) {
  #btn-filtros:hover { color: var(--hueso); }
}

/* El aviso de que hay filtros puestos con la fila cerrada */
.punto-filtros {
  position: absolute;
  top: 0.05rem;
  right: 0.05rem;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 999px;
  background: var(--ambar);
}

.punto-filtros[hidden] { display: none; }

#categorias { margin-bottom: 0.4rem; }

#filtros { padding: 0; flex: 1; min-width: 0; }

/* Los filtros, cayendo por su ventana como los avisos del plato */
#filtros[hidden] { display: none; }

#filtros .filtro {
  opacity: 0;
  translate: 0 -100%;
  clip-path: inset(100% 0 0 0);
}

#filtros.abierta .filtro {
  animation: caer-chip 340ms var(--sale) both;
}

#filtros.abierta .filtro:nth-child(1) { animation-delay: 0ms; }
#filtros.abierta .filtro:nth-child(2) { animation-delay: 55ms; }
#filtros.abierta .filtro:nth-child(3) { animation-delay: 110ms; }
#filtros.abierta .filtro:nth-child(4) { animation-delay: 165ms; }
#filtros.abierta .filtro:nth-child(5) { animation-delay: 220ms; }
#filtros.abierta .filtro:nth-child(6) { animation-delay: 275ms; }
#filtros.abierta .filtro:nth-child(n+7) { animation-delay: 330ms; }

@media (prefers-reduced-motion: reduce) {
  #filtros .filtro { opacity: 1; translate: 0 0; clip-path: none; }
  #filtros.abierta .filtro { animation: none; }
}

.pestana {
  flex: none;
  scroll-snap-align: start;
  padding: 0.4rem 0.15rem 0.5rem;
  margin-right: 0.7rem;
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--hueso-tenue);
  border-bottom: 2px solid transparent;
  transition: color 200ms ease, border-color 200ms ease,
              transform 140ms var(--sale);
  white-space: nowrap;
}

.pestana:active { transform: scale(0.94); }

.pestana[aria-current="true"] {
  color: var(--hueso);
  border-bottom-color: var(--ambar);
  font-weight: 500;
}

/* --- Chips de filtro ------------------------------------------------------
   Son ACUMULABLES y actuan sobre la categoria activa.
------------------------------------------------------------------------- */

.filtro {
  flex: none;
  scroll-snap-align: start;
  padding: 0.3rem 0.72rem 0.34rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--hueso-tenue);
  white-space: nowrap;
  transition: color 200ms ease, background-color 200ms ease,
              border-color 200ms ease, transform 140ms var(--sale);
}

/* Todo lo que se pulsa tiene que hundirse un poco bajo el dedo, o la
   interfaz parece que no ha oido nada. */
.filtro:active { transform: scale(0.96); }

@media (hover: hover) and (pointer: fine) {
  .filtro:not([aria-pressed="true"]):hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(246, 239, 231, 0.42);
    color: var(--hueso);
  }
}

.filtro[aria-pressed="true"] {
  color: var(--negro);
  background: var(--ambar);
  border-color: var(--ambar);
  font-weight: 500;
}

/* ==========================================================================
   Feed vertical
   100dvh y no 100vh: en Safari la barra de direcciones cambia de alto y con
   vh el layout salta en cada scroll.
   ========================================================================== */

#feed {
  height: 100dvh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  overscroll-behavior-y: contain;
  scrollbar-width: none;
}

#feed::-webkit-scrollbar { display: none; }

/* El apagado y el encendido del corte entre secciones lejanas. La escala
   es minima a proposito: lo justo para que la vuelta se lea como una
   llegada y no como un parpadeo. */
#feed.cortando {
  opacity: 0;
  scale: 0.992;
  transition: opacity 140ms ease-out, scale 140ms ease-out;
}

#feed.llegando {
  animation: llegar-seccion 300ms var(--sale);
}

@keyframes llegar-seccion {
  from { opacity: 0; scale: 1.012; }
  to   { opacity: 1; scale: 1; }
}

.plato {
  position: relative;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
  background: var(--negro) var(--blur) center / cover no-repeat;
}

/* El blur embebido se difumina, si no se ven los bordes del thumbnail. */
.plato::before {
  content: "";
  position: absolute;
  inset: -8%;
  background: inherit;
  filter: blur(26px) saturate(1.3);
  transform: scale(1.06);
}

.lienzo { position: absolute; inset: 0; }

.toma {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  /* Durante el cruce las dos fotos estan a media opacidad y a distinta
     escala, porque cada una va por su sitio del recorrido. El ojo separa
     las dos imagenes y lo lee como un parpadeo. Desenfocadas no: el
     desenfoque las funde en una sola cosa y el cambio parece un
     reenfoque de camara en vez de dos fotos superpuestas.
     Cinco pixeles: lo justo para que las dos imagenes dejen de leerse
     por separado, sin que se note que la foto entra desenfocada. */
  filter: blur(5px);
  /* La escala compensa lo que el desenfoque se come por los bordes: sin
     ella se veria una orla translucida alrededor de la foto. */
  scale: 1.02;
  transition: opacity var(--fundido) ease, filter var(--fundido) ease,
              scale var(--fundido) ease;
}

.toma.activa {
  opacity: 1;
  filter: blur(0);
  scale: 1;
}

/* --- Movimiento ------------------------------------------------------------
   Seis recorridos distintos, uno por toma, para que el feed no se sienta
   repetitivo: dos orbitas con rotacion, un zoom de entrada y otro de
   salida, una subida y un balanceo.

   El techo es 1.25 de escala y dos grados de giro, que es exactamente el
   margen que se le pide al modelo al generar la foto. Subirlo aqui sin
   subirlo alli empezaria a comerse las esquinas del plato.
------------------------------------------------------------------------- */

@keyframes orbita-izq {
  from { transform: scale(1.05) rotate(-1.6deg) translate3d(-2.4%, 1.2%, 0); }
  to   { transform: scale(1.21) rotate(0.7deg)  translate3d(2%, -1.4%, 0); }
}

@keyframes orbita-der {
  from { transform: scale(1.05) rotate(1.6deg)  translate3d(2.4%, 1.2%, 0); }
  to   { transform: scale(1.21) rotate(-0.7deg) translate3d(-2%, -1.4%, 0); }
}

@keyframes acercar-hondo {
  from { transform: scale(1.0)  rotate(0.3deg)  translate3d(0, 1.6%, 0); }
  to   { transform: scale(1.25) rotate(-0.5deg) translate3d(0, -1.8%, 0); }
}

@keyframes alejar-hondo {
  from { transform: scale(1.25) rotate(-0.6deg) translate3d(1.4%, -1.6%, 0); }
  to   { transform: scale(1.01) rotate(0.4deg)  translate3d(-0.8%, 1.2%, 0); }
}

@keyframes subir-girando {
  from { transform: scale(1.08) rotate(1.1deg)  translate3d(0.6%, 3.2%, 0); }
  to   { transform: scale(1.23) rotate(-0.9deg) translate3d(-0.6%, -2.6%, 0); }
}

@keyframes balanceo {
  0%   { transform: scale(1.12) rotate(-1.3deg) translate3d(-2.6%, 0, 0); }
  50%  { transform: scale(1.22) rotate(0.2deg)  translate3d(0.4%, -1.2%, 0); }
  100% { transform: scale(1.12) rotate(1.3deg)  translate3d(2.6%, 0, 0); }
}

/* La animacion se asigna SIEMPRE y solo se pausa fuera de foco. Antes se
   asignaba nada mas entrar en foco, y como el foco cambia al 60 por ciento
   de visibilidad, o sea a media pantalla, ahi la foto saltaba: al entrar
   pasaba de escala 1 al primer fotograma, y al salir caia de golpe desde
   donde estuviera, que tras unos segundos era 1.08 o mas, hasta 1.

   Pausada, la foto se queda quieta en el fotograma en el que va. No hay
   nada de donde saltar, ni al entrar ni al salir. */
/* La animacion va en `.toma`, NO en `.toma.activa`. Puesta en la clase
   que cambia, al pasar de foto la que se iba perdia su animacion de golpe
   y con ella su transform: se encogia de 1.09 a 1.00 en un fotograma
   cuando aun estaba al 90 por ciento de opacidad. Ese era el salto.

   Ahora cada foto conserva la suya y solo se pausa la que no manda, asi
   que la que sale se queda quieta donde iba mientras se desvanece. */
.toma {
  animation: orbita-izq var(--kb-dura) ease-in-out forwards;
  animation-play-state: paused;
}

/* Los seis recorridos se reparten al azar en cada pase, asi que cualquier
   toma puede llevar cualquiera. */
.toma[data-mov="0"] { animation-name: orbita-izq; }

.toma[data-mov="1"] { animation-name: orbita-der; }
.toma[data-mov="2"] { animation-name: acercar-hondo; }
.toma[data-mov="3"] { animation-name: alejar-hondo; }
.toma[data-mov="4"] { animation-name: subir-girando; }
.toma[data-mov="5"] { animation-name: balanceo; }

/* Corre mientras el plato este delante, tenga el turno o no. Atado solo
   a la que manda, la foto que se iba se quedaba congelada justo al
   empezar a desvanecerse: un segundo y pico de imagen parada en cada
   cambio, que es precisamente lo que no se quiere. */
.plato.enfoque .toma { animation-play-state: running; }

/* El degradado negro que cubria el tercio de abajo ya no hace falta: el
   texto no se apoya en la foto, se apoya en la lamina de cristal. Un velo
   sobre la comida ademas de la lamina seria oscurecer dos veces. */


/* ==========================================================================
   La lamina de cristal y lo que lleva dentro
   ========================================================================== */

/* Cristal esmerilado sobre la foto. El desenfoque es alto a proposito:
   tiene que dejar pasar el color de la comida sin dejar pasar sus formas,
   porque en cuanto se adivina un borde el texto deja de leerse limpio.

   Se recorta lo que sobresale para que el nombre del plato, que va mas
   rapido que la lamina por el parallax, asome desde detras del borde en
   vez de flotar por encima. */
.panel {
  position: absolute;
  /* Despegada de los bordes: asi se lee como una lamina apoyada sobre la
     foto y no como el final de la pantalla. */
  left: 10px; right: 10px;
  bottom: calc(10px + env(safe-area-inset-bottom));
  z-index: 2;
  padding: clamp(1.1rem, 4.5vw, 1.5rem) 0 0.95rem;
  border-radius: 30px;
  background: rgba(18, 12, 14, 0.58);
  backdrop-filter: blur(34px) saturate(1.45);
  -webkit-backdrop-filter: blur(34px) saturate(1.45);
  border: 1px solid rgba(246, 239, 231, 0.09);
  box-shadow: 0 -18px 50px -24px rgba(0, 0, 0, 0.85);
  overflow: hidden;
  transition: padding-bottom 320ms var(--cajon);
}

/* El mismo destello que recorre el borde de los ingredientes, aqui dando
   la vuelta a la lamina. El truco es el de siempre: un gradiente conico
   recortado a un anillo de un pixel con dos mascaras que se restan.

   Dos diferencias con el de los ingredientes, por el tamano. Tarda nueve
   segundos en lugar de tres y medio, porque el recorrido es mucho mas
   largo y a la velocidad de una caja pequena aqui pareceria una alarma. Y
   el destello es la mitad de fuerte y mas ancho, para que se lea como un
   reflejo que pasa y no como una luz encendida. */
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: conic-gradient(
    from var(--giro),
    transparent 0deg,
    rgba(246, 239, 231, 0.5) 30deg,
    rgba(245, 166, 35, 0.34) 56deg,
    transparent 96deg,
    transparent 360deg);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  -webkit-mask-composite: xor;
  animation: girar-borde 9s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .panel::before { animation: none; --giro: 200deg; }
}

body.con-seleccion .panel {
  padding-bottom: calc(0.95rem + 4rem);
}

/* ==========================================================================
   Informacion del plato
   ========================================================================== */

.info {
  position: relative;
  z-index: 2;
  padding: 0 clamp(1rem, 4.5vw, 1.8rem);
  display: flex;
  flex-direction: column;
  /* Apretado a proposito: cada decima de rem aqui es foto que se ve. */
  gap: 0.3rem;
}


/* Sin esto los chips se moverian en plano dentro del bloque de texto, y
   lo que se quiere es que salgan hacia delante de el. */
.chips { transform-style: preserve-3d; }

.desc.abierta { -webkit-line-clamp: unset; }

/* La pista de que hay mas texto. Solo se pone cuando de verdad no cabe, y
   va en absoluto porque un ::after normal se lo comeria el line-clamp.

   No lleva fondo. Antes tapaba la ultima palabra con un degradado oscuro,
   que sobre el negro de debajo colaba, pero sobre el cristal de la lamina
   se veia como una mancha pegada al final de la frase. En vez de tapar
   texto, ahora se le reserva sitio: el parrafo se estrecha por la derecha
   y el aviso cae en el hueco, sin nada encima ni debajo. */
.desc.plegable {
  cursor: pointer;
  position: relative;
  overflow: hidden;
  /* El hueco del aviso mas un respiro: los puntos suspensivos los pone el
     navegador al recortar, asi que la palabra no puede ir pegada a ellos
     o se leen cinco puntos seguidos. */
  padding-right: 2.9rem;
}

/* Abierto no hace falta el hueco: el ancho entero vuelve al texto. */
.desc.plegable.abierta { padding-right: 0; }

/* El nombre abre y cierra lo mismo que la descripcion, y es el objetivo
   grande: dos lineas de letra pequena son un blanco pobre para un pulgar. */
.nombre.abre-desc { cursor: pointer; }

.desc.plegable::after {
  content: attr(data-mas);
  position: absolute;
  right: 0;
  bottom: 0;
  color: var(--ambar-claro);
  font-weight: 500;
  white-space: nowrap;
}

.desc.plegable.abierta::after { content: none; }





.original {
  font-size: 0.82rem;
  color: var(--ambar-claro);
  letter-spacing: 0.01em;
  text-shadow: 0 1px 3px rgba(10, 7, 8, 0.9);
}

.original i { font-style: normal; color: var(--hueso-tenue); }

.nombre {
  font-family: var(--tipo-titulo);
  font-optical-sizing: auto;
  font-variation-settings: "SOFT" 40, "WONK" 1;
  font-weight: 470;
  font-size: clamp(1.75rem, 7.4vw, 2.6rem);
  line-height: 1.02;
  letter-spacing: -0.022em;
  text-wrap: balance;
  /* Al suavizar el degradado para que se vea la foto entera, el texto puede
     caer sobre comida clara. Tres sombras lo sostienen sin volver a tapar
     la imagen con un velo negro. */
  text-shadow:
    0 1px 2px rgba(10, 7, 8, 0.9),
    0 2px 16px rgba(10, 7, 8, 0.85),
    0 4px 40px rgba(10, 7, 8, 0.7);
}

.desc {
  font-size: 0.95rem;
  line-height: 1.52;
  font-weight: 350;
  color: rgba(246, 239, 231, 0.95);
  text-wrap: pretty;
  max-width: 46ch;
  /* Dos lineas y los puntos suspensivos los pone el navegador. Al abrirse
     no hay altura fija que animar, asi que la transicion la lleva el
     numero de lineas, que en la practica se ve como un despliegue. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-shadow:
    0 1px 2px rgba(10, 7, 8, 0.95),
    0 2px 14px rgba(10, 7, 8, 0.9);
}

/* --- Chips de ingredientes ------------------------------------------------
   Ambar: la preparacion que define el plato, explicada. Es el motivo de
   existir del producto: el comensal que no sabe que es la salsa satay.
   Rojo: alergenos. Verde: etiquetas dietarias.
------------------------------------------------------------------------- */

.chips { display: flex; flex-wrap: wrap; gap: 0.36rem; }

/* Los del glosario se pulsan para saber que son, asi que tienen que
   parecer pulsables: el punto de color y el nombre en su idioma lo dicen. */
button.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.34rem;
  cursor: pointer;
  text-align: left;
  transition: background 200ms, border-color 200ms, transform 180ms;
}

button.chip:active { transform: scale(0.96); }

button.chip .punto {
  width: 0.38rem;
  height: 0.38rem;
  border-radius: 999px;
  flex: none;
  background: currentColor;
  opacity: 0.85;
}

button.chip .nativo { margin-left: 0.12rem; font-size: 0.78rem; }

/* Estos NO son los filtros de arriba, aunque hasta ahora se les parecian
   demasiado: los dos eran pildoras con borde. Arriba se pulsa para elegir;
   aqui solo se lee lo que el plato lleva.

   Asi que dejan de ser pildora: rectangulo de esquina corta, sin borde,
   con una barra de color a la izquierda y la letra pequena y espaciada.
   Se leen como una etiqueta pegada al plato, no como un boton. */
/* Estos NO son los filtros de arriba: alli se pulsa para elegir, aqui solo
   se lee lo que el plato lleva. Rectangulo de esquina corta, sin borde, el
   icono delante y la letra pequena en mayusculas. El icono hace el trabajo
   que hacia la barra de color, y encima se reconoce de un vistazo. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.62rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 0.26rem 0.52rem 0.28rem 0.42rem;
  border-radius: 5px;
  border: none;
  background: rgba(10, 7, 8, 0.5);
  backdrop-filter: blur(10px) saturate(1.2);
  box-shadow: 0 2px 12px -4px rgba(10, 7, 8, 0.9);
  white-space: nowrap;
}

.icono-chip {
  width: 0.86rem;
  height: 0.86rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.9;
}

.chip.key {
  color: var(--ambar-claro);
  background: rgba(245, 166, 35, 0.16);
  white-space: normal;
}

.chip.warn {
  color: #ffb3ab;
  background: rgba(255, 107, 94, 0.14);
}

.chip.normal {
  color: #a8e6bd;
  background: rgba(111, 207, 143, 0.14);
}

/* --- Precio, picante y el boton de agregar ------------------------------- */

/* El precio baja a la linea del boton, a su izquierda: los dos datos que
   cierran la ficha, el que informa y el que actua, uno en cada punta. */
.pie {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 0.4rem;
  /* Sitio para el boton, que flota encima en posicion fija */
  padding-right: 8.4rem;
  min-height: 2.9rem;
}

/* El boton ocupa todo el ancho, debajo del precio: es el unico gesto de la
   pantalla y a una mano se alcanza mejor abajo que en una esquina. */
/* Clavado a la pantalla, no al plato. Es el unico control de la carta y
   tiene que estar siempre en el mismo sitio: el pulgar aprende una
   posicion y no se le puede mover debajo. */
/* El boton se queda en la esquina de abajo a la derecha de la lamina.
   Sigue clavado a la pantalla: como la lamina esta anclada abajo y crece
   hacia arriba, su ultima fila cae siempre a la misma altura sea cual sea
   el largo del texto, asi que el boton y la lamina coinciden siempre. */
#anadir-fijo {
  position: fixed;
  z-index: 40;
  left: auto;
  right: calc(10px + clamp(1rem, 4.5vw, 1.8rem));
  bottom: calc(10px + env(safe-area-inset-bottom) + 0.95rem);
  pointer-events: none;   /* el hueco no, el boton si */
  transition: bottom 320ms var(--cajon);
}

#anadir-fijo[hidden] { display: none; }

body.con-seleccion #anadir-fijo {
  bottom: calc(10px + env(safe-area-inset-bottom) + 4.15rem);
}

.agregar-ancho {
  pointer-events: auto;
  display: flex;
  align-items: center;
  width: auto;
  height: 2.9rem;
  border-radius: 999px;
  background: var(--ambar);
  color: #23160a;
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: 0.01em;
  box-shadow: 0 10px 30px -12px rgba(245, 166, 35, 0.8);
  overflow: hidden;
  transition: background-color 200ms ease, box-shadow 220ms ease,
              transform 140ms var(--sale);
}

/* En el movil no hay puntero, asi que esto es para tableta y escritorio.
   Sin encerrarlo, un toque dejaria el boton encendido hasta el siguiente. */
@media (hover: hover) and (pointer: fine) {
  .agregar-ancho:hover {
    background: var(--ambar-claro);
    box-shadow: 0 16px 42px -12px rgba(245, 166, 35, 1);
  }
  /* Los dos signos se encienden solo cuando el puntero esta encima de
     ellos, para que se vea que son dos objetivos dentro del grande. */
  .agregar-ancho button:hover { background: rgba(0, 0, 0, 0.1); }
}

/* El hundido lo lleva la caja entera, se pulse donde se pulse. Antes solo
   respondia el signo, que es la parte mas pequena del boton mas grande de
   la pantalla. */
.agregar-ancho:active { transform: scale(0.985); }

.agregar-ancho { cursor: pointer; }

/* El destello que cruza al anadir un plato. Anadir algo a la seleccion
   pasa unas pocas veces por comida, asi que aqui si cabe algo de gracia:
   es la unica confirmacion de que el plato entro en la lista. Cruza una
   vez y se quita solo. */
.agregar-ancho::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(
    105deg,
    transparent 38%,
    rgba(255, 255, 255, 0.62) 50%,
    transparent 62%);
  transform: translateX(-100%);
}

.agregar-ancho.suma::after {
  animation: cruzar-brillo 520ms var(--mueve);
}

@keyframes cruzar-brillo {
  from { opacity: 1; transform: translateX(-100%); }
  to   { opacity: 0; transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .agregar-ancho.suma::after { animation: none; }
}

.agregar-ancho .etiqueta {
  padding: 0 0.15rem 0 1.05rem;
  white-space: nowrap;
}

.agregar-ancho button {
  width: 2.8rem;
  height: 100%;
  display: grid;
  place-items: center;
  font-size: 1.35rem;
  line-height: 1;
  flex: none;
  transition: background 180ms;
}

/* El velo oscuro solo bajo el signo que se pulsa: dice cual de los dos se
   ha tocado, que el hundido de la caja entera ya no distingue. */
.agregar-ancho button:active { background: rgba(0, 0, 0, 0.18); }

.agregar-ancho .cantidad {
  flex: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: 1.15rem;
  font-weight: 500;
}

.agregar-ancho[data-n="0"] .menos,
.agregar-ancho[data-n="0"] .cantidad { display: none; }
.agregar-ancho:not([data-n="0"]) .etiqueta { display: none; }

.precio {
  font-family: var(--tipo-titulo);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-shadow:
    0 1px 2px rgba(10, 7, 8, 0.9),
    0 2px 14px rgba(10, 7, 8, 0.85);
}

.picante { display: flex; gap: 0.1rem; font-size: 0.9rem; opacity: 0.95; }
.picante[data-nivel="0"] { display: none; }

.agregar {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.2rem;
  background: var(--ambar);
  color: #23160a;
  border-radius: 999px;
  padding: 0.12rem;
  font-weight: 500;
  box-shadow: 0 8px 26px -10px rgba(245, 166, 35, 0.75);
}

.agregar button {
  /* 44 px. Estaban en 2,3rem (36,8 px), por debajo del minimo para un
     control que se pulsa de pie, con una mano y a media luz. */
  width: 2.75rem; height: 2.75rem;
  border-radius: 999px;
  display: grid; place-items: center;
  font-size: 1.15rem;
  line-height: 1;
  transition: background 200ms;
}

.agregar button:active { background: rgba(0, 0, 0, 0.13); }
.agregar .menos { display: none; }
.agregar[data-n="0"] .cantidad { display: none; }
.agregar[data-n="0"] .etiqueta { display: block; }
.agregar .etiqueta { display: none; padding: 0 0.85rem 0 0.6rem; font-size: 0.88rem; }
.agregar:not([data-n="0"]) .menos { display: grid; }
.agregar .cantidad { min-width: 1.5rem; text-align: center; font-variant-numeric: tabular-nums; }

/* El sello de "recreacion IA" ya no va encima de cada foto: repetido en
   cada plato era ruido. El aviso sigue existiendo, una vez, en el pie del
   menu y en la hoja de seleccion, que es lo que pide la normativa y lo que
   evita la sensacion de estar ocultandolo. */

/* Indicador de que hay mas platos abajo, solo en el primero */
.deslizar {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 33%;
  transition: opacity 500ms ease;
  translate: -50% 0;
  font-size: 0.64rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(246, 239, 231, 0.55);
  animation: respirar 2.4s ease-in-out infinite;
}

body.ya-deslizo .deslizar { opacity: 0 !important; }

@keyframes respirar {
  0%, 100% { opacity: 0.3; transform: translateY(0); }
  50%      { opacity: 0.85; transform: translateY(5px); }
}

/* ==========================================================================
   Vista lista compacta
   Para el comensal que ya sabe que quiere, para el que ve mal y para
   cuando la conexion no da.
   ========================================================================== */

#lista {
  padding: calc(var(--cabecera) + 0.6rem) clamp(0.9rem, 4vw, 1.6rem) 7rem;
  min-height: 100dvh;
}

.fila {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid rgba(246, 239, 231, 0.09);
}

.fila img {
  width: 4.2rem; height: 4.2rem;
  object-fit: cover;
  border-radius: 4px;
  flex: none;
  background: var(--negro-suave);
}

.fila .cuerpo { flex: 1; min-width: 0; }

.fila h3 {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1rem;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

.fila .resumen {
  font-size: 0.74rem;
  color: var(--hueso-tenue);
  margin-top: 0.22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fila .eur { font-size: 0.95rem; font-weight: 500; margin-top: 0.3rem; }

.grupo-lista > h2 {
  font-size: 0.66rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ambar);
  margin: 1.6rem 0 0.4rem;
  font-weight: 500;
}

/* ==========================================================================
   Barra de seleccion
   Se llama seleccion y no pedido a proposito: nada se envia a cocina.
   ========================================================================== */

#barra-seleccion {
  position: fixed;
  z-index: 40;
  left: 0; right: 0;
  bottom: 0;
  padding: 0.7rem clamp(0.9rem, 4vw, 1.6rem)
           calc(max(0.7rem, env(safe-area-inset-bottom)));
  display: flex;
  align-items: center;
  gap: 1rem;
  background: rgba(22, 16, 18, 0.94);
  backdrop-filter: blur(18px) saturate(1.3);
  border-top: 1px solid rgba(246, 239, 231, 0.1);
  transform: translateY(105%);
  transition: transform 320ms var(--cajon);
}

#barra-seleccion.visible { transform: none; }

#resumen-sel { flex: 1; min-width: 0; }
#resumen-sel .n { font-size: 0.76rem; color: var(--hueso-tenue); }
#resumen-sel .total {
  font-family: var(--tipo-titulo);
  font-size: 1.28rem;
  font-weight: 500;
}

.principal {
  background: var(--ambar);
  color: #23160a;
  font-weight: 500;
  font-size: 0.92rem;
  padding: 0.72rem 1.3rem;
  border-radius: 999px;
  flex: none;
}

/* ==========================================================================
   Hoja de seleccion y modo mesero
   ========================================================================== */

.hoja {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--negro-carta);
  overflow-y: auto;
  padding: max(1.1rem, env(safe-area-inset-top)) clamp(1rem, 4.5vw, 1.8rem)
           calc(max(1rem, env(safe-area-inset-bottom)) + 6rem);
  transform: translateY(100%);
  transition: transform 380ms var(--cajon);
}

.hoja.abierta { transform: none; }

.hoja-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.6rem;
}

.hoja-cabeza h2 {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1.55rem;
  letter-spacing: -0.02em;
}

.cerrar {
  width: 2.4rem; height: 2.4rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  display: grid; place-items: center;
  flex: none;
}

.cerrar svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; }

.linea {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid rgba(246, 239, 231, 0.09);
}

.linea .cuerpo { flex: 1; min-width: 0; }
.linea h3 { font-family: var(--tipo-titulo); font-weight: 460; font-size: 1rem; }
.linea .orig { font-size: 0.74rem; color: var(--hueso-tenue); margin-top: 0.15rem; }
.linea .sub { font-size: 0.92rem; font-weight: 500; min-width: 4.5ch; text-align: right; }

.contador {
  display: flex; align-items: center; gap: 0.15rem;
  border: 1px solid var(--hueso-debil);
  border-radius: 999px;
  flex: none;
}

.contador button { width: 2rem; height: 2rem; display: grid; place-items: center; }
.contador .n { min-width: 1.4rem; text-align: center; font-variant-numeric: tabular-nums; font-size: 0.9rem; }

.total-final {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 1.8rem 0 1.2rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--hueso-debil);
}

.total-final .etq { font-size: 0.72rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--hueso-tenue); }
.total-final .val { font-family: var(--tipo-titulo); font-size: 2rem; font-weight: 500; }

.ancho { width: 100%; text-align: center; }

.nota-legal {
  margin-top: 1.6rem;
  font-size: 0.72rem;
  line-height: 1.55;
  color: var(--hueso-tenue);
}

/* --- Modo mesero ---------------------------------------------------------
   Fondo claro y alto contraste: el comensal gira el telefono y el mesero lo
   lee de pie, a medio metro, con la luz baja de un restaurante.
------------------------------------------------------------------------- */

#mesero {
  background: #faf6f0;
  color: #16100f;
}

#mesero .hoja-cabeza h2 { color: #16100f; }
#mesero .cerrar { border-color: rgba(22, 16, 15, 0.3); }

#mesero .aviso-mesero {
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #8a6a2f;
  margin-bottom: 1.4rem;
}
/* Cuando la hoja puede estar incompleta, se ve. Un aviso del color del
   resto no lo lee nadie. */
.aviso-mesero.problema { color: var(--alerta, #ff6b5e); font-weight: 600; }

#mesero .pedido { border-bottom: 2px solid rgba(22, 16, 15, 0.12); padding: 1.1rem 0; display: flex; gap: 1rem; align-items: baseline; }
#mesero .cant { font-family: var(--tipo-titulo); font-size: 2.6rem; font-weight: 600; min-width: 2.6ch; line-height: 1; }
#mesero .nom-orig { font-size: 1.5rem; font-weight: 500; line-height: 1.2; }
#mesero .nom-trad { font-size: 0.92rem; color: #5c4a44; margin-top: 0.2rem; }

/* ==========================================================================
   Avisos legales y estados
   ========================================================================== */

/* ==========================================================================
   El configurador
   ==========================================================================
   Se abre al anadir un plato con opciones. El precio y los alergenos se
   actualizan mientras eliges, que es toda la gracia: un plato sin
   cacahuetes deja de llevarlos, y hay que verlo ANTES de pedirlo.
   ========================================================================== */

.grupo-config {
  border: 0;
  padding: 0;
  margin: 0 0 1.2rem;
}

.grupo-config legend {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 0.95rem;
  color: var(--hueso);
  margin-bottom: 0.5rem;
  padding: 0;
}

.opcion {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.2rem;
  border-bottom: 1px solid rgba(246, 239, 231, 0.07);
  cursor: pointer;
}
.opcion:last-child { border-bottom: 0; }

/* El control nativo, agrandado. Se deja el de serie y no un dibujo
   propio: un radio de verdad lo anuncia el lector de pantalla como
   "1 de 5", que es justo lo que hay que saber en un grupo de eleccion
   unica, y eso con un div no se consigue sin trabajo y sin riesgo. */
.opcion input {
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--ambar);
  flex: none;
}

.opcion-nombre {
  flex: 1;
  font-size: 0.92rem;
  color: var(--hueso);
}

.opcion-precio {
  font-size: 0.85rem;
  color: var(--ambar-claro);
  white-space: nowrap;
}

/* El tope del grupo, junto a su nombre. */
.grupo-tope {
  margin-left: 0.5rem;
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--hueso-tenue);
}

/* La opcion que ya no se puede marcar porque el grupo llego a su tope. */
.opcion.apagada { opacity: 0.38; cursor: default; }

/* Y el boton, mientras falte elegir algo obligatorio. */
#config-anadir:disabled {
  background: rgba(246, 239, 231, 0.12);
  color: var(--hueso-tenue);
  box-shadow: none;
  cursor: default;
}

#config-alergenos, #config-trazas { margin: 0.2rem 0; }
#config-anadir { margin-top: 1rem; }

/* ==========================================================================
   El cartel de Feature Lab
   ==========================================================================
   Permanente mientras la carta cargada sea simulada. Va pegado bajo la
   cabecera y no se puede cerrar: es la condicion para poder ensenar
   cocteles, cafe y filtros de alergeno inventados sin que nadie confunda
   esto con la carta de un restaurante que existe.
   ========================================================================== */
#cartel-simulado {
  position: fixed;
  top: var(--cabecera);
  left: 0; right: 0;
  z-index: 29;
  padding: 0.42rem clamp(0.9rem, 4vw, 1.6rem);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-align: center;
  color: #10202c;
  background: var(--ambar-claro);
}

/* Con el cartel puesto, todo lo que se ancla bajo la cabecera baja. */
body.simulado .rejilla,
body.simulado .fichas { padding-top: calc(var(--cabecera) + 2.6rem); }

/* Y el propio cartel no puede quedarse en una sola linea a la fuerza: en
   un telefono estrecho el texto es largo y se cortaba. */
#cartel-simulado { line-height: 1.25; }

/* ==========================================================================
   El modo informativo: la ficha media
   ==========================================================================
   Para lo que hay que explicar pero no contemplar: un vino de copa, un
   cafe, un coctel clasico. Una columna, no dos: aqui si hay texto que leer
   y partirlo en dos columnas estrechas lo haria ilegible.
   ========================================================================== */
.fichas {
  min-height: 100dvh;
  scroll-snap-align: start;
  padding: calc(var(--cabecera) + 1rem) clamp(0.9rem, 4vw, 1.6rem) 3rem;
  background: var(--negro);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* Una columna, no dos.
   La rejilla compacta si va a dos porque ahi solo hay un nombre y un
   precio. Aqui hay una frase que leer, y partirla en media pantalla la
   deja en cuatro lineas de tres palabras.
   El selector lleva .fichas delante porque .rejilla-grupo, que pone dos
   columnas, viene despues en este archivo y con la misma especificidad
   ganaba por orden. */
.fichas .fichas-grupo { grid-template-columns: minmax(0, 1fr); }

/* Y el control de anadir, en pequeno, como en la rejilla: el grande se
   salia de la tarjeta. */
.ficha .agregar { margin-left: 0; flex: none; }
.ficha .agregar .etiqueta { display: none; }
.ficha .agregar button { width: 2.05rem; height: 2.05rem; font-size: 1.1rem; }
.ficha .agregar .cantidad { min-width: 1.2rem; font-size: 0.88rem; }

.ficha {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 0;
  padding: 0.85rem 0.95rem;
  border-radius: 16px;
  border: 1px solid var(--hueso-debil);
  background: var(--negro-suave);
}

.ficha h3 {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1.02rem;
  line-height: 1.2;
  color: var(--hueso);
  overflow-wrap: anywhere;
}

/* Los descriptores de sabor, PRIMERO y en grande.
   A alguien que se esta decidiendo le dice mucho mas "citrico, lupulado,
   ligero" que un 35 de IBU, y el IBU no se lo dice nadie que no sea
   cervecero. */
.ficha-perfil {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.ficha-perfil span {
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 208, 137, 0.34);
  background: rgba(245, 166, 35, 0.09);
  color: var(--ambar-claro);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
}

.ficha-desc {
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--hueso-tenue);
}

/* Los datos tecnicos, despues y en pequeno: para quien los busque. */
.ficha-datos {
  font-size: 0.72rem;
  line-height: 1.4;
  letter-spacing: 0.02em;
  color: rgba(246, 239, 231, 0.45);
}

.ficha-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.15rem;
}

.ficha-precio {
  font-family: var(--tipo-titulo);
  font-weight: 500;
  font-size: 1.1rem;
  color: var(--hueso);
}

/* La linea de alergenos, compartida por la ficha y la tarjeta compacta.
   Lo que LLEVA en rojo; lo que PUEDE CONTENER va en la misma linea pero
   con el texto completo, porque una traza no es un ingrediente y
   abreviarlo a un chip las igualaria. */
.linea-alergenos {
  font-size: 0.68rem;
  line-height: 1.35;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--alerta);
  overflow-wrap: anywhere;
}

/* Las trazas. Mas apagadas que lo que el plato LLEVA, porque no es lo
   mismo y el color no puede decir que si lo es. Pero visibles: es el dato
   por el que alguien decide no pedir algo. */
.linea-trazas {
  font-size: 0.66rem;
  line-height: 1.35;
  letter-spacing: 0.02em;
  /* A plena opacidad: al 66 % daba 3,61:1 contra el fondo, por debajo del
     4,5:1 que pide WCAG AA para texto normal, y esto va ademas sobre
     fotos, donde es peor. De todo el texto de la carta, el de alergenos es
     el que menos puede permitirse ser dificil de leer. */
  color: var(--alerta);
}

.linea-alergenos.sin-confirmar {
  text-transform: none;
  letter-spacing: 0.005em;
  font-style: italic;
  color: var(--hueso-tenue);
}

/* ==========================================================================
   La rejilla compacta: refrescos y salsas
   ==========================================================================
   Al final de la carta, en dos columnas. Nombre y precio, y ya esta: no hay
   nada que descubrir en una Coca-Cola, y dedicarle una pantalla completa
   con foto y texto gastaba el sitio que merecen los platos.

   Es UNA seccion que ocupa al menos una pantalla, para que el scroll-snap
   la trate como a un plato mas y no se quede a medio camino.
   ========================================================================== */

.rejilla {
  min-height: 100dvh;
  scroll-snap-align: start;
  padding: calc(var(--cabecera) + 1rem) clamp(0.9rem, 4vw, 1.6rem) 7rem;
  background: var(--negro);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.rejilla-titulo {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
  color: var(--hueso);
  margin: 1.2rem 0 0.5rem;
}
.rejilla-titulo:first-child { margin-top: 0; }

.rejilla-grupo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.55rem;
}

/* En pantallas estrechas de verdad, una sola columna: dos nombres largos
   uno al lado del otro se parten en cuatro lineas y se lee peor que en
   una columna. */
@media (max-width: 340px) {
  .rejilla-grupo { grid-template-columns: 1fr; }
}

.compacto {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.5rem;
  /* Sin esto, una celda de rejilla no baja de su contenido y la columna de
     la derecha se sale de la pantalla: el control de anadir tiene un ancho
     minimo y empujaba la tarjeta. */
  min-width: 0;
  min-height: 4.8rem;
  padding: 0.65rem 0.7rem;
  border-radius: 14px;
  border: 1px solid var(--hueso-debil);
  background: var(--negro-suave);
}

.compacto h3 {
  font-family: var(--tipo-texto);
  font-weight: 400;
  font-size: 0.85rem;
  line-height: 1.25;
  color: var(--hueso);
  /* "MASSAMAN CURRY SAUCE 300ML" no cabe de una pieza en media pantalla. */
  overflow-wrap: anywhere;
}

/* La linea de alergenos, cuando el restaurante los ha aprobado. Seca y
   pequena: es un dato, no una alarma, y la tarjeta tiene dos lineas. */
.compacto-alergenos {
  font-size: 0.68rem;
  line-height: 1.3;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--alerta);
  overflow-wrap: anywhere;
}

.compacto-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.compacto-precio {
  font-family: var(--tipo-titulo);
  font-weight: 500;
  font-size: 0.98rem;
  color: var(--hueso);
  white-space: nowrap;
}

/* El control de anadir, en pequeno.
   El de pantalla completa lleva la palabra "Anadir" porque ahi hay sitio de
   sobra y es la llamada a la accion. Aqui hay media pantalla para el nombre,
   el precio y el boton, asi que se queda en el signo: la tarjeta entera ya
   dice de que producto se trata. */
.compacto .agregar {
  margin-left: 0;
  flex: none;
  box-shadow: 0 5px 16px -8px rgba(245, 166, 35, 0.7);
}
.compacto .agregar .etiqueta { display: none; }
.compacto .agregar button { width: 1.95rem; height: 1.95rem; font-size: 1.05rem; }
.compacto .agregar .cantidad { min-width: 1.15rem; font-size: 0.85rem; }

/* --------------------------------------------------------------------------
   El aviso que ocupa el sitio de los chips de alergeno
   --------------------------------------------------------------------------
   Deliberadamente apagado y no rojo. No es una alarma: es la ausencia de un
   dato. Lo que el detector automatico deduce es un borrador que acierta
   alrededor de la mitad de las veces, asi que hasta que el restaurante lo
   confirme, la carta dice que no lo sabe en vez de adivinar.
   -------------------------------------------------------------------------- */
.chip.aviso-alergenos {
  border-color: var(--hueso-debil);
  background: rgba(246, 239, 231, 0.05);
  color: var(--hueso-tenue);
  font-style: italic;
  letter-spacing: 0.005em;
}

/* El pie con los avisos legales.
   Lleva scroll-snap-align porque SIN EL NO SE ALCANZA: el feed usa
   scroll-snap obligatorio, y un elemento que no es punto de anclaje no
   puede quedarse quieto en pantalla. El scroll rebotaba al ultimo plato y
   el aviso de alergenos del reglamento FIC 1169/2011 no se leia nunca.
   `end` y no `start` para que se alinee por abajo y no deje media pantalla
   en blanco encima. */
#avisos {
  scroll-snap-align: end;
  padding: 2rem clamp(1rem, 4.5vw, 1.8rem) 6rem;
  font-size: 0.72rem;
  line-height: 1.6;
  color: rgba(246, 239, 231, 0.5);
  background: var(--negro);
  text-align: center;
}

#vacio {
  display: grid;
  place-items: center;
  height: 60dvh;
  padding: 2rem;
  text-align: center;
  color: var(--hueso-tenue);
}

#fallo {
  position: fixed; inset: 0; z-index: 90;
  display: none; place-items: center;
  padding: 2rem; text-align: center;
  background: var(--negro);
}

#fallo.visible { display: grid; }
#fallo p { max-width: 42ch; line-height: 1.6; color: var(--hueso-tenue); margin: 0 0 0.9rem; }
/* La primera linea, en el idioma mas probable del comensal (lo decide
   sinCarta() en app.js), un poco mas presente que las otras dos. */
#fallo p:first-child { color: var(--hueso); font-size: 1.05rem; }
#fallo code {
  display: block; margin-top: 1.2rem; padding: 0.8rem 1rem;
  font-size: 0.8rem; color: var(--ambar-claro);
  background: var(--negro-suave); border: 1px solid var(--hueso-debil);
  border-radius: 3px; user-select: all;
}

[hidden] { display: none !important; }

/* ==========================================================================
   Quien no quiere movimiento no lo tiene
   La especificacion lo exige: sin Ken Burns y sin alternancia automatica,
   solo la primera foto.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .toma.activa { animation: none; }
  .toma { transition: none; }
  .deslizar { animation: none; }
  #barra-seleccion, .hoja { transition: none; }
}

/* Texto solo para el lector de pantalla: fuera de la vista, dentro del
   arbol. Para los prefijos que aria-label no puede dar en un span o un p. */
.solo-voz {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Pantallas grandes: el feed se centra en una columna de movil */
@media (min-width: 760px) {
  body { background: #060405; }
  #cabecera, #barra-seleccion { max-width: 460px; margin-inline: auto; }
  #feed, #lista { max-width: 460px; margin-inline: auto; }
  .plato { border-inline: 1px solid rgba(246, 239, 231, 0.07); }
  .hoja { max-width: 460px; margin-inline: auto; }
}

/* El <picture> no debe generar caja: el img se posiciona sobre el lienzo. */
picture { display: contents; }


/* ==========================================================================
   Platos sin foto
   Cincuenta y uno de los sesenta y ocho platos del menu no tienen foto en
   Uber Eats: los curries, los stir-fries, las salsas y las bebidas. Repetir
   una foto generica cincuenta veces se ve peor que no ponerla, asi que
   llevan una lamina generada con el color de la casa y un icono segun su
   categoria. Se mueve igual que las fotos, para que el feed tenga un solo
   ritmo.
   ========================================================================== */

.lamina {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 80% at 50% 28%, rgba(224, 51, 140, 0.18), transparent 60%),
    radial-gradient(90% 60% at 22% 12%, rgba(245, 166, 35, 0.16), transparent 62%),
    linear-gradient(170deg, #231419 0%, #140d10 52%, #0a0708 100%);
}

.lamina::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.06;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

.lamina svg {
  width: min(38vw, 10rem);
  height: auto;
  fill: none;
  stroke: rgba(245, 166, 35, 0.5);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 8px 30px rgba(0, 0, 0, 0.6));
  transform: translateY(-9%);
}

.plato.enfoque .lamina svg { animation: flotar 7s ease-in-out infinite; }
/* Y quieto con el movimiento reducido. Va AQUI, debajo de la animacion y
   no en el bloque general de reduced-motion de mas arriba: misma
   especificidad, y en la cascada gana la ultima. Puesta arriba no hacia
   nada, y la prueba lo vio. */
@media (prefers-reduced-motion: reduce) {
  .plato.enfoque .lamina svg { animation: none; }
}

@keyframes flotar {
  0%, 100% { transform: translateY(-9%) rotate(-1.2deg) scale(1); }
  50%      { transform: translateY(-13%) rotate(1.2deg) scale(1.05); }
}

.sin-foto-nota {
  position: absolute;
  bottom: 34%;
  left: 50%;
  translate: -50% 0;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(246, 239, 231, 0.42);
  white-space: nowrap;
}

.fila .lamina-mini {
  width: 4.2rem; height: 4.2rem;
  border-radius: 4px;
  flex: none;
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, #241520, #120c0f);
}

.fila .lamina-mini svg {
  width: 55%; height: auto; fill: none;
  stroke: rgba(245, 166, 35, 0.55); stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ==========================================================================
   Ventana del glosario
   ========================================================================== */

#glosario {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  padding: clamp(1.2rem, 6vw, 3rem);
  background: rgba(6, 4, 5, 0.82);
  backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}

#glosario.abierto { opacity: 1; pointer-events: auto; }

#glosario .tarjeta-glosario {
  position: relative;
  width: min(30rem, 100%);
  padding: clamp(1.5rem, 6vw, 2.2rem);
  border-radius: 26px;
  background: linear-gradient(165deg, #23181c, #140d10);
  border: 1px solid rgba(246, 239, 231, 0.14);
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, 0.9);
  transform: translateY(14px) scale(0.97);
  transition: transform 260ms var(--sale), opacity 260ms var(--sale);
}

#glosario.abierto .tarjeta-glosario { transform: none; }

/* La foto del ingrediente: pequena y cuadrada, al lado del nombre. No es
   el protagonista de la ventana, solo sirve para reconocer de que se habla
   cuando el nombre no dice nada (ka chai, galanga). Mientras no exista la
   foto queda el hueco con su marco, que es donde ira. */
/* La palabra enlazada dentro de la definicion. Subrayado punteado y no
   color plano: tiene que verse pulsable sin convertir el parrafo en un
   arbol de navidad. */
#glosario .enlace-termino {
  display: inline;
  font: inherit;
  color: var(--ambar-claro);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: underline dotted currentColor;
  text-underline-offset: 3px;
  transition: color 180ms;
}

#glosario .enlace-termino[aria-expanded="true"] {
  text-decoration-style: solid;
}

#glosario .extension {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(246, 239, 231, 0.12);
  /* Transicion y no keyframe: se toca un enlace y enseguida otro, y un
     keyframe reempieza desde cero en cada cambio en vez de redirigirse
     desde donde iba. @starting-style es lo que da el estado de partida
     cuando el elemento pasa de no existir a existir.

     La curva es ease-in-out, no ease-out: esto no entra desde fuera de la
     pantalla, se abre en su sitio, y lo que se abre arranca despacio y
     acaba despacio. Se anima tambien la altura con interpolate-size, que
     es lo que permite ir de cero a auto sin medir nada a mano; donde no
     exista, queda el fundido, que ya es la mayor parte del gesto. */
  interpolate-size: allow-keywords;
  opacity: 1;
  height: auto;
  transform: translateY(0);
  overflow: hidden;
  transition: opacity 260ms var(--mueve), transform 260ms var(--mueve),
              height 260ms var(--mueve), margin-top 260ms var(--mueve),
              padding-top 260ms var(--mueve), display 260ms allow-discrete;
}

/* hidden quita el elemento del flujo; con allow-discrete el cambio
   de display espera a que termine la transicion de salida. */
#glosario .extension[hidden] { display: none; opacity: 0; }

@starting-style {
  #glosario .extension {
    opacity: 0;
    height: 0;
    margin-top: 0;
    padding-top: 0;
    transform: translateY(-6px);
  }
}

#glosario .extension picture { display: contents; }

#glosario .extension img {
  flex: none;
  width: 4rem;
  height: 4rem;
  border-radius: 12px;
  object-fit: cover;
  display: block;
}

#glosario .cuerpo-extension { min-width: 0; }

#glosario .nombre-extension {
  font-weight: 500;
  font-size: 0.92rem;
  margin-bottom: 0.25rem;
}

#glosario .explica-extension {
  font-size: 0.88rem;
  line-height: 1.5;
  color: rgba(246, 239, 231, 0.76);
}

#glosario .fila-glosario {
  display: flex;
  align-items: center;
  gap: clamp(0.8rem, 3.5vw, 1.1rem);
  margin-bottom: 1.1rem;
  padding-right: 3rem;   /* el boton de cerrar vive en esa esquina */
}

#glosario .titulo-glosario { min-width: 0; }

#glosario .foto-glosario {
  flex: none;
  width: 7.5rem;
  height: 7.5rem;
  margin: 0;
  border-radius: 18px;
  overflow: hidden;
  position: relative;
  background: rgba(246, 239, 231, 0.05);
  border: 1px solid rgba(246, 239, 231, 0.12);
  display: grid;
  place-items: center;
}

#glosario .foto-glosario picture { display: contents; }

#glosario .foto-glosario img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

#glosario .foto-glosario picture:not([hidden]) ~ .marca-foto { display: none; }

#glosario .marca-foto svg {
  width: 2.1rem;
  height: 2.1rem;
  fill: none;
  stroke: rgba(246, 239, 231, 0.28);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

#glosario .nativo-grande {
  font-size: clamp(2rem, 9vw, 2.9rem);
  line-height: 1.12;
  color: var(--ambar-claro);
  margin-bottom: 0.3rem;
}

#glosario .roman {
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hueso-tenue);
}

#glosario .nombre-glosario {
  font-family: var(--tipo-titulo);
  font-weight: 470;
  font-size: 1.45rem;
  letter-spacing: -0.015em;
  margin-bottom: 0.7rem;
}

#glosario .explica {
  font-size: 0.95rem;
  line-height: 1.6;
  font-weight: 300;
  color: rgba(246, 239, 231, 0.84);
  text-wrap: pretty;
}

#glosario .cerrar {
  position: absolute;
  top: 0.8rem;
  right: 0.8rem;
}

/* ==========================================================================
   Pantalla de idioma
   Lo primero que ve el comensal al escanear el QR. Tiene que resolverse de
   un toque: tres opciones, bandera grande y nada mas.
   ========================================================================== */

#idioma {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-content: center;
  gap: 2.4rem;
  padding: clamp(1.5rem, 7vw, 3rem);
  text-align: center;
  background:
    radial-gradient(120% 70% at 50% 18%, rgba(224, 51, 140, 0.16), transparent 62%),
    radial-gradient(90% 55% at 18% 8%, rgba(245, 166, 35, 0.14), transparent 60%),
    linear-gradient(170deg, #231419 0%, #140d10 55%, #0a0708 100%);
  transition: opacity 520ms ease;
}

#idioma.fuera { opacity: 0; pointer-events: none; }

#idioma .local {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: clamp(1.5rem, 6.5vw, 2.2rem);
  letter-spacing: -0.02em;
  line-height: 1.12;
  text-wrap: balance;
}

#idioma .pide {
  margin-top: 0.7rem;
  font-size: 0.7rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ambar);
}

.lenguas { display: grid; gap: 0.7rem; }

.lengua {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: min(20rem, 82vw);
  padding: 0.9rem 1.2rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  background: rgba(10, 7, 8, 0.44);
  backdrop-filter: blur(10px);
  font-size: 1.02rem;
  text-align: left;
  transition: border-color 240ms, background 240ms, transform 240ms;
}

.lengua:hover, .lengua:focus-visible {
  border-color: var(--ambar);
  background: rgba(245, 166, 35, 0.12);
  transform: translateY(-2px);
}

.lengua:active { transform: scale(0.97); }

.lengua .bandera {
  font-size: 1.7rem;
  line-height: 1;
  flex: none;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.6));
}

.lengua .propio { flex: 1; }

.lengua .en-su-idioma {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--hueso-tenue);
  margin-top: 0.12rem;
}

/* ==========================================================================
   Burbujas de ingrediente
   Pequenas, flotando despacio sobre la foto, con una X para quitarlas de
   en medio. Son la invitacion a tocar: el comensal que no sabe que es la
   salsa satay tiene que ver que ahi hay algo que preguntar.
   ========================================================================== */

.burbujas {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

/* Con el cartel de datos simulados puesto son DOS rotulos apilados sobre
   la cabecera, y la primera burbuja de ingrediente nacia justo debajo y
   quedaba tapada. Las burbujas empiezan mas abajo en ese mundo.

   Los 2,6rem las dejaban en reposo justo al borde del cartel, y las
   burbujas FLOTAN: suben entre 4 y 9 px. En lo alto del vaiven asomaban
   uno o dos pixeles por debajo del rotulo, y la prueba lo pillaba o no
   segun el instante. Los 11 px de mas son ese flote, y dos de margen. */
body.simulado .burbujas { top: calc(2.6rem + 11px); }

/* --- Los ingredientes, en su propio plano ---------------------------------
   Al pasar de un plato a otro, los chips no viajan pegados a la foto: se
   adelantan y se quedan atras, como si estuvieran unos centimetros por
   delante de la comida. Es el mismo efecto que mirar por la ventanilla de
   un coche, donde lo cercano se mueve mas rapido que el fondo.

   La linea de tiempo la lleva el scroll, no un reloj: el navegador la
   calcula fuera del hilo principal, asi que sigue fina mientras se cargan
   las fotos del plato siguiente. Donde no exista, no hay efecto y ya esta,
   que es justo lo que tiene que pasar con un adorno.

   La curva es ease-in-out y no lineal a proposito: ligada al scroll uno a
   uno el desfase se ve mecanico, y con aceleracion y frenada propias
   parece que el plano tiene su propia inercia. */
/* Los chips de alergeno, cayendo por su ventana.

   El recorte va del 100 al 0 por arriba mientras el chip baja su propia
   altura entera, asi que lo que se ve es el chip pasando por detras de una
   abertura fija, no un chip encendiendose en su sitio. Es el mismo efecto
   que un texto que sube por debajo de una linea: la abertura no existe, la
   dibuja el propio recorte. */
@keyframes caer-chip {
  from { opacity: 0; translate: 0 -100%; clip-path: inset(100% 0 0 0); }
  to   { opacity: 1; translate: 0 0;     clip-path: inset(0 0 0 0); }
}

.plato.asentado .info .chips .chip {
  animation: caer-chip 380ms var(--sale) both;
}

.plato.asentado .info .chips .chip:nth-child(1) { animation-delay: 40ms; }
.plato.asentado .info .chips .chip:nth-child(2) { animation-delay: 110ms; }
.plato.asentado .info .chips .chip:nth-child(3) { animation-delay: 180ms; }
.plato.asentado .info .chips .chip:nth-child(4) { animation-delay: 250ms; }
.plato.asentado .info .chips .chip:nth-child(n+5) { animation-delay: 320ms; }

/* El precio cierra la fila, por la misma ventana y detras del ultimo
   chip. Es el dato que decide, y llega el ultimo a proposito: cuando ya
   se sabe que es el plato y que lleva. */
.plato.asentado .info .precio {
  animation: caer-chip 380ms var(--sale) both;
  animation-delay: 340ms;
}

/* Los chiles, justo detras del precio. Son el ultimo aviso de la ficha y
   entran los ultimos, por la misma ventana que todo lo demas. */
.plato.asentado .info .picante {
  animation: caer-chip 380ms var(--sale) both;
  animation-delay: 410ms;
}

.info .precio, .info .picante { opacity: 0; }

@supports not (animation-timeline: view()) {
  .info .precio, .info .picante { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .plato.asentado .info .precio,
  .plato.asentado .info .picante { animation: none; opacity: 1; }
}

/* Sin linea de tiempo de scroll no hay nada que ocultar: los chips se
   quedan puestos y ya esta. */
@supports not (animation-timeline: view()) {
  .info .chips .chip { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .plato.asentado .info .chips .chip { animation: none; opacity: 1; }
}

/* ==========================================================================
   Parallax
   Cada capa esta a una distancia distinta del ojo y, al pasar de plato, se
   mueve a la velocidad que le toca por esa distancia: lo cercano corre,
   lo lejano apenas. Es lo mismo que mirar por la ventanilla de un coche,
   donde el poste pasa disparado y la montana casi no se mueve.

   Aqui NO se mueve nada en profundidad. La profundidad es fija y lo unico
   que cambia es cuanto recorre cada capa en vertical, que es precisamente
   lo que la hace parecer cercana o lejana. Mover las capas en Z seria un
   travelling de camara, otra cosa, y ademas cambiaria su tamano.

   Las cifras son el recorrido EXTRA sobre lo que ya las arrastra el
   scroll, de una punta a otra del paso de un plato:

     la foto          0 px     es el fondo y no se mueve
     la descripcion  100 px    plano medio
     el nombre       220 px    por delante de su propia descripcion
     los ingredientes 300 a 760 px  cada uno a su profundidad
   ========================================================================== */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .plato {
      view-timeline-name: --paso-plato;
      view-timeline-axis: block;
    }

    /* --- La lamina -----------------------------------------------------
       Se desvanece entera con el scroll, cristal incluido. Antes solo se
       iba el texto y la lamina se quedaba puesta, asi que entre plato y
       plato quedaba un rectangulo esmerilado vacio tapando la comida.

       Al irse tambien el desenfoque, mientras se pasa de plato la foto se
       ve limpia de arriba abajo, que es de lo que va esto. */
    .panel {
      animation-name: irse-la-lamina;
      animation-duration: auto;
      animation-timing-function: ease-in-out;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    @keyframes irse-la-lamina {
      0%, 34%    { opacity: 0; }
      47%, 53%   { opacity: 1; }
      82%, 100%  { opacity: 0; }
    }

    /* --- El bloque de texto ------------------------------------------ */
    .info {
      animation-name: parallax-texto;
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    /* El desplazamiento va con `translate` y no con `transform` para que
       el nombre y los chips puedan llevar el suyo encima sin pisarse: son
       propiedades distintas y se componen solas.

       La curva del desplazamiento es lineal a proposito. El parallax imita
       algo fisico y tiene que ir atado al dedo punto por punto; con una
       curva, la capa se adelantaria y se retrasaria respecto al scroll y
       se notaria el truco. La opacidad si lleva curva, que eso no es
       fisica sino gusto. */
    /* Solo desplazamiento. El fundido lo lleva la lamina: si lo llevaran
       las dos, las opacidades se multiplicarian y a media entrada el
       texto iria por detras de su propio fondo. */
    @keyframes parallax-texto {
      0%   { translate: 0 50px; }
      42%  { translate: 0 8px; }
      53%  { translate: 0 0; }
      100% { translate: 0 -50px; }
    }

    .sin-foto-nota,
    .deslizar {
      animation-name: irse-el-texto;
      animation-duration: auto;
      animation-timing-function: ease-in-out;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    @keyframes irse-el-texto {
      0%, 34%    { opacity: 0; }
      47%, 53%   { opacity: 1; }
      82%, 100%  { opacity: 0; }
    }

    /* --- El nombre del plato, mas cerca ------------------------------
       Recorre 110 px extra a cada lado, el doble que el bloque que lo
       contiene. Como su desplazamiento se suma al del bloque, el titulo
       adelanta a su propia descripcion al entrar y se va antes al salir.
       Esa diferencia es toda la profundidad: no hay escala ni Z. */
    .info .nombre {
      animation-name: parallax-nombre;
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    @keyframes parallax-nombre {
      0%   { translate: 0 110px; }
      50%  { translate: 0 0; }
      100% { translate: 0 -110px; }
    }

    /* --- Los ingredientes flotantes, lo mas cercano ------------------ */
    .burbujas {
      animation-name: parallax-chips;
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    @keyframes parallax-chips {
      0%   { translate: 0 90px;  opacity: 0; }
      22%  { translate: 0 50px;  opacity: 1; }
      50%  { translate: 0 0;     opacity: 1; }
      78%  { translate: 0 -50px; opacity: 1; }
      100% { translate: 0 -90px; opacity: 0; }
    }

    /* Y encima, cada ingrediente a la suya. Lo de arriba es el suelo
       comun de la capa; esto es lo que separa un ingrediente de otro, y
       se suma porque van en elementos distintos.

       El orden no es casual: el de mas arriba en la pantalla es el mas
       lejano y el de mas abajo el mas cercano, como al mirar una mesa. */
    .capa-burbuja {
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
      animation-range: entry 0% exit 100%;
    }

    .capa-burbuja[data-sitio="0"] { animation-name: hondo-0; }
    .capa-burbuja[data-sitio="1"] { animation-name: hondo-1; }
    .capa-burbuja[data-sitio="2"] { animation-name: hondo-2; }
    .capa-burbuja[data-sitio="3"] { animation-name: hondo-3; }

    @keyframes hondo-0 { from { translate: 0 0; }     to { translate: 0 0; } }
    @keyframes hondo-1 { from { translate: 0 150px; } to { translate: 0 -150px; } }
    @keyframes hondo-2 { from { translate: 0 320px; } to { translate: 0 -320px; } }
    @keyframes hondo-3 { from { translate: 0 520px; } to { translate: 0 -520px; } }

    /* --- Los chips de alergeno --------------------------------------
       Bajan uno detras de otro, de izquierda a derecha, y solo despues de
       que el nombre este puesto.

       El recorte es lo que hace el gesto: cada chip esta tapado por
       completo desde arriba y se va destapando hacia abajo mientras baja,
       asi que parece salir de detras de un borde en vez de encenderse en
       el sitio. El borde no existe, es el propio recorte del chip. */
    .info .chips .chip {
      animation-name: caer-chip;
      animation-duration: auto;
      animation-timing-function: var(--sale);
      animation-fill-mode: none;
      animation-timeline: --paso-plato;
    }

    /* Empiezan mas tarde que el bloque de texto, y cada uno algo mas
       tarde que el anterior. Tres puntos entre ellos, que al ritmo al que
       se pasa de plato son unas decimas. */
    /* Los chips NO van atados al scroll, y es la unica cosa de esta
       pantalla que no lo va. El motivo es que no cabe: entre que el
       nombre acaba de entrar y el plato se para hay nueve puntos del
       recorrido, unos 150 pixeles, y meter ahi cuatro entradas
       escalonadas sale un parpadeo que nadie llega a ver.

       Asi que se disparan con el reloj cuando el plato se asienta, que es
       cuando el comensal ya esta mirando. 380 ms cada uno y 70 de
       diferencia entre ellos: se leen como una cascada de izquierda a
       derecha sin que haya que esperar a nada. */
    .info .chips .chip { animation: none; opacity: 0; }

  }
}

.burbuja {
  position: relative;
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  max-width: 70vw;
  /* Caja, no pildora: lo justo para leer el nombre y cerrarla. El nombre
     nativo y la explicacion viven en la ventana, que es donde se leen de
     verdad. Pero tiene que leerse a un brazo de distancia, con el telefono
     sobre la mesa, asi que la letra no puede bajar de aqui. */
  padding: 0.33rem 0.33rem 0.36rem 0.66rem;
  border-radius: 12px;
  font-size: 0.91rem;
  line-height: 1.3;
  /* Azules. Los chips de abajo son informacion del plato y van en los
     colores de la carta; estos son otra cosa, algo que se toca para
     preguntar, y el azul los separa de un vistazo de todo lo demas, que
     en esta pantalla es ambar o rojo. */
  color: #bfe0ff;
  background: rgba(10, 20, 34, 0.62);
  border: 1px solid rgba(124, 197, 255, 0.34);
  transition: background-color 200ms ease, border-color 200ms ease;
  backdrop-filter: blur(12px) saturate(1.3);
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.85);
  opacity: 0;
  animation:
    entrar-burbuja 380ms var(--sale) forwards,
    flotar-burbuja 6.5s ease-in-out infinite;
}

@keyframes entrar-burbuja {
  from { opacity: 0; transform: translateY(10px) scale(0.9); }
  to   { opacity: 1; transform: none; }
}

/* El vaiven: lento y corto, para que se note sin marear. La altura la
   pone cada burbuja, que no todas suben lo mismo. */
@keyframes flotar-burbuja {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 calc(var(--flote-alto, 6px) * -1); }
}

/* El desfase, la duracion y la altura los sortea el JavaScript al crear
   cada burbuja, y entran por estas variables.

   Antes esto se hacia con nth-of-type, pero dejo de funcionar sin que se
   notara: al meter cada burbuja en su propia capa para darle profundidad,
   todas pasaron a ser la primera de su capa, cogieron el mismo desfase y
   se pusieron a subir y bajar a la vez, como un bloque. */
.burbuja {
  animation-delay: var(--flote-entra, 220ms), var(--flote-espera, 0s);
  animation-duration: 380ms, var(--flote-dura, 6.5s);
}

.burbuja { cursor: pointer; }

/* Es un <button> de verdad, para que el teclado y el lector de pantalla
   lleguen a el, pero no tiene que parecerlo: el aspecto entero lo pone la
   caja de .burbuja. Aqui solo se le quita la ropa que trae de serie
   (fondo, borde, tipografia propia, margenes) sin tocar nada visual. */
.burbuja .texto {
  appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.01em;
}

/* El termino que da nombre al plato se marca un poco mas fuerte que un
   ingrediente cualquiera, pero dentro del mismo azul. */
.burbuja.key { border-color: rgba(124, 197, 255, 0.55); color: #d8ecff; }
.burbuja.dato { border-color: rgba(124, 197, 255, 0.3); }

@property --giro {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.burbuja::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1.5px;
  pointer-events: none;
  background: conic-gradient(
    from var(--giro),
    transparent 0deg,
    var(--brillo-borde) 46deg,
    transparent 104deg,
    transparent 360deg);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  -webkit-mask-composite: xor;
  animation: girar-borde 3.6s linear infinite;
}

.burbuja { --brillo-borde: rgba(150, 210, 255, 0.95); }
.burbuja.key { --brillo-borde: rgba(190, 228, 255, 1); }

/* Desfasadas, o los cuatro destellos darian la vuelta en formacion */
.burbuja:nth-of-type(2)::before { animation-delay: -0.9s; }
.burbuja:nth-of-type(3)::before { animation-delay: -1.8s; }
.burbuja:nth-of-type(4)::before { animation-delay: -2.7s; }

@keyframes girar-borde { to { --giro: 360deg; } }

.burbuja .quitar {
  /* Medía 1,33rem (21 px): por debajo incluso del minimo de 24 px de
     WCAG 2.2. Ahora son 25,6 px de dibujo y la zona tocable se estira con
     el ::after de abajo hasta los 44, pero asimetrica: hacia afuera
     mucho y hacia el nombre poco, porque el nombre es OTRO control y
     comerle sitio cambiaria un problema por otro. */
  position: relative;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 8px;
  display: grid;
  place-items: center;
  flex: none;
  color: rgba(191, 224, 255, 0.55);
  background: rgba(124, 197, 255, 0.12);
  font-size: 0.84rem;
  line-height: 1;
  transition: background 200ms, color 200ms;
}

/* La zona tocable, sin cambiar el dibujo. */
.burbuja .quitar::after {
  content: "";
  position: absolute;
  inset: -9px -9px -9px -3px;
}

@media (hover: hover) and (pointer: fine) {
  .burbuja .quitar:hover { background: rgba(124, 197, 255, 0.24); color: #eaf5ff; }

  /* Un velo de nada. Lo justo para que se note que la caja responde, sin
     encenderla: esto flota sobre una foto y cualquier cosa mas fuerte se
     convierte en una mancha. */
  .burbuja:hover {
    background: rgba(40, 80, 120, 0.55);
    border-color: rgba(124, 197, 255, 0.6);
  }
}

.burbuja .quitar:active { transform: scale(0.9); }

.burbuja.cerrando {
  animation: salir-burbuja 320ms ease forwards;
  pointer-events: none;
}

@keyframes salir-burbuja {
  to { opacity: 0; transform: scale(0.82) translateY(-6px); }
}

.capa-burbuja { position: absolute; }

.capa-burbuja[data-sitio="0"] { top: 24%; left: 5%; }
.capa-burbuja[data-sitio="1"] { top: 33%; right: 5%; }
.capa-burbuja[data-sitio="2"] { top: 42%; left: 8%; }
.capa-burbuja[data-sitio="3"] { top: 51%; right: 7%; }

/* ==========================================================================
   Brasa: el borde que arde en los platos picantes
   Dos capas con ritmos distintos, para que el pulso no sea mecanico. La
   intensidad la marca el nivel de picante, de 1 a 3.
   ========================================================================== */

.brasa {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
}

.plato.enfoque .brasa { animation: arder 4.2s ease-in-out infinite; }
.plato.enfoque .brasa.lenta { animation: arder 6.8s ease-in-out infinite reverse; }

.brasa {
  box-shadow:
    inset 0 0 calc(30px * var(--ardor)) calc(4px * var(--ardor)) rgba(255, 74, 26, 0.55),
    inset 0 0 calc(90px * var(--ardor)) calc(16px * var(--ardor)) rgba(214, 27, 12, 0.34);
}

.brasa.lenta {
  box-shadow:
    inset 0 0 calc(56px * var(--ardor)) calc(10px * var(--ardor)) rgba(255, 140, 40, 0.3);
}

@keyframes arder {
  0%   { opacity: 0; }
  28%  { opacity: calc(0.42 * var(--ardor)); }
  46%  { opacity: calc(0.86 * var(--ardor)); }
  62%  { opacity: calc(0.38 * var(--ardor)); }
  80%  { opacity: calc(0.7 * var(--ardor)); }
  100% { opacity: 0; }
}

.plato[data-picante="0"] .brasa { display: none; }
.plato[data-picante="1"] { --ardor: 0.5; }
.plato[data-picante="2"] { --ardor: 0.78; }
.plato[data-picante="3"] { --ardor: 1; }

@media (prefers-reduced-motion: reduce) {
  .burbuja { animation: entrar-burbuja 1ms forwards; }
  .burbuja::before { animation: none; --giro: 135deg; }
  .plato.enfoque .brasa,
  .plato.enfoque .brasa.lenta { animation: none; opacity: calc(0.3 * var(--ardor)); }
}

/* El boton para volver a la pantalla de idioma, por si se toca el que no es */
#btn-idioma {
  display: grid;
  place-items: center;
  width: 2.3rem;
  height: 2.3rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  font-size: 1.1rem;
  line-height: 1;
  flex: none;
  transition: border-color 220ms, background 220ms;
}

@media (hover: hover) and (pointer: fine) {
  #btn-idioma:hover { border-color: var(--ambar); background: rgba(245, 166, 35, 0.12); }
}

#btn-idioma:active { transform: scale(0.94); }

.fila-marca { gap: 0.5rem; }
.fila-marca #marca { flex: 1; min-width: 0; }


/* ==========================================================================
   La mesa (paso 7): presencia y sugerencias
   Todo esto solo existe con el QR de una mesa y el servidor respondiendo:
   body.en-mesa lo enciende. Sin sesion, ni un pixel cambia.
   ========================================================================== */

/* Cuantos hay, en la cabecera. Un boton: abre "Nuestra mesa". */
#mesa-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  height: 2.3rem;
  padding: 0 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso-tenue);
  font-size: 0.84rem;
  flex: none;
  position: relative;
  transition: transform 140ms var(--sale), border-color 220ms;
}
#mesa-pill[hidden] { display: none; }
#mesa-pill:active { transform: scale(0.94); }
#mesa-pill svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
#mesa-pill .n { font-variant-numeric: tabular-nums; }
#mesa-pill .insignia {
  position: absolute;
  top: -0.35rem; right: -0.35rem;
  min-width: 1.15rem; height: 1.15rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--ambar);
  color: var(--negro);
  font-size: 0.68rem;
  font-weight: 700;
  display: grid;
  place-items: center;
}
#mesa-pill .insignia[hidden] { display: none; }

/* "2 lo estan mirando ahora", pegado encima de la lamina del plato. La
   lamina cambia de alto al desplegar la descripcion, asi que su altura
   se mide desde app.js y llega en --panel-alto. */
.plato .mirando {
  position: absolute;
  z-index: 3;
  left: 20px;
  bottom: calc(10px + env(safe-area-inset-bottom) + var(--panel-alto, 170px) + 0.55rem);
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.32rem 0.75rem 0.32rem 0.6rem;
  border-radius: 999px;
  background: rgba(224, 51, 140, 0.16);
  border: 1px solid rgba(224, 51, 140, 0.55);
  color: #ffd6ea;
  font-size: 0.78rem;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 1;
  transform: none;
  transition: opacity 220ms var(--sale), transform 220ms var(--sale);
  @starting-style { opacity: 0; transform: translateY(6px); }
}
.plato .mirando[hidden] { display: none; }
.mirando i, .mirando-mini i, .mesa-n i {
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  background: var(--magenta);
  box-shadow: 0 0 0 3px rgba(224, 51, 140, 0.28);
  flex: none;
}

/* La version pequena, en fichas y tarjetas compactas. */
.mirando-mini {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.5rem 0.15rem 0.4rem;
  border-radius: 999px;
  background: rgba(224, 51, 140, 0.14);
  border: 1px solid rgba(224, 51, 140, 0.45);
  color: #ffd6ea;
  font-size: 0.72rem;
  white-space: nowrap;
}
.mirando-mini[hidden] { display: none; }

/* El punto en la pestana: alguien de la mesa anda por esa seccion. */
.pestana .punto-mesa {
  display: inline-block;
  width: 0.38rem; height: 0.38rem;
  border-radius: 50%;
  background: var(--magenta);
  margin-left: 0.35rem;
  vertical-align: middle;
}

/* Sugerir a la mesa: el boton redondo junto a "Anadir". */
#anadir-fijo { display: flex; align-items: center; gap: 0.6rem; }
#sugerir-fijo {
  pointer-events: auto;
  width: 2.9rem; height: 2.9rem;
  border-radius: 999px;
  border: 1.5px solid rgba(246, 239, 231, 0.35);
  background: rgba(29, 21, 24, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--hueso);
  display: grid;
  place-items: center;
  flex: none;
  transition: transform 140ms var(--sale);
}
#sugerir-fijo:active { transform: scale(0.94); }
#sugerir-fijo svg, .sugerir-mini svg {
  width: 1.3rem; height: 1.3rem;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
body:not(.en-mesa) #sugerir-fijo { display: none; }

.sugerir-mini {
  width: 2rem; height: 2rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso-tenue);
  display: grid;
  place-items: center;
  flex: none;
  margin-left: auto;
  transition: transform 140ms var(--sale);
}
.sugerir-mini:active { transform: scale(0.94); }
.sugerir-mini svg { width: 1rem; height: 1rem; }
body:not(.en-mesa) .sugerir-mini { display: none; }
/* El boton de sugerir se lleva el hueco; el de anadir ya no lo necesita. */
body.en-mesa .ficha-pie .agregar, body.en-mesa .compacto-pie .agregar { margin-left: 0; }

/* Las dos tostadas: el aviso de arriba y la confirmacion de abajo. */
.tostada {
  position: fixed;
  left: 0.9rem; right: 0.9rem;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 0.8rem 0.7rem 1rem;
  border-radius: 1.1rem;
  background: rgba(29, 21, 24, 0.94);
  border: 1px solid rgba(246, 239, 231, 0.18);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
  color: var(--hueso);
  opacity: 1;
  transform: none;
  transition: opacity 220ms var(--sale), transform 220ms var(--sale);
}
.tostada[hidden] { display: none; }
.tostada.arriba { top: calc(var(--cabecera) + 3.6rem); @starting-style { opacity: 0; transform: translateY(-8px); } }
.tostada.abajo { bottom: 6rem; @starting-style { opacity: 0; transform: translateY(8px); } }
.tostada-texto { min-width: 0; }
.tostada .quien, .mesa-h3 {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ambar-claro);
}
.tostada .que {
  font-family: var(--tipo-titulo);
  font-size: 1.08rem;
  margin-top: 0.12rem;
  line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tostada .txt { font-size: 0.92rem; }
.tostada .ir {
  margin-left: auto;
  flex: none;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  background: var(--ambar);
  color: var(--negro);
  font-weight: 600;
  font-size: 0.9rem;
  transition: transform 140ms var(--sale);
}
.tostada .ir:active { transform: scale(0.96); }
.tostada .ok {
  width: 1.6rem; height: 1.6rem;
  border-radius: 50%;
  background: rgba(111, 207, 143, 0.18);
  color: var(--verde);
  display: grid; place-items: center;
  flex: none;
}
.tostada .ok svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* La hoja "Nuestra mesa". */
.mesa-sub { color: var(--hueso-tenue); font-size: 0.86rem; margin: -0.4rem 0 1.3rem; }
.mesa-h3 { margin: 1.4rem 0 0.2rem; }
.mesa-vacio { color: var(--hueso-tenue); font-size: 0.9rem; padding: 0.9rem 0; }
.mesa-linea {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: 100%;
  padding: 0.95rem 0;
  border-top: 1px solid rgba(246, 239, 231, 0.1);
  text-align: left;
  color: inherit;
}
.mesa-linea:first-child { border-top: 0; }
.mesa-linea .cuerpo { flex: 1; min-width: 0; }
/* Sin la sombra de tres capas de los nombres sobre foto: aqui hay fondo liso. */
.mesa-linea h3, .mesa-linea .nombre { display: block; font-family: var(--tipo-titulo); font-weight: 460; font-size: 1.05rem; text-shadow: none; }
.mesa-linea .orig { font-size: 0.76rem; color: var(--hueso-tenue); margin-top: 0.18rem; }
.mesa-linea.mesa-ir { transition: transform 140ms var(--sale); }
.mesa-linea.mesa-ir:active { transform: scale(0.985); }
.mesa-n { display: inline-flex; align-items: center; gap: 0.4rem; color: #ffd6ea; font-size: 0.82rem; flex: none; }
.mesa-mas {
  flex: none;
  width: 2.4rem; height: 2.4rem;
  border-radius: 999px;
  background: var(--ambar);
  color: var(--negro);
  display: grid; place-items: center;
  font-size: 1.4rem;
  font-weight: 600;
  transition: transform 140ms var(--sale);
}
.mesa-mas:active { transform: scale(0.94); }
.mesa-estado { flex: none; font-size: 0.8rem; color: var(--verde); }


/* ==========================================================================
   Comparar (paso 8)
   ========================================================================== */

/* El boton de comparar, junto a sugerir y anadir. Pulsado = ya elegido. */
#comparar-fijo {
  pointer-events: auto;
  width: 2.9rem; height: 2.9rem;
  border-radius: 999px;
  border: 1.5px solid rgba(246, 239, 231, 0.35);
  background: rgba(29, 21, 24, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--hueso);
  display: grid;
  place-items: center;
  flex: none;
  transition: transform 140ms var(--sale), border-color 200ms, background 200ms;
}
#comparar-fijo:active { transform: scale(0.94); }
#comparar-fijo svg, .comparar-mini svg {
  width: 1.3rem; height: 1.3rem;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.comparar-mini {
  width: 2rem; height: 2rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso-tenue);
  display: grid;
  place-items: center;
  flex: none;
  margin-left: auto;
  transition: transform 140ms var(--sale), border-color 200ms, background 200ms;
}
.comparar-mini:active { transform: scale(0.94); }
.comparar-mini svg { width: 1rem; height: 1rem; }
.comparar-mini + .sugerir-mini { margin-left: 0; }
#comparar-fijo[aria-pressed="true"], .comparar-mini[aria-pressed="true"] {
  border-color: var(--ambar);
  background: rgba(245, 166, 35, 0.22);
  color: var(--ambar-claro);
}

/* "Comparando X, elige otro plato": una barra fija mientras falte el otro. */
#comparar-barra {
  position: fixed;
  left: 0.9rem; right: 0.9rem;
  top: calc(var(--cabecera) + 3.6rem);
  z-index: 56;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.6rem 0.6rem 0.6rem 1rem;
  border-radius: 1.1rem;
  background: rgba(245, 166, 35, 0.14);
  border: 1px solid rgba(245, 166, 35, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--hueso);
  opacity: 1;
  transform: none;
  transition: opacity 220ms var(--sale), transform 220ms var(--sale);
  @starting-style { opacity: 0; transform: translateY(-8px); }
}
#comparar-barra[hidden] { display: none; }
#comparar-barra .cerrar { margin-left: auto; flex: none; }
/* Si llega un aviso mientras se compara, va debajo de la barra. */
body.comparando .tostada.arriba { top: calc(var(--cabecera) + 7.4rem); }

/* La hoja: una tabla de dos columnas con la etiqueta a la izquierda. */
.comparar-aviso {
  color: var(--ambar-claro);
  font-size: 0.88rem;
  margin: -0.4rem 0 1rem;
}
.comparar-tabla {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.comparar-tabla th, .comparar-tabla td {
  padding: 0.7rem 0.4rem;
  border-top: 1px solid rgba(246, 239, 231, 0.1);
  vertical-align: top;
  text-align: left;
  font-size: 0.9rem;
  overflow-wrap: anywhere;
}
.comparar-tabla thead th { border-top: 0; vertical-align: bottom; }
.comparar-tabla thead .nombre {
  display: block;
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1.05rem;
  line-height: 1.2;
  text-shadow: none;
}
.comparar-tabla thead .comparar-mas { margin-top: 0.5rem; width: 2.1rem; height: 2.1rem; font-size: 1.2rem; }
.comparar-tabla th[scope="row"], .comparar-tabla thead th:first-child {
  width: 28%;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hueso-tenue);
  padding-left: 0;
}
/* Lo que coincide se atenua: lo que se busca al comparar es la diferencia. */
.comparar-tabla tr.igual td { color: var(--hueso-tenue); }
.comparar-tabla td.sin-confirmar { color: var(--ambar-claro); }
.comparar-nota { color: var(--hueso-tenue); font-size: 0.8rem; margin: 0.9rem 0 1.4rem; }
.comparar-nota:empty { display: none; }
#comparar-compartir[hidden] { display: none; }

/* Las comparaciones en Nuestra mesa. */
.mesa-linea .vs { color: var(--hueso-tenue); font-family: var(--tipo-texto); font-size: 0.8rem; margin: 0 0.35rem; }


/* ==========================================================================
   Seleccion de la mesa (paso 9)
   ========================================================================== */

/* En Nuestra mesa: un grupo por comensal, sin nombres. */
.mesa-grupo { margin-top: 0.4rem; }
.mesa-grupo-cabeza {
  display: flex;
  justify-content: space-between;
  gap: 0.8rem;
  margin: 0.9rem 0 0.1rem;
  font-size: 0.8rem;
  color: var(--hueso-tenue);
}
.mesa-grupo-cabeza .quien { color: var(--hueso); font-weight: 500; }
.mesa-grupo .mesa-linea { padding: 0.6rem 0; }
.mesa-grupo .mesa-linea .nombre { font-size: 0.98rem; }
.mesa-linea .mesa-sub { flex: none; font-size: 0.9rem; font-weight: 500; font-variant-numeric: tabular-nums; }
.mesa-total { margin-top: 0.6rem; }
.mesa-total .val { font-size: 1.6rem; }

/* En Mi seleccion: el atajo a la mesa. */
#hoja-mesa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  margin: -0.4rem 0 1rem;
  font-size: 0.9rem;
  color: var(--hueso-tenue);
}
#hoja-mesa[hidden] { display: none; }
#hoja-ver-mesa {
  flex: none;
  padding: 0.5rem 0.95rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso);
  font-weight: 500;
  transition: transform 140ms var(--sale);
}
#hoja-ver-mesa:active { transform: scale(0.96); }

/* En la hoja del camarero (fondo claro): toda la mesa o solo lo mio. */
#mesero .alcance { display: flex; gap: 0.5rem; margin: 0 0 1rem; }
#mesero .alcance[hidden] { display: none; }
#mesero .alcance button {
  padding: 0.5rem 1rem;
  border-radius: 999px;
  border: 1.5px solid rgba(22, 16, 15, 0.35);
  color: #16100f;
  font-weight: 500;
  font-size: 0.92rem;
  transition: transform 140ms var(--sale), background 180ms, color 180ms;
}
#mesero .alcance button:active { transform: scale(0.96); }
#mesero .alcance button[aria-pressed="true"] { background: #16100f; color: var(--hueso); }
#mesero .pedido-opciones { font-size: 0.95rem; color: #16100f; margin-top: 0.25rem; font-weight: 500; }
#mesero .mesero-total {
  color: #16100f;
  border-top: 2px solid rgba(22, 16, 15, 0.2);
  margin-top: 1rem;
  padding-top: 1rem;
}
#mesero .mesero-total[hidden] { display: none; }
#mesero .mesero-total .etq { color: #5c4a44; }


/* ==========================================================================
   Post-comida (paso 11): como estuvo, y la segunda decision
   ========================================================================== */

/* El cartel de la sobremesa, debajo de la cabecera (y debajo del de datos
   simulados cuando lo hay: app.js le pasa el alto en --cartel-alto). */
#cartel-segunda {
  position: fixed;
  top: calc(var(--cabecera) + var(--cartel-alto, 0px));
  left: 0; right: 0;
  z-index: 29;
  padding: 0.42rem clamp(0.9rem, 4vw, 1.6rem);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-align: center;
  color: var(--negro);
  background: var(--ambar);
}
#cartel-segunda[hidden] { display: none; }

.feedback-plato { padding: 1.1rem 0; border-top: 1px solid rgba(246, 239, 231, 0.1); }
.feedback-plato:first-child { border-top: 0; padding-top: 0.2rem; }
.feedback-plato h3 {
  font-family: var(--tipo-titulo);
  font-weight: 460;
  font-size: 1.1rem;
  margin-bottom: 0.7rem;
  text-shadow: none;
}
.feedback-votos { display: flex; gap: 0.45rem; flex-wrap: wrap; }
.feedback-votos button {
  flex: 1 1 auto;
  padding: 0.62rem 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso);
  font-size: 0.9rem;
  white-space: nowrap;
  transition: color 200ms ease, background-color 200ms ease,
              border-color 200ms ease, transform 140ms var(--sale);
}
.feedback-votos button:active { transform: scale(0.97); }
.feedback-votos button[aria-pressed="true"] {
  color: var(--negro);
  background: var(--ambar);
  border-color: var(--ambar);
  font-weight: 500;
}
/* "No lo probe" pulsado va en gris, no en ambar: no es una opinion. */
.feedback-votos button[data-voto="noProbe"][aria-pressed="true"] {
  color: var(--negro);
  background: var(--hueso-tenue);
  border-color: transparent;
}
.feedback-razones { margin-top: 0.8rem; }
.feedback-razones[hidden] { display: none; }
.feedback-razones .chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.45rem; }
.feedback-razones .filtro { scroll-snap-align: none; }
.feedback-gracias { color: var(--verde); font-size: 0.92rem; margin: 1.1rem 0 0.4rem; }
.feedback-gracias[hidden] { display: none; }
#feedback-segunda { margin-top: 1rem; }
#feedback-segunda[hidden] { display: none; }
#feedback-ver-seleccion {
  width: 100%;
  margin-top: 0.6rem;
  padding: 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--hueso-debil);
  color: var(--hueso);
  font-weight: 500;
  transition: transform 140ms var(--sale);
}
#feedback-ver-seleccion:active { transform: scale(0.98); }


/* ==========================================================================
   El motor dinamico (paso 12): agotado, destacado, promociones
   ========================================================================== */
.insignias { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.5rem; }
.insignias:empty { display: none; }
.insignia {
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.24rem 0.6rem;
  border-radius: 999px;
  text-shadow: none;
}
.insignia.destacado { background: var(--ambar); color: var(--negro); }
.insignia.agotado { background: rgba(246, 239, 231, 0.2); color: var(--hueso); }
/* La promocion: se comunica, no se descuenta. El precio no cambia aqui. */
.promo {
  color: var(--ambar-claro);
  font-size: 0.86rem;
  margin: 0.15rem 0 0.35rem;
}
.promo .en-caja { color: var(--hueso-tenue); font-size: 0.76rem; }
.ficha .insignias, .compacto .insignias { margin: 0.3rem 0 0.5rem; }
.ficha .promo, .compacto .promo { font-size: 0.8rem; }

/* Agotado: el precio se apaga y el boton no anade. */
.agotado .precio, .agotado .ficha-precio, .agotado .compacto-precio { color: var(--hueso-tenue); }
.agregar-ancho.agotado, .agregar.agotado {
  background: rgba(246, 239, 231, 0.16);
  color: var(--hueso-tenue);
  box-shadow: none;
  pointer-events: none;
}
.agregar-ancho.agotado .mas, .agregar-ancho.agotado .menos,
.agregar.agotado .mas, .agregar.agotado .menos { visibility: hidden; }
.agregar-ancho.agotado .etiqueta, .agregar.agotado .etiqueta { display: block; padding: 0 1rem; }

/* --------------------------------------------------------------------------
   Cuando las opciones rompen un filtro sensible
   --------------------------------------------------------------------------
   Esto no es un dato mas de la ficha: es una correccion a lo que el comensal
   cree. Filtro por sin gluten, la carta le ensena este plato, y al elegir una
   opcion deja de cumplirlo. Asi que se separa de la linea de alergenos con
   caja y borde propios, en vez de ser otra linea pequena mas del mismo color
   que el resto.

   Sin animacion de entrada a proposito. Aparece y desaparece al marcar y
   desmarcar una opcion, o sea muchas veces seguidas, y un aviso que parpadea
   cada vez que tocas algo se convierte en ruido y se deja de leer.
   -------------------------------------------------------------------------- */
.aviso-filtro {
  margin: 0.7rem 0 0.2rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--alerta-borde);
  border-radius: 10px;
  background: var(--alerta-fondo);
  color: var(--alerta);
  font-size: 0.74rem;
  line-height: 1.4;
  text-wrap: pretty;
}
