/* Hoja de estilos unica: publico y panel. Sin dependencias externas. */

/* --- `hidden` ESCONDE. SIEMPRE. -----------------------------------------
 *
 * Esto tiene que ir lo primero, y no es una precaucion teorica: el campo de
 * «cuales» de las alergias y el «¿cuantas?» de las preguntas del restaurante
 * salian SIEMPRE visibles aunque su casilla estuviera sin marcar. El guion
 * ponia `hidden` bien; lo que fallaba era la hoja.
 *
 * El motivo, que hay que entender una vez para no repetirlo: `[hidden]` vive
 * en la hoja DEL NAVEGADOR, y cualquier regla nuestra le gana, tenga la
 * especificidad que tenga. Con `label { display: block }` escrita aqui, un
 * `<label hidden>` se sigue viendo.
 *
 * Ya habia mordido dos veces -el plano de sala y la barra de un bloque-, y las
 * dos se parchearon una a una con su propio `[hidden]`. Esto lo cierra de una
 * vez para todo: `hidden` significa escondido, y ninguna regla de mas abajo
 * puede desdecirlo. Es el unico `!important` que se gana el sitio.
 */
[hidden] { display: none !important; }

/* --- Los dos temas ------------------------------------------------------ */
/*
   Cada color se escribe UNA vez, con prefijo --c- (claro) u --o- (oscuro).
   Debajo, tres bloques deciden cual de las dos paletas alimenta a las
   variables que usa el resto de la hoja. Antes la paleta oscura estaba
   repetida dentro de una media query; con el interruptor manual habrian
   hecho falta dos copias y se habrian ido separando con el tiempo.

   Quien manda:

     data-tema="claro"    lo eligio la persona     -> claro, pase lo que pase
     data-tema="oscuro"   lo eligio la persona     -> oscuro, pase lo que pase
     sin atributo         nadie ha elegido nada    -> lo que diga el sistema

   El atributo lo pone `tema.js` en <html> antes de que se pinte nada. Sin
   JavaScript no hay atributo y se sigue al sistema, que es como funcionaba
   hasta ahora.
*/
:root {
  --c-fondo: #f6f5f3;
  --c-superficie: #ffffff;
  --c-texto: #1c1b19;
  --c-texto-suave: #6b6862;
  --c-borde: #e2ded8;
  --c-acento: #8c2f24;
  --c-acento-suave: #f4e9e7;
  --c-verde: #2f6b46;
  --c-ambar: #9a6a12;
  --c-rojo: #a32b22;
  --c-sombra: 0 1px 2px rgba(0,0,0,.05), 0 4px 16px rgba(0,0,0,.05);
  /* LA LETRA QUE VA ENCIMA DE UN FONDO DE ACENTO, y se da la vuelta con el
     tema. Estaba escrita a mano como `#fff` en nueve sitios, y en el tema
     oscuro los acentos son tonos CLAROS: el boton «Apagar online» -el mas
     grande de la pantalla del dia- se quedaba en 2.58:1. Ilegible.

     En claro no cambia nada: sigue siendo blanco. Lo que se arregla es el
     oscuro, donde ninguno de los cinco fondos llegaba al minimo. */
  --c-sobre-relleno: #ffffff;

  --o-fondo: #17161a;
  --o-superficie: #201f24;
  --o-texto: #ece9e4;
  --o-texto-suave: #9b968e;
  --o-borde: #33313a;
  --o-acento: #e0705f;
  --o-acento-suave: #33221f;
  --o-verde: #63b184;
  --o-ambar: #d7a441;
  --o-rojo: #e0705f;
  --o-sombra: 0 1px 2px rgba(0,0,0,.3), 0 4px 16px rgba(0,0,0,.3);
  /* Casi negro, no el texto claro del tema: encima de un acento claro. Da
     entre 5.7 y 8.0 sobre los cinco fondos, medido uno a uno. */
  --o-sobre-relleno: #17161a;

  --radio: 10px;
}

/* Claro: lo de partida, y tambien lo que se aplica si alguien lo pide a mano
   teniendo el sistema en oscuro. */
:root,
:root[data-tema="claro"] {
  --fondo: var(--c-fondo);
  --superficie: var(--c-superficie);
  --texto: var(--c-texto);
  --texto-suave: var(--c-texto-suave);
  --borde: var(--c-borde);
  --acento: var(--c-acento);
  --acento-suave: var(--c-acento-suave);
  --verde: var(--c-verde);
  --ambar: var(--c-ambar);
  --rojo: var(--c-rojo);
  --sombra: var(--c-sombra);
  --sobre-relleno: var(--c-sobre-relleno);
  color-scheme: light;
}

/* Oscuro por decision de la persona. */
:root[data-tema="oscuro"] {
  --fondo: var(--o-fondo);
  --superficie: var(--o-superficie);
  --texto: var(--o-texto);
  --texto-suave: var(--o-texto-suave);
  --borde: var(--o-borde);
  --acento: var(--o-acento);
  --acento-suave: var(--o-acento-suave);
  --verde: var(--o-verde);
  --ambar: var(--o-ambar);
  --rojo: var(--o-rojo);
  --sombra: var(--o-sombra);
  --sobre-relleno: var(--o-sobre-relleno);
  color-scheme: dark;
}

/* Oscuro porque lo dice el sistema y nadie ha elegido lo contrario. El
   :not() es lo que hace que la eleccion manual gane a la del sistema. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --fondo: var(--o-fondo);
    --superficie: var(--o-superficie);
    --texto: var(--o-texto);
    --texto-suave: var(--o-texto-suave);
    --borde: var(--o-borde);
    --acento: var(--o-acento);
    --acento-suave: var(--o-acento-suave);
    --verde: var(--o-verde);
    --ambar: var(--o-ambar);
    --rojo: var(--o-rojo);
    --sombra: var(--o-sombra);
    --sobre-relleno: var(--o-sobre-relleno);
    color-scheme: dark;
  }
}

* { box-sizing: border-box; }

/* No habia ninguna regla para los enlaces de texto corrido, asi que salian con
   el azul subrayado del navegador, que no pega con nada del resto. Los que van
   con clase propia (.boton, .marca, la navegacion) ganan por especificidad y
   no se ven afectados. */
a { color: var(--acento); }
a:hover { text-decoration: none; }

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* --- Estructura --------------------------------------------------------- */

.cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: .9rem 1.5rem;
  background: var(--superficie);
  border-bottom: 1px solid var(--borde);
}
.marca {
  font-weight: 650; font-size: 1.05rem; letter-spacing: -.01em;
  color: var(--texto); text-decoration: none;
}
.marca small { color: var(--texto-suave); font-weight: 400; }
.cabecera nav { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.cabecera nav a {
  color: var(--texto-suave); text-decoration: none; font-size: .93rem;
}
.cabecera nav a:hover { color: var(--acento); }
.cabecera nav a.salir { color: var(--rojo); }

/* «Salir» es un <button> dentro de un <form>, no un enlace: cerrar sesion
   cambia el estado y tiene que ir por POST con su token. Se le quita el
   aspecto de boton para que siga leyendose como el resto del menu. */
.enlace-boton {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: var(--rojo); cursor: pointer;
}
.enlace-boton:hover { text-decoration: underline; }

/* El botón de pantalla completa, en la cabecera del panel. Hereda el color de
   los enlaces del menú y no el rojo de «Salir»: no es una acción de riesgo, es
   una comodidad. `kbd` es para decir «se sale con Esc» sin adornos. */
/* UN BOTON DE SOLO ICONO, al lado del de «Menu» y con su mismo aspecto.
 *
 * Estaba dentro del menu desplegable y con rotulo: escondido detras de dos
 * pulsaciones justo en la tablet de la barra, que es donde mas se usa. Fuera y
 * sin texto, porque al lado de «Menu» dos palabras compiten en una barra que
 * ya va justa y el simbolo se entiende solo.
 *
 * Cuadrado y del alto del otro boton: dos botones vecinos de distinto alto se
 * ven como un descuido. Lo que dice que es va en `title` y en `aria-label`. */
.boton-icono {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid var(--borde); border-radius: 8px;
  background: var(--fondo); color: var(--texto); cursor: pointer;
}
.boton-icono:hover { border-color: var(--acento); color: var(--acento); }
/* Dentro ya se esta: se marca como encendido para que no haya que acordarse. */
.pantalla-completa[aria-pressed="true"] {
  color: var(--acento); border-color: var(--acento);
}
kbd {
  font-family: ui-monospace, Consolas, monospace; font-size: .85em;
  padding: .05rem .3rem; border: 1px solid var(--borde); border-radius: .25rem;
}

/* --- Interruptor de tema ------------------------------------------------ */
/* Lo inserta tema.js; en el HTML no hay nada. Si no hay JavaScript no aparece,
   que es lo correcto: un boton que no hace nada es peor que ninguno. */

.tema {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0;
  border: 1px solid var(--borde); border-radius: 999px;
  background: var(--superficie); color: var(--texto-suave);
  font-size: .95rem; line-height: 1; cursor: pointer;
}
.tema:hover { color: var(--acento); border-color: var(--acento); }
.tema:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }

/* Cuando la pagina no tiene cabecera -las de entrar, por ejemplo- el boton se
   queda flotando en la esquina. Ahi tambien hace falta: alguien puede querer
   cambiar el tema antes de escribir su contrasena. */
.tema-suelto {
  position: fixed; top: .9rem; right: .9rem; z-index: 20;
  box-shadow: var(--sombra);
}

@media print { .tema { display: none; } }

/* --- Aviso de ausencias en otros restaurantes --------------------------- */
/* Tiene que verse sin buscarlo -es lo que evita guardarle la mesa buena de un
   sabado a quien ya ha faltado tres veces- pero sin gritar mas que el propio
   nombre del cliente: es un dato para tener en cuenta, no una condena. */

.aviso-noshow {
  margin: .5rem 0 0;
  padding: .45rem .6rem;
  border-left: 3px solid var(--ambar);
  border-radius: 0 var(--radio) var(--radio) 0;
  background: color-mix(in srgb, var(--ambar) 12%, transparent);
  color: var(--texto);
  font-size: .85rem; line-height: 1.4;
}
.aviso-noshow.grave {
  border-left-color: var(--rojo);
  background: color-mix(in srgb, var(--rojo) 12%, transparent);
}

/* --- Logotipo del restaurante ------------------------------------------- */
/* El logotipo dentro de la tarjeta, centrado y encima del titulo. Es lo
   primero que ve quien entra a reservar, tanto en la pagina publica como en el
   formulario incrustado en la web del restaurante. */
.logo-portada {
  margin: 0 0 1rem; text-align: center;
}
.logo-portada img {
  height: auto; max-height: 84px; max-width: 100%;
  object-fit: contain;
}
h1.centrado { text-align: center; }

/* Lo que el restaurante quiera contar, al pie y encima de la direccion. */
.mensaje-publico {
  margin: 0 0 .35rem;
  color: var(--texto); font-size: .92rem;
}
.pie-widget {
  margin-top: 1.5rem; padding-top: 1rem;
  border-top: 1px solid var(--borde);
  text-align: center; color: var(--texto-suave);
}
.pie-widget p { margin: 0 0 .25rem; }

.contenido { max-width: 640px; margin: 2rem auto; padding: 0 1.25rem; }

/* Las pantallas de trabajo -el panel, los listados de /central y de
   /plataforma- usan TODO el ancho del aparato. Antes estaban topadas a
   1180 px, y en un monitor de sobremesa eso dejaba dos franjas vacias a los
   lados mientras el plano de sala peleaba por caber en el centro.
   El relleno lateral se mantiene: pegar el contenido al borde de la pantalla
   no es aprovecharla, es que no se lea la primera letra. */
.contenido.ancho { max-width: none; padding: 0 1.5rem; }

.pie {
  display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap;
  padding: 2rem 1rem; color: var(--texto-suave); font-size: .85rem;
}

.tarjeta {
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 1.75rem;
}
.tarjeta.centrada { text-align: center; }
.tarjeta.estrecha { max-width: 380px; margin: 0 auto; }

/* AQUI NO PINTA NADA, y la regla existe para decirlo.
   La lleva el formulario de regalar, que es una plantilla compartida por las
   dos pieles: en la OTRA hoja esta clase es la que viste sus campos, y sin
   ella salian de 21 px de alto, por debajo del minimo tactil. En esta hoja los
   `input` ya se visten solos con las reglas generales y basta con `.tarjeta`.
   Escrita a proposito y no omitida: `prueba_tema` exige que toda clase que
   aparezca en una plantilla tenga regla, y con razon — una clase sin regla
   suele ser una errata que nadie ve hasta que un cliente lo ve raro. */
.tarjeta-reserva { /* la viste la otra hoja; aqui no hace falta nada */ }

/* Una tarjeta debajo de otra. Con una clase y no con `.tarjeta + .tarjeta`:
   dentro de `.fila-tarjetas` las tarjetas SON hermanas, y esa regla le meteria
   un margen suelto a la segunda columna de una rejilla que ya tiene su hueco. */
.apilada { margin-top: 1.25rem; }

/* Un apartado nuevo dentro del mismo formulario -«A quien se lo regalas»-.
   Separa mas de lo que separa un `h2` normal porque aqui la pregunta cambia de
   persona, y sin ese aire los dos bloques de nombre y correo se leen como uno
   solo de cuatro campos. */
.apartado { margin-top: 1.5rem; }

/* Volver, debajo del todo. Separado del boton de pagar a proposito: es una
   salida, no una alternativa, y pegado parecen dos opciones del mismo peso. */
.volver { margin-top: 1.25rem; }

/* Dos tarjetas en la misma linea. `align-items: start` para que la corta se
   quede de su alto en vez de estirarse hasta igualar a la de al lado, que es
   lo que hace una rejilla por defecto y deja un hueco muerto debajo del campo.
   En pantalla estrecha se apilan: dos columnas en un movil no son columnas. */
.fila-tarjetas {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 1.25rem; align-items: start; margin-top: 1.25rem;
}
/* Este corte SI se queda en 900 aunque los demas hayan bajado a 700, y no es
   un descuido. MEDIDO en la pagina del widget a 753 px forzando las dos
   columnas: cada tarjeta cae en 343 px y el formulario de dentro pide 307 en
   285, o sea que se corta solo. Dos columnas ahi no caben, y punto.

   No es la «version de tableta» que se quito: eso era ensenar OTRA pantalla.
   Esto es la misma pantalla en una sola columna porque no hay ancho. */
@media (max-width: 900px) {
  .fila-tarjetas { grid-template-columns: 1fr; }
}

/* Para lo que es un solo campo. Con el relleno de una tarjeta normal, un
   numero suelto ocupa lo mismo que un apartado entero y parece mas importante
   de lo que es. Sin `max-width`: dentro de la fila la anchura la manda la
   rejilla, y suelta se ajusta a lo que haya. */
.tarjeta-corta { padding: 1rem 1.25rem; }
.tarjeta-corta h3 { margin: 0 0 .6rem; font-size: 1rem; }
.tarjeta-corta .linea { margin: 0; }
.tarjeta-corta input[type=number] { width: 6rem; }
.tarjeta-corta .apunte { margin: .6rem 0 0; }
.tarjeta-corta .aviso { margin-top: .6rem; }

h1 { font-size: 1.5rem; margin: 0 0 .5rem; letter-spacing: -.02em; }
/* h2 no tenia regla y caia en el 1.5em del navegador, o sea MAS grande que el
   h1 de la propia pantalla. Se veia en el area del distribuidor y en central,
   que son las que lo usan. */
h2 { font-size: 1.15rem; margin: 0 0 .6rem; letter-spacing: -.01em; }
h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .08em;
     color: var(--texto-suave); margin: 0 0 .6rem; font-weight: 600; }
.parrafo { color: var(--texto-suave); margin: 0 0 1.5rem; }
.apunte { color: var(--texto-suave); font-size: .87rem; }
/* Un parrafo suelto detras de otro se pegaba: el margen de por defecto del
   navegador es 1em arriba y abajo y aqui muchas pantallas encadenan apuntes. */
.apunte + .apunte { margin-top: -.4rem; }

/* Ficha de datos en dos columnas: etiqueta a la izquierda, valor a la derecha.
   La usa «Mi cuenta» del distribuidor y no tenia ninguna regla, asi que salia
   con la sangria por defecto del navegador para las listas de definiciones. */
.ficha {
  display: grid; grid-template-columns: auto 1fr; gap: .4rem 1rem;
  margin: 0 0 1rem;
}
.ficha dt { color: var(--texto-suave); font-size: .87rem; }
.ficha dd { margin: 0; }
@media (max-width: 480px) {
  .ficha { grid-template-columns: 1fr; gap: 0 0; }
  .ficha dd { margin-bottom: .6rem; }
}

/* --- Formularios -------------------------------------------------------- */

label { display: block; margin-bottom: 1rem; }
label > span { display: block; font-size: .87rem; font-weight: 550; margin-bottom: .35rem; }
label > span em { font-weight: 400; color: var(--texto-suave); font-style: normal; }

input[type=text], input[type=tel], input[type=email], input[type=password],
input[type=date], input[type=time], input[type=number], input[type=search],
select, textarea {
  width: 100%; padding: .6rem .7rem;
  font: inherit; font-size: .95rem;
  color: var(--texto); background: var(--superficie);
  border: 1px solid var(--borde); border-radius: 8px;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--acento); outline-offset: 1px; border-color: transparent;
}
textarea { resize: vertical; }

/* En pantalla pequena los campos van a 16px EXACTOS, ni uno menos. Safari del
   iPhone hace zoom sobre cualquier campo con letra mas pequena en cuanto lo
   tocas, y el formulario se sale de la pantalla justo cuando el cliente esta
   escribiendo su telefono. Es el fallo de usabilidad mas caro que puede tener
   una pagina de reservas: pasa en el movil, que es por donde entra la mayoria. */
@media (max-width: 640px) {
  input[type=text], input[type=tel], input[type=email], input[type=password],
  input[type=date], input[type=time], input[type=number], input[type=search],
  select, textarea { font-size: 16px; }
}

/* Un campo obligatorio que se deja vacio, o un correo mal escrito: el navegador
   ya lo sabe, solo que no lo decia. :user-invalid y no :invalid, que marcaria
   en rojo un campo vacio que la persona todavia no ha llegado a rellenar. */
input:user-invalid, select:user-invalid, textarea:user-invalid {
  border-color: var(--rojo);
}

input:disabled, select:disabled, textarea:disabled {
  opacity: .6; cursor: not-allowed;
}

fieldset { border: none; padding: 0; margin: 0 0 1rem; }
fieldset.bloque {
  border-top: 1px solid var(--borde); padding-top: 1.25rem; margin-top: 1.5rem;
}
legend { font-size: .87rem; font-weight: 600; padding: 0; }

.rejilla-dos { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
.rejilla-formulario {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0 1rem; align-items: end; margin-top: 1rem;
}
.rejilla-formulario .ancho-total { grid-column: 1 / -1; }
.linea { display: inline; margin: 0; }

.casilla { display: flex; align-items: center; gap: .45rem; }
.casilla input { width: auto; }
.casilla span { margin: 0; font-weight: 400; font-size: .9rem; }
.casillas-linea { display: flex; flex-wrap: wrap; gap: .35rem 1.1rem; margin-top: .4rem; }

@media (max-width: 560px) { .rejilla-dos { grid-template-columns: 1fr; } }

/* --- Botones ------------------------------------------------------------ */

.boton {
  display: inline-flex; align-items: center; justify-content: center;
  /* min-height y no solo padding: asi un boton con icono, uno con texto largo
     y uno pequeno miden lo mismo y no bailan al ponerlos en fila. */
  min-height: 40px;
  padding: .65rem 1.3rem;
  font: inherit; font-size: .93rem; font-weight: 550;
  color: var(--sobre-relleno); background: var(--acento);
  border: 1px solid transparent; border-radius: 8px;
  cursor: pointer; text-decoration: none; text-align: center;
  transition: filter .12s ease, transform .06s ease, background-color .12s ease;
}
.boton:hover { filter: brightness(1.08); }
/* Respuesta al pulsar. Sin esto, en una conexion lenta no pasa nada visible al
   tocar y la gente pulsa dos veces: dos reservas, dos correos. */
.boton:active { transform: translateY(1px); filter: brightness(.95); }
.boton.grande { width: 100%; min-height: 48px; padding: .8rem; font-size: 1rem; margin-top: .5rem; }
.boton.pequeno { min-height: 32px; padding: .35rem .75rem; font-size: .82rem; }
/* --texto y no --texto-suave: en gris claro sobre blanco se quedaba por debajo
   del contraste minimo y en el movil, a pleno sol, no se leia. */
.boton.secundario { background: transparent; color: var(--texto); border-color: var(--borde); }
.boton.secundario:hover { border-color: var(--acento); color: var(--acento); }
.boton.peligro { background: var(--rojo); }
/* Para los botones que son ademas una LUZ DE ESTADO: el interruptor de la
   venta online va verde mientras entra venta y rojo cuando esta parada, y el
   texto dice lo que hace al pulsarlo. El color se lee desde la barra sin
   acercarse; la etiqueta, cuando ya has decidido tocarlo. */
.boton.verde { background: var(--verde); }

/* Un boton apagado tiene que PARECER apagado. El de «Dar de alta 0 mesas» de
   la vista previa de importacion salia igual que uno normal. */
.boton:disabled, .boton[disabled] {
  opacity: .5; cursor: not-allowed; filter: none; transform: none;
}

/* --- Foco visible para quien va con el teclado --------------------------- */
/*
   Los campos ya tenian foco marcado; los botones, los enlaces y los huecos de
   hora no. Quien navega con el tabulador -por costumbre o porque lo necesita-
   iba completamente a ciegas por la pagina de reservas.

   :focus-visible y no :focus: el navegador solo lo pinta cuando de verdad hace
   falta, asi que un boton pulsado con el raton no se queda con el cerco puesto.
*/
.boton:focus-visible,
.hueco:focus-visible,
a:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
  border-radius: 6px;
}

/* =========================================================================
   UN <details> CERRADO NO OCUPA SITIO. ESCRITO, Y NO DADO POR SUPUESTO.

   Toda la plataforma pliega cosas con <details>: los desplegables de los
   botones, los dialogos del tablero, las filas que se editan, los apartados
   largos de cada pantalla. Nunca hubo una regla que escondiera lo de dentro
   al estar cerrado, porque no hacia falta: el navegador lo hacia solo.

   YA NO. Los navegadores han cambiado como se dibuja el contenido de un
   <details> cerrado -ahora se salta su CONTENIDO pero el elemento sigue
   teniendo caja-, y el resultado es que quedaban tarjetas fantasma flotando
   por encima de la pagina: con borde, con sombra, vacias por dentro y, lo
   peor, capturando el dedo. `pointer-events: auto`.

   MEDIDO en un telefono de 375 px, con todo cerrado:
     - «Añadir reserva por telefono»: 343x780, o sea casi la pantalla entera
     - «Imprimir»: 343x389 tapando la parte de arriba
     - «Datos de la sala»: 343x489
     - y en Sala y mesas, una lista de 293x2336 -dos mil trescientos- por
       encima de todo lo demas

   Eso es lo que hacia el panel imposible de usar con el movil: no era el
   tamaño de la letra ni el `viewport`, era que se pulsaba encima de una caja
   invisible. En el ordenador tambien pasaba, pero ahi las cajas caian en los
   margenes y se notaba menos.

   Una linea, y vuelve a ser lo que siempre se dio por hecho. No se pone
   `!important`: si algun dia hace falta un plegado con animacion, que pueda
   pisarla una regla mas concreta a proposito.
   ========================================================================= */
details:not([open]) > *:not(summary) { display: none; }

/* Quien ha pedido en su sistema que no haya animaciones, no las tiene. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* --- Huecos horarios ---------------------------------------------------- */

.turno { margin-bottom: 1.25rem; }
.huecos { display: flex; flex-wrap: wrap; gap: .5rem; }
.hueco {
  /* 44px de alto y 64 de ancho: es el tamano que recomiendan tanto Apple como
     Google para algo que se toca con el dedo. Es EL boton mas pulsado de todo
     el producto -elegir la hora, en el movil- y estaba en 36. Fallar aqui
     significa que el cliente le da a las 21:00 en vez de a las 21:30. */
  min-height: 44px; min-width: 64px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: .5rem .85rem; font: inherit; font-size: .95rem;
  color: var(--texto); background: var(--superficie);
  border: 1px solid var(--borde); border-radius: 8px; cursor: pointer;
  transition: border-color .12s ease, color .12s ease, background-color .12s ease;
}
.hueco:hover { border-color: var(--acento); color: var(--acento); }
.hueco:active { transform: translateY(1px); }
.hueco.elegido {
  background: var(--acento); border-color: var(--acento); color: var(--sobre-relleno);
  font-weight: 600;
}

.aviso {
  padding: .8rem 1rem; border-radius: 8px; font-size: .9rem;
  background: var(--acento-suave); color: var(--acento);
  border: 1px solid color-mix(in srgb, var(--acento) 25%, transparent);
}

/* --- «Esto conviene saberlo» NO es «esto está mal» ------------------------
 *
 * `.aviso` va en el color de marca —rojizo— y eso está bien para lo que hay
 * que arreglar AHORA: una serie que no existe, un agente que no lee. El
 * problema es que la misma caja se estaba usando para explicaciones y consejos
 * que no son ningún problema, y una pantalla con siete cajas rojas de las
 * cuales dos son de verdad **enseña a no mirar ninguna**. Justo lo contrario
 * de lo que se quería.
 *
 * `consejo` es la misma caja en tono neutro: se lee, se distingue del texto
 * corrido, y no grita. La regla para elegir, y conviene respetarla:
 *
 *     .aviso            algo está mal AHORA y hay que hacer algo
 *     .aviso.consejo    esto hay que saberlo antes de configurar
 *
 * El borde de la izquierda es lo que las separa además del color: quien no
 * distinga estos dos tonos sigue viendo dos cajas distintas. */
.aviso.consejo {
  background: color-mix(in srgb, var(--texto-suave) 8%, transparent);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-left: 3px solid var(--texto-suave);
}

/* Grupos grandes: en vez de huecos, el telefono. Ocupa el sitio donde iban las
   horas para que el salto no descoloque la pagina, y el boton va a lo grande
   porque en el movil es lo unico que hay que tocar. */
.aviso-grupo {
  padding: 1rem; border-radius: 8px; margin: .75rem 0;
  background: var(--acento-suave);
  border: 1px solid color-mix(in srgb, var(--acento) 25%, transparent);
  text-align: center;
}
.aviso-grupo p { margin: 0 0 .75rem; }
.aviso-grupo .apunte { margin: .5rem 0 0; }
.aviso-grupo .boton { gap: .5rem; }

/* Campos que solo aparecen al marcar su casilla: hoy, el detalle de las
   alergias. La casilla no necesita nada propio -es una casilla normal- pero se
   le deja la clase para que el guion la encuentre. El detalle se sangra un
   poco para que se lea como lo que es: una pregunta que cuelga de la de
   arriba. */
/* El desplegable de la antelacion, dentro de la celda de la tabla de correos.
   Sin margen para que no descuadre la fila. */
.linea-antelacion { margin: 0; }
.linea-antelacion select { padding: .25rem .4rem; font-size: .85rem; }

.abre-detalle { /* solo es el enganche de detalle_extra.js */ }
.detalle-extra {
  margin-left: 1.6rem;
  border-left: 2px solid var(--borde);
  padding-left: .9rem;
}

/* Un número de dos cifras y nada más: cuántas entradas. Estrecho a propósito
   —un campo del ancho de la pantalla para escribir «2» invita a pensar que
   cabe algo más— pero no tanto como para que no quepan dos dígitos con las
   flechitas del navegador al lado.

   `input[type=number].hueco-cifras` Y NO `.hueco-cifras` a secas: un selector
   de atributo pesa lo mismo que una clase, así que la regla general
   `input[type=number] { width: 100% }` le ganaba a la clase y el campo seguía
   saliendo del ancho de la pantalla. */
input[type=number].hueco-cifras { width: 5rem; }

/* «¿Cuántas?» y su hueco EN LA MISMA LÍNEA.
   La etiqueta es una palabra y el número tiene dos dígitos —el máximo es 99—,
   así que la regla general de «etiqueta encima, campo debajo» gastaba dos
   renglones para pedir un número y alejaba la pregunta de la casilla que la
   explica.
   `flex-wrap` para que en un móvil estrecho, o con la letra muy grande, baje
   en vez de salirse: una línea es lo bueno, no lo obligatorio. */
.detalle-extra.cuantas {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
}
.detalle-extra.cuantas > span { display: inline; margin: 0; }
/* Estrecho a propósito, pero no tanto como para que no quepan dos cifras con
   las flechitas del navegador al lado. */
.detalle-extra.cuantas input[type=number] { width: 4.5rem; }

/* --- Piezas que se quedaron sin regla ------------------------------------
 *
 * Estaban puestas en las plantillas pero no existian en la hoja, asi que
 * salian con lo que decidiera el navegador. Se detectan comparando las clases
 * que usan las plantillas con las que define este fichero.
 */

/* El aviso de proteccion de datos, debajo del formulario de reserva. Separado
   del resto y algo mas apagado: tiene que estar y poder leerse, pero no
   competir con el boton de reservar. */
.aviso-privacidad {
  margin-top: 1rem; padding-top: .9rem;
  border-top: 1px solid var(--borde);
  line-height: 1.5;
}

/* El campo donde el cliente teclea el codigo que le ha llegado por SMS. Ancho,
   centrado y con las cifras separadas: se copia mirando el movil con una mano
   y equivocarse de digito es lo normal si van pegadas. */
.campo-codigo {
  text-align: center;
  font-size: 1.6rem; font-weight: 600;
  letter-spacing: .4em; text-indent: .4em;   /* compensa el hueco del final */
  padding: .7rem .5rem;
}
@media (max-width: 640px) { .campo-codigo { font-size: 1.6rem; } }

/* «No me ha llegado, mandalo otra vez». Va debajo y en pequeno: es la salida
   de emergencia, no la accion principal. */
.reenviar-codigo { margin-top: 1.25rem; text-align: center; }

/* La politica de privacidad es texto largo de leer, no una ficha de datos: se
   le ensancha la linea y se separan los apartados. */
.detalle-largo dd { line-height: 1.6; margin-bottom: 1.25rem; }

/* --- Detalle de reserva ------------------------------------------------- */

.etiqueta {
  display: inline-block; margin: 0 0 .75rem;
  padding: .2rem .7rem; border-radius: 999px;
  font-size: .78rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
}
.etiqueta.confirmada { background: color-mix(in srgb, var(--verde) 15%, transparent); color: var(--verde); }
.etiqueta.pendiente  { background: color-mix(in srgb, var(--ambar) 15%, transparent); color: var(--ambar); }
.etiqueta.cancelada  { background: color-mix(in srgb, var(--rojo) 15%, transparent);  color: var(--rojo); }

.detalle { margin: 1.5rem 0; padding: 0; }
.detalle > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .6rem 0; border-bottom: 1px solid var(--borde);
}
.detalle dt { color: var(--texto-suave); font-size: .9rem; }
.detalle dd { margin: 0; font-weight: 550; text-align: right; }
.codigo { font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
          font-size: 1.1rem; letter-spacing: .12em; }

/* El codigo de local, en la pantalla de Ayuda: se lee de aqui para decirlo por
   telefono, asi que va grande y con su boton de copiar al lado. */
.codigo-local {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: .5rem 0;
}
.codigo-local .apunte { margin: 0; }
.codigo-local .codigo {
  font-size: 1.35rem; font-weight: 600;
  padding: .15rem .5rem; border-radius: .4rem;
  background: color-mix(in srgb, var(--acento) 12%, transparent);
  color: var(--acento);
}

/* --- Panel -------------------------------------------------------------- */

.barra-dia { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.barra-dia input[type=date] { width: auto; }

/* La ocupacion por franjas es su propio bloque del tablero, y de fabrica va
   arriba al lado de la fecha: es lo que se mira al elegir un dia, antes de
   decidir si hay sitio. Suelta seria un bloque de dos tarjetas altas; aqui hay
   que encogerla o se come media pantalla.
   `align-items: stretch` para que los dos turnos midan lo mismo aunque uno
   tenga cuatro franjas y el otro tres. */
.bloque-ocupacion .ocupacion {
  flex: 1 1 320px; margin: 0; gap: .6rem; align-items: stretch;
}
.bloque-ocupacion .ocupacion-turno { flex: 1 1 200px; padding: .5rem .7rem; }
.bloque-ocupacion .ocupacion-turno h3 { margin: 0 0 .3rem; font-size: .72rem; }
.bloque-ocupacion .franjas { gap: .1rem; }
.bloque-ocupacion .franja { font-size: .75rem; gap: .35rem; }
.bloque-ocupacion .franja-hora { width: 2.5rem; }
.bloque-ocupacion .franja-barra { height: .4rem; }
.bloque-ocupacion .franja-pax { width: 2rem; }

/* Dentro de un bloque la barra no lleva margen: el hueco lo pone el tablero. */
.tablero .bloque .barra-dia { margin-bottom: 0; }
/* Las herramientas, pegadas a la derecha de su bloque. */
.barra-dia .herramientas-dia { margin-left: auto; }

/* --- Los bloques de repaso ------------------------------------------------
   Listas cortas y densas: se leen de un vistazo pasando por la barra, no se
   estudian. Ver `app/servicios/repaso.py`. */
.repaso { display: flex; flex-direction: column; gap: .9rem; }
.repaso-grupo h3 {
  margin: 0 0 .35rem; font-size: .75rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--texto-suave);
}
/* Lo unico que el sistema no puede resolver solo va marcado. Todo lo demas se
   prepara; una reserva sin mesa hay que decidirla. */
.repaso-grupo.grave h3 { color: var(--peligro, #b3261e); }
.repaso ul, .llegadas, .cobros-abiertos {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: .3rem;
}
/* Cada linea pasa a llevar sus tres botones -sentar, llamar, ver ficha-, asi
   que deja de ser una linea de texto y pasa a ser una fila: el texto a la
   izquierda y las acciones siempre en el mismo sitio, a la derecha. Con `wrap`
   los botones caen debajo en una tablet estrecha en vez de desbordarse. */
.repaso li, .llegadas li {
  font-size: .9rem;
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
}
.repaso .apunte, .llegadas .apunte { margin: 0; display: inline; }

/* UN BLOQUE QUE ES UN BOTON.
   Llena su bloque entero -alto y ancho- en vez de tener un tamano propio, asi
   que se hace mas grande o mas ancho estirando el bloque por el tirador de la
   esquina, como cualquier otro. Sin bordes: el color ya dice que se pulsa.
   El texto crece con el bloque (`cqw`) para que al agrandarlo se lea desde la
   otra punta de la barra, que es para lo que se agranda. */
.boton-bloque {
  container-type: inline-size;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .15rem;
  width: 100%; height: 100%; box-sizing: border-box; padding: .6rem;
  border: 0; border-radius: var(--radio);
  /* El color va por variable y no a pelo, para que el realce al pasar por
     encima pueda partir de ELLA. Escrito a pelo, el boton verde de la venta se
     ponia del color de la casa al pasar el raton -la regla del dialogo
     centrado le pisaba el fondo- y por un momento parecia otro boton. */
  --tono-bloque: var(--acento);
  background: var(--tono-bloque); color: var(--sobre-relleno);
  text-align: center; text-decoration: none; font-weight: 600;
  transition: filter .12s ease;
  /* Cuando el boton es un <summary> deja de tener triangulito: es un boton
     para quien lo mira, y el adorno de desplegable lo desmiente. */
  list-style: none;
}
.boton-bloque::-webkit-details-marker { display: none; }
.boton-bloque:hover { filter: brightness(1.08); }
.boton-bloque:focus-visible { outline: 3px solid var(--ambar); outline-offset: 2px; }
/* Los colores son ESTADO, no adorno: verde entrando venta, rojo parada, gris
   cuando no hay nada que mirar. El texto dice la accion. */
.boton-bloque.verde   { --tono-bloque: var(--verde); }
.boton-bloque.rojo    { --tono-bloque: var(--rojo); }
.boton-bloque.apagado { --tono-bloque: var(--texto-suave); }
.boton-bloque-titulo { font-size: clamp(.95rem, 7cqw, 2rem); line-height: 1.1; }
.boton-bloque-cifra {
  font-size: clamp(.75rem, 5cqw, 1.4rem); font-weight: 500; opacity: .9;
}

/* Los tres botones de una reserva (macro `_acciones.html`). `margin-left:auto`
   los empuja a la derecha: se usan con la gente entrando por la puerta y tienen
   que estar donde la mano ya sabe, fila tras fila. */
.acciones-reserva {
  margin-left: auto; display: inline-flex; align-items: center;
  gap: .35rem; flex-wrap: wrap;
}
.llegada-hora { min-width: 3rem; display: inline-block; }
.llegada-nombre { font-weight: 500; }
.marca-extra {
  font-size: .75rem; font-weight: 600;
  border-radius: 999px; padding: .05rem .45rem; margin-left: .25rem;
  background: color-mix(in srgb, var(--acento) 14%, transparent);
  color: var(--acento);
}
.salas-libres { display: flex; gap: .6rem; flex-wrap: wrap; }
.sala-libre {
  flex: 1 1 6rem; text-align: center;
  border: 1px solid var(--borde); border-radius: var(--radio);
  padding: .5rem .6rem;
}
.sala-libre strong { display: block; font-size: 1.4rem; line-height: 1.1; }
.sala-libre span { font-size: .8rem; }
.sala-libre.llena { border-color: var(--acento); color: var(--acento); }
.cobros-abiertos li {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; flex-wrap: wrap; font-size: .9rem;
  border-bottom: 1px solid var(--borde); padding-bottom: .35rem;
}
.cobros-abiertos li:last-child { border-bottom: none; }

/* --- La ficha del cliente al apuntar una reserva a mano -------------------
   Sale al teclear un telefono que ya tenemos fichado. Va marcada como algo que
   hay que MIRAR y decidir, no como un dato ya aplicado: nada se rellena hasta
   que alguien pulsa el boton. Ver `app/static/alta_telefono.js`. */
.ficha-encontrada {
  border: 1px solid var(--acento); border-radius: var(--radio);
  padding: .8rem .9rem; margin: 0;
  background: color-mix(in srgb, var(--acento) 6%, transparent);
}
.ficha-encontrada-cabecera {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  margin-bottom: .35rem;
}
.ficha-encontrada p { margin: .2rem 0; }
.ficha-encontrada .linea-botones { margin-top: .7rem; }
/* Las notas son lo que el restaurante apunto de el: «prefiere terraza»,
   «alergico severo». Es lo mas util de toda la tarjeta, asi que no va de
   apunte gris. */
.ficha-encontrada-notas { font-weight: 600; }
.etiqueta-fiabilidad {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--texto-suave);
  border: 1px solid var(--borde); border-radius: 999px; padding: .1rem .5rem;
}

.cifras { display: flex; gap: .75rem; flex-wrap: wrap; margin: 1.25rem 0 1.75rem; }
.cifra {
  flex: 1 1 120px; padding: .85rem 1rem;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio);
}
.cifra strong { display: block; font-size: 1.6rem; line-height: 1.1; letter-spacing: -.02em; }
.cifra span { font-size: .82rem; color: var(--texto-suave); }
.cifra.alerta { border-color: var(--ambar); color: var(--ambar); }
/* La cifra que ADEMAS es un enlace: «17 de los de siempre llevan medio año sin
   venir» lleva a esa lista. Un número que informa y no se puede seguir obliga
   a ir a buscar la lista a mano, y entonces no se va. */
.cifra-aviso {
  text-decoration: none; color: inherit;
  border-color: var(--ambar);
}
.cifra-aviso strong { color: var(--ambar); }
.cifra-aviso:hover { border-color: var(--acento); }

/* Los grupos de clientes: VIP, celiacos, los del vermut. Los inventa la casa,
   asi que los colores son una lista cerrada -aqui- y no texto libre: escritos
   a mano acabarian saliendo etiquetas amarillas sobre fondo blanco. */
/* Que a este ya se le mandó un regalo, visto desde la lista. Es un emoji con
   su `title`, no un rótulo: la columna es estrecha y lo que hace falta es
   poder recorrer doscientas filas de un vistazo. */
.marca-regalado { cursor: help; }

.grupo-marca {
  display: inline-block; padding: .05rem .5rem; border-radius: 999px;
  font-size: .72rem; font-weight: 600; white-space: nowrap;
  background: color-mix(in srgb, var(--tono-grupo) 16%, transparent);
  color: var(--tono-grupo);
  --tono-grupo: var(--texto-suave);
}
.grupo-marca.color-gris   { --tono-grupo: var(--texto-suave); }
.grupo-marca.color-verde  { --tono-grupo: var(--verde); }
.grupo-marca.color-azul   { --tono-grupo: var(--acento); }
.grupo-marca.color-ambar  { --tono-grupo: var(--ambar); }
.grupo-marca.color-rojo   { --tono-grupo: var(--rojo); }
.grupo-marca.color-morado { --tono-grupo: color-mix(in srgb, var(--rojo) 55%, var(--acento)); }
.grupos-ficha { display: inline-flex; flex-wrap: wrap; gap: .2rem; margin-left: .3rem; }

.lista-grupos { list-style: none; margin: .5rem 0; padding: 0; }
.lista-grupos li {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .3rem 0; border-bottom: 1px solid var(--borde);
}
.lista-grupos li:last-child { border-bottom: none; }
.lista-grupos form { margin: 0; margin-left: auto; }

/* Listas cortas dentro de una celda o de un desplegable: los modulos regalados
   a un restaurante, en /central y en /plataforma. Sin viñeta y sin sangria
   porque van dentro de un <td> que ya es estrecho, y con el boton de quitar
   empujado a la derecha para que la lista se lea en columna. */
.lista-menuda { list-style: none; margin: .3rem 0; padding: 0; font-size: .87rem; }
.lista-menuda li {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  padding: .25rem 0; border-bottom: 1px solid var(--borde);
}
.lista-menuda li:last-child { border-bottom: none; }
.lista-menuda form { margin: 0; margin-left: auto; }

/* Lo que se hace con los marcados. Debajo de la tabla y pegajoso: en una lista
   de trescientas fichas se marca bajando, y el boton tiene que seguir ahi. */
.acciones-marcados {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  margin-top: .6rem; padding: .55rem .7rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
}
.acciones-marcados select { width: auto; }

/* Para lectores de pantalla: la columna de las casillas necesita un rotulo que
   no ocupe sitio en una cabecera que ya va justa. */
.oculto-visual {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.tabla {
  width: 100%; border-collapse: collapse;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); overflow: hidden; font-size: .92rem;
}
.tabla th {
  text-align: left; padding: .6rem .75rem; font-size: .78rem;
  text-transform: uppercase; letter-spacing: .05em; color: var(--texto-suave);
  border-bottom: 1px solid var(--borde); font-weight: 600;
}
.tabla td { padding: .6rem .75rem; border-bottom: 1px solid var(--borde); vertical-align: top; }
.tabla tr:last-child td { border-bottom: none; }
.tabla .centro { text-align: center; }
.tabla .hora { font-weight: 650; white-space: nowrap; }
.tabla .menudo { font-size: .84rem; color: var(--texto-suave); }
.tabla select { padding: .3rem .4rem; font-size: .85rem; }
.selector-mesas { min-width: 110px; }
/* Mientras espera para guardar. El desplegable de mesas ya no guarda al primer
   clic —así se pueden marcar dos mesas de una reserva de ocho sin que se
   cierre—, y esos dos segundos de silencio se leen como «no ha hecho nada» si
   no se dice. Ver `mesas_multiples.js`. */
.selector-mesas.guardando {
  border-color: var(--acento);
  box-shadow: 0 0 0 2px var(--acento-suave);
}

/* Una anulada con dinero detrás no se borra, y se dice en el sitio del botón
   en vez de dejar que alguien haga todo el camino para recibir un error. */
.no-borrable { color: var(--texto-suave); }

/* --- Eligiendo mesas desde el plano --------------------------------------
   Mientras el desplegable de mesas de una reserva está abierto, el plano es
   suyo: pulsar una mesa la marca o la desmarca. Se avisa de que el plano ha
   cambiado de significado —si no, un clic haría algo distinto de lo que hace
   siempre sin que nada lo dijera— y se ven cuáles tiene puestas.
   Ver `mesas_multiples.js`. */
/* EL MODO NUNCA ES INVISIBLE. Se queda puesto tras guardar —eso es lo que
   permite repartir un grupo en varias mesas— y sin cartel eso es una trampa:
   te vas, y el siguiente que roza el plano asigna una mesa sin enterarse.
   Ver `mesas_multiples.js`. */
.cartel-eligiendo {
  position: fixed; z-index: 55;
  left: 50%; bottom: 1rem; transform: translateX(-50%);
  display: flex; align-items: center; gap: .5rem;
  padding: .5rem .9rem;
  background: var(--acento); color: var(--sobre-relleno);
  border-radius: 999px; box-shadow: var(--sombra);
  font-size: .9rem; font-weight: 600;
}
.cartel-eligiendo .boton { background: var(--superficie); }
/* Lo que queda de modo. En cifras tabulares para que no baile el ancho al
   pasar de 10 a 9: un numero que se mueve solo llama la atencion mas que el
   propio aviso. */
.cuenta-eligiendo { font-variant-numeric: tabular-nums; opacity: .85; }

/* Las tres fichas de plan, una al lado de otra. En rejilla y no en columna
   porque lo que se hace aqui es COMPARARLAS: «¿que separa al Profesional del
   Conectado?» se contesta de un vistazo con las tres a la vista, y leyendo tres
   listas seguidas hay que acordarse de la anterior. */
.rejilla-planes {
  display: grid; gap: 1rem; margin: 1rem 0;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/* Un grupo de casillas que van juntas y significan una sola decision -«que
   formas de cobro usais»-. `fieldset` y `legend` de verdad y no un `div` con
   un titulo: es lo que le dice a un lector de pantalla que esas tres casillas
   son una pregunta y no tres sueltas. El borde de la izquierda lo dice
   tambien para quien lo ve. */
.grupo-casillas {
  border: none; border-left: 3px solid var(--borde);
  margin: .75rem 0; padding: .25rem 0 .25rem .75rem;
}
.grupo-casillas legend {
  padding: 0; font-size: .87rem; font-weight: 600; color: var(--texto-suave);
}

.plano.eligiendo-mesas { outline: 2px dashed var(--acento); outline-offset: 4px; }
.plano.eligiendo-mesas .mesa { cursor: copy; }
/* Las mesas que lleva esa reserva mientras se están repartiendo. Más gruesas
   por lo mismo que la marcada: esto se mira de pie y con la sala llena. No
   parpadean —pueden ser cuatro a la vez y cuatro cosas parpadeando no señalan
   nada—; el parpadeo se reserva para cuando se busca UNA. */
.plano .mesa.mesa-elegida {
  outline: 5px solid var(--acento);
  outline-offset: 1px;
}

/* Quién tiene entrada para hoy. No son reservas: es gente que ha comprado su
   entrada, y por eso no está en la lista del día. */
.cifra-entradas { margin: 0 0 .5rem; font-size: 1.1rem; }
.lista-entradas { list-style: none; margin: 0; padding: 0; }
.entrada-fila {
  padding: .4rem 0;
  border-bottom: 1px solid var(--borde);
}
.entrada-fila:last-child { border-bottom: none; }
/* Una compra anulada se lee, pero apagada: está para saber que existió. */
.entrada-fila.estado-cancelada,
.entrada-fila.estado-caducada { opacity: .55; }
.marca-extra.alerta { color: var(--rojo); }

/* --- «¿Sigue ocupada esa mesa?» ------------------------------------------
   Sale solo, encima de todo, cuando una mesa sentada pasa de su hora. Tiene
   que verse desde el otro lado de la barra: la tablet está a metro y medio y
   quien la mira tiene las manos ocupadas. Ver `mesa_ocupada.js`. */
.dialogo-mesa {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, .5);
}
.dialogo-mesa-caja {
  width: min(30rem, 100%);
  max-height: calc(100vh - 2rem); overflow: auto;
  padding: 1.25rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  box-shadow: var(--sombra);
}
.dialogo-mesa-caja h3 { margin: 0 0 .5rem; }
/* Una mesa puede tener DOS reservas a la vez —dos turnos, o un grupo
   repartido—, y el menu saca un bloque por cada una. Sin esta linea que las
   separa, las dos se leen como una sola ficha con seis botones y no se sabe
   cual es de quien: el «Liberar la mesa» del primero queda pegado al nombre
   del segundo. */
/* Cerrar sin tocar nada. Va separado y discreto: todo lo demas del dialogo
   cambia algo, y quien lo abrio por error necesita una salida evidente que no
   haga nada. Sin ella pulsa cualquier cosa. */
.cerrar-menu-mesa { margin-top: 1rem; opacity: .8; }

.menu-mesa-reserva + .menu-mesa-reserva {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--borde);
}
.dialogo-mesa-caja form { margin-top: .75rem; flex-wrap: wrap; }
/* «Ya está libre» es la respuesta que se busca, así que se ve como la
   principal. Las otras dos son secundarias de verdad: aplazan. */
.dialogo-mesa-caja form:first-of-type .boton { min-height: 44px; }

/* Un campo que hay que rellenar y no se rellenó. Se marca en el propio campo
   y no solo con un texto arriba: en un formulario de doce huecos, un aviso en
   la cabecera no dice CUÁL falta. Ver `senal_obligatoria.js`. */
/* Una sala cerrada a internet. Se ve de un vistazo cuál está cerrada sin
   tener que leer: con cinco salas, leerlas todas es justo lo que no se hace
   con la lluvia cayendo. Ver `CupoZona.cerrada`. */
.sala-cupo.cerrada {
  border-color: var(--rojo);
  background: color-mix(in srgb, var(--rojo) 6%, transparent);
}
.sala-cupo.cerrada .cupo-porcentaje { opacity: .6; }
.cupo-porcentaje { margin-top: .5rem; }

select.falta, input.falta {
  border-color: var(--rojo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--rojo) 25%, transparent);
}
/* Las filas se resaltan al pasar por encima: en una tabla de veinte lineas con
   varias columnas, seguir la fila con la vista de un extremo al otro sin nada
   que la marque es donde se cometen los errores. */
.tabla tbody tr:hover { background: var(--acento-suave); }
.tabla tbody tr.inactiva:hover { background: transparent; }

/* En el movil, una tabla de seis columnas no cabe, y sin esto el ancho de la
   tabla estiraba la PAGINA entera: se movia todo de lado, cabecera incluida.
   Ahora la que se desplaza es la tabla, dentro de su sitio. */
@media (max-width: 720px) {
  .tabla {
    display: block; overflow-x: auto; -webkit-overflow-scrolling: touch;
  }
  .tabla thead, .tabla tbody, .tabla tr { display: table; width: 100%; }
  .tabla th, .tabla td { white-space: nowrap; }
}

.codigo-pequeno {
  display: block; font-family: ui-monospace, Consolas, monospace;
  font-size: .75rem; color: var(--texto-suave); letter-spacing: .06em;
}
.enlace-menudo { font-size: .84rem; color: var(--acento); }

/* Una fila apagada se ve apagada, PERO SUS BOTONES NO.
 *
 * `opacity` no solo aclara: crea un contexto de apilado y se lo aplica a TODA
 * la descendencia, incluidos los `position: fixed`. Y dentro de la celda de
 * acciones cuelga el diálogo de editar, con su velo a pantalla completa. Al
 * abrirlo desde un evento sin publicar —que es justo el que se quiere
 * recuperar— salía la pantalla entera al 45%: el velo casi transparente y el
 * recuadro con los campos apenas legible. Parecía un problema del diálogo y
 * era de la fila que lo contiene.
 *
 * Así que se apaga lo que se lee y no lo que se pulsa. Es la misma regla que
 * ya sigue `.fila-editable.inactiva`, y por el mismo motivo: los controles
 * para recuperar algo apagado tienen que verse bien, o no se recupera.
 */
tr.estado-cancelada td:not(:has(.acciones-fila)),
tr.estado-no_show td:not(:has(.acciones-fila)),
tr.inactiva td:not(:has(.acciones-fila)) { opacity: .45; }
tr.estado-cancelada .hora { text-decoration: line-through; }

/* --- Listas editables en linea (mesas y turnos) --------------------------
   No se usa <table>: un <td> con display:flex deja de ser celda y el navegador
   ignora su colspan. Con flex puro las cabeceras y las filas comparten los
   mismos anchos y todo queda alineado.
   Los controles van FUERA del <form> y lo referencian con el atributo form=,
   asi cada fila puede tener varios formularios (guardar, activar, borrar). */

.lista-editable {
  --anchoTexto: 7rem;
  --anchoNumero: 3.6rem;
  --anchoHora: 6.2rem;
  --anchoDia: 4.8rem;
  --anchoExtra: 6.8rem;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
}

.cabecera-lista, .fila-editable {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .4rem .6rem; padding: .55rem .75rem;
}
.cabecera-lista {
  border-bottom: 1px solid var(--borde);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--texto-suave); font-weight: 600;
}
.fila-editable { border-bottom: 1px solid var(--borde); }
.fila-editable:last-child { border-bottom: none; }
.fila-editable.inactiva > *:not(.acciones-fila) { opacity: .5; }

.lista-editable form[hidden] { display: none; }
.lista-editable input, .lista-editable select {
  padding: .35rem .45rem; font-size: .87rem;
}

/* Los mismos anchos en la cabecera y en la fila: por eso quedan alineadas.
   Van anidados bajo .lista-editable a proposito: la regla global
   input[type=text] {width:100%} tiene mas especificidad que una clase suelta
   y apilaria los campos uno debajo de otro. */
.lista-editable .c-texto  { width: var(--anchoTexto);  flex: none; }
.lista-editable .c-numero { width: var(--anchoNumero); flex: none; text-align: center; }
.lista-editable .c-hora   { width: var(--anchoHora);   flex: none; }
.lista-editable .c-dia    { width: var(--anchoDia);    flex: none; font-size: .86rem; }
.lista-editable .c-extra  { width: var(--anchoExtra);  flex: none; }
.lista-editable .c-extra.casilla span { font-size: .82rem; }
.lista-editable .casilla input[type=checkbox] { width: auto; flex: none; }

.lista-editable .c-ancho  { width: 14rem; flex: none; }

/* «2 mesas cada 15 min»: dos campos que se leen como una frase.
   Sueltos y numerados obligaban a subir a la cabecera para saber cual era
   cual; con el «cada» en medio se entiende sin leer nada mas. */
.cada-cuanto {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .82rem; color: var(--texto-suave);
}
.cada-cuanto input[type=number] { width: 3.2rem; text-align: center; }
.cada-cuanto select { width: auto; }

/* LOS TRES TOPES, JUNTOS. Aforo, Pax/h y Mesas cada dicen lo mismo desde tres
   sitios -a cuanta gente y a cuantas mesas quieres atender- y sueltos en la
   fila se leian como tres ajustes sin relacion.

   Un fondo apenas mas oscuro y nada mas: SUTIL A PROPOSITO. Con borde se
   convertirian en una seccion aparte dentro de la fila, y no lo son.

   Y el MISMO envoltorio en la cabecera y en la fila. Esa es la otra mitad: la
   cabecera y la fila eran dos listas de anchos distintos, asi que en cuanto
   uno de los campos crecio, los rotulos de la derecha -«Mesas/tramo» y
   «Estado»- se quedaron corridos sobre lo que no rotulaban. Compartiendo
   envoltorio no se pueden descuadrar. */
.grupo-aforo {
  display: inline-flex; align-items: center; gap: .35rem; flex: none;
  padding: .2rem .35rem; border-radius: .45rem;
  background: color-mix(in srgb, var(--texto-suave) 8%, transparent);
}
.cabecera-lista .grupo-aforo { background: none; }
.lista-editable .c-mesas { width: 8.4rem; flex: none; }

.acciones-fila { display: flex; gap: .4rem; align-items: center; margin-left: auto; }
.acciones-fila form { margin: 0; }
.acciones-fila input { padding: .35rem .45rem; font-size: .85rem; }

/* 700 Y NO 820. Este corte tapaba los rotulos de las columnas en cualquier
   tableta, que es la franja 753-834, y esa es la pantalla de la barra: el
   camarero veia seis casillas sin nombre donde el de la oficina lee «Sala»,
   «Comensales»... y son las MISMAS listas de mesas y de turnos.

   Se quito por «falta de sitio para alinear», y eso resulto ser falso: medida
   la pagina de mesas a 768, la cabecera cae en 54-166, 176-288, 297-409... y
   la fila cae exactamente en los mismos numeros. Se parte en dos lineas, si,
   pero la fila se parte por el mismo sitio, asi que sigue cuadrando.

   Por debajo de 700 -telefono- si estorba de verdad y ahi se sigue quitando. */
@media (max-width: 700px) {
  .cabecera-lista { display: none; }
  .fila-editable { border-bottom-width: 2px; }
}

/* --- Editar una fila de una tabla ----------------------------------------
   La fila de edicion va debajo de la que edita y ocupa todo el ancho: los
   formularios largos no caben en la columna de acciones. Cerrada no tiene
   que dejar rastro, de ahi que el hueco y el borde se quiten en el <td> y
   no en el <details>, que es lo unico que se ve al abrirla. ---------------- */

.fila-edicion > td { padding: 0 .75rem; border: none; }
.fila-edicion .edicion { padding: .35rem 0 .6rem; }
.fila-edicion .edicion[open] { padding-bottom: 1.25rem; }
.fila-edicion summary { display: inline-flex; list-style: none; }
.fila-edicion summary::-webkit-details-marker { display: none; }
.fila-edicion .rejilla-formulario { margin-top: .6rem; }

/* --- Plano de sala --------------------------------------------------------
   Las piezas se posicionan en PORCENTAJE sobre un lienzo con proporcion fija.
   Asi el mismo plano vale en el movil del encargado y en la pantalla de la
   barra sin recalcular coordenadas ni guardar pixeles. */

.plano-marco { overflow-x: auto; margin: .5rem 0 1rem; }
.plano {
  position: relative; width: 100%; min-width: 620px;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  /* Rejilla de fondo: sin una referencia visual es imposible alinear nada. */
  background-image:
    linear-gradient(var(--borde) 1px, transparent 1px),
    linear-gradient(90deg, var(--borde) 1px, transparent 1px);
  background-size: 5% 7.5%;
  touch-action: none;      /* el arrastre no debe hacer scroll en tablet */
  overflow: hidden;
}
.plano.solo-lectura { touch-action: auto; }
/* El plano del servicio con el candado ABIERTO. Es el mismo plano de mirar, no
   el editor de la sala: aqui solo se arrastra.
   `touch-action: none` es imprescindible en la tablet -sin el, el dedo hace
   scroll de la pagina en vez de mover la mesa- y `user-select` evita que
   arrastrar seleccione los nombres de los clientes de las mesas de al lado. */
.plano.movible { touch-action: none; user-select: none; cursor: grab; }
.plano.movible .pieza.mesa { cursor: grab; }
.plano.movible .pieza.mesa.moviendose {
  cursor: grabbing; z-index: 5;
  outline: 3px solid var(--acento); outline-offset: 2px;
}
/* La barra del candado: el boton, lo que hace y como deshacerlo, en una fila.
   Va pegada al plano y no en un menu porque se usa con las manos ocupadas.

   DEBAJO DEL PLANO Y A LA DERECHA. Debajo porque esta pantalla se abre mil
   veces al dia para MIRAR la sala y muy pocas para recolocarla: encima del
   plano le robaba una linea al dibujo en cada una de esas mil. Y a la derecha
   -`justify-content: flex-end`- porque es donde acaba la mano despues de
   arrastrar una mesa, y asi se mueve el comedor y se guarda sin cruzar la
   pantalla entera.

   El texto explicativo va DELANTE de los botones aunque la fila este alineada
   a la derecha: leyendo de izquierda a derecha, primero se lee lo que pasa y
   despues se pulsa. */
.barra-candado {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: flex-end; gap: .5rem;
  margin: .6rem 0;
}
.barra-candado .apunte { margin: 0; }
/* En el movil se apila y ahi la derecha no significa nada: la fila ocupa el
   ancho entero, asi que se vuelve a la izquierda, que es donde empieza a leer
   cualquiera. */
@media (max-width: 600px) {
  .barra-candado { justify-content: flex-start; }
}

.pieza {
  position: absolute; display: flex; align-items: center; justify-content: center;
  box-sizing: border-box; user-select: none;
}
.plano:not(.solo-lectura) .pieza { cursor: grab; }
/* El tamano del rotulo lo elige quien monta la sala, pieza a pieza, y viaja
   como un numero suelto en --texto-tam (100 = el de siempre). Va en calc y no
   en una clase por cada tamano porque es un continuo, no cuatro opciones. */
.pieza-texto {
  font-size: calc(.74rem * var(--texto-tam, 100) / 100);
  line-height: 1.15; text-align: center;
  padding: 2px; overflow: hidden;
}
/* En em y no en rem: asi la capacidad crece con el nombre de la mesa en vez
   de quedarse clavada cuando se agranda el rotulo. */
/* La segunda linea de una pieza: «pax 4» en una mesa libre, la hora y los
   comensales en una ocupada. Va con etiqueta y no como un numero suelto: una
   mesa que pone «12» encima de un «4» son dos numeros sin nombre, y cual es
   cual se adivina distinto cada dia.

   `.85em` y no `.9em`: al numero le ha salido delante una palabra, y en una
   mesa pequena del plano ese poco de mas es lo que evita que parta en dos
   renglones. */
.pieza-texto small {
  display: block;
  opacity: .75;
  font-size: .85em;
  white-space: nowrap;
}
.pieza-texto strong { display: block; }

.mesa {
  background: color-mix(in srgb, var(--acento) 12%, var(--superficie));
  border: 2px solid var(--acento); color: var(--texto);
}
.mesa.forma-redonda { border-radius: 50%; }
.mesa.forma-cuadrada { border-radius: 8px; }
.mesa.forma-rectangular { border-radius: 8px; }
.mesa.inactiva { opacity: .4; border-style: dashed; }
.pieza.elegida { outline: 3px solid var(--ambar); outline-offset: 2px; z-index: 5; }

/* Estados en la vista del servicio */
.mesa.estado-libre {
  background: color-mix(in srgb, var(--verde) 10%, var(--superficie));
  border-color: var(--verde);
}
.mesa.estado-ocupada {
  background: color-mix(in srgb, var(--acento) 22%, var(--superficie));
  border-color: var(--acento); font-weight: 600;
}
.mesa.estado-inactiva {
  background: var(--fondo); border-color: var(--borde);
  border-style: dashed; opacity: .5;
}

/* MODO «SENTAR»: las mesas donde SI se puede sentar a quien se esta
   colocando. Sin esto, el plano en modo sentar se ve igual que siempre y hay
   que ir pulsando a ver cual responde. Con la sala llena, las que quedan
   libres son dos o tres y tienen que saltar a la vista.

   Se marca ademas del verde de «libre»: libre y «pulsable ahora» no son lo
   mismo -la mesa de la lista de espera esta libre y no vale-, y confundirlos
   es sentar a alguien en una mesa de mentira. */
.mesa.sentable {
  outline: 3px solid var(--ambar);
  outline-offset: 2px;
  z-index: 4;
}
.mesa.sentable:hover, .mesa.sentable:focus-visible {
  background: color-mix(in srgb, var(--ambar) 25%, var(--superficie));
}

/* El aviso de a quien se esta sentando. Amarillo y no gris: dice que la
   pantalla esta en un modo distinto del normal, y un aviso de modo que no se
   nota es peor que ninguno -se pulsa una mesa creyendo que se abre el alta-. */
.franja-sentando {
  border-left: 4px solid var(--ambar);
  background: color-mix(in srgb, var(--ambar) 10%, var(--superficie));
}

.elemento { background: var(--texto-suave); color: var(--superficie); border-radius: 3px; }
.elemento.rotulo {
  background: transparent; color: var(--texto-suave);
  border: 1px dashed var(--borde); font-weight: 600;
}
.elemento.barra { background: var(--texto); border-radius: 6px; }
.elemento.puerta {
  background: transparent; border: 3px dashed var(--acento); color: var(--acento);
}

.tirador {
  position: absolute; right: -5px; bottom: -5px;
  width: 14px; height: 14px; border-radius: 3px;
  background: var(--ambar); border: 2px solid var(--superficie);
  cursor: nwse-resize;
}
.plano.solo-lectura .tirador { display: none; }

.plano-herramientas {
  display: flex; gap: .4rem; flex-wrap: wrap; align-items: center;
  margin-bottom: .6rem;
}
.plano-seleccion {
  display: flex; gap: .35rem; align-items: center;
  padding: .25rem .6rem; border-left: 1px solid var(--borde);
  font-size: .84rem;
}
/* Sin esto la barra de la pieza elegida se ve SIEMPRE, aunque no haya nada
   elegido: `display: flex` de arriba empata en especificidad con el
   `[hidden] { display: none }` del navegador y, al ser nuestra, gana. Se veian
   los botones de forma y de tamano sin nada a lo que aplicarselos. */
.plano-seleccion[hidden] { display: none; }

.leyenda {
  display: inline-block; width: .85rem; height: .85rem;
  border-radius: 3px; vertical-align: -2px; margin: 0 .2rem 0 .8rem;
  border: 2px solid var(--borde);
}
.leyenda.libre { background: color-mix(in srgb, var(--verde) 10%, transparent); border-color: var(--verde); }
.leyenda.ocupada { background: color-mix(in srgb, var(--acento) 22%, transparent); border-color: var(--acento); }
.leyenda.inactiva { background: var(--fondo); border-style: dashed; }

/* --- Campos adicionales del formulario ------------------------------------
   Van agrupados y algo apagados: son opcionales y no deben competir con el
   nombre y el telefono, que son lo que de verdad hace falta. */

/* LAS PREGUNTAS DEL RESTAURANTE, EN DOS COLUMNAS.
 *
 * Iban una debajo de otra y eran ocho o diez renglones de preguntas cortas
 * -«trona», «carrito», «alergias»- justo antes del botón de reservar. Todo ese
 * scroll para decidir cosas que se contestan de un vistazo, y con el botón
 * fuera de la pantalla mientras tanto: cuanto más largo es un formulario de
 * reserva, más gente lo abandona a mitad.
 *
 * `auto-fit` con un mínimo y no dos columnas fijas: nadie tiene que elegir el
 * número de columnas, las pone el ancho que haya.
 *
 * EL MÍNIMO ES 8rem, Y ESO ES LO QUE DECIDE EL MÓVIL.
 *
 * Con 13rem hacían falta 428px para dos columnas, así que en un teléfono salía
 * una sola. A petición: en el móvil también de dos en dos. Con 8rem caben dos
 * desde unos 280px de hueco, o sea desde un teléfono normal.
 *
 * Queda estrecho —«Marca si necesitas trona para un niño» ocupa tres
 * renglones— y aun así sale a cuenta: son tres renglones ANCHOS contra dos
 * preguntas apiladas, y lo que se gana es que el botón de reservar entre antes
 * en la pantalla.
 *
 * Y sigue habiendo suelo: en un teléfono muy estrecho —320px— no caben dos de
 * 8rem y vuelve a una sola columna sin que nadie haga nada. Eso es `auto-fit`,
 * y por eso aquí no hay ninguna media query.
 *
 * HAY UNA REGLA GEMELA EN LA HOJA DE LA OTRA PIEL, y hay que tocar las dos.
 * No se cargan nunca juntas —cada restaurante usa una—, así que lo que solo
 * esté aquí no existe para la mitad de los clientes. Ya pasó: se tocó solo
 * ésta y el widget siguió exactamente igual.
 *
 * (Y esta hoja no la nombra a propósito: son independientes y una suite lo
 * comprueba. Si se nombraran, dejarían de serlo.)
 *
 * En columna sigue siendo `flex` por debajo del mínimo, así que lo de siempre
 * no cambia donde no cabe. */
.extras {
  margin: .25rem 0 1rem; padding: .85rem 1rem;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px;
  display: grid; gap: .6rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  align-items: start;
}

/* La casilla y su detalle son UNA celda, no dos.
 *
 * Sueltos como hermanos caían en columnas distintas: «Alergias» a la izquierda
 * y «¿cuáles?» a la derecha, separados y sin que se viera que uno es del otro.
 * Ver `_formulario_reserva.html`, donde van envueltos. */
.extra-uno { display: flex; flex-direction: column; gap: .4rem; }

/* Los dos códigos opcionales, en paralelo. Son cortos, casi nadie los rellena
 * y uno debajo de otro son dos renglones de scroll para nada. */
.pareja-campos {
  display: grid; gap: .25rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
}
.extra-campo { margin: 0; }
.extra-campo > span { font-size: .84rem; }
.extra-campo input[type=number] { width: 5rem; }
.casilla.extra span { display: block; }
.casilla.extra small { display: block; color: var(--texto-suave); font-size: .78rem; }
.extras .casilla span em, .extra-campo span em {
  color: var(--texto-suave); font-style: normal; font-weight: 400;
}

/* En el panel: lo operativo se ve, lo critico se ve mas. */
.extra-marca {
  display: inline-block; margin: 0 .3rem .2rem 0; padding: .1rem .4rem;
  border-radius: 4px; background: var(--fondo); border: 1px solid var(--borde);
  font-size: .76rem;
}
.extra-marca.destacada {
  background: color-mix(in srgb, var(--ambar) 16%, transparent);
  border-color: color-mix(in srgb, var(--ambar) 40%, transparent);
  color: var(--ambar); font-weight: 600;
}

/* --- Graficos de barras --------------------------------------------------
   En CSS, sin libreria de graficos: una dependencia de JavaScript solo para
   pintar barras horizontales no se justifica, y ademas imprime bien. */

.rejilla-graficos {
  display: grid; gap: 1rem; margin-top: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.tarjeta-grafico {
  padding: 1rem 1.25rem;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio);
}

.barras { display: flex; flex-direction: column; gap: .35rem; }
.barras.dias { max-height: 22rem; overflow-y: auto; }

.barra-fila { display: flex; align-items: center; gap: .5rem; font-size: .84rem; }
.barra-nombre {
  width: 8.5rem; flex: none; color: var(--texto-suave);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.barra-canal {
  flex: 1; min-width: 2rem; height: .6rem; border-radius: 999px;
  background: var(--fondo); border: 1px solid var(--borde); overflow: hidden;
}
.barra-relleno { display: block; height: 100%; background: var(--acento); }
.barra-valor {
  width: 2.5rem; flex: none; text-align: right; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.barra-pct {
  width: 3.6rem; flex: none; text-align: right; color: var(--texto-suave);
  font-size: .78rem; font-variant-numeric: tabular-nums;
}

/* --- Ocupacion por franja horaria ----------------------------------------
   De un vistazo: donde se esta llenando el servicio. Sin esto, el limite de
   plazas por hora existe pero nadie ve como va. */

.ocupacion { display: flex; gap: 1rem; flex-wrap: wrap; margin: 0 0 1.5rem; }
.ocupacion-turno {
  flex: 1 1 260px; padding: .85rem 1rem;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio);
}
.ocupacion-turno h3 { margin: 0 0 .6rem; display: flex; justify-content: space-between; gap: .5rem; }
.ocupacion-turno h3 small { font-weight: 400; text-transform: none; letter-spacing: 0; }

.franjas { display: flex; flex-direction: column; gap: .25rem; }
.franja { display: flex; align-items: center; gap: .5rem; font-size: .82rem; }
.franja-hora { width: 3rem; color: var(--texto-suave); font-variant-numeric: tabular-nums; }
.franja-barra {
  flex: 1; height: .5rem; border-radius: 999px;
  background: var(--fondo); border: 1px solid var(--borde); overflow: hidden;
}
.franja-relleno { display: block; height: 100%; background: var(--verde); }
.franja-pax {
  width: 3.4rem; text-align: right; color: var(--texto-suave);
  font-variant-numeric: tabular-nums;
}
.franja.llena .franja-relleno { background: var(--ambar); }
.franja.llena .franja-pax { color: var(--ambar); font-weight: 600; }

/* Cobrar o liberar la tarjeta, dentro de la fila de la reserva. */
.acciones-cobro { display: flex; flex-direction: column; gap: .3rem; margin-top: .35rem; }
.acciones-cobro form { display: flex; gap: .25rem; margin: 0; }
.acciones-cobro input { padding: .25rem .35rem; font-size: .8rem; }

/* «¿Te dejamos invitado a un postre?»: lo que se le ofrece a quien no ha
   encontrado mesa. Va recuadrado y aparte del resto del fragmento de horas
   porque NO es parte de reservar: es otra conversacion, y mezclarlas haria
   que dejar el correo pareciera reservar. */
.pedir-detalle {
  margin-top: 1rem; padding: .85rem 1rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
}
.detalle-titulo { margin: 0 0 .2rem; font-weight: 600; }
.detalle-linea {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
  margin: .5rem 0;
}
.detalle-linea input[type=email] { flex: 1; min-width: 11rem; width: auto; }

/* «¿Necesitas cambiar algo?»: lo PRIMERO que se le ofrece al cliente que llega
   por el enlace de su correo. Recuadrado y a la vista, no plegado: estuvo
   dentro de un desplegable y nadie lo abria, asi que el que llegaba tarde
   pulsaba el boton rojo de anular y volvia a reservar. */
.tarjeta-cambio {
  margin-top: 1.5rem; padding: 1rem 1.25rem;
  background: var(--superficie);
  border: 1px solid var(--acento); border-radius: var(--radio);
}
.tarjeta-cambio h3 { margin: 0 0 .3rem; }

/* Y anular, abajo y sin gritar. Un enlace y no un boton rojo: el que de verdad
   no puede venir lo encuentra -y tiene que encontrarlo, o la mesa no se libera
   y es un no-show- y al que solo llegaba tarde ya no le llama la atencion,
   porque lo suyo lo ha resuelto ahi arriba. */
.anular-discreto {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem;
  margin-top: 1.75rem;
}
.anular-discreto form { margin: 0; }
.anular-discreto .apunte { margin: 0; }

/* El cambio que hace el cliente desde el enlace de su correo: la hora, cuantos
   son y guardar. En una fila cuando cabe y apilado en el movil, que es donde
   se abre casi siempre -el enlace se pulsa desde el correo del telefono. */
.cambiar-reserva {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem;
  margin: .5rem 0;
}
.cambiar-reserva label { display: flex; flex-direction: column; gap: .25rem; }
/* MAS GRANDES QUE UN CAMPO CUALQUIERA, y a proposito. Esto no es un formulario
   de configuracion: es lo unico que el cliente viene a hacer a esta pagina,
   muchas veces desde el movil y con prisa. Un rotulo de .85rem y un desplegable
   de tamano normal se leen como «un ajuste mas» y se pasan de largo. */
.cambiar-reserva span { font-size: 1rem; font-weight: 600; }
.cambiar-reserva select,
.cambiar-reserva input[type=number] {
  font-size: 1.15rem; padding: .5rem .6rem; min-height: 44px;
}
.cambiar-reserva select { width: auto; min-width: 7.5rem; }
/* «Cuántos» del MISMO tamano que la hora y en la MISMA linea: son las dos
   mitades de la misma pregunta -a que hora y cuantos-, y con una grande y otra
   pequena parecia que una era el cambio y la otra un detalle. Dos digitos
   bastan: nadie escribe aqui noventa y nueve. */
.cambiar-reserva input[type=number] { width: 5.5rem; text-align: center; }

/* Elegir la comunidad para los festivos autonómicos, en la propia pantalla de
   festivos: es donde se nota que faltan. */
.elegir-comunidad {
  display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap;
  margin: .5rem 0 1rem;
}
.elegir-comunidad label { display: flex; flex-direction: column; gap: .2rem; }
.elegir-comunidad span { font-size: .8rem; font-weight: 600; }
.elegir-comunidad select { width: auto; min-width: 12rem; }

/* Los filtros del registro de actividad: uno general y uno por columna.
   En rejilla y no en fila porque son cinco: en fila se salen de la pantalla en
   una tablet y acaban partidos por la mitad. */
.filtros-actividad {
  display: grid; gap: .5rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  align-items: end; margin: .6rem 0 1rem;
}
.filtros-actividad label { display: flex; flex-direction: column; gap: .2rem; }
.filtros-actividad span { font-size: .8rem; font-weight: 600; }
/* El general ocupa dos huecos: es el que se usa cuando no se sabe por dónde
   empezar, y ahí se escriben frases enteras, no una palabra. */
.filtros-actividad .filtro-ancho { grid-column: span 2; }
.filtros-botones { display: flex; gap: .4rem; align-items: center; }

/* Una tabla ancha dentro de una pantalla estrecha se desborda y empuja el
   resto. Con esto se desplaza ELLA sola y la página no se mueve. */
.tabla-ancha { overflow-x: auto; }

.desplegable {
  margin-top: 1.75rem; padding: 1rem 1.25rem;
  background: var(--superficie); border: 1px solid var(--borde); border-radius: var(--radio);
}
.desplegable summary {
  cursor: pointer; font-weight: 550; font-size: .93rem;
  /* Alto de dedo y el area pulsable estirada al ancho de la tarjeta: antes
     solo se abria acertando en las letras, y en una tablet eso se falla. */
  min-height: 32px; display: flex; align-items: center;
  margin: -.35rem -.35rem; padding: .35rem;
  border-radius: 6px;
}
.desplegable summary:hover { color: var(--acento); }
/* Abierto, el titulo se separa del contenido que acaba de aparecer. */
.desplegable[open] > summary { margin-bottom: .5rem; }

/* El de "anadir reserva" va arriba del todo y es una accion, no un apartado
   que se consulta. Se le da color de accion y un "+" delante para que se
   encuentre de un vistazo con el telefono en la oreja. El margen superior se
   reduce porque ahi arriba no separa nada, solo aleja. */
/* Aqui vivia `.desplegable-accion`, el estilo del alta por telefono cuando
   crecia hacia abajo. Se quito al pasarla a dialogo centrado: ya no la usaba
   ninguna plantilla, y una regla sin duenio se queda anos hasta que alguien la
   copia creyendo que hace algo. */

/* --- Widget incrustado ---------------------------------------------------
   Dentro del iframe no hay cabecera ni pie: solo la tarjeta, sin margenes
   propios, para que se funda con la web del restaurante. */
body.incrustado { background: transparent; }
body.incrustado .contenido { margin: 0; padding: 0; max-width: none; }
body.incrustado .tarjeta { border-radius: 0; border: none; box-shadow: none; }

/* --- Codigo para copiar --------------------------------------------------- */

.codigo-bloque {
  margin: .75rem 0; padding: .8rem 1rem;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: .82rem; line-height: 1.6;
  white-space: pre-wrap; word-break: break-all;
}

.aviso.correcto {
  background: color-mix(in srgb, var(--verde) 12%, transparent);
  color: var(--verde);
  border-color: color-mix(in srgb, var(--verde) 30%, transparent);
}

.cabecera nav .quien {
  color: var(--texto); font-weight: 550;
  padding-left: .75rem; border-left: 1px solid var(--borde);
}

/* --- La agenda dentro del TPV Agora --------------------------------------
   Se ve en una pantalla tactil, muchas veces pequena y con el camarero de
   pie. Todo mas grande de lo normal: los botones se pulsan con el dedo y a
   veces con guantes. */

body.tpv { background: var(--fondo); margin: 0; }

.tpv-cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: .7rem 1rem;
  background: var(--superficie); border-bottom: 1px solid var(--borde);
  position: sticky; top: 0; z-index: 5;
}
.tpv-cabecera strong { display: block; font-size: 1rem; }
.tpv-cabecera small { color: var(--texto-suave); font-size: .82rem; }
.tpv-acciones { display: flex; gap: .5rem; }

.tpv-lista { padding: .6rem; display: flex; flex-direction: column; gap: .5rem; }

.tpv-ficha {
  display: flex; align-items: center; gap: .9rem;
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); padding: .7rem .9rem;
}
/* Lo que ya ha terminado se ve, pero apagado: sigue haciendo falta para
   saber quien ha pasado por esa mesa, y no debe competir con lo que viene. */
.tpv-ficha.pasada { opacity: .55; }
.tpv-ficha.estado-cancelada, .tpv-ficha.estado-no_show { opacity: .45; }

.tpv-hora {
  font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums;
  min-width: 3.6rem;
}
.tpv-datos { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.tpv-datos strong { font-size: 1.05rem; }
.tpv-menudo { font-size: .85rem; color: var(--texto-suave); }
.tpv-peticiones { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .15rem; }
.tpv-etiqueta { font-size: .85rem; color: var(--texto-suave); }

/* Botones de dedo: 48px es el minimo para acertar sin mirar. */
.tpv-boton .boton { min-height: 48px; min-width: 7rem; font-size: 1rem; }
.tpv-acciones .boton { min-height: 40px; }

.tpv-mesa-estado { font-size: .82rem; font-weight: 600; margin-top: .2rem; }
.tpv-mesa-estado.ocupada { color: var(--acento); }
.tpv-mesa-estado.libre { color: var(--verde); }

/* La casilla de ofertas. Va separada del resto del formulario y algo apagada:
   es opcional, y no debe parecer un requisito para reservar. */
.casilla.ofertas {
  align-items: flex-start; margin: .9rem 0 .2rem;
  padding: .6rem .7rem;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px;
}
.casilla.ofertas small {
  display: block; color: var(--texto-suave); font-size: .8rem; font-weight: 400;
}

/* Una cifra que conviene mirar, sin llegar a alarma roja. */
.alerta-celda { color: var(--ambar); font-weight: 700; }

/* Etiqueta de festivo. Tres ambitos, tres colores, para distinguir de un
   vistazo lo que se calcula solo de lo que ha puesto el restaurante. */
.ambito {
  display: inline-block; padding: .1rem .5rem; border-radius: 999px;
  font-size: .78rem; font-weight: 600; vertical-align: middle;
  border: 1px solid currentColor;
}
.ambito-nacional {
  color: var(--acento);
  background: color-mix(in srgb, var(--acento) 10%, transparent);
}
.ambito-autonomico {
  color: var(--ambar);
  background: color-mix(in srgb, var(--ambar) 12%, transparent);
}
.ambito-local {
  color: var(--verde);
  background: color-mix(in srgb, var(--verde) 12%, transparent);
}

/* Instrucciones paso a paso, como las de configurar la ficha de Google. */
.pasos { margin: .5rem 0 0; padding-left: 1.3rem; font-size: .9rem; }
.pasos li { margin-bottom: .35rem; }

/* --- Pantalla del servicio: la sala a la izquierda, las reservas a la
   derecha, y se senalan entre si al pincharlas. ---------------------------- */

/* --- A donde mandar al cliente cuando no queda sitio ----------------------
   Sale bajo el aviso de "no hay huecos". Se ve claramente como otra cosa y no
   como mas horas de este restaurante: son otros locales. */
.alternativas {
  margin: .9rem 0 0; padding: .9rem 1rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
}
.alternativas-titulo { margin: 0 0 .6rem; font-weight: 600; font-size: .92rem; }
.alternativa {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; flex-wrap: wrap;
  padding: .55rem 0; border-top: 1px solid var(--borde);
}
.alternativa:first-of-type { border-top: none; padding-top: 0; }
.alternativa .apunte { margin: .15rem 0 0; }
.alternativa-ir { display: flex; gap: .4rem; }
/* Lo unico que se dice de la ocupacion del otro, y solo cuando se ha
   comprobado: que le quedan mesas. Ni cuantas, ni a que horas. */
.alternativa-libre {
  margin-left: .4rem; padding: .1rem .45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--verde) 18%, transparent);
  color: var(--verde); font-size: .74rem; font-weight: 600;
}

/* --- El tablero: bloques colocables --------------------------------------
   Como el editor del plano: los bloques van en posicion absoluta y se
   arrastran. `left` y `width` en PORCENTAJE -para que la colocacion valga en
   cualquier monitor- y `top`/`height` en pixeles, porque aqui dentro hay texto
   y no puede escalar con la anchura. El alto del contenedor lo calcula el
   guion a partir del bloque que llega mas abajo. */
.tablero { position: relative; margin-bottom: 1.5rem; }

/* EL TABLERO EMPIEZA ARRIBA DEL TODO.
   La pantalla del dia ya no tiene titulo propio -la fecha se fue a la barra de
   cabecera-, asi que el aire de fabrica del contenedor era lo unico que
   quedaba entre la barra y el primer bloque. Quitarlo es lo que permite subir
   un bloque hasta el borde de arriba, que es para lo que se hizo el cambio.
   Solo en esta pantalla: el resto del panel es texto y necesita su aire. */
.contenido:has(> .pantalla-dia) { margin-top: .75rem; }

/* TODO lo de aqui abajo va colgado de `.tablero` y no puede dejar de estarlo.
   `.bloque` no es un nombre nuestro en exclusiva: la pagina publica lo usa
   desde siempre en sus `fieldset` -«Hora», «Tus datos»- como «bloque de un
   formulario», que es un nombre igual de razonable.

   Sin el `.tablero` delante, este `position: absolute` se los aplicaba: los
   dos fieldset salian del flujo, el formulario se quedaba con 86 px de alto y
   la cartelera de eventos se pintaba ENCIMA de los datos del cliente. Medido
   en la pagina de un cliente. Es la segunda vez que un nombre de clase del
   tablero se cuela donde no debe -paso con `bloque-barra`-, asi que: al anadir
   una regla nueva aqui, `.tablero` delante. */
.tablero .bloque { position: absolute; min-width: 0; overflow: auto; }

/* Lo que se despliega dentro de un bloque tiene que taparlo TODO, no
   recortarse. El `overflow: auto` de arriba es lo que hace que un bloque con
   muchas reservas tenga su propia barra de desplazamiento, y eso mismo
   recortaba cualquier panel flotante: el calendario salia cortado por el
   borde del bloque y con una barra propia para verlo a trozos.

   Mientras hay uno abierto, ese bloque suelta el recorte y se pone por encima
   de sus vecinos.

   **Van enumerados los paneles que flotan, y hay que anadir aqui los que
   vengan.** Se probo a hacerlo generico y no se puede: un `.menu-desplegado`
   esta SIEMPRE en el arbol -lo que cambia es si su <details> esta abierto- asi
   que un `:has()` sin el estado abierto valdria siempre y ningun bloque
   volveria a recortar nada. */
.tablero .bloque:has(.desplegable-menu[open]),
.tablero .bloque:has(.calendario-panel:not([hidden])) {
  overflow: visible;
  z-index: 40;
}
.tablero .bloque.esta-oculto { display: none; }
.bloque-cuerpo { min-width: 0; }
/* Un bloque que ES un boton tiene que llenarlo: si no, se queda del alto de su
   texto y estirar el bloque no hace nada visible. Fue justo lo que paso con la
   lista de espera. `100%` del cuerpo, y el cuerpo del alto del bloque. */
.tablero.con-guion .bloque-cuerpo:has(.boton-bloque) { height: 100%; }
/* Un boton dentro de un <form> -el interruptor de la venta- tiene que llenar
   igual: el formulario es un envoltorio que no pinta nada. */
.tablero .bloque-cuerpo > form:has(> .boton-bloque),
.tablero .bloque-cuerpo > details:has(> .boton-bloque) {
  height: 100%; margin: 0; display: flex;
}
.tablero .bloque-cuerpo > form > .boton-bloque,
.tablero .bloque-cuerpo > details > .boton-bloque { flex: 1; }
/* El <summary> hace de boton: se le quita el triangulito para que lo parezca
   del todo. NO se esconde al abrir, aunque lo parezca: este dialogo pone su
   velo de fondo en el `::before` del propio summary, y escondiendolo
   desaparece el velo y con el la unica forma de cerrar pulsando fuera. */
.venta-apagar > summary { list-style: none; }
.venta-apagar > summary::-webkit-details-marker { display: none; }
.venta-apagar form { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.venta-apagar input[type=text] { width: auto; min-width: 12rem; flex: 1; }
/* «¿Qué apagamos?»: la comida, la cena o todo.
   Fila entera (`flex: 1 0 100%`) y no un hueco mas de la linea: compartiendo
   fila con el motivo y con «Apagar», el boton queda al lado de los redondeles
   y se pulsa antes de haber elegido nada. La eleccion va ARRIBA y sola. */
.venta-apagar .que-apagar {
  flex: 1 0 100%;
  display: flex; flex-wrap: wrap; gap: .15rem 1.1rem;
  margin: 0; padding: 0; border: 0;
}
.venta-apagar .que-apagar legend { float: left; width: 100%; padding: 0; }


/* Desbloqueado, el bloque entero se agarra: mover es mantener pulsado encima.
   `touch-action: none` para que el dedo no desplace la pagina mientras tanto;
   solo desbloqueado, que si no la pantalla del dia dejaria de poder hacer
   scroll con el dedo.

   `user-select: none` NO ES COSMETICA: sin ella, mantener pulsado sobre un
   texto empieza una SELECCION, el navegador se queda con el gesto y manda un
   `pointercancel`. El cursor cambiaba a mano cerrada y el bloque no se movia,
   que es exactamente lo que se veia. */
.tablero.desbloqueado .bloque {
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.tablero.desbloqueado .bloque.moviendo { cursor: grabbing; }

/* COLOCANDO NO SE OPERA. Mientras la pantalla esta desbloqueada, lo de dentro
   de los bloques deja de responder: se esta ordenando la pantalla, no usando
   el restaurante.
   No es una comodidad, son dos cosas:
     - La pastilla «Mover» esta en el CENTRO del bloque, que es justo donde
       suele estar el boton. Pulsar el centro pulsaba la pastilla y el boton
       parecia roto. Paso con «Apagar online» y con «Anadir reserva».
     - Y al reves, lo que si llegaba: colocando bloques se podia apagar la
       venta por internet de un clic sin querer.
   Los mandos de colocar -pastilla, nombre, x y tirador- van FUERA de
   `.bloque-cuerpo`, asi que siguen respondiendo. */
.tablero.desbloqueado .bloque-cuerpo { pointer-events: none; }

/* UN BLOQUE ENCIMA DE OTRO NO PUEDE APAGARLO.
   Los bloques se colocan libremente y se solapan: uno alto y medio vacio queda
   por encima del de al lado, y aunque no se vea nada ahi, su CAJA se comia los
   clics. Se pulsaba un boton o una mesa del plano y no pasaba nada, sin ninguna
   pista de por que -no hay nada que ver, el culpable es transparente-.
   Bloqueada la pantalla la caja deja de interceptar y solo responde lo que
   tiene dentro. Desbloqueada NO se aplica: ahi la caja entera tiene que
   recibir el gesto para poder agarrarla y moverla. */
.tablero.con-guion:not(.desbloqueado) .bloque { pointer-events: none; }
.tablero.con-guion:not(.desbloqueado) .bloque > * { pointer-events: auto; }

/* EL LIENZO DEL PLANO NO ES UNA SUPERFICIE, son las mesas.
   Ocupa un rectangulo grande y casi todo el es hueco entre mesas. Encima de
   otro bloque, ese hueco se comia sus clics: se veia el boton perfectamente
   -el lienzo es transparente- y no respondia.
   Paso de verdad: el plano quedo colocado sobre «Apagar online» y «Anadir
   reserva por telefono», y los dos dejaron de funcionar sin ninguna pista.
   Ahora solo responden las piezas; el hueco deja pasar. */
.tablero .plano.solo-lectura { pointer-events: none; }
.tablero .plano.solo-lectura .pieza { pointer-events: auto; }

/* Dos bloques pisandose. Lo que se ve luego es que algo «no hace nada», porque
   lo que estorba es transparente. Aqui se ve mientras se coloca, que es cuando
   se puede arreglar. */
.tablero.desbloqueado .bloque.se-pisa {
  outline: 2px solid var(--rojo); outline-offset: 2px;
}
.tablero.desbloqueado .bloque.se-pisa .bloque-nombre { background: var(--rojo); }
.tablero.desbloqueado .bloque.se-pisa .bloque-nombre::after {
  content: " · encima de otro";
  font-weight: 500;
}

/* EL NOMBRE, SOLO MIENTRAS SE COLOCA. Es cuando hace falta -se agarra una caja
   y hay que saber cual- y es justo cuando no molesta, porque no se esta
   leyendo el contenido. En la pantalla normal desaparece y no gasta ni un
   pixel. Va flotando, sin ocupar sitio en el bloque. */
/* EL AGARRE DEL CENTRO. Mantener pulsado en cualquier sitio sigue valiendo,
   pero obliga a acertar en un hueco sin controles y a esperar; en un bloque
   lleno de desplegables eso es incomodo. Esta zona es grande, esta siempre en
   el mismo sitio -el centro- y arrastra al momento.

   `pointer-events: auto` explicito: hereda de un contenedor que los apaga en
   el nombre, y sin esto no recibiria el gesto. */
.bloque-mover { display: none; }
.tablero.desbloqueado .bloque-mover {
  display: flex; align-items: center; justify-content: center; gap: .3rem;
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 4; pointer-events: auto;
  min-width: 6.5rem; padding: .5rem .9rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--acento) 92%, transparent);
  color: var(--sobre-relleno); font-size: .85rem; font-weight: 600;
  box-shadow: 0 2px 10px rgb(0 0 0 / .25);
  cursor: grab; touch-action: none; user-select: none;
}
.tablero.desbloqueado .bloque-mover:hover { filter: brightness(1.08); }
.tablero.desbloqueado .bloque.moviendo .bloque-mover { cursor: grabbing; }

.bloque-nombre { display: none; }
.tablero.desbloqueado .bloque-nombre {
  display: block; position: absolute; top: 2px; left: 4px; z-index: 3;
  padding: .1rem .4rem; border-radius: 999px;
  background: var(--acento); color: var(--sobre-relleno);
  font-size: .7rem; font-weight: 600; letter-spacing: .01em;
  pointer-events: none; white-space: nowrap;
}
.tablero .bloque.moviendo { opacity: .75; z-index: 5; }

/* Sin JavaScript los bloques no se posicionan: se apilan y se ve todo. Es la
   red de seguridad, y por eso la posicion absoluta la enciende `con-guion`. */
.tablero:not(.con-guion) .bloque {
  position: static; width: auto !important; height: auto !important;
  margin-bottom: 1.25rem;
}

/* La barra ya no es una barra: es la × sola, flotando en la esquina. Antes
   ocupaba una linea por bloque para un rotulo que ya se sabe. `position:
   absolute` para que no gaste alto: en una pantalla con diez bloques, diez
   lineas de titulo son media pantalla.

   `[hidden]` PRIMERO Y GANANDO. Una regla `display: flex` a secas pisa el
   `hidden` del HTML -que es solo `display: none` del navegador-, y la × salia
   en la pantalla normal, donde no hay ningun manejador escuchando: un boton
   de borrar que no borra nada. Paso al quitar el rotulo. */
.bloque-barra[hidden] { display: none; }
.bloque-barra {
  position: absolute; top: 2px; right: 2px; z-index: 3;
  display: flex; align-items: center;
}
.bloque-boton {
  min-width: 26px; min-height: 26px; padding: 0 .3rem;
  background: var(--superficie); color: var(--texto-suave);
  border: 1px solid var(--borde); border-radius: 6px;
  font: inherit; font-size: .75rem; line-height: 1; cursor: pointer;
}
.bloque-boton:hover { border-color: var(--acento); color: var(--acento); }

/* El tirador de la esquina, igual que en el plano. Solo desbloqueado: si se
   viera siempre, seria un adorno que invita a arrastrar y no hace nada. */
.bloque-tirador { display: none; }
.tablero.desbloqueado .bloque {
  outline: 1px dashed var(--borde); outline-offset: 2px;
}
.tablero.desbloqueado .bloque-tirador {
  display: block; position: absolute; right: 0; bottom: 0;
  width: 16px; height: 16px; cursor: nwse-resize; touch-action: none;
  background: var(--acento); border-radius: 3px 0 var(--radio) 0; opacity: .55;
}
.tablero.desbloqueado .bloque-tirador:hover { opacity: 1; }

.tablero-pie {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
.tablero-ocultos { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  color: var(--texto-suave); font-size: .85rem; }
.tablero-aviso { color: var(--acento); font-size: .85rem; font-weight: 600; }
/* El mismo aviso dicho de dos maneras: con raton se arrastra, con el dedo se
   sube y se baja. Cual de las dos se ve lo decide el ancho, abajo. */
.solo-dedo { display: none; }
/* Con la pantalla bloqueada los escondidos se nombran pero no se pueden traer:
   se ve QUE falta, que es lo que no se veia antes. */
.tablero-escondido {
  font-size: .85rem; color: var(--texto-suave);
  border: 1px dashed var(--borde); border-radius: 6px; padding: .15rem .5rem;
}

/* En pantalla estrecha se apilan y no se coloca nada: con el telefono en la
   mano hace falta el orden util, no reorganizar la pantalla.

   700 Y NO 900 NI 767, y ese numero es el que hacia que una tableta se viera
   distinta de un ordenador. Una tableta de pie mide 768-834 px, asi que 900
   la apilaba: la misma pantalla se veia de dos formas segun el aparato, que
   es justo lo que no se quiere en la barra.

   Y 767 tampoco vale, MEDIDO: una ventana de 768 px con barra de desplazamiento
   clasica declara 753 px a la consulta de medios -la barra se descuenta-, o sea
   que la tableta volvia a caer dentro del corte por quince pixeles. 700 deja
   fuera cualquier tableta aunque le sobre barra, y dentro cualquier telefono
   de pie (360-430) y los pequeños tumbados (667).

   A cambio, un telefono grande tumbado (780-930) se ve como un ordenador. Se
   asume: en la barra el telefono se lleva de pie. */
@media (max-width: 700px) {
  .tablero, .tablero.con-guion {
    height: auto !important;
    /* Columna flexible para poder imponer el orden de abajo. Sin esto, el
       apilado seguiria el orden en que estan GUARDADOS los bloques, que es el
       que cada uno haya dejado en su monitor: en el movil eso puede dejar el
       resumen del dia por delante de las reservas. */
    display: flex; flex-direction: column;
  }
  .tablero .bloque, .tablero.con-guion .bloque {
    position: static; width: auto !important; height: auto !important;
    left: auto !important; top: auto !important; margin-bottom: 1.25rem;
    outline: none;
  }
  /* EL ORDEN LO PONE CADA UNO, y por eso ya no hay aqui una regla por bloque.
     Estuvo asi -`.bloque-fecha { order: 0 }` y ocho lineas mas- y el efecto
     era que la pantalla del telefono era la misma para todo el mundo: se podia
     colocar la del ordenador al gusto y la del movil no se tocaba.

     Ahora el puesto viaja en `--orden-movil`, que pone la plantilla desde la
     colocacion guardada de cada persona, y se cambia con las flechas del modo
     editar. El 9 de reserva es para un bloque que llegue sin puesto: al final,
     que es donde debe estar lo accesorio. */
  .tablero .bloque { order: var(--orden-movil, 9); }

  /* La barra para colocar la pantalla del telefono: subir, bajar y quitar.
     Solo sale con la pantalla desbloqueada -la pone `tablero.js`- asi que
     aqui no hace falta condicion ninguna.

     Pegada arriba del bloque y con el nombre a la izquierda: hay que saber
     QUE se esta subiendo, y en el telefono los bloques no llevan rotulo. */
  .orden-movil {
    display: flex; align-items: center; gap: .35rem;
    margin: 0 0 .5rem; padding: .35rem .5rem;
    background: var(--acento-suave); border-radius: var(--radio);
  }
  .orden-movil-nombre {
    flex: 1; min-width: 0; font-size: .9rem; font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* Cuadradas y de dedo. 44 px es el minimo de las guias para algo que se
     pulsa, y estas se pulsan varias veces seguidas para subir un bloque. */
  .orden-movil .boton {
    flex: none; min-width: 44px; min-height: 44px;
    padding: 0; font-size: 1.1rem; line-height: 1;
  }
  /* Deshabilitada, NO escondida: el primero de la lista no puede subir, pero
     si desaparece su flecha las de los demas bailan de sitio y se pulsa la
     que no era. */
  .orden-movil .boton:disabled { opacity: .3; }
  /* LA BARRA DE AGARRE Y EL TIRADOR NO, porque en el telefono no se arrastra
     ni se estira: los bloques van en columna a todo el ancho.

     PERO EL PIE SÍ. Estaba escondido con los otros dos, y con él se escondía
     «Recolocar la pantalla», que es lo ÚNICO que enciende el modo de colocar.
     O sea que las flechas de subir y bajar —que existen y son para el
     teléfono— no había forma de sacarlas desde un teléfono: había que
     desbloquear en un ordenador y volver al móvil. Quien lleva la barra no
     tiene un ordenador delante. */
  .bloque-barra, .bloque-tirador { display: none !important; }

  /* En columna y con los botones de dedo: aquí el pie no es una franja de
     herramientas al lado de un tablero ancho, es lo último de la pantalla. */
  .tablero-pie {
    flex-direction: column; align-items: stretch; gap: .5rem;
  }
  .tablero-pie .boton { min-height: 44px; }
  /* «Puedes mover y estirar los bloques» es del ratón: aquí se sube, se baja y
     se quita. Se cambia el texto, no se calla. */
  .solo-raton { display: none; }
  .solo-dedo { display: revert; }

  /* --- Y SE DESHACE LA COMPACTACION ---------------------------------------
     Con el telefono la pantalla se veia entera pero MUY PEQUENA, y no era el
     zoom ni el `meta viewport`: es que los bloques llevan una capa de estilos
     para caber apretados en un tablero ancho -letra al 72%, barras de cuatro
     pixeles, huecos de una decima-. Ahi tiene sentido, porque el bloque mide
     300 px al lado de otros cinco. En el telefono cada bloque ocupa el ancho
     ENTERO y esa compactacion no compra nada: solo encoge.

     Y encoge en cadena, que es lo que la volvia ilegible. MEDIDO en una
     pantalla de 375: el `h3` del turno a 11,5 px y el «0 pax» de dentro a
     NUEVE COMA SEIS, porque un `small` es el 80% de su padre y su padre ya
     venia al 72%. En el plano igual: el nombre de la mesa a 11,8 y el «pax 4»
     a 10. Cada regla por separado parece razonable; multiplicadas, no.

     Aqui se devuelven a su tamano normal. Nada baja de 13 px. */
  .bloque-ocupacion .ocupacion-turno h3 { font-size: .95rem; margin-bottom: .5rem; }
  .bloque-ocupacion .ocupacion-turno h3 small { font-size: .9em; }
  .bloque-ocupacion .franja { font-size: .9rem; gap: .5rem; }
  .bloque-ocupacion .franja-hora { width: 3rem; }
  .bloque-ocupacion .franja-barra { height: .55rem; }
  .bloque-ocupacion .franja-pax { width: 3rem; }

  /* El rotulo de la mesa. Sigue mandando `--texto-tam` -el tamano que eligio
     quien monto la sala, mesa a mesa-, lo que sube es el punto de partida. */
  .pieza-texto { font-size: calc(.95rem * var(--texto-tam, 100) / 100); }
  .pieza-texto small { font-size: .85em; }

  /* Lo que se lee de verdad con el telefono en la mano. */
  .apunte { font-size: .95rem; }
  .boton.pequeno { font-size: .9rem; }
  .casilla small { font-size: .85rem; }
}

/* El precio de antes, cuando hay recargo. Tachado y en pequeño: lo que manda
   es el precio de ahora, y esto solo explica de dónde viene. */
.precio-antes { text-decoration: line-through; color: var(--texto-suave); }

/* El bloque de recargos del formulario de un evento. Va apartado del resto de
   campos: son ajustes opcionales y no hay que rellenarlos para crear nada. */
.recargos {
  border: 1px solid var(--borde); border-radius: var(--radio);
  padding: .9rem 1rem; margin-top: .5rem;
}
.recargos h4 { margin: 0 0 .3rem; font-size: .95rem; }
.recargos .apunte { margin: .3rem 0 .6rem; }

/* El cartel de un evento. `max-width: 100%` para que una imagen grande no
   desborde la tarjeta, y `height: auto` para no deformarla. */
.cartel-evento-grande {
  display: block; width: 100%; height: auto;
  border-radius: var(--radio); margin-bottom: 1rem;
}
.cartel-evento { margin-top: 1rem; }
.cartel-evento h4 { margin: 0 0 .4rem; font-size: .9rem; }
.cartel-previo {
  display: block; max-width: 260px; height: auto;
  border: 1px solid var(--borde); border-radius: var(--radio);
  margin-bottom: .5rem;
}

/* --- La puerta: leer entradas con la camara -------------------------------
   Esto se usa DE PIE, con una mano, de noche y con gente delante. Todo lo de
   aqui sale de ahi: los objetivos son grandes, el resultado es enorme y el
   color nunca va solo. */
.puerta { display: flex; flex-direction: column; gap: .6rem; height: 100%; }

/* Los dos modos, como dos mitades de una barra. Radios de verdad debajo: lo
   que se pinta es la etiqueta, y el navegador se ocupa de que solo haya uno. */
.puerta-modos { display: flex; gap: .3rem; }
.puerta-modo { flex: 1; margin: 0; }
.puerta-modo input { position: absolute; opacity: 0; pointer-events: none; }
.puerta-modo span {
  display: flex; align-items: center; justify-content: center;
  min-height: 48px; padding: .4rem;
  border: 2px solid var(--borde); border-radius: var(--radio);
  font-weight: 600; cursor: pointer;
}
/* DOS SEÑALES: el relleno y el peso del texto. Con el color solo, quien no lo
   distingue no sabe si esta leyendo entradas o salidas — y ahi la diferencia
   es dejar pasar o no. */
.puerta-modo input:checked + span {
  background: var(--acento); color: var(--sobre-relleno);
  border-color: var(--acento); font-weight: 700;
}
.puerta-modo input:focus-visible + span {
  outline: 3px solid var(--ambar); outline-offset: 2px;
}

.puerta-camara { display: flex; flex-direction: column; gap: .4rem; }
/* El video se recorta al ancho del bloque. `object-fit: cover` y no `contain`:
   con bandas negras a los lados, el QR sale mas pequeño y se lee peor. */
.puerta-camara video {
  width: 100%; max-height: 15rem; object-fit: cover;
  background: #000; border-radius: var(--radio);
}

.puerta-mano { display: flex; gap: .4rem; }
.puerta-mano input { flex: 1; min-width: 6rem; text-transform: uppercase; }

/* El resultado. Grande a proposito: se lee de un vistazo mientras se mira a la
   persona, no acercando la cara a la pantalla. */
.puerta-resultado {
  margin: 0; padding: .7rem .8rem; border-radius: var(--radio);
  border-left: 9px solid transparent;
  font-size: 1.05rem; font-weight: 600; line-height: 1.35;
}
.puerta-resultado:empty { display: none; }
/* Verde pasa, rojo no pasa, ambar «mira esto». Y el texto de dentro ya dice
   cual es cual: el color acompaña, nunca informa solo. */
.puerta-admitida, .puerta-vuelve, .puerta-salida {
  background: color-mix(in srgb, var(--verde) 14%, transparent);
  border-left-color: var(--verde); color: var(--verde);
}
.puerta-repetida, .puerta-anulada, .puerta-sin_pagar, .puerta-desconocida {
  background: color-mix(in srgb, var(--rojo) 14%, transparent);
  border-left-color: var(--rojo); color: var(--rojo);
}
/* «Es un vale» va en ambar y no en rojo, y la diferencia importa: quien lo
   trae tiene un regalo de verdad, pagado, que sencillamente no se valida aqui.
   En rojo, la puerta le dice que su regalo no sirve. */
.puerta-no_estaba, .puerta-es_vale, .puerta-error {
  background: color-mix(in srgb, var(--ambar) 16%, transparent);
  border-left-color: var(--ambar); color: var(--texto);
}

/* Los eventos del dia, en su bloque de la pantalla del dia. */
.eventos-dia { list-style: none; margin: 0; padding: 0; }
.eventos-dia li {
  padding: .45rem 0; border-bottom: 1px solid var(--borde); font-size: .9rem;
}
.eventos-dia li:last-child { border-bottom: none; }
.eventos-dia .apunte { margin: 0; }
.evento-nombre { font-weight: 500; }

/* La cartelera de eventos en la pagina publica del restaurante. */
.cartelera { list-style: none; margin: 0; padding: 0; }
.cartelera li {
  display: flex; flex-direction: column; gap: .1rem;
  padding: .6rem 0; border-bottom: 1px solid var(--borde);
}
.cartelera li:last-child { border-bottom: none; }
.cartelera .apunte { margin: 0; }
/* La fecha manda sobre el nombre, y no al reves. Esta lista sale igual elijas
   el dia que elijas en el formulario de arriba, y con la fecha en gris y
   pequena se leia como «lo que hay el dia que he elegido». */
.cartelera-fecha {
  display: block; font-size: .8rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--acento);
}
.cartelera-nombre { font-weight: 600; }

/* --- La portada del producto ----------------------------------------------
   Mas ancha que una pagina de reservar mesa, que va estrecha a proposito para
   leerse en el movil. Se apoya en las tarjetas que ya existen en vez de
   inventarse un juego de estilos aparte: asi cuando cambie la paleta, cambia
   con todo lo demas. */
.contenido.portada { max-width: 1000px; }

.bloque-portada { margin: 0 0 3rem; }
.bloque-portada > h2 {
  margin: 0 0 .4rem; font-size: 1.5rem;
  padding-bottom: .4rem; border-bottom: 1px solid var(--borde);
}
.bloque-portada > h3 { margin: 1.5rem 0 .6rem; font-size: 1rem; }

.portada-entrada { text-align: center; margin-bottom: 3.5rem; }
.portada-entrada h1 {
  font-size: clamp(1.6rem, 4.5vw, 2.4rem); line-height: 1.15;
  margin: 1rem 0 .75rem;
}
.portada-lema {
  max-width: 44rem; margin: 0 auto 1.5rem;
  font-size: 1.05rem; color: var(--texto-suave);
}
.portada-botones {
  display: flex; gap: .6rem; flex-wrap: wrap; justify-content: center;
  margin: 0 0 1rem;
}
/* `.boton.grande` nace a todo el ancho: se hizo para el boton de llamar del
   movil. Aqui son dos en una fila, asi que se le devuelve su ancho. */
.portada-botones .boton.grande {
  width: auto; margin-top: 0; padding: .8rem 1.4rem;
}
@media (max-width: 480px) {
  .portada-botones { flex-direction: column; }
  .portada-botones .boton.grande { width: 100%; }
}
/* Rejilla que se adapta sola: sin puntos de corte escritos a mano, que son los
   que luego se quedan viejos al anadir una tarjeta mas. */
.portada-rejilla {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.portada-rejilla .tarjeta { margin: 0; }
.portada-rejilla .apunte { margin: 0; }

.portada-demo {
  border: 1px solid var(--acento); border-radius: var(--radio);
  padding: 1.5rem; text-align: center;
  background: color-mix(in srgb, var(--acento) 5%, transparent);
}
.portada-demo > h2 { border-bottom: none; }

/* --- Ver la pantalla como en un movil -------------------------------------
   Un boton del tablero para montar la colocacion del telefono sin sacarlo del
   bolsillo. Ver `app/static/modo_pantalla.js`.

   EL MODO TABLETA SE QUITO. La pantalla del dia se ve igual en una tableta que
   en un ordenador -misma colocacion, misma rejilla, mismos bloques-, asi que
   aquello era un boton para ver lo que ya se estaba viendo. En el movil si
   cambia: los bloques se apilan.

   ES LA PAGINA DE VERDAD DENTRO DE UN MARCO DE 390 px, no una imitacion.

   Antes se le ponia una clase a la pagina y se estrechaba el contenido. El
   apilado de los bloques si cambiaba -estaba duplicado a mano, regla por
   regla- pero nada mas, porque toda la capa responsive del panel va con
   `@media`, y una `@media` mira la VENTANA: una ventana de ordenador lo sigue
   siendo por mucho que se estreche lo de dentro. Resultado: en la vista previa
   salia el menu de ORDENADOR desplegado en seis filas, las fichas sin plegar y
   la letra sin ninguno de los ajustes del telefono. Se enseñaba algo peor que
   el producto.

   Un marco tiene su propia ventana, asi que las `@media` se aplican solas. No
   queda una sola regla duplicada que se pueda quedar desfasada, que era el
   otro problema: habia que acordarse de tocar las dos.

   Ver `app/static/modo_pantalla.js`. Hizo falta pasar la cabecera de marcos de
   `DENY` a `SAMEORIGIN`. */
.velo-telefono {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, .55);
}
.marco-telefono {
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  box-shadow: 0 1.25rem 3rem rgba(0, 0, 0, .35);
  padding: .6rem;
  max-height: 100%; display: flex; flex-direction: column; gap: .5rem;
}
.marco-telefono-barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; font-size: .9rem; color: var(--texto-suave);
}
/* Fondo blanco propio y sin borde: dentro va una pagina entera y tiene que
   verse como se ve en el aparato, no teñida por lo de detras. */
.pantalla-telefono {
  border: 0; border-radius: 6px; display: block;
  background: var(--fondo);
  /* Que quepa en un portatil bajito: si no cabe a lo alto, se encoge y se
     desplaza por dentro, que es lo que hace un telefono de todos modos. */
  max-height: calc(100vh - 6rem);
  max-width: calc(100vw - 4rem);
}

.modo-pantalla .boton { width: 100%; }
.modo-pantalla .apunte { margin: .5rem 0 0; }

/* Las dos columnas de la pantalla del dia las hace ahora el TABLERO, con las
   coordenadas de cada bloque. Lo que queda aqui es lo de dentro de dos de esos
   bloques: la lista de reservas y el plano. */
.servicio-lista { display: flex; flex-direction: column; gap: .6rem; }

/* Elegir servicio encima de la lista: Comida, Cena, Todo el dia.
   Pegajoso arriba (`sticky`) porque la lista de un sabado son cuarenta fichas
   y el selector tiene que seguir a mano despues de bajar treinta. */
/* EL RENGLON DE PESTAÑAS. Los dos grupos -servicio y por donde va- en la misma
   linea: son dos maneras de filtrar la misma lista y en dos renglones se
   comian dos dedos de alto del bloque para nueve botones que caben en uno.
   El hueco entre grupos es mayor que el de dentro de cada grupo: es lo que
   dice que son dos preguntas distintas sin dibujar una raya.
   Pegajoso AQUI y no en cada grupo: asi lo que se queda clavado al bajar por
   la lista es un renglon, no dos. */
.barra-pestanas {
  position: sticky; top: 0; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem 1.1rem;
  padding: .35rem 0 .6rem; background: var(--fondo);
}
.elegir-servicio,
.elegir-estado {
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
}
.pestana-servicio {
  padding: .3rem .75rem; border: 1px solid var(--borde); border-radius: 999px;
  color: var(--texto-suave); text-decoration: none;
  font-size: .85rem; font-weight: 600; white-space: nowrap;
  min-height: 32px; display: inline-flex; align-items: center;
}
.pestana-servicio:hover { border-color: var(--acento); color: var(--acento); }
.pestana-servicio.puesta {
  background: var(--acento); border-color: var(--acento);
  /* Nunca blanco a mano: hay casas con el acento en amarillo. */
  color: var(--sobre-relleno);
}
/* La cifra dentro de la pestaña -cuantas hay ahi detras-. Va en una pildora
   propia y no como texto suelto para que se lea de un vistazo sin tener que
   leer la palabra: en un servicio se mira la cifra, no el rotulo. */
.pestana-cifra {
  margin-left: .35rem; padding: 0 .35rem; border-radius: 999px;
  background: var(--fondo); color: var(--texto-suave);
  font-variant-numeric: tabular-nums; font-size: .8em;
}
.pestana-servicio.puesta .pestana-cifra {
  /* Sobre el acento, la pildora se pinta con el mismo color del texto de
     encima a media opacidad: asi vale con cualquier acento, tambien los
     claros, sin escribir un color a mano. */
  background: color-mix(in srgb, var(--sobre-relleno) 25%, transparent);
  color: var(--sobre-relleno);
}

/* --- La fecha del dia, DENTRO DE LA CABECERA -----------------------------
   Estaba en un titulo suyo, en una franja de lado a lado del monitor para
   cuatro palabras, y esa franja era justo lo que impedia subir los bloques del
   tablero hasta arriba. Aqui va en la barra de cabecera, en el hueco que ya
   habia entre el nombre del local y el menu.

   Sigue siendo el `h1`, asi que hay que quitarle el tamano y los margenes de
   fabrica del navegador: aqui es un rotulo, no un titular. */
.titulo-dia {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem;
  margin: 0; font-size: 1rem; font-weight: 600;
}
/* Un envoltorio propio para que el nombre del festivo no se separe del dia al
   repartir el hueco. `min-width: 0` para que encoja antes de partir la barra. */
.titulo-fecha { min-width: 0; }
.titulo-pulso { display: flex; flex-wrap: wrap; gap: .75rem; align-items: baseline; }
.pulso-dato {
  font-size: .85rem; font-weight: 400; color: var(--texto-suave);
  text-decoration: none; white-space: nowrap;
  padding: .15rem .5rem; border-radius: 999px; border: 1px solid transparent;
}
.pulso-dato strong { font-variant-numeric: tabular-nums; color: var(--texto); }
.pulso-dato:hover { border-color: var(--borde); color: var(--acento); }

/* El plano cabe en media pantalla; sin esto se iria a barra de desplazamiento
   siempre, porque el general pide 620px de ancho minimo. */
.servicio-sala .plano { min-width: 380px; }

@media (max-width: 620px) {
  /* En el movil el plano se encoge, pero NO hasta cero.
     Va DESPUES de la regla de arriba: misma especificidad, gana la ultima.

     Antes ponia `min-width: 0` para que el plano cupiera entero, y el motivo
     escrito era que si no «el contenido se iria de lado y habria que arrastrar
     la pagina». Eso ya no es verdad: el plano vive dentro de `.plano-marco`,
     que tiene `overflow-x: auto`, asi que lo que se arrastra es el plano
     dentro de su caja y la pagina no se mueve. MEDIDO: desborde de pagina 0.

     Y encogerlo del todo tenia un precio que no se vio: las piezas se colocan
     en PORCENTAJE, asi que a 320 px de pantalla el plano quedaba en 272 y una
     mesa del 7,5% en VEINTE PIXELES de lado. Sentar a alguien tocando su mesa
     es la accion principal de esta pantalla y con el dedo no se acierta.

     480 sale de la cuenta al reves: 7,5% de 480 son 36 px, que ya se pulsan, y
     con la proporcion de fabrica -1200x600- el plano queda en 240 de alto, que
     cabe en un movil de pie sin comerse la lista de reservas. */
  .servicio-sala .plano { min-width: 480px; }
}

.controles-sala { display: flex; gap: .75rem; flex-wrap: wrap; align-items: end; }
.linea-control { margin: 0; }
.linea-control > span { font-size: .8rem; }

.cifras.compactas { margin: .6rem 0 .4rem; gap: .5rem; }
.cifras.compactas .cifra { flex-basis: 80px; padding: .5rem .7rem; }
.cifras.compactas .cifra strong { font-size: 1.2rem; }

/* Las mesas del plano son botones para poder pincharlas con el teclado. Hay
   que devolverles el aspecto que tenian como <div>. */
.plano button.pieza {
  font: inherit; color: inherit; padding: 0; cursor: pointer;
}
/* LA MESA QUE SE ACABA DE MARCAR, en el plano.
 *
 * Tres pixeles de borde no se ven: esto se mira de pie, a un metro de la
 * pantalla y con la sala llena, que es cuando hace falta —«¿dónde está esa
 * reserva?»—. Cinco, y con un halo alrededor para que despegue del resto de
 * mesas aunque caiga sobre una zona con mucho dibujo.
 *
 * Y PARPADEA. Es lo único de esta pantalla que parpadea, y por eso funciona:
 * en un plano con cuarenta mesas quietas, la que se mueve se encuentra sin
 * buscarla. Tres pulsos y se queda fija: un parpadeo que no para deja de ser
 * un aviso y pasa a ser una molestia que no se puede apagar.
 *
 * `prefers-reduced-motion` lo respeta y deja solo el borde grueso. Para quien
 * tiene vértigo o migraña, una cosa que late en pantalla no es un detalle. */
.pieza.mesa.resaltada {
  outline: 5px solid var(--ambar); outline-offset: 2px; z-index: 6;
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--ambar) 30%, transparent);
}

/* PARPADEA SOLO LA MESA QUE TIENE RESERVA.
 *
 * El latido sirve para una cosa: pulsas la ficha de una reserva y encuentras
 * su mesa en el plano sin buscarla. Una mesa LIBRE marcada no es eso —es la
 * que se acaba de pulsar para apuntar a alguien, y ya se sabe cuál es porque
 * la acabas de pulsar—: ahí el parpadeo no señala nada y encima distrae
 * mientras se rellena el formulario.
 *
 * `:not([data-libre])` es exactamente esa distinción: `data-libre` lo pone la
 * plantilla en las mesas que se pueden usar para apuntar una reserva. */
.pieza.mesa.resaltada:not([data-libre]) {
  animation: latido-mesa .6s ease-in-out 3;
}
@keyframes latido-mesa {
  0%, 100% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--ambar) 30%, transparent); }
  50% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--ambar) 55%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .pieza.mesa.resaltada { animation: none; }
}

.ficha-reserva {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); padding: .7rem .85rem;
  cursor: pointer; scroll-margin: 1rem;
}
.ficha-reserva:hover { border-color: color-mix(in srgb, var(--acento) 45%, var(--borde)); }
.ficha-reserva:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
/* LA FICHA QUE SE ACABA DE MARCAR.
 *
 * El borde era de 1px con un halo de 2: en una lista de treinta fichas todas
 * con borde, esa diferencia no se ve. Se sube a 3 y el halo a 4, que es lo que
 * hace falta para encontrarla sin leerlas todas.
 *
 * `border-width` explícito y no solo el color: subir el grosor mueve la ficha
 * dos píxeles, y en una lista eso se nota como un salto. Se compensa con el
 * padding para que la caja mida lo mismo marcada que sin marcar. */
.ficha-reserva.resaltada {
  border-color: var(--ambar); border-width: 3px;
  padding: calc(.7rem - 2px) calc(.85rem - 2px);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ambar) 35%, transparent);
}
/* --- LA BANDA DE COLOR DE CADA ESTADO ------------------------------------
   El estado se lee de un vistazo, de pie y a un metro de la pantalla, mientras
   se pasa el servicio: el color es lo unico que se ve a esa distancia.

   El COLOR lo pone el restaurante en Ajustes y llega en `--color-estado-*`
   desde `base_panel.html`. Lo de aqui es el COMO -donde va la banda, que
   gruesa, si ademas se atenua-, y esta separado a proposito: retocar el
   aspecto no deberia obligar a tocar Python.

   Banda a la izquierda y no fondo entero: un fondo de color detras de un texto
   gris obliga a mirar dos veces para leerlo, y estas fichas se leen mucho.

   NUEVE PIXELES, y antes eran cinco. A un metro de la pantalla y de reojo, una
   banda de cinco no se distingue del borde de la ficha: hay que acercarse a
   mirarla, que es justo lo que no se puede hacer pasando un servicio. Nueve se
   ve sin buscarla y sigue siendo una banda, no un fondo. */
/* EL COLOR DEL ESTADO, UNA SOLA VEZ. Cada ficha se guarda el suyo en
   `--tono-estado` y de ahi tiran la banda de la izquierda y el estado de
   dentro. Antes cada sitio repetia los ocho casos, y por eso el desplegable
   del estado -lo que se mira y se toca con la ficha abierta- se habia quedado
   gris mientras la banda de al lado iba de color. */
.ficha-reserva { border-left: 9px solid transparent; --tono-estado: var(--texto-suave); }
.ficha-reserva.estado-esperando_pago { --tono-estado: var(--color-estado-esperando_pago); }
.ficha-reserva.estado-pendiente { --tono-estado: var(--color-estado-pendiente); }
.ficha-reserva.estado-confirmada { --tono-estado: var(--color-estado-confirmada); }
.ficha-reserva.estado-sentada { --tono-estado: var(--color-estado-sentada); }
.ficha-reserva.estado-completada { --tono-estado: var(--color-estado-completada); }
.ficha-reserva.estado-cancelada { --tono-estado: var(--color-estado-cancelada); }
.ficha-reserva.estado-no_show { --tono-estado: var(--color-estado-no_show); }
.ficha-reserva.estado-caducada { --tono-estado: var(--color-estado-caducada); }
.ficha-reserva[class*="estado-"] { border-left-color: var(--tono-estado); }

/* El estado, dentro de la ficha, del color del estado.
   `!important` en el borde NO es un capricho: la regla general de los campos
   -`select { border: 1px solid var(--borde) }`- se escribe despues en la hoja
   y con la misma especificidad, asi que sin esto gana ella y el desplegable
   vuelve a salir gris. Es el mismo empate que ya paso con la caja roja del
   interruptor de la venta. */
.ficha-reserva select[name="estado"],
.ficha-reserva .estado-texto {
  color: var(--tono-estado); font-weight: 600;
  border: 1px solid var(--tono-estado) !important;
  border-radius: .4rem; padding: .2rem .4rem;
  background: color-mix(in srgb, var(--tono-estado) 12%, var(--fondo));
}
.ficha-reserva .estado-texto { display: inline-block; }

/* SE LE ESTÁ ACABANDO EL TIEMPO.
   La reserva de las 21:00 con un cuarto de hora de cortesía hay que llamarla a
   las 21:10; a las 21:15 se ha perdido. Entre esos dos momentos está todo lo
   que se puede hacer, y en la lista se veía igual que la de dentro de dos
   horas. La marca la pone `retraso.js`, que es quien sabe qué hora es.

   Ámbar y no rojo: nadie ha hecho nada mal, es algo que hay que mirar. */
/* Dos campos en el hueco de uno. Para los ajustes que son la misma decision
   partida en dos -«a los cuantos minutos» y «con cronometro»-: en dos filas
   pareceria que no tienen nada que ver. */
/* LAS PREGUNTAS AL CLIENTE, EN EL ALTA POR TELEFONO.
   En rejilla y apretadas, no en columna como en la pagina publica: esto lo
   rellena alguien del equipo con el telefono en la oreja, y cada linea de mas
   es tiempo con el cliente esperando. Las casillas caben de dos en dos o de
   tres en tres segun el ancho; lo que pide texto ocupa la fila entera. */
.extras-alta {
  display: grid; gap: .35rem .9rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin: .4rem 0; padding: .6rem .8rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: color-mix(in srgb, var(--texto-suave) 4%, transparent);
}
.extras-alta legend {
  font-size: .78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--texto-suave); padding: 0 .3rem;
}
.extras-alta .casilla span { font-size: .88rem; }
/* La casilla y su detalle, juntos y a lo ancho: «alergias» sin poder decir
   cuales no sirve de nada, y es el campo que mas se rellena. */
.extras-alta .extra-con-detalle {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
.extras-alta .extra-con-detalle .detalle-extra { flex: 1; min-width: 9rem; }
.extras-alta .extra-con-detalle .detalle-extra.cuantas { flex: 0 0 auto; }
.extras-alta .extra-largo { grid-column: 1 / -1; }
.extras-alta label { display: flex; flex-direction: column; gap: .15rem; }
.extras-alta label.casilla { flex-direction: row; align-items: center; }
.extras-alta span { font-size: .8rem; font-weight: 600; }
.extras-alta input[type=text],
.extras-alta input[type=number] { padding: .3rem .45rem; font-size: .88rem; }
.extras-alta .extra-corto input[type=number] { width: 4.5rem; }

.a-la-mitad {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  align-items: end;
}

/* EL CRONOMETRO. Cuenta atras de lo que le queda de cortesia y, pasada, lo que
   lleva de mas. Tabular para que no baile: con cifras de anchos distintos, un
   numero que corre se mueve de lado y cansa de mirar. */
.ficha-crono {
  font-variant-numeric: tabular-nums;
  font-weight: 700; font-size: .82rem;
  padding: .05rem .4rem; border-radius: 999px;
  background: color-mix(in srgb, var(--ambar) 18%, transparent);
  color: var(--ambar);
  white-space: nowrap;
}
/* Se acabo el tiempo. Rojo y no ambar: ha dejado de ser «mira esto» y ha
   pasado a ser «esa mesa ya no es suya si no la quieres guardar». */
.ficha-crono.agotado {
  background: color-mix(in srgb, var(--rojo) 18%, transparent);
  color: var(--rojo);
}

.ficha-reserva.se-retrasa {
  --tono-estado: var(--ambar);
  background: color-mix(in srgb, var(--ambar) 10%, var(--superficie));
  animation: latido-retraso 1.6s ease-in-out infinite;
}
@keyframes latido-retraso {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ambar) 55%, transparent); }
  50%      { box-shadow: 0 0 0 4px color-mix(in srgb, var(--ambar) 0%, transparent); }
}
/* QUIEN HA PEDIDO NO VER ANIMACIONES NO LAS VE, y la marca no se pierde: se
   queda el fondo ámbar, fijo. Un aviso que solo existe como parpadeo deja sin
   aviso a quien no puede con él. */
@media (prefers-reduced-motion: reduce) {
  .ficha-reserva.se-retrasa { animation: none; border-left-color: var(--ambar); }
}

/* EL TEXTO DEL ANEXO, para leerlo antes de firmarlo.
   Alto fijo y con desplazamiento propio: son varias pantallas de texto y sin
   esto el botón de firmar queda tan abajo que hay que ir a buscarlo. Así se
   lee dentro de su caja y la firma está siempre a la vista. */
.texto-legal {
  max-height: 22rem; overflow-y: auto;
  padding: .75rem 1rem; border: 1px solid var(--borde); border-radius: .5rem;
  background: var(--fondo);
}
.texto-legal h3 { margin: 1rem 0 .35rem; font-size: 1rem; }
.texto-legal h3:first-child { margin-top: 0; }

/* EL RECUADRO DE LA FIRMA.
   `touch-action: none` es lo que hace que se pueda firmar con el dedo: sin
   ello, mover el dedo por el recuadro desplaza la página y la firma sale a
   trozos. Y el cursor de cruz dice que ahí se dibuja. */
.caja-firma {
  border: 1px dashed var(--borde); border-radius: .5rem;
  background: #ffffff; padding: .25rem; max-width: 34rem;
}
.caja-firma canvas {
  display: block; width: 100%; height: auto;
  touch-action: none; cursor: crosshair;
}

/* LAS HORAS QUE SÍ QUEDAN, cuando la elegida se acaba de ocupar.
   Cada una es su propio <form> —reenvía la reserva entera con esa hora—, así
   que hay que deshacerles el margen inferior que la regla general de los
   formularios les pone, o la fila de horas se convierte en una escalera. */
.huecos-sin-sitio {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin: .5rem 0 1rem;
}
.huecos-sin-sitio form { margin: 0; }
.boton.hueco {
  font-variant-numeric: tabular-nums;
  padding: .5rem .9rem;
}
.titulo-huecos { font-size: 1.05rem; margin: 1.25rem 0 .25rem; }

/* El morado del remonte, DERIVADO de los colores del tema y no escrito a mano.
   Así sale bien en claro y en oscuro sin tener que definirlo tres veces —una
   por bloque de tema— y sin que se quede uno viejo el día que se retoque la
   paleta. Es la misma receta que usan las marcas de grupo. */
:root { --morado-remonte: color-mix(in srgb, var(--rojo) 45%, var(--acento)); }

/* HAY QUE REMONTAR ESA MESA.
 *
 * La reserva ya ha pasado de su hora de fin y sigue sentada: hay que recoger,
 * porque el siguiente tiene hora. Es la única mesa de la sala sobre la que hay
 * algo que hacer AHORA, y se veía igual que cualquier otra ocupada.
 *
 * MORADO Y NO ÁMBAR NI ROJO, y no es capricho. El ámbar ya es «llega tarde» y
 * el rojo «se acabó el tiempo de cortesía»: si esto fuera de uno de esos dos
 * colores, en la misma pantalla habría dos cosas distintas del mismo color y
 * el color dejaría de decir nada. El morado no está usado en el servicio.
 *
 * Y parpadea, como el retraso, porque también es un trabajo pendiente. No se
 * pisan nunca: quien no ha llegado no puede estar sentado. */
.ficha-reserva.en-remonte {
  --tono-estado: var(--morado-remonte);
  background: color-mix(in srgb, var(--morado-remonte) 12%, var(--superficie));
  animation: latido-remonte 1.6s ease-in-out infinite;
}
@keyframes latido-remonte {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--morado-remonte) 60%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--morado-remonte) 0%, transparent); }
}
.ficha-remonte {
  font-weight: 700; font-size: .78rem; white-space: nowrap;
  padding: .05rem .45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--morado-remonte) 20%, transparent);
  color: var(--morado-remonte);
}

/* LA MESA EN EL PLANO, con su cartel encima.
 *
 * En el plano no cabe una frase, así que el aviso va en una pastilla pegada a
 * la mesa. El texto lo pone `remonte.js` en `data-aviso-remonte`: así el
 * marcado no cambia y una mesa sin marcar no pinta nada. */
.pieza.mesa.en-remonte {
  animation: latido-remonte 1.6s ease-in-out infinite;
  outline: 2px solid var(--morado-remonte);
  outline-offset: 1px;
}
.pieza.mesa.en-remonte::after {
  content: attr(data-aviso-remonte);
  position: absolute; left: 50%; top: -.55rem;
  transform: translateX(-50%);
  padding: .05rem .4rem; border-radius: 999px;
  /* El texto sale de `--sobre-relleno` y no de un blanco escrito a mano: en
     tema claro y en oscuro el relleno no es el mismo, y un #fff fijo se lee
     mal en uno de los dos. Lo vigila `prueba_tema`. */
  background: var(--morado-remonte); color: var(--sobre-relleno);
  font-size: .62rem; font-weight: 700; letter-spacing: .02em;
  white-space: nowrap; pointer-events: none;
}

/* La marca NO puede vivir solo en el parpadeo: quien ha pedido no ver
   animaciones se quedaría sin aviso. Se queda el fondo y el contorno. */
@media (prefers-reduced-motion: reduce) {
  .ficha-reserva.en-remonte,
  .pieza.mesa.en-remonte { animation: none; }
}

/* Igual que en la tabla de antes: lo anulado se ve, pero apagado. */
.ficha-reserva.estado-cancelada, .ficha-reserva.estado-no_show { opacity: .5; }
.ficha-reserva.estado-cancelada .ficha-hora { text-decoration: line-through; }

/* Es un <label>, asi que hay que deshacerle lo que la regla general de los
   formularios le pone: el display:block, el margen inferior y el tamano y peso
   que `label > span` le da a cada hijo. */
.ficha-cabecera {
  display: flex; align-items: baseline; gap: .6rem;
  margin: 0; cursor: pointer;
}
.ficha-cabecera > span {
  display: inline-block; margin: 0; font-size: inherit; font-weight: inherit;
}
.ficha-cabecera > .ficha-hora { font-weight: 700; font-variant-numeric: tabular-nums; }
.ficha-cabecera > .ficha-nombre { flex: 1; min-width: 0; }
.ficha-nombre strong { display: block; }
/* LOS COMENSALES, DESTACADOS. Es el dato que decide la mesa y el que se busca
   al pasar la lista -«¿cuántos son?»- y salía en la misma letra gris que el
   resto. En su pastilla se ve de un vistazo sin leer la ficha.

   La cifra grande y el «pax» pequeño: lo que se lee es el número; la unidad
   solo hace falta la primera vez. */
.ficha-cabecera > .ficha-pax {
  display: inline-flex; align-items: baseline; gap: .2rem;
  padding: .1rem .45rem; border-radius: 999px;
  background: color-mix(in srgb, var(--texto-suave) 12%, transparent);
  font-size: .72rem; color: var(--texto-suave); white-space: nowrap;
}
.ficha-cabecera > .ficha-pax strong {
  font-size: 1.05rem; font-weight: 700; color: var(--texto);
  line-height: 1;
}
/* El estado y la flecha solo existen en movil, donde la ficha va plegada. */
.ficha-cabecera > .ficha-estado-marca,
.ficha-cabecera > .ficha-flecha { display: none; }

/* LA FICHA, A LA MITAD DE ALTO CON LOS MISMOS DATOS.
   Antes cada cosa gastaba su propia linea: la etiqueta encima del
   desplegable, el contacto en un parrafo, los botones en otra fila y el pie
   en una cuarta. Siete lineas para decir lo que cabe en cuatro, y en una
   pantalla de servicio eso son tres reservas menos a la vista.
   No se ha escondido nada: se han juntado las filas. */
.ficha-cuerpo { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: .35rem; }
.ficha-dato { flex: 1 1 45%; min-width: 8rem; display: flex; align-items: center; gap: .4rem; }
.ficha-dato form { margin: 0; flex: 1; min-width: 0; }
/* La etiqueta AL LADO, no encima: dice lo mismo y no gasta un renglon. */
.ficha-etiqueta {
  font-size: .74rem; color: var(--texto-suave); white-space: nowrap;
}
.ficha-peticiones { margin: .4rem 0 0; }
.ficha-pie {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .4rem;
}
/* Empuja las acciones a la derecha: el contacto se lee de un vistazo a la
   izquierda y los botones quedan siempre en el mismo sitio, ficha tras ficha. */
.ficha-pie .ficha-contacto { margin-right: auto; }
.ficha-pie form { margin: 0; }

/* Hora partida en dos desplegables, dentro de la rejilla del formulario.
   Imita a un <label> normal para que quede alineado con los demas campos. */
/* Repite lo de `label` y `label > span` en vez de heredarlo: esto no es un
   <label>, porque un label no puede apuntar a dos controles a la vez. Sin el
   margen inferior, su fila de la rejilla quedaria pegada a la siguiente. */
/* El alta manual llevaba dos desplegables sueltos, hora y minutos, con las
   veinticuatro horas y los cuartos. Ahora es un solo desplegable con las horas
   que ese dia tienen servicio, asi que sus reglas ya no hacen falta: se
   quitaron con el campo. */

/* --- El asistente de configuracion ---------------------------------------
   Mas estrecho que el resto del panel a proposito: aqui se lee y se rellena de
   arriba abajo, y una linea de mil pixeles se lee mal. -------------------- */

.asistente { max-width: 720px; margin: 0 auto; }

.asistente-cuenta {
  margin: 0 0 .4rem; font-size: .8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; color: var(--texto-suave);
}

/* La escalerilla de pasos. Es informativa: no se pincha, porque saltar al paso
   5 sin haber pasado por el 2 deja el restaurante a medias sin avisar. */
.asistente-pasos {
  display: flex; flex-wrap: wrap; gap: .35rem .8rem;
  list-style: none; margin: 0 0 1.5rem; padding: 0;
  font-size: .82rem; color: var(--texto-suave);
}
.asistente-pasos li { display: flex; align-items: center; gap: .35rem; }
.asistente-pasos .punto {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; flex: none;
  border: 1px solid var(--borde); border-radius: 999px;
  font-size: .72rem; font-weight: 700;
}
.asistente-pasos .hecho { color: var(--verde); }
.asistente-pasos .hecho .punto { border-color: var(--verde); }
.asistente-pasos .ahora { color: var(--texto); font-weight: 600; }
.asistente-pasos .ahora .punto {
  background: var(--acento); border-color: var(--acento); color: var(--sobre-relleno);
}
/* En movil solo se lee el paso actual: siete nombres en una pantalla de 360 px
   son siete renglones de ruido antes de llegar al formulario. */
@media (max-width: 640px) {
  .asistente-pasos li:not(.ahora) .nombre { display: none; }
}

.lista-pasos { margin: 0 0 1.5rem; padding-left: 1.2rem; }
.lista-pasos li { margin-bottom: .3rem; }
.lista-siguiente { padding-left: 1.2rem; }
.lista-siguiente li { margin-bottom: .6rem; }

/* Marco para lo que borra. Se usa en la portada del asistente y en su boton de
   Ajustes: en los dos sitios hay que mirarlo dos veces antes de pulsar. */
.peligro-marco {
  border: 1px solid color-mix(in srgb, var(--rojo) 45%, var(--borde));
  border-left-width: 4px;
  border-radius: var(--radio);
  padding: 1rem 1.1rem; margin: 1.25rem 0;
  background: color-mix(in srgb, var(--rojo) 6%, transparent);
}
.peligro-marco h2, .peligro-marco h3 { margin-top: 0; }
.peligro-marco ul { margin: .4rem 0 .8rem; padding-left: 1.2rem; }
.peligro-marco li { margin-bottom: .25rem; }

/* Filas que se anaden y se quitan: salas y personal. */
.fila-asistente {
  display: flex; gap: .7rem; align-items: end; flex-wrap: wrap;
  padding: .6rem 0; border-bottom: 1px solid var(--borde);
}
.fila-asistente label { flex: 1 1 11rem; margin-bottom: 0; }
.fila-asistente .quitar-fila { flex: none; }
.filas-asistente + p { margin-top: .8rem; }

.bloque-sala, .bloque-turno {
  border: 1px solid var(--borde); border-radius: var(--radio);
  padding: .9rem 1rem; margin: 0 0 1rem;
}
.bloque-sala legend, .bloque-turno legend {
  padding: 0 .4rem; font-size: .95rem; font-weight: 650;
}
.etiqueta-grupo {
  margin: .2rem 0 .1rem; font-size: .87rem; font-weight: 550;
}

/* La salida del asistente: un boton que parece un enlace, porque irse no es la
   accion principal de ninguna de estas pantallas. */
.asistente-salida {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--borde);
}
.asistente-salida form { margin: 0; }
.asistente-salida button.enlace-menudo {
  background: none; border: none; padding: 0; font: inherit;
  color: var(--acento); cursor: pointer; text-decoration: underline;
}

@media (max-width: 640px) {
  .fila-asistente label { flex: 1 1 100%; }
  .fila-asistente .quitar-fila { width: 100%; min-height: 44px; }
}

/* --- Cuanto de cada sala se vende por internet --------------------------- */
/* Una ficha por sala, no una tabla: cada una se guarda por su cuenta y la
   tabla obligaria a un boton suelto por fila, que se lee peor. */

.salas-cupo {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: .8rem; margin: 0 0 1rem;
}
.sala-cupo {
  background: var(--superficie); border: 1px solid var(--borde);
  border-radius: var(--radio); padding: .85rem .9rem; margin: 0;
}
.sala-cupo h3 {
  margin: 0 0 .6rem; font-size: 1rem;
  display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
}
.sala-cupo h3 small {
  font-weight: 400; font-size: .78rem; color: var(--texto-suave);
  white-space: nowrap;
}
.sala-cupo label { margin-bottom: .5rem; }

/* El campo y el % pegados, para que se lea como una sola cosa. */
.linea-cupo { display: flex; align-items: center; gap: .4rem; }
.linea-cupo input { width: 5.5rem; }
.linea-cupo .unidad { color: var(--texto-suave); }

/* El numero de mesas es la traduccion del porcentaje y es lo que de verdad se
   entiende, asi que va destacado y no como un apunte mas. */
.resultado-cupo {
  margin: 0 0 .7rem; font-size: .85rem; color: var(--texto-suave);
}
.resultado-cupo strong {
  font-size: 1.25rem; color: var(--texto); margin-right: .15rem;
  font-variant-numeric: tabular-nums;
}

/* Botones de una celda de tabla, uno al lado del otro sin separarse. */
.acciones-celda { display: flex; gap: .4rem; align-items: center; }
.acciones-celda form { margin: 0; }

/* Aviso de que la plataforma esta metida en el panel de un restaurante.
   Va arriba del todo, en ambar y a lo ancho, porque es facil olvidarlo y
   acabar cambiandole los horarios al restaurante equivocado. */
.franja-suplantacion {
  display: flex; flex-wrap: wrap; gap: .75rem;
  align-items: center; justify-content: space-between;
  padding: .55rem 1.1rem;
  background: color-mix(in srgb, var(--ambar) 16%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--ambar) 40%, transparent);
  color: var(--ambar);
  font-size: .88rem;
}
.franja-suplantacion a {
  color: var(--ambar); font-weight: 600; white-space: nowrap;
}

/* La tabla del panel se desborda en movil: mejor scroll que romper el diseno. */
@media (max-width: 900px) {
  .contenido.ancho { overflow-x: auto; }
  .tabla { min-width: 780px; }
}

/* =========================================================================
   EL PANEL EN EL MOVIL

   El corte esta en 700 px: SOLO telefonos de pie. Una tableta -768 px de ancho
   para arriba- se ve exactamente igual que un ordenador, y eso es un requisito,
   no una casualidad: la tablet de la barra y el ordenador de la oficina tienen
   que ensenar la misma pantalla, con la misma colocacion, para que lo que se
   monta en uno valga en el otro. Con el corte anterior, en 900, una tableta en
   vertical caia dentro y se le plegaba el menu y se le apilaban los bloques.

   Y no vale 767 aunque la tableta mida 768: MEDIDO en el navegador, una ventana
   de 768 con barra de desplazamiento clasica le dice 753 px a la consulta de
   medios, porque la barra no cuenta. Los quince pixeles de la barra volvian a
   meter la tableta en la vista de telefono. 700 deja sitio para esa barra.

   Dos decisiones, y las dos salen de para que se coge el telefono en un
   restaurante -para mirar y tocar las reservas del dia, casi nunca para otra
   cosa-:

     1. **El menu se pliega.** En una pantalla estrecha los trece enlaces
        entran, pero a costa de empujar las reservas por debajo del pliegue.
     2. **La pantalla del dia se reordena**: apuntar una reserva, la lista, el
        plano y al final el resto. Es el orden en el que se usa con el
        telefono en una mano y el cliente delante.

   Todo con CSS. Ni el menu ni las fichas dependen de JavaScript para abrirse:
   son casillas ocultas con su etiqueta, que es lo unico que permite estar
   abierto de fabrica en una pantalla y cerrado en otra.
   ========================================================================= */

/* El boton existe en TODAS las pantallas. En el movil despliega un menu que
   nace plegado; en el ordenador lo esconde para dejarle el ancho al plano.
   O sea que la casilla significa lo contrario a cada lado, y por eso hay dos
   reglas y no una: es la unica forma de tener un valor por defecto distinto en
   cada anchura sin JavaScript.

   Oculta a la vista pero NO con display:none: asi sigue recibiendo el foco y
   se abre con la barra espaciadora desde el teclado. */
.menu-interruptor,
/* La casilla que pliega cada ficha de reserva. Estaba escondida SOLO dentro
   del `@media` del movil, asi que en el ordenador se veia una casilla suelta
   al lado de cada reserva, sin etiqueta y sin decir para que era. En el
   ordenador no pinta nada -alli la ficha se ve entera- pero tiene que seguir
   existiendo y recibiendo el foco, no valia un `display: none`. */
.ficha-interruptor {
  position: absolute;
  width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.menu-boton {
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 40px; padding: .45rem .8rem; margin: 0;
  border: 1px solid var(--borde); border-radius: 8px;
  background: var(--fondo); color: var(--texto);
  font-size: .9rem; font-weight: 550; cursor: pointer;
}
/* El foco vive en la casilla, que no se ve: hay que pintarlo en la etiqueta. */
.menu-interruptor:focus-visible + .menu-boton {
  outline: 2px solid var(--acento); outline-offset: 2px;
}

/* El menu va RECOGIDO en todas las pantallas, no solo en el movil.
   Antes se desplegaba de fabrica en el ordenador y la casilla lo escondia -la
   regla iba al reves que en el movil-, asi que el mismo boton hacia una cosa
   en el portatil y la contraria en el telefono. Ahora se abre igual en todas
   partes, y la barra de arriba queda para lo que importa: el restaurante. */
.cabecera-panel nav { display: none; }

/* PERO SOLO DONDE HAY UN BOTON QUE LO ABRA.
 *
 * La regla de arriba esconde el menu y lo abre la casilla `menu-interruptor`,
 * que vive en la base del PANEL. /central y /plataforma reusan esta misma clase
 * para su cabecera y **no tienen esa casilla**: el resultado era una barra con
 * el nombre y nada mas, con sus enlaces escritos en el HTML y ocultos para
 * siempre. A esas zonas solo se podia llegar tecleando la direccion.
 *
 * No se noto en su dia porque el cambio fue en el panel y estas dos pantallas
 * comparten la clase sin compartir el boton. `sin-menu` dice justamente eso:
 * aqui no hay nada que desplegar, asi que se ve. */
.cabecera-panel.sin-menu nav {
  display: flex; flex-wrap: wrap; align-items: center; gap: .2rem 1rem;
}
.menu-interruptor:checked ~ nav {
  display: flex; flex-direction: column; gap: 0;
  flex-basis: 100%;
  margin-top: .6rem; padding-top: .6rem;
  border-top: 1px solid var(--borde);
}

/* 701 Y NO 901: es el reverso exacto del corte del movil. Con 901 quedaba una
   franja de 701 a 900 -toda tableta de pie- que no entraba ni en un lado ni en
   el otro y se quedaba con el menu en columna y los botones de dedo, o sea
   distinta del ordenador. Los dos numeros tienen que ser consecutivos. */
@media (min-width: 701px) {
  .menu-boton { min-height: 34px; padding: .3rem .7rem; font-size: .85rem; }
  /* En pantalla ancha caben en fila y se leen mejor asi que en columna. */
  .menu-interruptor:checked ~ nav {
    flex-direction: row; flex-wrap: wrap; gap: .2rem 1rem;
  }
}

@media (max-width: 700px) {

  /* --- Nada por debajo de 13 px -------------------------------------------
     Los ultimos rotulos que se quedaban diminutos con el telefono. MEDIDO a
     375 px despues de arreglar los bloques: «Zona» en 12,8, «6 mesas activas»
     y las cabeceras de las tablas en 12,48.

     VAN AQUI, AL FINAL DE LA HOJA, Y NO CON LOS DEMAS. Se pusieron primero
     junto al resto de los ajustes del telefono, doscientas lineas antes, y
     «Zona» siguio midiendo 12,8: su regla normal -`.linea-control > span`-
     esta en la linea 1696, o sea DESPUES, y con la misma especificidad gana
     la que va la ultima. Estar dentro de una `@media` no da preferencia
     ninguna. Aqui abajo no hay nada detras que las pise. */
  .linea-control > span { font-size: .85rem; }
  .tabla th { font-size: .85rem; }
  .barra-pct { font-size: .85rem; }

  /* --- Los margenes, que se suman ------------------------------------------
     MEDIDO en la pantalla de reservar de un telefono de 375 px: el contenido
     pone 20 px a cada lado y la tarjeta otros 28, o sea NOVENTA Y SEIS px de
     hueco -un cuarto de la pantalla- para dejar el formulario en 277.

     Cada uno de los dos margenes es razonable por separado; el problema es que
     se suman, y en un monitor de 1400 px no se nota porque sobra sitio. En un
     telefono es la diferencia entre tres horas por fila y cuatro. */
  .contenido { padding-left: .75rem; padding-right: .75rem; }
  .tarjeta { padding-left: 1rem; padding-right: 1rem; }

  /* El titulo de cada apartado. En el ordenador va pequeño a proposito -va en
     mayusculas y espaciado, y asi no compite con el contenido-, pero 12,8 px
     en mayusculas y en gris claro, en un telefono, no se lee de un vistazo. */
  h3 { font-size: .9rem; }

  /* Y el suelo de todos los `small`. Uno cualquiera es el 80% de su padre, y
     ese padre suele venir ya reducido: es la multiplicacion la que los hunde,
     no cada regla. Con `max` se queda en lo que sea mayor, o sea que un small
     dentro de un texto grande sigue creciendo -no se le clava el tamano- y
     solo se le pone tope por abajo. */
  small { font-size: max(.8125rem, .85em); }
  /* Estos dos se colaban por debajo del suelo de arriba, y no por ir despues
     sino por SER MAS ESPECIFICOS: `.casilla.extra small` y `.etiqueta` llevan
     clase, y una clase gana a un `small` a secas por mucho que este mas
     abajo. El orden solo desempata cuando la especificidad es la misma. */
  .casilla.extra small { font-size: max(.8125rem, .85em); }
  .sala-cupo h3 small { font-size: max(.8125rem, .85em); }
  .etiqueta, .ambito { font-size: .8125rem; }

  /* --- El menu plegado --------------------------------------------------- */

  .menu-boton { min-height: 44px; padding: .5rem .9rem; font-size: .93rem; }

  .cabecera-panel { padding: .7rem 1rem; gap: .6rem; }
  .cabecera-panel .marca { flex: 1; min-width: 0; }

  /* Plegarlo y desplegarlo ya se hereda de la regla general: aqui solo queda
     lo que de verdad cambia en un telefono, que es el tamano del blanco. */
  /* Renglones altos y separados: se tocan con el pulgar, no con el raton. */
  .cabecera-panel nav a {
    display: block; padding: .7rem .2rem; font-size: 1rem;
    border-bottom: 1px solid color-mix(in srgb, var(--borde) 55%, transparent);
  }
  .cabecera-panel nav a:last-of-type { border-bottom: none; }
  .cabecera-panel nav .quien { color: var(--texto-suave); }

  /* --- El orden de la pantalla del dia ------------------------------------ */

  /* El contenido de trabajo son ahora los BLOQUES del tablero, y su orden en
     pantalla estrecha se fija junto al resto de reglas del tablero (buscar
     `.tablero .bloque-fecha` mas arriba). Aqui solo queda lo que no es un
     bloque: el titulo, los avisos y el interruptor de la venta online. */
  .pantalla-dia { display: flex; flex-direction: column; }
  /* Lo que no se nombre aqui cae al final, que es donde debe estar lo
     accesorio. */
  .pantalla-dia > *        { order: 9; }
  .pantalla-dia > .aviso   { order: 1; }
  .pantalla-dia > .tablero { order: 3; }
  /* La fecha ya no esta aqui: se fue a la barra de cabecera. Alli, en el
     movil, se pone en su propia linea debajo del nombre del local en vez de
     pelearse con el boton del menu por el mismo renglon. */
  .cabecera-panel .titulo-dia { flex-basis: 100%; font-size: .95rem; }

  /* Apuntar una reserva es lo primero que se hace y lo mas urgente: boton a
     todo lo ancho y bien alto, no un renglon de texto.
     Se ancla en `.bloque-alta`, que es su bloque del tablero: el dialogo
     centrado lo usan tambien otras pantallas y ahi no debe crecer. */
  .bloque-alta .dialogo-centrado { display: block; margin: 0 0 1rem; }
  .bloque-alta .dialogo-centrado > summary {
    /* `column` explicito: esta regla pesa mas que `.boton-bloque` y con un
       `display: flex` a secas ponia el titulo y su linea uno al lado del otro
       solo en el movil, que es justo donde menos ancho hay. */
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    min-height: 48px; padding: .7rem 1rem;
    font-size: 1rem; font-weight: 600;
  }

  .barra-dia { gap: .4rem; margin-bottom: .9rem; }

  .barra-dia .boton.pequeno { min-height: 40px; }
  .herramientas-dia { margin-left: 0; flex-basis: 100%; }

  /* Las cifras del dia bajan al final, asi que ya no son un panel: una linea
     de numeros pequenos basta. */
  /* Descendiente y no hijo: entre el bloque y su contenido va `.bloque-cuerpo`. */
  .bloque-cifras .cifras { gap: .4rem; margin: 1.25rem 0 .5rem; }
  .bloque-cifras .cifras .cifra { flex: 1 1 auto; padding: .5rem .6rem; }
  .bloque-cifras .cifras .cifra strong { font-size: 1.15rem; }

  /* --- La lista de reservas, plegada -------------------------------------- */

  .ficha-interruptor:focus-visible ~ .ficha-cabecera {
    outline: 2px solid var(--acento); outline-offset: 2px; border-radius: 6px;
  }

  /* El relleno se aprieta, la banda NO: en el movil se mira mas deprisa
     y de mas cerca del bolsillo que de la mesa. */
  .ficha-reserva { padding: .1rem .7rem; border-left-width: 9px; }
  .ficha-cabecera {
    align-items: center; gap: .55rem;
    min-height: 52px; padding: .35rem 0;
  }
  .ficha-cabecera > .ficha-nombre strong {
    /* Un nombre largo no puede empujar al estado fuera de la pantalla. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* El codigo y el origen no se leen de pasada: viven en el detalle. */
  .ficha-cabecera > .ficha-nombre .codigo-pequeno { display: none; }
  .ficha-cabecera > .ficha-pax { font-size: .78rem; }
  .ficha-cabecera > .ficha-pax strong { font-size: 1.15rem; }

  .ficha-cabecera > .ficha-estado-marca {
    display: inline-block;
    padding: .15rem .5rem; border-radius: 999px;
    background: color-mix(in srgb, var(--texto-suave) 15%, transparent);
    color: var(--texto-suave);
    font-size: .74rem; font-weight: 600; white-space: nowrap;
  }
  /* La marca del estado, con el color que haya elegido esta casa. Antes eran
     cuatro casos escritos a mano -confirmada, pendiente, sentada y las dos
     rojas- y los otros cuatro estados salian en gris, todos iguales. */
  .estado-esperando_pago .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-esperando_pago) 18%, transparent);
    color: var(--color-estado-esperando_pago);
  }
  .estado-pendiente .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-pendiente) 18%, transparent);
    color: var(--color-estado-pendiente);
  }
  .estado-confirmada .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-confirmada) 18%, transparent);
    color: var(--color-estado-confirmada);
  }
  .estado-sentada .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-sentada) 18%, transparent);
    color: var(--color-estado-sentada);
  }
  .estado-completada .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-completada) 18%, transparent);
    color: var(--color-estado-completada);
  }
  .estado-cancelada .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-cancelada) 18%, transparent);
    color: var(--color-estado-cancelada);
  }
  .estado-no_show .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-no_show) 18%, transparent);
    color: var(--color-estado-no_show);
  }
  .estado-caducada .ficha-estado-marca {
    background: color-mix(in srgb, var(--color-estado-caducada) 18%, transparent);
    color: var(--color-estado-caducada);
  }

  /* Punta de flecha dibujada con dos bordes: gira al desplegar. */
  .ficha-cabecera > .ficha-flecha {
    display: block; width: .5rem; height: .5rem; flex: none;
    border-right: 2px solid var(--texto-suave);
    border-bottom: 2px solid var(--texto-suave);
    transform: rotate(45deg); margin-bottom: .2rem;
    transition: transform .15s ease;
  }
  .ficha-interruptor:checked ~ .ficha-cabecera > .ficha-flecha {
    transform: rotate(-135deg); margin-bottom: -.2rem;
  }

  .ficha-detalle { display: none; }
  .ficha-interruptor:checked ~ .ficha-detalle {
    display: block; padding-bottom: .6rem;
    border-top: 1px solid var(--borde); margin-top: .1rem; padding-top: .6rem;
  }
  /* Dentro del detalle, cada dato en su renglon: dos columnas de 8rem en una
     pantalla de 360 px no son dos columnas, son dos amasijos. */
  .ficha-cuerpo { flex-direction: column; gap: .6rem; }
  .ficha-dato { flex: 1 1 auto; min-width: 0; }
  .enviar-correo { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }

  /* --- El plano ------------------------------------------------------------ */

  /* Debajo de la lista y con altura acotada: es para orientarse de un vistazo,
     no para trabajar. Sin el tope, un salon alargado ocupa media pantalla de
     desplazamiento antes de llegar a nada. */
  /* El Guardar de cada sala se toca con el pulgar, y a lo ancho de la ficha:
     un boton pequeno en la esquina de una tarjeta es de los que se fallan. */
  .sala-cupo button { width: 100%; min-height: 44px; }

  .servicio-sala .plano-marco { max-height: 60vh; overflow: auto; }
  .controles-sala { gap: .5rem; }
  .controles-sala .linea-control { flex: 1 1 8rem; }
}

/* El telefono en vertical: hasta las cifras compactas de la sala estorban. */
@media (max-width: 560px) {
  .cifras.compactas .cifra { flex: 1 1 auto; }
  .barra-dia form { flex: 1 1 100%; }
  .barra-dia .calendario,
  .barra-dia input[type=date] { width: 100%; min-width: 0; }
}

/* --- Calendario desplegable con los festivos en rojo ----------------------
   Sustituye al calendario del navegador, que no se puede colorear porque lo
   pinta el por su cuenta y no forma parte del documento. El <input> original
   sigue ahi, oculto, con el valor: si el guion no llega, se ve el campo de
   fecha de siempre y todo funciona igual. ---------------------------------- */

.calendario { position: relative; display: block; }

/* El boton imita al campo de texto de al lado: si no, en una fila con otros
   campos canta que uno de ellos es distinto. */
.calendario-valor {
  width: 100%; text-align: left; cursor: pointer;
  padding: .55rem .7rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie); color: var(--texto);
  font: inherit; font-size: .95rem;
}
.calendario-valor:hover { border-color: var(--acento); }
.calendario-valor:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }
.calendario-valor.vacio { color: var(--texto-suave); }

.calendario-panel {
  position: absolute; z-index: 40; top: calc(100% + .35rem); left: 0;
  width: 19rem; max-width: calc(100vw - 2rem);
  padding: .6rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  box-shadow: var(--sombra);
}

.calendario-cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .4rem;
}
.calendario-cabecera strong { font-size: .95rem; text-transform: capitalize; }
.calendario-flecha {
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: none; color: var(--texto); cursor: pointer;
  padding: .15rem .55rem; font-size: 1rem; line-height: 1.4;
}
.calendario-flecha:hover { border-color: var(--acento); color: var(--acento); }

.calendario-semana, .calendario-rejilla {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
}
.calendario-semana span {
  text-align: center; font-size: .72rem; font-weight: 600;
  color: var(--texto-suave); padding-bottom: .2rem;
}

.calendario-dia {
  aspect-ratio: 1 / 1; min-height: 2rem;
  border: 1px solid transparent; border-radius: var(--radio);
  background: none; color: var(--texto);
  font: inherit; font-size: .85rem; cursor: pointer;
}
.calendario-dia:hover:not(:disabled) { background: var(--acento-suave); }
.calendario-dia.otro-mes { color: var(--texto-suave); opacity: .55; }
.calendario-dia.hoy { border-color: var(--borde); font-weight: 700; }
.calendario-dia:disabled { opacity: .3; cursor: default; }

/* Lo que pidio el restaurante: los festivos, en rojo. Ademas del color va en
   negrita y con un punto debajo, porque solo por color no lo distingue quien
   no ve bien los rojos, que es mas gente de la que parece. */
.calendario-dia.festivo {
  color: var(--rojo); font-weight: 700;
  background: color-mix(in srgb, var(--rojo) 10%, transparent);
}
.calendario-dia.festivo::after {
  content: ""; display: block; margin: -.15rem auto 0;
  width: 4px; height: 4px; border-radius: 50%; background: var(--rojo);
}

/* El elegido va el ultimo para que gane a festivo: si el 25 de diciembre es el
   dia que estas mirando, importa mas eso que el color de la fiesta. */
.calendario-dia.elegido, .calendario-dia.elegido.festivo {
  background: var(--acento); color: var(--sobre-relleno); border-color: var(--acento);
  font-weight: 700;
}
.calendario-dia.elegido.festivo::after { background: #fff; }

.calendario-pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-top: .5rem; padding-top: .45rem;
  border-top: 1px solid var(--borde);
  font-size: .78rem; color: var(--texto-suave);
}
.calendario-leyenda { display: inline-flex; align-items: center; gap: .35rem; }
.punto-festivo {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--rojo); display: inline-block;
}
.calendario-quitar {
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: none; color: var(--texto-suave); cursor: pointer;
  font: inherit; font-size: .78rem; padding: .15rem .5rem;
}
.calendario-quitar:hover { color: var(--acento); border-color: var(--acento); }

/* En la barra del dia el calendario va suelto entre dos botones, no dentro de
   una columna de formulario: sin esto se estiraria a todo lo ancho. */
.barra-dia .calendario { display: inline-block; min-width: 15rem; }
.calendario-falta { margin: .4rem 0 0; font-size: .82rem; }

/* --- Correos al cliente ---------------------------------------------------
   El editor por bloques y la galeria de imagenes. -------------------------- */

.tabla-correos td { vertical-align: top; }
.acciones-fila { display: flex; gap: .4rem; align-items: center; }

.galeria-correo {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}
.galeria-correo figure {
  margin: 0; padding: .75rem; text-align: center;
  border: 1px solid var(--borde); border-radius: var(--radio);
}
.galeria-correo img {
  max-width: 100%; max-height: 110px; height: auto; display: block;
  margin: 0 auto .5rem;
}
.galeria-correo figcaption {
  font-size: .8rem; color: var(--texto-suave);
  overflow-wrap: anywhere; margin-bottom: .5rem;
}

.bloque-correo {
  margin-bottom: .85rem; padding: .75rem .9rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--fondo);
}
.bloque-cabecera {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .5rem;
}
.bloque-cabecera strong { font-size: .85rem; color: var(--texto-suave); }
.bloque-mandos { display: inline-flex; gap: .25rem; }
.bloque-mando {
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie); color: var(--texto);
  cursor: pointer; font: inherit; font-size: .85rem;
  width: 1.9rem; height: 1.9rem; line-height: 1;
}
.bloque-mando:hover:not(:disabled) { border-color: var(--acento); color: var(--acento); }
.bloque-mando:disabled { opacity: .3; cursor: default; }
.bloque-correo textarea { width: 100%; font: inherit; font-size: .95rem; }
.bloque-correo label { margin-bottom: .6rem; }
.vista-imagen {
  display: block; max-width: 100%; max-height: 120px; height: auto;
  margin-top: .5rem; border-radius: var(--radio);
}

.anadir-bloques { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }

/* Ojo: .hueco a secas ya es el boton de una hora libre en la pagina publica.
   Estos son otra cosa y llevan su propio nombre; con el mismo, el ultimo de
   los dos bloques le ganaria al otro y romperia una pantalla que ya estaba. */
.huecos-correo { display: flex; flex-wrap: wrap; gap: .4rem; }
.hueco-correo {
  border: 1px solid var(--borde); border-radius: 999px;
  background: var(--fondo); color: var(--texto);
  cursor: pointer; font: inherit; font-size: .8rem;
  padding: .2rem .65rem; font-family: ui-monospace, monospace;
}
.hueco-correo:hover { border-color: var(--acento); color: var(--acento); }

/* El correo que se puede mandar a mano desde una reserva. */
.enviar-correo { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.enviar-correo select { font-size: .85rem; padding: .3rem .5rem; }

/* Los dos botones de tamano de texto del editor del plano, con el valor
   actual en medio para saber de que se parte. */
.tam-texto { display: inline-flex; align-items: center; gap: .25rem; }
.tam-texto output {
  font-size: .78rem; color: var(--texto-suave);
  min-width: 2.9rem; text-align: center; font-variant-numeric: tabular-nums;
}

/* --- Interruptor de la venta online ---------------------------------------
   Ya no tiene estilos propios: es un `.boton-bloque` como el de la lista de
   espera, y el color -verde entrando venta, rojo parada- dice el estado.

   Su caja se quito y no fue por limpieza. `.venta-online.cerrada` vivia AQUI,
   por debajo de la regla que la neutralizaba dentro del tablero y con la misma
   especificidad, asi que ganaba por ir despues y volvia a pintar un recuadro
   rojo alrededor del boton rojo. Se veia mal y leyendo la plantilla no habia
   forma de saber por que. Sin envoltorio no hay nada que neutralizar. */
/* Se quitaron `.venta-estado`, los puntitos y todo lo del `<details>` de
   cerrar: el bloque es ahora un solo boton, calcado al de la lista de espera,
   y ninguna plantilla usaba ya esas clases. Reglas sin marcado detras es lo
   que hace que la hoja crezca y nadie se atreva a tocarla. */

/* --- Herramientas del dia: lupa e impresora ------------------------------- */

.herramientas-dia { display: inline-flex; gap: .4rem; margin-left: auto; }

.boton.icono {
  display: inline-flex; align-items: center; gap: .35rem;
  /* list-style y ::-webkit sirven para cuando el boton es un <summary>. */
  list-style: none;
}
.boton.icono::-webkit-details-marker { display: none; }
.boton.icono svg { flex: none; }

/* Menu que cuelga de un boton. Absoluto para que no empuje la pagina al
   abrirse: si empujara, el plano y la lista darian un salto justo debajo. */
.desplegable-menu { position: relative; display: inline-block; }
.menu-desplegado {
  position: absolute; z-index: 30; right: 0; top: calc(100% + .35rem);
  width: 22rem; max-width: calc(100vw - 2rem);
  padding: .85rem; text-align: left;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  box-shadow: var(--sombra);
}
.menu-desplegado .apunte { margin: .5rem 0 .35rem; }
.menu-desplegado .apunte:first-child { margin-top: 0; }

/* --- El mismo desplegable, pero en el centro de la pantalla ---------------
   Para los que viven al PIE de una pagina larga: «Recolocar la pantalla» esta
   abajo del todo, y un menu que se abre hacia abajo y hacia la derecha se
   queda fuera de la vista justo ahi. Este se centra y se pone un velo detras.

   El velo es el `::before` del propio `summary`, no un elemento aparte: asi
   pulsar fuera cierra el dialogo -es contenido del summary, y el summary
   alterna el `details`- sin una sola linea de JavaScript. */
.dialogo-centrado[open] > summary::before {
  content: ""; position: fixed; inset: 0; z-index: 40;
  background: rgba(0, 0, 0, .45);
}

/* NO TOCAR sin leer esto: aqui no puede haber `filter` ni `transform`.
   Los dos convierten al elemento en bloque contenedor de sus descendientes
   `position: fixed`. Y el velo de arriba es un `fixed` que cuelga de este
   summary, asi que en cuanto uno de los dos se aplica, el velo deja de cubrir
   la pantalla y se encoge al tamano del boton.

   Eso es justo lo que pasaba. Estos summary llevan `.boton`, que trae
   `filter: brightness()` al pasar por encima; y el raton pasa por encima del
   summary SIEMPRE, porque el velo es parte de el. Resultado: cerrar pulsando
   fuera no funcionaba nunca, en ninguno de los tres dialogos.

   El realce al pasar por encima se hace con el color de fondo, que no crea
   bloque contenedor y se ve igual. */
.dialogo-centrado > summary:hover,
.dialogo-centrado > summary:active {
  filter: none;
  transform: none;
  background: color-mix(in srgb, var(--acento) 82%, #fff);
}
.dialogo-centrado > summary.peligro:hover,
.dialogo-centrado > summary.peligro:active {
  background: color-mix(in srgb, var(--rojo) 82%, #fff);
}
.dialogo-centrado > summary.secundario:hover,
.dialogo-centrado > summary.secundario:active {
  background: var(--acento-suave);
}
/* Un boton de bloque que ademas abre un dialogo -apagar la venta, apuntar una
   reserva- se realza con SU color, no con el de la casa. Sin esto, el verde de
   la venta se volvia del color del acento al pasar el raton por encima y
   parecia otro boton.
   Va DESPUES de las tres de arriba y con mas peso, y sigue sin `filter` ni
   `transform` por lo que explica el bloque grande de mas arriba: los dos
   romperian el velo. */
.dialogo-centrado > summary.boton-bloque:hover,
.dialogo-centrado > summary.boton-bloque:active {
  filter: none;
  transform: none;
  background: color-mix(in srgb, var(--tono-bloque) 82%, #fff);
}
.dialogo-centrado > .menu-desplegado {
  position: fixed; z-index: 41;
  top: 50%; left: 50%; right: auto; transform: translate(-50%, -50%);
  width: min(28rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem); overflow: auto;
  padding: 1.25rem;
  box-shadow: 0 1.25rem 3rem rgba(0, 0, 0, .35);
}
.dialogo-centrado > .menu-desplegado .linea { margin-top: .75rem; }
.dialogo-centrado > .menu-desplegado input[type=password] { flex: 1; min-width: 9rem; }

/* Para el alta por telefono, que son diez campos en dos columnas. Con los
   28rem de arriba la rejilla se quedaba en una sola columna y el formulario
   salia mas largo que la pantalla. */
.dialogo-ancho > .menu-desplegado { width: min(42rem, calc(100vw - 2rem)); }
/* La salida sin contrasena. Pulsar el velo tambien cierra, pero eso no se
   adivina mirando la pantalla. */
.menu-pie {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: .9rem 0 0;
}
.menu-pie .apunte { margin: 0; }
.linea-botones {
  display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; margin: 0;
}
.linea-botones input[type=email] { width: auto; flex: 1; min-width: 10rem; }

.aviso.exito {
  background: color-mix(in srgb, var(--verde) 12%, transparent);
  color: var(--verde);
  border-color: color-mix(in srgb, var(--verde) 30%, transparent);
}

/* --- Buscador de reservas ------------------------------------------------- */

.barra-buscar {
  display: flex; gap: .5rem; margin: 1rem 0 1.25rem; flex-wrap: wrap;
}
.barra-buscar input[type=search] {
  flex: 1; min-width: 14rem;
  padding: .6rem .7rem; font: inherit; font-size: .95rem;
  color: var(--texto); background: var(--superficie);
  border: 1px solid var(--borde); border-radius: 8px;
}

/* --- Volcado de ventas a Agora -------------------------------------------- */
/*
   La etiqueta va con su propia clase y no reutiliza `.ficha-estado-marca`
   porque aquella esta pensada para las fichas de reserva y arrastra tamanos
   que aqui, dentro de una celda de tabla, quedan enormes.
*/
.etiqueta-estado {
  display: inline-block; padding: .15rem .5rem; border-radius: 999px;
  font-size: .8rem; font-weight: 600; text-transform: capitalize;
  background: color-mix(in srgb, var(--texto) 10%, transparent);
}
.etiqueta-estado.estado-pendiente {
  background: color-mix(in srgb, var(--ambar) 20%, transparent); color: var(--ambar);
}
.etiqueta-estado.estado-enviado {
  background: color-mix(in srgb, var(--verde) 18%, transparent); color: var(--verde);
}
.etiqueta-estado.estado-error {
  background: color-mix(in srgb, var(--rojo) 18%, transparent); color: var(--rojo);
}

/* --- Dia reservado para un evento ----------------------------------------- */
/*
   Sustituye a la lista de horas, no se suma a ella: son dos respuestas
   distintas a la misma pregunta y ensenar las dos era lo que confundia.
*/
.evento-del-dia { text-align: center; }
.evento-del-dia .aviso { text-align: left; }
.evento-del-dia .boton { margin: .5rem 0 .25rem; }

/* --- Sala y mesas: los dos bloques ---------------------------------------- */
/*
   Nacen cerrados, tambien en el ordenador. Esta pantalla se configura muchas
   veces desde la tablet de la barra, y alli una pagina con la lista de mesas,
   los cupos por sala y el plano desplegados a la vez no se recorre con el
   dedo: se pierde uno.

   El titulo lleva el estado al lado -«12 dadas de alta», «3 sin colocar»-
   justamente para no tener que abrirlo para saber como va.
*/
.bloque-sala { margin: 1.25rem 0; }
.bloque-sala > summary {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  /* 48 px de alto: el minimo de Google para tocar con el dedo. Un summary de
     una linea de texto se falla una vez de cada tres en una tablet. */
  min-height: 48px; padding: .75rem 1rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  cursor: pointer; list-style: none;
}
.bloque-sala > summary::-webkit-details-marker { display: none; }
.bloque-sala > summary::after {
  content: "▾"; margin-left: auto; color: var(--texto-suave);
}
.bloque-sala[open] > summary::after { content: "▴"; }
.bloque-sala[open] > summary { border-radius: var(--radio) var(--radio) 0 0; }
.bloque-sala-titulo { font-size: 1.05rem; font-weight: 650; }
.bloque-sala-estado { color: var(--texto-suave); font-size: .88rem; }
.bloque-sala[open] > *:not(summary) { padding: 0 1rem; }
.bloque-sala[open] {
  border: 1px solid var(--borde); border-top: none;
  border-radius: 0 0 var(--radio) var(--radio);
  padding-bottom: 1rem;
}

/* Las salas, como blancos grandes en vez de una lista de enlaces. */
.salas-plano {
  display: grid; gap: .6rem; margin: 1rem 0;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.sala-plano {
  display: flex; flex-direction: column; gap: .2rem;
  min-height: 64px; padding: .8rem 1rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--superficie); color: var(--texto); text-decoration: none;
}
.sala-plano:hover { border-color: var(--acento); color: var(--acento); }
.sala-plano small { color: var(--texto-suave); }

/* --- Franja de «hecho» --------------------------------------------------- */
/*
   Sale arriba al volver de guardar y se va sola. La pinta avisos.js, que
   ademas te devuelve a donde estabas en la pagina.

   Va pegada arriba y no dentro del contenido a proposito: el sitio donde se
   guarda puede estar en cualquier parte de una pantalla larga, y un mensaje
   metido en el flujo aparece justo donde no estas mirando.

   z-index 60 la deja por encima de todo lo demas (lo mas alto era 41, el
   contenido de los dialogos). Un «guardado» tapado por un dialogo no existe.
*/
.franja-aviso {
  position: fixed;
  top: 1rem;
  left: 50%;
  z-index: 60;
  max-width: min(90vw, 28rem);
  padding: .7rem 1.25rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--superficie);
  box-shadow: var(--sombra);
  color: var(--texto);
  font-weight: 600;
  text-align: center;
  /* Sin puntero: es un cartel, no un boton, y esta justo encima de la
     cabecera. Si atrapara los clics, taparia lo que hay debajo. */
  pointer-events: none;
  /* Empieza fuera y transparente; `.puesta` la baja. `translate` en X es fijo:
     el -50% es lo que la centra de verdad, porque `left:50%` deja su borde
     izquierdo en el centro, no su centro. */
  opacity: 0;
  transform: translate(-50%, -.75rem);
  transition: opacity .25s ease, transform .25s ease;
}

.franja-aviso.puesta {
  opacity: 1;
  transform: translate(-50%, 0);
}

.franja-aviso::before {
  content: "✓";
  margin-right: .5rem;
  color: var(--verde);
  font-weight: 700;
}

/* --- Distintivo de estado ------------------------------------------------ */
/*
   Va en la solapa de un desplegable y dice, en una linea, si aquello funciona.
   Nace de un dia perdido: la integracion con Agora estaba apagada, el agente
   del restaurante llamaba cada minuto y se le contestaba que no, y la pantalla
   no lo decia en ningun sitio. El estado tiene que verse SIN abrir nada.

   Los colores no van solos: el texto ya dice que pasa. Quien no distingue el
   verde del rojo lee «El agente pasó hace 40 segundos» igual de bien.
*/
.chip-estado {
  display: inline-block;
  margin-left: .5rem;
  padding: .15rem .6rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--fondo);
  color: var(--texto-suave);
  font-size: .8125rem;
  font-weight: 600;
  /* Que no herede el peso de la solapa ni la parta a la mitad. */
  white-space: normal;
}

/* --- EL MAPA DE PASOS DE ÁGORA -------------------------------------------
   Lo primero que se ve al abrir esa parte: por dónde vas. Antes era una pared
   de quince campos y veinte párrafos, todos con el mismo peso, cuando en
   realidad son una secuencia —sin el programita no hay catálogo, y sin
   catálogo los desplegables están vacíos—.

   Cada línea lleva a su paso. No esconde nada: los campos siguen todos abajo,
   porque un campo escondido no se envía y un campo que no se envía borra lo
   que hubiera guardado. */
.mapa-pasos {
  margin: .75rem 0 1rem; padding: .75rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
  background: var(--fondo);
}
.mapa-pasos-cuenta { margin: 0 0 .5rem; }
.lista-pasos { list-style: none; margin: 0; padding: 0; }
.lista-pasos > li + li { margin-top: .25rem; }
.lista-pasos a {
  display: flex; align-items: center; gap: .6rem;
  padding: .4rem .5rem; border-radius: var(--radio-control, 6px);
  color: inherit; text-decoration: none;
}
.lista-pasos a:hover { background: var(--superficie); }
.paso-texto { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.paso-texto small { color: var(--texto-suave); }
/* El chip del final se va a la derecha y no se parte. */
.lista-pasos .chip-estado { margin-left: auto; flex: none; }

/* El número del paso, o el ✓ cuando está hecho. Redondo y del color de su
   estado: es lo que se lee de un vistazo sin tener que leer nada. */
.paso-numero {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; border-radius: 999px;
  border: 2px solid var(--borde);
  font-weight: 700; font-size: .9rem;
  font-variant-numeric: tabular-nums;
}
.paso-bien   .paso-numero,
.paso-numero.paso-bien   { border-color: var(--verde); color: var(--verde); }
.paso-aviso  .paso-numero,
.paso-numero.paso-aviso  { border-color: var(--ambar); color: var(--ambar); }
.paso-espera .paso-numero,
.paso-numero.paso-espera { border-color: var(--borde); color: var(--texto-suave); }

/* El título de cada paso dentro del formulario, para que se vea que empieza
   otro tramo y no una fila más de campos. */
.titulo-paso {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin: 1.75rem 0 .25rem; padding-top: .75rem;
  border-top: 1px solid var(--borde);
}
.titulo-paso .chip-estado { margin-left: auto; }

.chip-estado.chip-bien   { border-color: var(--verde); color: var(--verde); }
.chip-estado.chip-aviso  { border-color: var(--ambar); color: var(--ambar); }
.chip-estado.chip-mal    { border-color: var(--rojo);  color: var(--rojo); }
.chip-estado.chip-espera { border-color: var(--ambar); color: var(--ambar); }

/* --- Tocar varias mesas a la vez ----------------------------------------- */
/*
   La casilla de cada fila y la barra que sale al marcar mas de una. Al montar
   una sala, o al cerrar la terraza en octubre, se toca la sala entera: de una
   en una son cincuenta pulsaciones.
*/
.casilla-lote {
  /* Sin `<span>` de texto al lado: lo que dice para que sirve son su `title` y
     su `aria-label`, y una etiqueta escrita aqui repetiria «Seleccionar»
     cincuenta veces en una pantalla que ya va llena. */
  margin-left: .25rem;
  padding: .25rem;
}

/* Se apunta por la clase de la casilla y no por `.casilla-lote input`: es la
   misma que usa el guion para encontrarlas, y tener dos formas distintas de
   señalar el mismo elemento es como se acaba cambiando una y olvidando la
   otra. Ademas, una clase usada en las plantillas y sin regla en la hoja la
   caza `prueba_tema`, y con razon. */
.marca-lote {
  /* 20px y no el tamano de fabrica: esto se toca con el dedo en una tablet, y
     una casilla de 13px al lado de un boton de «Borrar» es una pulsacion mal
     dada esperando a ocurrir. */
  width: 20px;
  height: 20px;
}

.barra-lote {
  position: sticky;
  /* Pegada arriba mientras se recorre la lista: las mesas se marcan bajando, y
     una barra que se queda en la cabecera obliga a subir para pulsarla. */
  top: .5rem;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-bottom: .75rem;
  padding: .6rem .9rem;
  border: 1px solid var(--acento);
  border-radius: var(--radio);
  background: var(--superficie);
  box-shadow: var(--sombra);
}

/* --- El aviso del restaurante en el formulario de reservas --------------- */
/*
   Lo escribe el restaurante y lo lee el cliente justo debajo del titulo, antes
   de elegir nada. Se distingue del texto normal pero sin gritar: no es un
   error ni una alarma, es una condicion de la casa.
*/
.aviso-widget {
  margin: .75rem 0 1rem;
  padding: .7rem .9rem;
  border-left: 3px solid var(--acento);
  border-radius: 0 var(--radio) var(--radio) 0;
  background: var(--acento-suave);
  color: var(--texto);
  /* Los saltos de linea que escriba se respetan: si separa dos condiciones en
     dos renglones, es porque son dos. */
  white-space: pre-wrap;
}

/* --- Apuntar una reserva pinchando una mesa del plano -------------------- */
/*
   Solo las libres, y solo para quien puede apuntar reservas: `alta_en_mesa.js`
   marca esas con `data-libre`. Las demas se quedan como estaban, para mirar.
*/
.plano.solo-lectura .pieza.mesa[data-libre] {
  cursor: pointer;
}

.plano.solo-lectura .pieza.mesa[data-libre]:hover {
  /* Un borde y no un cambio de fondo: el fondo de una mesa YA significa algo
     -libre, ocupada, desactivada- y pisarlo al pasar por encima haria dudar
     de lo que se esta viendo. */
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}

/* --- Ver un bloque escondido sin colocarlo -------------------------------- */
/*
   Los botones del pie de Reservas ENSENAN su informacion en el centro de la
   pantalla. Colocarlos en el tablero sigue detras de «Recolocar la pantalla»:
   esa pantalla vive abierta todo el servicio en la tablet de la barra y no
   puede descolocarse de un roce. Mirar no descoloca nada.
*/
.ficha-velo {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, .45);
}

.ficha-caja {
  width: min(680px, 100%);
  /* Que quepa en la tablet de la barra en horizontal, con su barra de
     desplazamiento propia si el bloque es largo. */
  max-height: 85vh;
  overflow: auto;
  padding: .85rem 1rem 1rem;
  border-radius: var(--radio);
  background: var(--superficie);
  box-shadow: var(--sombra);
}

.ficha-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .6rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--borde);
}

/* Dentro de la ficha el bloque deja de estar COLOCADO: en el tablero va con
   position absoluta y medidas en pixeles, y eso aqui lo sacaria del recuadro o
   lo dejaria de tres dedos de alto. */
.ficha-caja .bloque.en-ficha {
  position: static;
  left: auto;
  top: auto;
  width: auto;
  height: auto;
  max-height: none;
  /* Y sin el recorte del tablero, que es lo que esconde lo que sobra. */
  overflow: visible;
}

/* La barra de arrastrar y el tirador no pintan nada aqui: desde la ficha no se
   coloca. */
.ficha-caja .bloque-barra,
.ficha-caja .bloque-tirador { display: none; }

/* --- La lista de escondidos, con su orden -------------------------------- */
/*
   Un numero al lado de cada uno: 1 el primero, 2 el segundo. Se probo antes a
   ordenarlos arrastrandolos y no valia: acertar con el dedo es dificil, y
   sobre todo NO SE VE el orden -no hay forma de decir «este el quinto» sin ir
   moviendolo de uno en uno-. Escribir el numero se hace de un vistazo.
*/
.lista-escondidos {
  display: flex;
  flex-direction: column;
  gap: .35rem;
}

.fila-escondido {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .3rem .4rem;
  border-radius: var(--radio);
}

.fila-escondido:hover { background: var(--fondo); }

.fila-escondido input[type=number] {
  /* Justo para dos cifras: mas ancho invita a escribir cosas que no son un
     orden, y en una tablet cada milimetro cuenta. */
  width: 4rem;
  flex: 0 0 auto;
  text-align: center;
}

.lista-escondidos button[type=submit] { margin-top: .5rem; align-self: start; }

/* --- La cola de la lista de espera --------------------------------------- */
/*
   Se lee de pie, en la puerta, mientras alguien pregunta cuanto falta. Lo
   unico que importa es el orden, asi que el numero manda.
*/
.cola-espera {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .6rem;
}

.turno-espera { padding: .8rem 1rem; }

.turno-cabeza {
  display: flex;
  align-items: flex-start;
  gap: .9rem;
  margin-bottom: .6rem;
}

.turno-numero {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 2.2rem: el numero del turno se busca de un vistazo desde medio metro, que
     es a lo que se mira una tablet apoyada en la barra. */
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 999px;
  background: var(--acento);
  color: var(--sobre-relleno);
  font-weight: 700;
}

/* La mesa de la espera, en el plano. Se distingue de una mesa de verdad: no se
   sienta a nadie ahi, se pulsa para ver la cola. */
.pieza.mesa[data-espera] {
  border-style: dashed;
  cursor: pointer;
}

/* --- Los dos botones de quien esta esperando ----------------------------- */
/*
   «Avisar: mesa lista» y «Llamar», en la ficha de una reserva que esta en la
   lista de espera. Separados del resto de la ficha porque son acciones sobre
   una persona que esta de pie en la puerta: se buscan con prisa.
*/
.espera-acciones {
  margin-top: .5rem;
  padding-top: .5rem;
  border-top: 1px dashed var(--borde);
}

/* --- «Sitio para ordenador» encendido en un telefono ----------------------
   Una franja arriba del todo, no un dialogo: no tapa nada, no hay que cerrarla
   para seguir y se lee de camino. Ver `app/static/aviso_escritorio.js`, que es
   quien decide cuando sale -y solo sale con las tres condiciones a la vez-. */
.aviso-escritorio {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: .75rem 1rem;
  background: var(--ambar-suave, #fff4d6);
  border-bottom: 2px solid var(--ambar, #d98d00);
  color: #4a3200;
}
.aviso-escritorio p { margin: 0; font-size: 1rem; line-height: 1.35; flex: 1 1 16rem; }
.aviso-escritorio strong { font-weight: 700; }
/* El boton NO hereda el color de la franja: en modo oscuro el texto va en
   marron sobre ambar y un boton de ese marron sobre ese ambar no se lee. */
.aviso-escritorio .boton { flex: none; }


/* --- Elegir el color de cada estado, en Ajustes --------------------------- */
.rejilla-colores {
  display: grid; gap: .6rem; margin: .5rem 0 .75rem;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}
.color-estado {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  margin: 0; padding: .4rem .6rem;
  border: 1px solid var(--borde); border-radius: var(--radio);
}
.color-estado > span { font-size: .9rem; font-weight: 500; }
/* 44 px de lado: esto se toca con el dedo en la tablet de la barra, y un
   selector de color pequeno es de lo mas dificil de acertar que hay. */
.color-estado input[type=color] {
  width: 44px; height: 44px; padding: 0; flex: none;
  border: 1px solid var(--borde); border-radius: 6px; background: none;
  cursor: pointer;
}


/* --- La pantalla de Ayuda ------------------------------------------------- */
.buscador-ayuda { display: flex; gap: .5rem; margin: 0 0 1rem; }
.buscador-ayuda input[type=search] { flex: 1; min-width: 0; }
/* 44 px: se toca con el dedo en la tablet de la barra. */
.buscador-ayuda input[type=search], .buscador-ayuda .boton { min-height: 44px; }

.lista-ayuda { list-style: none; margin: .25rem 0 1rem; padding: 0; }
.lista-ayuda > li {
  padding: .6rem 0; border-bottom: 1px solid var(--borde);
}
.lista-ayuda > li:last-child { border-bottom: none; }
.lista-ayuda > li > a { font-weight: 600; display: block; }
/* El resumen debajo y no al lado: al lado, en un telefono, parte el titulo en
   tres lineas y deja de leerse cual es cual. */
.lista-ayuda > li > .apunte { display: block; margin: .15rem 0 0; }

.ayuda-seccion {
  margin: 1.25rem 0 .25rem; font-size: .8rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--texto-suave);
}

/* El cuerpo de un articulo. Se le da aire y una medida de linea comoda: son
   textos para leer, no para ojear. */
.articulo-ayuda { line-height: 1.6; max-width: 42rem; }
.articulo-ayuda p { margin: 0 0 .9rem; }
.articulo-ayuda ul, .articulo-ayuda ol { margin: 0 0 .9rem 1.2rem; }
.articulo-ayuda li { margin: 0 0 .4rem; }
.articulo-ayuda code {
  font-family: ui-monospace, Consolas, monospace; font-size: .9em;
  background: var(--acento-suave); padding: .1rem .3rem; border-radius: 4px;
}

/* Para las etiquetas que solo tienen que leer los lectores de pantalla. */
.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* --- Pestañas de una pantalla con dos caras ------------------------------- */
.pestanas {
  display: flex; gap: .25rem; flex-wrap: wrap;
  margin: 0 0 1.25rem; border-bottom: 1px solid var(--borde);
}
.pestana {
  padding: .55rem .9rem; border-radius: var(--radio) var(--radio) 0 0;
  color: var(--texto-suave); text-decoration: none; font-weight: 500;
  /* Un borde transparente SIEMPRE, no solo en la activa: si se pone solo en
     una, al cambiar de pestaña las demas se mueven dos pixeles. */
  border: 1px solid transparent; border-bottom: none;
  min-height: 44px; display: flex; align-items: center;
}
.pestana:hover { color: var(--texto); background: var(--acento-suave); }
.pestana.activa {
  color: var(--texto); font-weight: 600;
  background: var(--superficie); border-color: var(--borde);
  /* Tapa la linea de abajo: es lo que hace que parezca una carpeta abierta y
     no un boton mas. */
  margin-bottom: -1px; padding-bottom: calc(.55rem + 1px);
}

/* --- La vista previa del widget, en la pantalla de ajustes ----------------
   Vive en la hoja DE SIEMPRE porque la pantalla que la enseña es del panel de
   siempre. Lo que pinta son variables propias -`--ap-*`- y no los tokens de la
   piel nueva: si usara los tokens, la previa cambiaria al cambiar el tema del
   panel y estaria enseñando algo que no es lo que vera el cliente. */
.previa-widget {
  --ap-acento: #86653C;
  --ap-encima: #F2EDE6;
  --ap-titulo: Georgia, serif;
  --ap-texto: system-ui, sans-serif;
  --ap-radio: 4px;
  --ap-radio-carta: 10px;
  --ap-aire: 1;
  --ap-fondo: #FAF7F2;
  --ap-tinta: #1A1714;
  --ap-suave: #4A443D;
  --ap-borde: #E8E0D4;

  background: var(--ap-fondo);
  color: var(--ap-tinta);
  border: 1px solid var(--ap-borde);
  border-radius: var(--ap-radio-carta);
  padding: calc(1.5rem * var(--ap-aire));
  font-family: var(--ap-texto);
}
.previa-widget[data-tema="oscuro"] {
  --ap-fondo: #14120F; --ap-tinta: #F2EDE6;
  --ap-suave: #A9A196; --ap-borde: #2A2620;
}
.previa-titulo {
  font-family: var(--ap-titulo);
  font-size: 1.6rem; line-height: 1.15; margin: 0 0 .4rem;
}
.previa-apunte { color: var(--ap-suave); margin: 0 0 calc(1rem * var(--ap-aire)); }
.previa-horas {
  display: flex; gap: .5rem; flex-wrap: wrap;
  margin-bottom: calc(1rem * var(--ap-aire));
}
.previa-hora {
  padding: .5rem .75rem; min-width: 4.5rem; text-align: center;
  border: 1px solid var(--ap-borde); border-radius: var(--ap-radio-carta);
  font-variant-numeric: tabular-nums;
}
.previa-boton {
  display: block; text-align: center;
  padding: calc(.85rem * var(--ap-aire)) 1rem;
  background: var(--ap-acento); color: var(--ap-encima);
  border-radius: var(--ap-radio); font-weight: 600;
}

/* =========================================================================
   EL PLANO DEL CLIENTE: elegir mesa al reservar
   =========================================================================

   Solo sale si el restaurante enciende `elegir_mesa_online`. Es una pantalla
   nueva, no un cambio de la que habia: quien no lo encienda no ve nada de
   esto.

   El marcado es UNO y sirve para las dos formas de verlo, porque son botones
   de radio de verdad y lo unico que cambia es donde se colocan:

     - en el ordenador, sobre el lienzo, con las coordenadas del plano,
     - en el telefono, sueltos, en una lista de fichas que se puede tocar.

   Por eso la geometria viaja en --x/--y/--w/--h y no en `left`/`top`: un
   `left` escrito en el atributo `style` gana a cualquier hoja y habria que
   pelearlo con `!important` en cada pieza. Una propiedad la usa quien quiere.
   ========================================================================= */
.elegir-mesa { margin-top: 1rem; }
.elegir-mesa .sala-titulo {
  margin: 1rem 0 .35rem; font-weight: 600; font-size: .9rem;
  color: var(--texto-suave, inherit);
}
.sitio-cualquiera {
  display: flex; align-items: center; gap: .5rem;
  /* 44 px de alto: es la primera opcion y la que mas gente va a pulsar. */
  min-height: 44px;
}
.sitio-cualquiera input { width: 1.15rem; height: 1.15rem; }

.plano-cliente {
  position: relative; width: 100%;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  overflow: hidden;
}

/* La pieza no pinta nada: lo pinta su texto. Asi el estado -elegida, apagada,
   con el foco- se puede sacar con `input:checked + .sitio-texto`, que funciona
   en todos los navegadores, en vez de con `:has()` en el padre. */
.sitio { display: block; }
.sitio input {
  /* El radio no se esconde con `display: none`: eso lo saca del recorrido del
     teclado y deja de poder elegirse sin raton. Se aparta a un pixel invisible
     y sigue existiendo para todo lo demas. */
  position: absolute; width: 1px; height: 1px;
  opacity: 0; margin: 0; pointer-events: none;
}
.sitio-texto {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; width: 100%; height: 100%;
  padding: 2px; overflow: hidden; text-align: center;
  line-height: 1.15; font-size: .78rem;
  background: color-mix(in srgb, var(--verde) 10%, var(--superficie));
  border: 2px solid var(--verde);
  color: var(--texto);
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease;
}
.sitio-texto strong { display: block; }
.sitio-texto small { display: block; opacity: .8; font-size: .85em; }

.sitio.forma-redonda .sitio-texto { border-radius: 50%; }
.sitio.forma-cuadrada .sitio-texto,
.sitio.forma-rectangular .sitio-texto { border-radius: 8px; }

.sitio input:checked + .sitio-texto {
  background: var(--acento); border-color: var(--acento);
  /* Blanco a pelo, como `.boton`: es el mismo fondo y en esta piel el acento
     no se le deja elegir al restaurante, asi que no hay nada que calcular. */
  color: var(--sobre-relleno);
  /* La elegida se nota por TRES cosas -color, sombra y tamaño-, no solo por
     el color: en un plano lleno de recuadros verdes, un verde distinto no lo
     ve quien no distingue bien los colores. */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--acento) 35%, transparent);
  transform: scale(1.06);
}
/* El foco SIEMPRE visible: es lo unico que tiene quien navega con teclado
   para saber en que mesa esta. */
.sitio input:focus-visible + .sitio-texto {
  outline: 3px solid var(--acento); outline-offset: 3px;
}
.sitio input:disabled + .sitio-texto {
  background: var(--superficie); border-color: var(--borde);
  border-style: dashed; color: var(--texto-suave, inherit);
  opacity: .65; cursor: not-allowed; transform: none; box-shadow: none;
}

.plano-cliente .adorno {
  position: absolute;
  left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  display: flex; align-items: center; justify-content: center;
  font-size: .7rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--texto-suave, inherit);
  background: color-mix(in srgb, var(--borde) 45%, transparent);
  border-radius: 4px;
}
.plano-cliente .adorno.rotulo { background: none; }

/* --- En pantalla ancha: el plano de verdad ------------------------------- */
@media (min-width: 701px) {
  .plano-cliente {
    aspect-ratio: var(--lienzo, 2 / 1);
    /* La rejilla de fondo, como en el editor: sin una referencia, un plano
       flotando en blanco no se lee como una sala. */
    background-image:
      linear-gradient(var(--borde) 1px, transparent 1px),
      linear-gradient(90deg, var(--borde) 1px, transparent 1px);
    background-size: 5% 7.5%;
  }
  .plano-cliente .sitio {
    position: absolute;
    left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  }
}

/* --- En el telefono: fichas, no plano -----------------------------------
   Un lienzo de 1200 px de ancho reducido a 360 deja mesas de 25 px: no se
   pueden leer y no se pueden tocar. Antes que un plano ilegible, la misma
   lista de mesas en fichas de 44 px, que es lo que se pide para tocar con el
   pulgar.

   Los adornos desaparecen: sin plano no orientan a nadie, y en una lista son
   recuadros grises sin sentido. */
@media (max-width: 700px) {
  .plano-cliente {
    display: flex; flex-wrap: wrap; gap: .5rem;
    padding: .6rem; border-radius: var(--radio);
  }
  .plano-cliente .adorno { display: none; }
  .plano-cliente .sitio { flex: 1 1 7.5rem; max-width: 12rem; }
  .sitio-texto {
    min-height: 44px; padding: .45rem .3rem; font-size: .85rem;
  }
  /* En fichas, la forma de la mesa no dice nada de donde esta: todas iguales
     y que mande el texto. */
  .plano-cliente .sitio .sitio-texto { border-radius: 8px; }
}

/* El marco: en pantalla ancha el plano SE SALE de la columna del formulario.
   La columna mide 540 px de lectura y ahi un lienzo de 1200 deja mesas de
   41 px con el rotulo cortado -medido, siete de quince-. Y si aun asi no cabe,
   se desplaza de lado, como el plano del panel. */
.plano-marco-cliente { margin: 0 0 .5rem; }
@media (min-width: 701px) {
  .plano-marco-cliente {
    width: min(88vw, 900px);
    /* Centrado y desbordando la columna: si la columna es mas ancha que el
       tope, el margen sale positivo y simplemente queda centrado. */
    margin-left: calc((100% - min(88vw, 900px)) / 2);
    overflow-x: auto;
  }
  /* Por debajo de esto los rotulos dejan de leerse: antes que encogerlos mas,
     que se desplace. */
  .plano-cliente { min-width: 620px; }
}
/* Y si aun asi un rotulo no cabe, que termine en puntos suspensivos en vez de
   partirse en dos renglones dentro de una mesa de 40 px. */
.sitio-texto small {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%;
}

/* --- Sin conexión --------------------------------------------------------
   La franja que sale cuando el panel está enseñando lo último que descargó.

   Va en ROJO y no en ámbar, al contrario que la de suplantación: aquello es
   un aviso -«ojo, estás dentro de otro restaurante»- y esto es una
   imposibilidad -«no se puede guardar nada»-. Si las dos se pintaran igual,
   la segunda se leería como la primera y alguien seguiría dando por hecho que
   lo que toca se guarda.

   Solo la pinta `instalar.js`, que únicamente se carga en el panel y para quien
   tenga la interfaz nueva. Ver `sw.js`. */
.franja-sin-linea {
  padding: .55rem 1.1rem;
  background: color-mix(in srgb, var(--rojo) 16%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--rojo) 40%, transparent);
  color: var(--rojo);
  font-size: .88rem;
  font-weight: 600;
  text-align: center;
}

/* --- Las entradas de un evento ------------------------------------------
   El QR de cada una, para enseñarlo en la puerta. Una por persona: la entrada
   de Ágora se consume entera y no hay «admite N». */
.entradas {
  display: flex; flex-wrap: wrap; gap: 1rem;
  margin: 1rem 0;
}
.entrada {
  flex: 1 1 12rem; max-width: 16rem;
  padding: 1rem;
  background: var(--superficie);
  border: 1px solid var(--borde); border-radius: var(--radio);
  text-align: center;
}
/* FONDO BLANCO SIEMPRE, tambien en tema oscuro. Un QR en negativo no lo lee
   la mitad de los lectores, y este se escanea en la puerta de un local de
   noche: no es el sitio para descubrirlo. */
.entrada-qr {
  display: block; width: 100%; height: auto; max-width: 232px;
  margin: 0 auto .5rem;
  background: #fff; padding: 4px; border-radius: 4px;
  image-rendering: pixelated;      /* que los cuadraditos no se emborronen */
}
.entrada .codigo { font-size: 1.05rem; letter-spacing: .08em; margin: 0; }

/* --- El editor de la descripcion, en el panel ------------------------------
   La lista de bloques a la izquierda y como va a quedar a la derecha. Mismo
   corte que el editor del papel y por el mismo motivo medido: por debajo de
   900 px las dos columnas dejan cada una en la mitad de nada. */
.desc-taller { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; align-items: start; }
/* Apiladas, LA PREVIA VA PRIMERO. Puesta debajo de la lista había que bajar
   por todos los bloques para ver el resultado de lo que se acababa de
   escribir, o sea que no se veía: lo que se está mirando mientras se teclea
   tiene que estar arriba. Y con tope de alto, o en un teléfono la previa se
   come la pantalla y no queda sitio para escribir. */
@media (max-width: 900px) {
  .desc-taller { grid-template-columns: 1fr; }
  .desc-previa { order: -1; }
  .desc-previa-caja { max-height: 45vh; overflow: auto; }
}

/* La columna de la izquierda: la lista de bloques. Sin regla propia salvo el
   hueco, pero escrita a proposito — `prueba_tema` exige que toda clase usada
   en una plantilla tenga regla, y con razon: una clase sin regla suele ser una
   errata que nadie ve hasta que un cliente lo ve raro. */
.desc-lista { min-width: 0; }

.desc-bloque {
  border: 1px solid var(--borde); border-radius: var(--radio);
  padding: .8rem .9rem; margin-bottom: .8rem;
}
.desc-bloque:last-child { margin-bottom: 0; }
.desc-bloque label { margin-bottom: .6rem; }
.desc-bloque label:last-child { margin-bottom: 0; }
.desc-bloque-cabecera {
  display: flex; align-items: center; gap: .35rem; margin-bottom: .7rem;
}
.desc-bloque-tipo {
  flex: 1; min-width: 0; font-size: .8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--texto-suave);
}
/* Cuadradas y de dedo: se pulsan varias veces seguidas para subir un bloque. */
.desc-bloque-cabecera .boton {
  flex: none; min-width: 40px; min-height: 40px; padding: 0; line-height: 1;
}
/* La previa se queda a la vista mientras se baja por una lista larga. */
.desc-previa { position: sticky; top: 1rem; }
.desc-previa h3 { margin-top: 0; }
.desc-previa-caja { padding: 1.25rem; }
.desc-previa-caja .descripcion-evento:empty::after {
  content: "Aquí se verá la descripción."; color: var(--texto-suave); font-size: .87rem;
}

/* --- La descripcion de un evento, por bloques -----------------------------
   Lo que elige el restaurante es el PAPEL de cada trozo -titular, texto, pie-
   y aqui se decide como se ve. Ni una medida en pixeles para el texto: en
   `em`, para que crezca con la letra que tenga puesta cada uno.

   Y NADA DE POSICIONES. Esto se ve en un monitor de 27 pulgadas y en un
   telefono de 360 px: lo unico que sobrevive a ese cambio de ancho es el
   tamano, el alineado y la clase de letra. Un bloque puesto «a 8 cm del
   borde» se sale de la pantalla del telefono y no hay CSS que lo salve. */
.descripcion-evento { margin: 0 0 1.5rem; }
.descripcion-evento > * { margin: 0 0 .9rem; }
.descripcion-evento > *:last-child { margin-bottom: 0; }

.de-titulo { letter-spacing: -.01em; line-height: 1.2; }
.de-texto { color: var(--texto-suave); line-height: 1.6; white-space: pre-line; }
/* El recuadro: para lo que no se puede pasar por alto -«ven en ayunas», «se
   paga entero al reservar»-. Con borde Y fondo, nunca solo color: un aviso
   que solo se distingue por el tono no lo ve quien no distingue ese tono. */
.de-destacado {
  padding: .8rem 1rem; line-height: 1.55;
  background: var(--acento-suave);
  border-left: 3px solid var(--acento);
  border-radius: 0 var(--radio) var(--radio) 0;
  white-space: pre-line;
}
.de-separador {
  border: none; border-top: 1px solid var(--borde); margin: 1.4rem 0;
}

/* Los cuatro tamanos, por lo que SON. `em` y no `px`: asi «grande» sigue
   siendo grande si alguien tiene el navegador a 20 px. */
.descripcion-evento .pequeno { font-size: .85em; }
.descripcion-evento .normal  { font-size: 1em; }
.descripcion-evento .grande  { font-size: 1.35em; }
.descripcion-evento .enorme  { font-size: 1.8em; }

.descripcion-evento .hacia-izquierda { text-align: left; }
.descripcion-evento .hacia-centro    { text-align: center; }
.descripcion-evento .hacia-derecha   { text-align: right; }

/* CON GRACIAS O SIN ELLAS, y son las dos que el restaurante ya eligio en
   Ajustes. No hay un selector de fuentes: con uno, la pagina del evento
   dejaria de parecerse al resto de su web. */
.descripcion-evento .letra-gracias     { font-family: var(--serif, Georgia, serif); }
.descripcion-evento .letra-sin_gracias { font-family: var(--sans, system-ui, sans-serif); }

.de-imagen { margin-inline: auto; }
.de-imagen img {
  display: block; width: 100%; height: auto; border-radius: var(--radio);
}
.de-imagen figcaption { margin-top: .4rem; text-align: center; }
/* En porcentaje del ancho disponible, no en pixeles. Y en el telefono todas a
   ancho completo: una imagen al 45% de 360 px son 160 px, que no es una foto,
   es un sello. */
.de-imagen.ancho-estrecha { max-width: 45%; }
.de-imagen.ancho-media    { max-width: 70%; }
.de-imagen.ancho-completa { max-width: 100%; }
@media (max-width: 560px) {
  .de-imagen.ancho-estrecha, .de-imagen.ancho-media { max-width: 100%; }
}

/* --- Los campos de cada pasarela -----------------------------------------
   Cada una pide datos distintos -una, clave publica y secreto de webhook;
   otra, comercio y terminal- y ensenarlos todos a la vez es como se rellena el
   campo equivocado.

   Quien decide cual se ve es la clase que pone el SERVIDOR en el formulario.
   Sin JavaScript se ven los de la pasarela guardada, que es lo correcto; el
   guion solo adelanta el cambio al momento de elegir en el desplegable.

   `revert` y no `block`: aqui dentro hay `span`, `label`, `div` y `p`, y
   forzarles a todos el mismo `display` convertiria las etiquetas en bloques y
   partiria las lineas. */
.solo-stripe, .solo-redsys { display: none; }
.pasarela-stripe .solo-stripe,
.pasarela-redsys .solo-redsys { display: revert; }

/* --- El editor del papel del regalo ---------------------------------------
   La hoja se pinta con la proporcion de una A5 apaisada -210 x 148 mm- y todo
   lo de dentro lo coloca `papel_regalo.js` en pixeles calculados a partir de
   su ancho. Aqui no hay ni una medida de las piezas: si estuvieran en los dos
   sitios, un dia dirian cosas distintas. */
.papel-barra {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
  justify-content: space-between; margin-bottom: .9rem;
}
.papel-anadir, .papel-acciones { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }

.papel-taller { display: grid; grid-template-columns: 1fr 20rem; gap: 1.25rem; align-items: start; }
/* En pantalla estrecha, la hoja arriba y sus ajustes debajo.

   ESTE CORTE ES 900 Y NO 700 COMO EL RESTO, y es el mismo caso que
   `.fila-tarjetas`: no es la regla general, es una medida. MEDIDO en el
   navegador a 768 px -una tableta de pie- forzando las dos columnas: el lado
   se queda en sus 320 px y la hoja cae a 322 x 227. Una A5 de ese tamaño hace
   que un texto de 9 puntos se pinte de 7 px y que una pieza de tres
   milimetros mida cuatro: no se puede colocar nada con el dedo. Ahi la hoja
   entera arriba y los ajustes debajo es mejor pantalla, no una version
   recortada.

   Y OJO CON DONDE VIVE ESTA REGLA: `prueba_movil` mira el trozo de hoja que
   va de `.tablero` a `.servicio-lista` y exige que ahi NO haya ningun corte en
   900, porque en la pantalla del dia un corte asi le apila los bloques a una
   tableta. Esto no es la pantalla del dia; por eso esta seccion vive aqui,
   lejos de aquella. */
@media (max-width: 900px) { .papel-taller { grid-template-columns: 1fr; } }

.papel-hoja {
  position: relative;
  aspect-ratio: 210 / 148;
  background: #ffffff;
  border: 1px solid var(--borde);
  box-shadow: var(--sombra);
  /* La hoja es blanca SIEMPRE, tambien en modo oscuro: se esta colocando algo
     que se va a imprimir en papel blanco, y ensenarlo sobre fondo negro
     enganaria sobre como queda. Por eso el texto de dentro tampoco hereda el
     color del tema. */
  color: #000000;
  overflow: hidden;
  touch-action: none;   /* o el navegador se lleva el gesto como scroll */
}

.papel-pieza {
  position: absolute; display: flex; align-items: center; justify-content: center;
  overflow: hidden; cursor: move; outline: none;
}
.papel-pieza span { display: block; width: 100%; line-height: 1.2; }
.papel-pieza img { max-width: 100%; max-height: 100%; object-fit: contain; }
.papel-marco { border: 1px solid #000000; }
.papel-linea::after { content: ""; display: block; width: 100%; border-top: 1px solid #000000; }
.papel-qr {
  border: 1px dashed #999; color: #666; font-size: .7rem; letter-spacing: .1em;
}
/* La elegida se marca con borde Y con el tirador, no solo con color: una
   marca que solo es un tono no la ve quien no distingue ese tono. */
.papel-pieza.elegida { outline: 2px solid var(--acento); outline-offset: 1px; }
.papel-tirador {
  position: absolute; right: 0; bottom: 0; width: 14px; height: 14px;
  background: var(--acento); cursor: nwse-resize;
}

.papel-lado h3 { margin-top: 0; }
.papel-huecos { margin-top: 1rem; }
.papel-huecos summary { cursor: pointer; font-size: .87rem; }
.papel-huecos code { font-size: .82rem; }

.papel-galeria { list-style: none; display: flex; flex-wrap: wrap; gap: .8rem; padding: 0; margin: 0 0 1rem; }
.papel-galeria li { width: 7rem; }
.papel-galeria img {
  display: block; width: 100%; height: 4.5rem; object-fit: contain;
  background: #fff; border: 1px solid var(--borde); border-radius: var(--radio);
}


/* --- Una pregunta de sí o no en los ajustes ------------------------------
   El campo con su casilla de «¿cuántas?» EN LA MISMA FILA. Antes iban en dos
   filas cada una y con la explicación repetida: ocho bloques apilados para
   configurar cuatro preguntas, que es donde se pierde quien las configura.

   La casilla se alinea abajo (`align-items: end`) porque el campo lleva su
   etiqueta encima: centrada, quedaba flotando a media altura del hueco. */
.pregunta-casilla {
  display: flex; align-items: end; gap: .75rem; flex-wrap: wrap;
  margin-bottom: .6rem;
}
.pregunta-casilla > label:first-child { flex: 1 1 18rem; margin: 0; }
/* Alto de campo para que la casilla no baile respecto al hueco de al lado. */
.pregunta-casilla .casilla { min-height: 42px; white-space: nowrap; }

/* LOS BOTONES DE «¿carta o menú?».
 *
 * Con el aspecto del boton de enviar, que es lo que se pidio. PERO el elegido
 * va macizo y los demas no: si todos fueran del color de marca no se veria
 * cual esta marcado -lo unico que este control tiene que decir- y competirian
 * con el boton que de verdad cierra la reserva.
 *
 * Por dentro son radios escondidos: funciona sin JavaScript y el teclado
 * elige con las flechas. */
.elegir-menu { border: none; margin: .5rem 0 1rem; padding: 0; }
.elegir-menu legend {
  padding: 0 0 .4rem; font-size: .87rem; font-weight: 600;
  color: var(--texto-suave);
}
.botones-menu { display: flex; flex-wrap: wrap; gap: .5rem; }

.boton-menu {
  flex: 1 1 11rem;
  display: flex; flex-direction: column; align-items: center; gap: .15rem;
  margin: 0; padding: .7rem 1rem; min-height: 44px;
  border: 2px solid var(--acento); border-radius: 8px;
  background: transparent; color: var(--texto);
  font: inherit; font-weight: 600; text-align: center; cursor: pointer;
}
/* Invisible pero NO `display:none`: sin ella en el flujo no recibe el foco. */
.boton-menu input[type=radio] {
  position: absolute; opacity: 0; width: 1px; height: 1px;
}
.boton-menu:hover { background: var(--acento-suave); }
.boton-menu:has(:checked) { background: var(--acento); color: var(--sobre-relleno); }
.boton-menu:has(:focus-visible) { outline: 2px solid var(--acento); outline-offset: 2px; }
.boton-menu-titulo { font-size: 1rem; }
.boton-menu-precio { font-size: .87rem; font-weight: 400; }
.boton-menu-pie { font-size: .8rem; font-weight: 400; opacity: .8; }

/* «Comen» dentro de la ficha de reserva.
 *
 * Se abre HACIA ABAJO y empuja lo de debajo. Iba como menú flotante y se salía
 * de la tarjeta tapando el correo y la mesa de al lado: un panel colocado a
 * mano encima de una lista que se repinta es algo que se desencaja tarde o
 * temprano. Empujando no hay nada que colocar.
 *
 * `ancho-total` en su fila para que la lista tenga el ancho de la ficha y no
 * el de una columna: «Primeros: 2 ensaladas y 1 rabo de toro» no cabe en un
 * tercio de tarjeta. */
.comen-detalle > summary { cursor: pointer; }
.comen-lista {
  margin-top: .35rem; padding: .5rem .7rem;
  background: var(--fondo); border: 1px solid var(--borde); border-radius: 8px;
}
.comen-lista p { margin: 0 0 .25rem; }
.comen-lista p:last-child { margin-bottom: 0; }

/* --- El paso de «carta o menú» del formulario público ---------------------
   Las cajas que lo sostienen. Los botones tienen sus reglas más arriba; esto
   es lo que las agrupa y lo que se enseña o se esconde según lo elegido.

   `menu-platos` y `menu-comensal` nacen escondidos con `hidden` y los enseña
   `menu_comensales.js`: aquí solo se les da forma, para que quien los enseñe
   no tenga que saber nada de estilos. */
.bloque-menus { margin: .5rem 0 1rem; }
.menu-opcion { margin: 0; }
.menu-platos { margin-top: .6rem; }
.menu-comensal {
  margin-top: .6rem; padding-top: .6rem; border-top: 1px solid var(--borde);
}
.menu-comensal:first-of-type { border-top: none; padding-top: 0; }

/* --- La hoja de cocina ----------------------------------------------------
   Las cifras en grande: ese papel se lee de lejos, colgado y con las manos
   ocupadas. Y `no-imprimir` para los botones que no deben salir en el papel.
   Van también aquí, además de en la propia plantilla, porque una clase usada
   en una plantilla tiene que tener regla en la hoja: es lo que comprueba
   `prueba_tema`, y esa comprobación existe para que no se queden clases
   huérfanas de un rediseño a medias. */
.cocina-total { font-size: 1.6rem; font-weight: 700; }
.cocina-plato { font-size: 1.1rem; }
.no-imprimir { }
