/* ============================================================
   MESAS LLENAS — Estilos base
   ============================================================ */
:root{
  --ink:#121016;
  --ink-2:#1d1a24;
  --ink-3:#2a2633;
  --lavanda:#C9B7DB;
  --lavanda-suave:#efe9f5;
  --lavanda-hover:#b9a3d0;
  --blanco:#ffffff;
  --fondo:#f7f5f3;
  --gris-100:#f1efec;
  --gris-200:#e6e3de;
  --gris-300:#d2cec7;
  /* --gris-500 se oscureció de #8b8680 a #7a746d el 2026-08-18. El anterior
     daba 3.6:1 sobre blanco y hace falta 4.5:1 para texto normal (WCAG AA);
     es el color de los subtítulos, las notas y las ayudas — o sea, de casi
     todo el texto explicativo del panel. La diferencia se nota poco de lejos
     y mucho en una tablet a contraluz, que es donde el host lo usa. */
  --gris-500:#7a746d;
  --gris-700:#4d4a45;
  --radio:12px;
  --sombra:0 1px 3px rgba(18,16,22,.06), 0 4px 16px rgba(18,16,22,.06);
  --sombra-alta:0 8px 40px rgba(18,16,22,.22);
  /* Estados */
  --amber-bg:#fdf3d7;   --amber-fg:#8a6410;
  --verde-bg:#ddf2e2;   --verde-fg:#1c7a3a;
  --azul-bg:#dcebfa;    --azul-fg:#1c5f9e;
  --gris-bg:#ecebe8;    --gris-fg:#6b6761;
  --rojo-bg:#fbe0dd;    --rojo-fg:#b3352b;
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
/* iOS: cualquier elemento que mida unos px más que el viewport genera
   deslizamiento lateral de toda la página. `clip` no crea contenedor de
   scroll (la topbar sticky sigue funcionando); `hidden` es el fallback. */
html,body{overflow-x:hidden;overflow-x:clip}
body{
  font-family:'Archivo',system-ui,sans-serif;
  background:var(--fondo);
  color:var(--ink);
  font-size:15px;
  line-height:1.45;
}
button{font-family:inherit;font-size:inherit;cursor:pointer}
input,select,textarea{font-family:inherit;font-size:inherit;color:var(--ink)}
h1,h2,h3{line-height:1.2}
[hidden]{display:none !important}

.wordmark{
  font-family:'Archivo Black',sans-serif;
  letter-spacing:.04em;
  line-height:.95;
  text-transform:uppercase;
}

/* ---------- Botones ---------- */
.btn{
  display:inline-flex;align-items:center;gap:8px;justify-content:center;
  border:none;border-radius:var(--radio);
  padding:10px 18px;font-weight:600;
  transition:background .18s ease, transform .12s ease, box-shadow .18s ease;
  background:var(--gris-100);color:var(--ink);
}
.btn:hover{background:var(--gris-200)}
.btn:active{transform:scale(.98)}
.btn-primario{background:var(--ink);color:var(--blanco)}
.btn-primario:hover{background:var(--ink-3)}
.btn-lavanda{background:var(--lavanda);color:var(--ink)}
.btn-lavanda:hover{background:var(--lavanda-hover)}
.btn-peligro{background:var(--rojo-bg);color:var(--rojo-fg)}
.btn-peligro:hover{background:#f6cdc8}
.btn-fantasma{background:transparent;border:1.5px solid var(--gris-200)}
.btn-fantasma:hover{background:var(--gris-100)}
.btn-mini{padding:6px 12px;font-size:13px;border-radius:9px}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* UN BOTON QUE ESTA GUARDANDO NO ES UN BOTON ROTO, y hasta ahora se veían
   igual: los dos apagados al 50%. El host que no sabe si le llegó el toque
   vuelve a pulsar, y eso es como se envían dos veces las cosas.
   Lo marca `ocupado()` de lib/dom.js. Se queda MAS OPACO que un desactivado
   normal —está vivo, solo ocupado— y lleva un anillo que gira.

   SE LLAMA `ocupado` Y NO `cargando`, Y NO ES CAPRICHO: `.cargando` ya existe
   más abajo —es el bloque centrado que se enseña mientras carga una vista
   entera, con `padding:48px`—. El botón heredó ese relleno y pasó de 26px de
   alto a 96. Es exactamente el mismo golpe que la mesa que se llamaba
   `.principal` y se iba 224px a la derecha, y está documentado tres pantallas
   más abajo. Volví a pisarlo igual. Antes de estrenar una clase, se busca. */
.btn.ocupado, .salon-op.ocupado{
  opacity:.75;cursor:progress;position:relative;
}
/* EL ANILLO VA ABSOLUTO Y NO COMO HIJO FLEX, y esto lo aprendí midiendo: como
   hijo entraba en el reparto de la caja y el botón pasaba de 124x26 a 203x113.
   Justo el salto de maquetación que este ayudante decía evitar. Absoluto no
   ocupa sitio: la caja no se entera de que está ahí. */
.btn.ocupado::after, .salon-op.ocupado::after{
  content:'';position:absolute;right:9px;top:50%;
  width:12px;height:12px;margin-top:-6px;
  border:2px solid currentColor;border-top-color:transparent;border-radius:50%;
  animation:girando .7s linear infinite;
}
/* Sitio para el anillo sin que la caja crezca: se come el relleno derecho. */
.btn.ocupado{padding-right:28px}
@keyframes girando{to{transform:rotate(360deg)}}
/* Quien haya pedido menos movimiento no ve girar nada: el anillo se queda
   quieto, y sigue distinguiendo «ocupado» de «desactivado». */
@media (prefers-reduced-motion:reduce){
  .btn.ocupado::after, .salon-op.ocupado::after{animation:none;opacity:.55}
}

/* ---------- Formularios ---------- */
.campo{margin-bottom:16px}
.campo label{display:block;font-size:13px;font-weight:600;color:var(--gris-700);margin-bottom:6px}
.campo .ayuda{font-size:12px;color:var(--gris-500);margin-top:4px}
/* LA LISTA DE TIPOS ES EL PROBLEMA DE ESTA REGLA, y ya mordió: `url` faltaba,
   así que el «Link de reseñas en Google» se quedaba con el ancho por defecto
   del navegador —177 px dentro de una columna de 469— desde que se añadió ese
   campo. No daba error, solo se veía chico, y así lleva en producción.
   Cada `type` nuevo que se use en un formulario hay que añadirlo aquí. */
.input, .campo input[type=text], .campo input[type=email], .campo input[type=tel],
.campo input[type=password], .campo input[type=date], .campo input[type=time],
.campo input[type=number], .campo input[type=url], .campo input[type=search],
.campo select, .campo textarea{
  width:100%;padding:10px 12px;border:1.5px solid var(--gris-200);
  border-radius:10px;background:var(--blanco);outline:none;
  transition:border-color .15s ease, box-shadow .15s ease;
}
.campo input:focus, .campo select:focus, .campo textarea:focus{
  border-color:var(--lavanda);box-shadow:0 0 0 3px rgba(201,183,219,.35);
}
.campo textarea{resize:vertical;min-height:70px}
.fila-campos{display:flex;gap:14px}
.fila-campos>.campo{flex:1;min-width:0}
/* UN NUMERO NO GANA NADA MIDIENDO 950 px. Al pasar los formularios de
   Configuración a ancho completo, un campo suelto de «duración en minutos» o
   una hora quedaban estirados de lado a lado para tres caracteres de dato.
   Los de texto sí ocupan su columna: ahí el contenido puede ser largo. */
.card .campo input[type=number],
.card .campo input[type=time],
.card .campo input[type=date]{max-width:230px}
.check-linea{display:flex;align-items:center;gap:10px;font-weight:500;cursor:pointer;user-select:none}
.check-linea input{width:18px;height:18px;accent-color:var(--ink)}

/* Toggle */
.toggle{position:relative;display:inline-block;width:44px;height:24px;flex-shrink:0}
.toggle input{opacity:0;width:0;height:0}
.toggle .pista{
  position:absolute;inset:0;background:var(--gris-300);border-radius:99px;
  transition:background .18s ease;
}
.toggle .pista::after{
  content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;
  background:var(--blanco);transition:transform .18s ease;box-shadow:0 1px 3px rgba(0,0,0,.25);
}
.toggle input:checked + .pista{background:var(--ink)}
.toggle input:checked + .pista::after{transform:translateX(20px)}

/* ============================================================
   LOGIN
   ============================================================ */
#pantalla-login{
  position:fixed;inset:0;background:var(--ink);z-index:200;
  display:flex;align-items:center;justify-content:center;padding:20px;
}
#pantalla-login::before{
  content:"";position:absolute;width:520px;height:520px;border-radius:50%;
  background:radial-gradient(circle, rgba(201,183,219,.22), transparent 70%);
  top:-160px;right:-120px;pointer-events:none;
}
.card-login{
  background:var(--blanco);border-radius:20px;padding:44px 40px;width:100%;max-width:420px;
  box-shadow:var(--sombra-alta);position:relative;
}
.card-login .wordmark{font-size:30px;color:var(--ink);margin-bottom:4px}
.card-login .wordmark em{font-style:normal;color:#8f74ab}
.card-login .sub{color:var(--gris-500);font-size:14px;margin-bottom:28px}
.error-login{
  background:var(--rojo-bg);color:var(--rojo-fg);border-radius:10px;
  padding:10px 14px;font-size:13.5px;font-weight:500;margin-bottom:14px;
}
.card-login .btn{width:100%;padding:13px}
.link-olvido{
  display:block;width:100%;margin-top:14px;background:none;border:none;
  color:var(--gris-500);font-size:13px;text-decoration:underline;cursor:pointer;
}
.link-olvido:hover{color:var(--ink)}

/* Selector de restaurante */
.lista-restaurantes{display:flex;flex-direction:column;gap:10px;margin-top:6px}
.item-restaurante{
  display:flex;align-items:center;gap:12px;text-align:left;
  border:1.5px solid var(--gris-200);border-radius:var(--radio);
  padding:12px 16px;background:var(--blanco);transition:border-color .15s, background .15s;
}
.item-restaurante:hover{border-color:var(--lavanda);background:var(--lavanda-suave)}
.item-restaurante img{width:36px;height:36px;border-radius:8px;object-fit:cover}
.item-restaurante .ini{
  width:36px;height:36px;border-radius:8px;background:var(--lavanda);
  display:flex;align-items:center;justify-content:center;font-weight:700;
}

/* ============================================================
   LAYOUT (sidebar + main)
   ============================================================ */
/* 100dvh: alto real en móvil (100vh ignora la barra del navegador y tapaba
   la navegación inferior). El 100vh de la línea anterior queda de fallback
   para navegadores viejos que no conocen dvh. */
#app{display:flex;min-height:100vh;min-height:100dvh}

.sidebar{
  width:224px;background:var(--ink);color:var(--blanco);
  position:fixed;top:0;bottom:0;left:0;z-index:50;
  display:flex;flex-direction:column;padding:26px 14px 18px;
}
.sidebar .wordmark{font-size:21px;color:var(--blanco);padding:0 10px;margin-bottom:34px}
.sidebar .wordmark span{color:var(--lavanda)}
.nav-lateral{display:flex;flex-direction:column;gap:4px;flex:1}
.nav-item{
  display:flex;align-items:center;gap:12px;
  padding:11px 12px;border-radius:var(--radio);border:none;background:transparent;
  color:rgba(255,255,255,.72);font-weight:500;font-size:14.5px;text-align:left;
  transition:background .16s ease, color .16s ease;
}
.nav-item svg{width:19px;height:19px;flex-shrink:0}
.nav-item:hover{background:var(--ink-2);color:var(--blanco)}
.nav-item.activo{background:var(--lavanda);color:var(--ink);font-weight:700}
.sidebar .pie{font-size:11px;color:rgba(255,255,255,.35);padding:0 10px}

.principal{flex:1;margin-left:224px;min-width:0;display:flex;flex-direction:column}

.topbar{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding:16px 32px;background:var(--blanco);border-bottom:1px solid var(--gris-200);
  position:sticky;top:0;z-index:40;
}
/* `contain` y ancho variable, NO un cuadrado con `cover`.
   Antes esto recortaba el logo a un cuadrado desde el centro: la mayoría de
   los logos de restaurante son una franja horizontal con el nombre, así que
   se veía un trozo del medio sin nombre ni símbolo. Y como la vista previa de
   Configuración hacía lo mismo, el dueño probaba medida tras medida sin que
   ninguna «diera»: el problema no era la imagen, era el recorte. */
.topbar .logo-resto{height:34px;width:auto;max-width:130px;border-radius:9px;object-fit:contain;background:var(--gris-100)}
.topbar .ini-resto{
  width:34px;height:34px;border-radius:9px;background:var(--lavanda);
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:15px;
}
.topbar .nombre-resto{
  font-weight:700;font-size:16px;
  /* En móvil el nombre largo se partía en dos líneas y rompía la barra */
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;
}
.topbar .espacio{flex:1}
.contenido{padding:28px 32px 60px;max-width:1120px;width:100%;margin:0 auto}

.cabecera-vista{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:22px}
.cabecera-vista h1{font-family:'Archivo Black',sans-serif;font-size:24px;letter-spacing:.01em}
.cabecera-vista .sub{color:var(--gris-500);font-size:14px;margin-top:2px}

/* ============================================================
   TARJETAS / GENERALES
   ============================================================ */
.card{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);padding:20px}
.grid-kpi{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:14px;margin-bottom:24px}
.kpi{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);padding:16px 18px}
.kpi .valor{font-family:'Archivo Black',sans-serif;font-size:26px;margin-bottom:2px}
.kpi .etiqueta{font-size:12.5px;color:var(--gris-500);font-weight:500}
.kpi.acento{background:var(--lavanda)}
.kpi.acento .etiqueta{color:rgba(18,16,22,.6)}

.vacio{
  text-align:center;padding:56px 20px;color:var(--gris-500);
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
}
.vacio .grande{font-size:34px;margin-bottom:8px}

/* ---------- Badges de estado ---------- */
.badge{
  display:inline-flex;align-items:center;gap:5px;
  font-size:12px;font-weight:700;padding:3px 10px;border-radius:99px;white-space:nowrap;
}
.badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
.badge-pending{background:var(--amber-bg);color:var(--amber-fg)}
.badge-confirmed{background:var(--verde-bg);color:var(--verde-fg)}
.badge-seated{background:var(--azul-bg);color:var(--azul-fg)}
.badge-completed{background:var(--gris-bg);color:var(--gris-fg)}
.badge-no_show{background:var(--rojo-bg);color:var(--rojo-fg)}
.badge-cancelled{background:var(--gris-bg);color:var(--gris-fg);text-decoration:line-through}
.select-estado-lead{
  padding:6px 10px;border:1.5px solid var(--gris-200);border-radius:10px;
  background:var(--blanco);font-weight:600;font-size:13px;cursor:pointer;
}

/* ============================================================
   RESERVAS
   ============================================================ */
.nav-dia{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
  padding:12px 16px;margin-bottom:18px;
}
.nav-dia .fecha-larga{font-weight:700;font-size:15.5px;text-transform:capitalize;flex:1;min-width:180px}
.nav-dia input[type=date]{
  padding:8px 10px;border:1.5px solid var(--gris-200);border-radius:10px;background:var(--blanco);
}
.btn-flecha{
  width:36px;height:36px;border-radius:10px;border:1.5px solid var(--gris-200);
  background:var(--blanco);display:flex;align-items:center;justify-content:center;
  font-size:16px;transition:background .15s;
}
.btn-flecha:hover{background:var(--gris-100)}

.barra-filtros{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:18px}
.buscador{
  flex:1;min-width:200px;display:flex;align-items:center;gap:8px;
  background:var(--blanco);border:1.5px solid var(--gris-200);border-radius:var(--radio);
  padding:9px 14px;
}
.buscador input{border:none;outline:none;flex:1;background:transparent;min-width:0}
.buscador svg{width:16px;height:16px;color:var(--gris-500);flex-shrink:0}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.chip{
  border:1.5px solid var(--gris-200);background:var(--blanco);border-radius:99px;
  padding:6px 13px;font-size:13px;font-weight:600;color:var(--gris-700);
  transition:all .15s ease;
}
.chip:hover{border-color:var(--lavanda)}
.chip.activo{background:var(--ink);border-color:var(--ink);color:var(--blanco)}

/* Timeline */
.timeline{display:flex;flex-direction:column;gap:22px}
.bloque-hora{display:flex;gap:16px}
.bloque-hora .hora{
  font-family:'Archivo Black',sans-serif;font-size:16px;width:56px;flex-shrink:0;
  padding-top:14px;text-align:right;color:var(--ink);
}
.bloque-hora .linea{
  width:2px;background:var(--gris-200);border-radius:2px;position:relative;flex-shrink:0;
}
.bloque-hora .linea::before{
  content:"";position:absolute;top:20px;left:-4px;width:10px;height:10px;border-radius:50%;
  background:var(--lavanda);border:2px solid var(--fondo);
}
.bloque-hora .tarjetas{flex:1;display:flex;flex-direction:column;gap:10px;min-width:0}
.tarjeta-reserva{
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
  padding:14px 18px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  transition:box-shadow .18s ease;
}
.tarjeta-reserva:hover{box-shadow:0 4px 20px rgba(18,16,22,.12)}
.tarjeta-reserva.cancelada .nombre{text-decoration:line-through;color:var(--gris-500)}
.tarjeta-reserva .info{flex:1;min-width:150px}
.tarjeta-reserva .nombre{font-weight:700;font-size:15.5px}
.tarjeta-reserva .meta{font-size:13px;color:var(--gris-500);margin-top:2px;display:flex;gap:10px;flex-wrap:wrap}
.tarjeta-reserva .meta .codigo{font-weight:700;letter-spacing:.06em;color:var(--gris-700)}
/* CUANDO SE HIZO LA RESERVA. La normal va en gris, como el resto de la meta.
   La que se hizo por la web pegada a su propia hora va en rojo y en negrita:
   es la que el host necesita ver desde el otro lado del mostrador, con el
   cliente delante diciendo que tiene reserva. */
.tarjeta-reserva .meta .creada{color:var(--gris-500)}
.tarjeta-reserva .meta .creada-justa{color:var(--rojo-fg);font-weight:700}
/* El cliente contestó que viene. Verde y en negrita: es lo que el host
   busca con los ojos cuando decide si guarda la mesa. */
.tarjeta-reserva .meta .confirmo{color:var(--verde-fg);font-weight:700}
.tarjeta-reserva .notas{
  flex-basis:100%;font-size:13px;color:var(--gris-700);
  background:var(--gris-100);border-radius:8px;padding:7px 10px;margin-top:2px;
}
.pax-pill{
  background:var(--lavanda-suave);color:var(--ink);font-weight:700;font-size:13px;
  border-radius:99px;padding:4px 11px;white-space:nowrap;
}
.acciones-reserva{display:flex;gap:6px;flex-wrap:wrap}

/* ============================================================
   TABLAS
   ============================================================ */
.tabla-envoltura{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);overflow-x:auto}
table.tabla{width:100%;border-collapse:collapse;min-width:560px}
.tabla th{
  text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--gris-500);font-weight:700;padding:14px 18px;border-bottom:1px solid var(--gris-200);
}
.tabla td{padding:13px 18px;border-bottom:1px solid var(--gris-100);vertical-align:middle}
.tabla tr:last-child td{border-bottom:none}
.tabla tbody tr.clicable{cursor:pointer;transition:background .13s}
.tabla tbody tr.clicable:hover{background:var(--lavanda-suave)}

/* ============================================================
   INFORMES
   ============================================================ */
.grafico-card{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);padding:20px;margin-bottom:20px}
.grafico-card h3{font-size:15px;margin-bottom:14px}
/* Vista Inicio */
.inicio-acciones{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
.inicio-rating{font-size:15px}

/* El mensaje de pausa, dentro de la tarjeta de «Reservas por la web».
   VA PLEGADO y no como un formulario más: en un día normal nadie lo toca, y
   una tarjeta que abre con tres campos convierte un interruptor claro en un
   panel de ajustes. Se despliega solo cuando las reservas ya están pausadas,
   que es justo cuando el mensaje importa. */
.pausa-msg{margin-top:14px;border-top:1px solid var(--gris-200);padding-top:10px}
.pausa-msg>summary{
  cursor:pointer;font-size:13px;font-weight:600;color:var(--gris-700);
  list-style:none;padding:4px 0;user-select:none;
}
.pausa-msg>summary::-webkit-details-marker{display:none}
.pausa-msg>summary:hover{color:var(--ink)}
.pausa-msg[open]>summary{margin-bottom:10px}
.pausa-msg-cuerpo .campo{margin-bottom:12px}
.pausa-msg-cuerpo textarea{min-height:72px;resize:vertical}
.pausa-msg-pie{display:flex;align-items:center;gap:12px;margin-top:12px}
.pausa-msg-pie .ayuda{margin:0}
.chart-scroll{overflow-x:auto}
.chart-scroll svg{display:block}

/* ============================================================
   CONFIGURACIÓN
   ============================================================ */
/* LA LINEA ES LO QUE HACE QUE LA TIRA NO FLOTE.
   Las pestañas son pastillas sueltas y la tarjeta de abajo está topada a 640
   px: dos anchos que nunca se hablaron. Con 6 pestañas la tira medía 662 px y
   los 22 px de diferencia no se veían; la séptima la llevó a 810 y se notó.
   Igualar los dos números sería atarlos —y volvería a romperse a la octava—,
   así que en vez de eso se ancla la tira al borde del contenido con una línea.
   La tarjeta queda debajo con su ancho de lectura, y se lee como una decisión
   en vez de como un descuadre. */
.tabs-config{
  display:flex;gap:6px;flex-wrap:wrap;
  padding-bottom:10px;margin-bottom:20px;
  border-bottom:1.5px solid var(--gris-200);
}
.tab-config{
  border:none;background:transparent;padding:9px 16px;border-radius:10px;
  font-weight:600;color:var(--gris-700);transition:all .15s ease;
}
.tab-config:hover{background:var(--gris-200)}
.tab-config.activo{background:var(--ink);color:var(--blanco)}

/* EL RECUADRO SE AJUSTA AL LOGO, no al revés.
   La versión anterior era una caja fija de 150x64 con la proporción del
   widget, pensando que así se vería «lo que ve el cliente». El razonamiento
   estaba mal: en la página de reservas NO hay ninguna caja — el logo va
   suelto, hasta 56 px de alto. Ese marco solo existía en el panel, y con un
   logo cuadrado dejaba casi 90 px de aire a los lados.
   Ahora el alto manda (64 px, como se verá) y el ancho lo pone el propio
   logo: uno cuadrado da un recuadro cuadrado, uno horizontal uno alargado. */
.preview-logo{
  /* `min-width:64px` y no 96: con 96 un logo cuadrado —que es el caso más
     común— seguía con 34 px de aire al lado. El estado «Sin logo» consigue su
     ancho del propio texto (ver la regla de abajo), no forzando la caja. */
  height:64px;width:auto;min-width:64px;max-width:200px;
  border-radius:14px;background:var(--gris-100);
  display:inline-flex;align-items:center;justify-content:center;overflow:hidden;
  border:1.5px dashed var(--gris-300);flex-shrink:0;padding:5px;
}
/* `height:100%` y `width:auto`: la imagen fija el alto y el recuadro se
   encoge hasta abrazarla. Con `max-width` en porcentaje volvería a depender
   de un ancho de caja que ya no existe. */
.preview-logo img{height:100%;width:auto;max-width:190px;object-fit:contain}
.preview-logo span{padding:0 16px;white-space:nowrap}
.linea-color{display:flex;align-items:center;gap:12px}
.linea-color input[type=color]{
  width:52px;height:38px;border:1.5px solid var(--gris-200);border-radius:10px;
  padding:3px;background:var(--blanco);cursor:pointer;
}
.swatch-preview{
  flex:1;border-radius:10px;padding:9px 14px;font-weight:700;font-size:13.5px;text-align:center;
}

/* Horarios */
.dia-horario{border-bottom:1px solid var(--gris-100);padding:16px 0}
.dia-horario:last-of-type{border-bottom:none}
.dia-horario .cab-dia{display:flex;align-items:center;gap:12px;margin-bottom:10px;flex-wrap:wrap}
.dia-horario .cab-dia h4{font-size:15px;flex:1;min-width:80px}
.fila-turno{
  display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  background:var(--gris-100);border-radius:10px;padding:10px 12px;margin-bottom:8px;
}
.fila-turno input[type=text]{width:120px}
.fila-turno input[type=time]{width:106px}
.fila-turno input[type=number]{width:76px}
.fila-turno input, .fila-turno select{
  padding:8px 10px;border:1.5px solid var(--gris-200);border-radius:9px;background:var(--blanco);outline:none;
}
.fila-turno input:focus{border-color:var(--lavanda)}
.fila-turno .lbl{font-size:11.5px;color:var(--gris-500);font-weight:600;display:block;margin-bottom:3px}
.fila-turno .grupo{display:flex;flex-direction:column}
.fila-turno .btn-x{
  width:32px;height:32px;border-radius:9px;border:none;background:var(--rojo-bg);
  color:var(--rojo-fg);font-weight:700;margin-top:16px;
}
.dia-cerrado{color:var(--gris-500);font-size:13.5px;font-style:italic;padding:4px 0 8px}

/* Blackouts */
.item-blackout{
  display:flex;align-items:center;gap:14px;padding:12px 16px;
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);margin-bottom:10px;flex-wrap:wrap;
}
.item-blackout .fecha{font-weight:700;text-transform:capitalize}
.item-blackout .detalle{color:var(--gris-500);font-size:13.5px;flex:1;min-width:120px}

/* Widget / snippet */
.snippet{
  background:var(--ink);color:#d9d4e2;border-radius:var(--radio);
  padding:18px;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px;
  overflow-x:auto;white-space:pre;line-height:1.6;
}
.snippet .tag{color:var(--lavanda)}

/* ============================================================
   RESTAURANTES (superadmin)
   ============================================================ */
.item-resto-admin{
  display:flex;align-items:center;gap:14px;padding:14px 18px;
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
  margin-bottom:10px;flex-wrap:wrap;
}
/* LA MARCA DE CADA SEDE EN LA LISTA. Era un punto de 14 px con el color de la
   marca: con once sedes, once puntos de colores no ayudan a encontrar ninguna.
   Ahora es el logo, que es como el dueño reconoce lo suyo. Mismo tamaño y mismo
   redondeo que el de la barra de arriba, para que sea el mismo objeto.

   SI NO HAY LOGO, LA INICIAL sobre el color de la marca — no un hueco gris. Una
   sede recién creada todavía no subió su logo, y esa es justo la que más se mira
   en esta pantalla. */
.item-resto-admin .marca-sede{
  position:relative;
  width:40px;height:40px;border-radius:10px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
  border:1px solid var(--gris-200);
}
/* EL LOGO VA ENCIMA DE LA INICIAL, no en su lugar: si la imagen no carga
   —borrada del almacenamiento, sin internet— debajo sigue estando la inicial
   en vez de un recuadro vacío. */
.item-resto-admin .marca-sede img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:contain;background:var(--blanco);
}
.item-resto-admin .marca-sede .inicial{
  font-weight:700;font-size:17px;line-height:1;
}
.item-resto-admin .datos{flex:1;min-width:150px}
.item-resto-admin .nombre{font-weight:700}
.item-resto-admin .slug{
  font-size:12.5px;color:var(--gris-500);
  font-family:ui-monospace,Menlo,Consolas,monospace;
}
.item-resto-admin .acciones{display:flex;gap:6px;flex-wrap:wrap}

/* ============================================================
   MODALES
   ============================================================ */
.modal-overlay{
  position:fixed;inset:0;background:rgba(18,16,22,.55);z-index:150;
  display:flex;align-items:center;justify-content:center;padding:18px;
  animation:aparecer .18s ease;
}
@keyframes aparecer{from{opacity:0}to{opacity:1}}
.modal{
  background:var(--blanco);border-radius:16px;box-shadow:var(--sombra-alta);
  width:100%;max-width:480px;max-height:calc(100vh - 40px);overflow-y:auto;
  animation:subir .22s ease;
}
@keyframes subir{from{transform:translateY(14px);opacity:0}to{transform:none;opacity:1}}
.modal-cabecera{
  display:flex;align-items:center;justify-content:space-between;
  padding:20px 24px 0;
}
.modal-cabecera h2{font-size:18px}
.modal-cuerpo{padding:18px 24px 24px}
.modal-pie{display:flex;gap:10px;justify-content:flex-end;margin-top:8px}
.btn-cerrar-modal{
  width:34px;height:34px;border-radius:10px;border:none;background:var(--gris-100);
  font-size:16px;line-height:1;color:var(--gris-700);
}
.btn-cerrar-modal:hover{background:var(--gris-200)}

/* Autocompletado comensal */
.auto-caja{position:relative}
.auto-lista{
  position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--blanco);
  border:1.5px solid var(--gris-200);border-radius:10px;box-shadow:var(--sombra-alta);
  z-index:20;max-height:220px;overflow-y:auto;
}
.auto-item{
  display:block;width:100%;text-align:left;padding:10px 14px;border:none;background:transparent;
}
.auto-item:hover{background:var(--lavanda-suave)}
.auto-item .tel{font-size:12.5px;color:var(--gris-500)}
.comensal-elegido{
  display:flex;align-items:center;gap:10px;background:var(--lavanda-suave);
  border-radius:10px;padding:10px 14px;margin-bottom:14px;
}
.comensal-elegido b{flex:1}

/* Historial en modal comensal */
.hist-item{
  display:flex;align-items:center;gap:10px;padding:9px 0;
  border-bottom:1px solid var(--gris-100);font-size:13.5px;flex-wrap:wrap;
}
.hist-item:last-child{border-bottom:none}
.hist-item .f{font-weight:600;text-transform:capitalize;flex:1;min-width:140px}

/* Importar comensales (CSV) */
.dropzone{
  border:2px dashed var(--gris-300);border-radius:var(--radio);
  padding:30px 18px;text-align:center;color:var(--gris-500);font-size:13.5px;
  cursor:pointer;transition:border-color .15s ease, background .15s ease;
}
.dropzone:hover, .dropzone.encima{border-color:var(--lavanda);background:var(--lavanda-suave)}
.dropzone:focus-visible{outline:2px solid #7c5f99;outline-offset:2px}
.pasos-import{display:flex;gap:6px;margin-bottom:18px}
.pasos-import .punto{flex:1;height:4px;border-radius:99px;background:var(--gris-200);transition:background .2s ease}
.pasos-import .punto.activo{background:var(--lavanda)}
.barra-progreso{height:10px;background:var(--gris-100);border-radius:99px;overflow:hidden;margin:14px 0}
.barra-progreso>div{height:100%;width:0;background:var(--lavanda);border-radius:99px;transition:width .25s ease}
.resumen-import{display:flex;flex-direction:column;gap:8px;margin:14px 0}
.resumen-import .linea-res{display:flex;justify-content:space-between;gap:12px;font-size:13.5px;background:var(--gris-100);border-radius:9px;padding:9px 13px}
.resumen-import .linea-res b{font-family:'Archivo Black',sans-serif}

/* ============================================================
   TOASTS
   ============================================================ */
#toasts{
  position:fixed;bottom:24px;right:24px;z-index:300;
  display:flex;flex-direction:column;gap:10px;align-items:flex-end;
}
.toast{
  background:var(--ink);color:var(--blanco);border-radius:var(--radio);
  padding:12px 18px;font-weight:600;font-size:14px;box-shadow:var(--sombra-alta);
  display:flex;align-items:center;gap:10px;max-width:340px;
  animation:toastIn .25s ease;
}
@keyframes toastIn{from{transform:translateY(10px);opacity:0}to{transform:none;opacity:1}}
.toast.saliendo{opacity:0;transform:translateY(6px);transition:all .3s ease}
.toast::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--lavanda);flex-shrink:0}
.toast.error::before{background:#e4685c}
.toast.nuevo{background:var(--lavanda);color:var(--ink)}
.toast.nuevo::before{background:var(--ink)}

/* Spinner */
.cargando{display:flex;justify-content:center;padding:48px}
.spinner{
  width:30px;height:30px;border-radius:50%;
  border:3px solid var(--gris-200);border-top-color:var(--lavanda);
  animation:girar .8s linear infinite;
}
@keyframes girar{to{transform:rotate(360deg)}}

/* ============================================================
   SEGMENTED CONTROL (Día | Semana | Mes)
   ============================================================ */
.segmented{display:inline-flex;background:var(--gris-100);border-radius:11px;padding:3px;gap:2px}
.segmented button{
  border:none;background:transparent;padding:7px 14px;border-radius:9px;
  font-weight:600;font-size:13px;color:var(--gris-700);min-height:34px;
  transition:background .15s ease, color .15s ease;
}
.segmented button:hover{color:var(--ink)}
.segmented button.activo{background:var(--blanco);color:var(--ink);font-weight:700;box-shadow:0 1px 3px rgba(18,16,22,.14)}

/* ============================================================
   VISTA SEMANA
   ============================================================ */
.semana-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:10px;align-items:start}
.col-dia{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);padding:8px;min-width:0}
.col-dia.hoy{outline:2px solid var(--lavanda)}
.col-dia .cab{
  width:100%;border:none;background:transparent;text-align:left;
  padding:6px 8px;border-radius:8px;cursor:pointer;min-height:40px;
  transition:background .15s ease;
}
.col-dia .cab:hover{background:var(--lavanda-suave)}
.col-dia.hoy .cab{background:var(--lavanda-suave)}
.col-dia .cab .dnombre{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--gris-500);font-weight:700}
.col-dia .cab .dnum{font-family:'Archivo Black',sans-serif;font-size:18px;line-height:1.15}
.col-dia.hoy .cab .dnum{color:#7c5f99}
.col-dia .resumen{font-size:11.5px;color:var(--gris-500);font-weight:600;padding:2px 8px 8px;min-height:22px}
.mini-reserva{
  display:flex;align-items:center;gap:7px;background:var(--gris-100);
  border-radius:8px;padding:7px 9px;margin-bottom:6px;font-size:12.5px;min-width:0;
}
.mini-reserva.cancelada{opacity:.55}
.mini-reserva.cancelada .n{text-decoration:line-through}
.mini-reserva .h{font-weight:700;flex-shrink:0}
.mini-reserva .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mini-reserva .p{color:var(--gris-500);font-weight:600;flex-shrink:0}
.punto-estado{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.punto-estado.pending{background:var(--amber-fg)}
.punto-estado.confirmed{background:var(--verde-fg)}
.punto-estado.seated{background:var(--azul-fg)}
.punto-estado.completed{background:var(--gris-fg)}
.punto-estado.no_show{background:var(--rojo-fg)}
.punto-estado.cancelled{background:var(--gris-300)}
.ver-mas-dia{
  width:100%;border:none;background:transparent;color:var(--gris-700);
  font-size:12px;font-weight:700;padding:9px 4px;border-radius:8px;min-height:40px;
}
.ver-mas-dia:hover{background:var(--gris-100)}
.col-dia .sin-res{font-size:12px;color:var(--gris-500);text-align:center;padding:14px 4px 10px}

/* ============================================================
   VISTA MES
   ============================================================ */
.mes-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.mes-cab{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--gris-500);font-weight:700;text-align:center;padding:4px 0}
.celda-mes{
  background:var(--blanco);border:1.5px solid transparent;border-radius:10px;box-shadow:var(--sombra);
  min-height:78px;padding:8px;text-align:left;cursor:pointer;
  display:flex;flex-direction:column;gap:3px;min-width:0;
  transition:border-color .15s ease, transform .12s ease;
}
.celda-mes:hover{border-color:var(--lavanda)}
.celda-mes:active{transform:scale(.98)}
.celda-mes .num{font-weight:700;font-size:13px}
.celda-mes.otro-mes{opacity:.4}
.celda-mes.hoy{border-color:var(--ink)}
.celda-mes .res-info{font-size:11px;font-weight:700;color:var(--ink);background:rgba(255,255,255,.55);border-radius:6px;padding:1px 6px;align-self:flex-start;white-space:nowrap}
.celda-mes .res-pax{font-size:10.5px;color:var(--gris-700);font-weight:600;white-space:nowrap}
.celda-mes.calor-1{background:var(--lavanda-suave)}
.celda-mes.calor-2{background:#ddccea}
.celda-mes.calor-3{background:var(--lavanda)}
.nota-mes{color:var(--gris-500);font-size:12px;margin-top:10px}

/* ============================================================
   INFORMES — extras
   ============================================================ */
.kpi .delta{font-size:12px;font-weight:700;margin-top:3px}
.delta-up{color:var(--verde-fg)}
.delta-down{color:var(--rojo-fg)}
.delta-neutro{color:var(--gris-500)}
.leyenda{display:flex;gap:12px 16px;flex-wrap:wrap;margin-top:12px;font-size:12.5px;color:var(--gris-700)}
.leyenda span{display:inline-flex;align-items:center;gap:6px;font-weight:600}
.rango-custom{
  display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
  padding:10px 14px;margin-bottom:18px;font-size:13px;
}
.rango-custom .lbl-rc{font-weight:700;color:var(--gris-700)}
.rango-custom input[type=date]{padding:8px 10px;border:1.5px solid var(--gris-200);border-radius:10px;background:var(--blanco)}
.chips-origen{display:flex;gap:8px;flex-wrap:wrap}
.chip-dato{background:var(--gris-100);border-radius:99px;padding:8px 15px;font-size:13px;font-weight:600;color:var(--gris-700)}
.chip-dato b{font-family:'Archivo Black',sans-serif;color:var(--ink)}
.nota-aprox{color:var(--gris-500);font-size:12px;margin:-12px 0 22px;line-height:1.5}
/* EL MARGEN NEGATIVO DE ARRIBA ES A PROPOSITO: estas notas nacieron para ir
   pegadas debajo de un gráfico, que trae su propio hueco. Puestas después de
   una lista o una tabla, ese -12px las sube ENCIMA del último renglón — pasó
   en la tarjeta de actividad, con «El tiempo de limpieza…» montado sobre
   «Pata rota». `.suelta` es la misma nota sin la corrección de gráfico. */
.nota-aprox.suelta{margin-top:16px}

/* ============================================================
   ENCUESTAS — barras y layout
   ============================================================ */
.enc-barras-dia{display:flex;flex-direction:column;gap:5px;padding-top:4px}
.enc-barras-preg{display:flex;flex-direction:column;gap:5px;padding-top:4px}
.enc-barra-fila{display:flex;align-items:center;gap:10px;min-height:26px}
.enc-barra-etiq{font-size:12.5px;color:var(--gris-700);font-weight:500;width:96px;flex-shrink:0;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.enc-barra-contenedor{flex:1;height:14px;background:var(--gris-100);border-radius:7px;overflow:hidden;min-width:40px}
.enc-barra-fill{height:100%;background:var(--lavanda);border-radius:7px;min-width:3px;transition:width .35s ease}
.enc-barra-val{font-size:12.5px;font-weight:700;color:var(--ink);min-width:28px}
.enc-kpi-sub{font-size:12px;color:var(--gris-500);margin-top:3px}
.enc-grids{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px;margin-bottom:24px}
.enc-resp-negativa td{background:var(--rojo-bg)}
.enc-comentario{background:var(--gris-100);border-radius:8px;padding:7px 10px;line-height:1.5;font-size:13px}
.enc-comentario.negativo{background:rgba(179,53,43,.09)}
.enc-atendida{color:var(--verde-fg);font-weight:700;font-size:13px;white-space:nowrap}
.enc-nota-interna{background:var(--gris-100);border-left:3px solid var(--gris-300);border-radius:0 6px 6px 0;
  padding:6px 9px;margin-top:6px;font-size:12.5px;line-height:1.45;color:var(--gris-700);white-space:pre-wrap}
/* Botón que se ve como enlace: acción secundaria dentro de una celda ya
   ocupada, donde un botón sólido competiría con el estado que la celda
   comunica. Sigue siendo <button> por accesibilidad — no un <a> sin href. */
.btn-enlace{background:none;border:0;padding:2px 0;margin-top:4px;cursor:pointer;
  font:inherit;font-size:12px;color:var(--gris-500);text-decoration:underline}
.btn-enlace:hover{color:var(--ink)}

/* ── Buscador global (topbar) ───────────────────────────────── */
.buscador-global{position:relative;display:flex;align-items:center;gap:6px;
  background:var(--gris-100);border:1px solid var(--gris-200);border-radius:99px;
  padding:0 12px;height:32px;min-width:210px;max-width:320px;flex:1}
.buscador-global:focus-within{border-color:var(--gris-300);background:#fff}
.bg-lupa{color:var(--gris-500);flex-shrink:0}
#bg-input{border:0;background:none;outline:none;width:100%;font-size:13px;padding:0}
#bg-input::-webkit-search-cancel-button{cursor:pointer}
.bg-panel{position:absolute;top:calc(100% + 6px);right:0;left:0;min-width:300px;z-index:60;
  background:#fff;border:1px solid var(--gris-200);border-radius:12px;
  box-shadow:0 10px 34px rgba(0,0,0,.13);max-height:60vh;overflow-y:auto;padding:6px}
.bg-grupo{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;
  color:var(--gris-500);padding:8px 10px 4px}
.bg-item{display:block;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:8px 10px;border-radius:8px;font:inherit;font-size:13px;color:var(--ink)}
.bg-item:hover,.bg-item:focus-visible{background:var(--gris-100);outline:none}
.bg-item .sec{display:block;font-size:12px;color:var(--gris-500);margin-top:1px}
.bg-vacio{padding:14px 10px;font-size:13px;color:var(--gris-500);text-align:center}
/* En móvil el buscador se lleva su propia línea: en la topbar competiría con
   el nombre del restaurante y los botones, y quedarían todos ilegibles. */
@media (max-width:760px){
  /* `min-width:0` además del flex-basis. Con el `min-width:210px` de arriba,
     un elemento flex NO puede encogerse por debajo de su contenido, así que
     en una pantalla de 390 px se salía 235 px por la derecha. Y como la
     topbar no tenía `flex-wrap`, tampoco bajaba de línea: se quedaba fuera de
     la pantalla, con su campo de texto dentro.
     En iOS eso mueve la página: Safari desplaza el viewport hacia cualquier
     campo enfocable que esté fuera de vista. En Android no se notaba. */
  .buscador-global{order:99;flex-basis:100%;min-width:0;max-width:none;margin-top:8px}
  .bg-panel{min-width:0}
}

/* ============================================================
   PANTALLAS QUE SE TOCAN CON EL DEDO
   ============================================================ */
/* EL HOST TRABAJA CON EL DEDO SOBRE UNA TABLET, no con un ratón. Y este panel
   nació en un escritorio: 35 botones medían menos de 40px de alto en un móvil
   y 12 los seguían midiendo en escritorio. «Cambiar» son 76x28. La guía táctil
   son 44px, y no es una cifra de manual: por debajo de eso, en hora pico y con
   el salón lleno, se le da al botón de al lado.

   Va por `pointer:coarse` y NO por ancho de pantalla, que es la diferencia que
   importa aquí. Lo que decide el tamaño de un botón no es cuántos píxeles hay,
   es con qué se toca: una tablet de 1024px se usa con el dedo y un portátil de
   1024px con un trackpad. Por ancho, la tablet del salón —que es justo el caso
   real— se habría quedado con los botones de ratón.

   No se toca el ancho ni la tipografía: solo se garantiza el alto y se reparte
   el aire de más arriba y abajo. Nada cambia de sitio. */
@media (pointer: coarse){
  .btn, .salon-op, .chips button, .segmented button,
  .nav-item, [role="button"]:not(.salon-mesa):not(.salon-elemento):not(.salon-paso){
    min-height:44px;
  }
  /* Los mini siguen siendo visualmente pequeños —el ancho no cambia— pero
     ganan zona de toque por arriba y por abajo. */
  .btn-mini{padding-top:10px;padding-bottom:10px}
  /* Los redondos crecen en los dos ejes o dejan de ser redondos. El «?» se
     llama `btn-ayuda`; escribí `ayuda-btn` de memoria y la regla no cogía
     nada — se vio porque la medición lo siguió sacando a 22x22. */
  .btn-flecha{min-width:44px;min-height:44px}
  /* El «?» va PEGADO a un título, así que crecer en los dos ejes lo separaría
     de su palabra. Crece solo la zona que se toca, con un pseudo-elemento
     centrado que no ocupa sitio en el diseño. */
  .btn-ayuda{position:relative}
  .btn-ayuda::before{
    content:'';position:absolute;left:50%;top:50%;
    width:44px;height:44px;transform:translate(-50%,-50%);
  }
  /* El aspa de cerrar un modal es el botón que más se falla: está en una
     esquina y al lado del borde de la pantalla. */
  .modal-cerrar{min-width:44px;min-height:44px}
}

/* ============================================================
   ACCESIBILIDAD
   ============================================================ */
/* FOCO VISIBLE EN TODO LO ENFOCABLE, no en una lista de clases.
   Antes esto era una lista de 13 selectores, y era una lista que envejecía
   sola: cada componente nuevo —el plano del salón, el paginador, los
   artículos de Documentación, el selector de personas— nacía sin foco
   visible, y nadie lo notaba porque quien lo programa usa el ratón.
   Una regla general no se queda vieja. */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible,
summary:focus-visible, details:focus-visible, [role="button"]:focus-visible{
  outline:2px solid #7c5f99;outline-offset:2px;border-radius:4px;
}
/* Los campos ya señalan el foco con su propio borde de color (ver .campo
   input:focus): un contorno encima se vería doble. */
input:focus-visible, select:focus-visible, textarea:focus-visible{outline:none}

/* Salto al contenido: primer elemento enfocable de la página. Sin esto, quien
   navega con teclado o con lector de pantalla tiene que recorrer el menú
   entero —diez elementos— en cada cambio de vista para llegar a lo que vino
   a hacer. Sale de su escondite solo cuando recibe el foco. */
.saltar-contenido{
  position:absolute;left:-9999px;top:0;z-index:200;
  background:var(--ink);color:#fff;padding:10px 16px;border-radius:0 0 var(--radio) 0;
  font-weight:600;font-size:14px;text-decoration:none;
}
.saltar-contenido:focus{left:0}

/* Texto solo para lectores de pantalla: presente en el árbol de
   accesibilidad, invisible en pantalla. `clip-path` y no `display:none`,
   que lo sacaría también del lector. */
.solo-lector{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ============================================================
   RESPONSIVE — bottom-nav en móvil
   ============================================================ */
@media (max-width:820px){
  .sidebar{
    top:auto;bottom:0;left:0;right:0;width:100%;height:64px;
    flex-direction:row;align-items:center;padding:0 8px;
    border-top:1px solid var(--ink-3);
  }
  .sidebar .wordmark, .sidebar .pie{display:none}
  /* LA BARRA SE DESPLAZA DENTRO DE SI MISMA.
     Con `flex:1` los diez botones deberían encogerse para caber, pero un
     elemento flex tiene `min-width:auto`: no baja de lo que mide su texto.
     «Documentación» y «Restaurantes» no encogen, así que la barra medía unos
     850 px en una pantalla de 390 y los últimos botones quedaban fuera.
     Ahora la barra es un carril que se desliza: nada sale del viewport y
     todas las entradas siguen siendo alcanzables. */
  .nav-lateral{
    flex-direction:row;width:100%;gap:2px;
    overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;
    /* SE VE QUE HAY MAS A LOS LADOS. El carril ya se deslizaba y todas las
       entradas eran alcanzables, pero nada lo decía: «Restaurantes» aparecía
       cortado a media palabra y quien no probara a arrastrar se quedaba sin
       la mitad del menú. Se difumina el contenido en los bordes con una
       máscara.

       Va en los DOS extremos aunque en reposo el izquierdo no oculte nada: en
       cuanto se desliza, el que corta es ese. Hacerlo bien —que cada lado
       aparezca solo cuando hay algo detrás— pide leer `scrollLeft` desde JS y
       repintar clases, y no vale seis líneas de riesgo en una barra que ya
       funciona. Se deja estrecho, 14px, para que roce la primera letra y no
       se la coma.
       Va con `mask` y no con un degradado encima: un pseudo-elemento fijo
       taparía el botón del borde y se comería su toque. */
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 14px,
                       #000 calc(100% - 14px), transparent 100%);
            mask-image:linear-gradient(to right, transparent 0, #000 14px,
                       #000 calc(100% - 14px), transparent 100%);
    scroll-snap-type:x proximity;
  }
  .nav-lateral::-webkit-scrollbar{display:none}
  .nav-lateral .nav-item{scroll-snap-align:center}
  .nav-item{
    flex:0 0 auto;min-width:66px;flex-direction:column;gap:3px;padding:8px 4px;font-size:10.5px;
    align-items:center;justify-content:center;border-radius:10px;
  }
  .nav-item span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .nav-item svg{width:21px;height:21px}
  .principal{margin-left:0;padding-bottom:80px}
  .topbar{padding:12px 16px}
  .contenido{padding:20px 16px 40px}
  .bloque-hora .hora{width:44px;font-size:14px}
  #toasts{bottom:84px;right:14px;left:14px;align-items:center}
  .fila-campos{flex-direction:column;gap:0}
  /* Vistas semana/mes en móvil */
  .semana-grid{grid-template-columns:1fr}
  .col-dia .cab{display:flex;align-items:baseline;gap:10px}
  .mes-grid{gap:4px}
  .celda-mes{min-height:58px;padding:5px 6px}
  .celda-mes .res-info{font-size:10px;padding:1px 4px}
  .celda-mes .res-pax{font-size:9.5px}
  .segmented{width:100%;justify-content:stretch}
  .segmented button{flex:1;min-height:40px}
  .nav-dia .fecha-larga{order:5;flex-basis:100%;min-width:0}
  /* La ayuda ocupa la pantalla entera, menos la barra inferior de navegación */
  .panel-ayuda{width:100%;max-width:none;bottom:64px}
}

/* ============================================================
   SALÓN — el plano de mesas en vivo
   ============================================================ */
/* Ver js/modulos/salon.js. El lienzo mantiene la proporción de la
   ilustración del salón y se escala por ALTO: el plano es vertical y lo que
   escasea en un escritorio es el alto, no el ancho. */

/* El plano a la izquierda y los dos paneles del host a la derecha. Por debajo
   de 1080px se apilan: en tablet el plano manda y los avisos van debajo. */
.salon-cols{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px;align-items:start}
@media (max-width:1080px){.salon-cols{grid-template-columns:1fr}}

.salon-reloj{
  font-family:'Archivo Black',sans-serif;font-size:20px;letter-spacing:.03em;
  background:var(--ink);color:#fff;border-radius:12px;padding:6px 14px;
}

.salon-wrap{display:flex;flex-direction:column;align-items:center;gap:12px}
/* LA PROPORCION DE AQUI ES SOLO EL ARRANQUE. El `onload` de la imagen la
   sustituye por la del plano de esa sede, para que NO SE RECORTE NADA.
   945/1633 es la del plano de Ciro BBQ, que fue el primero y durante semanas el
   unico — por eso estuvo fija.
   Se cayo con el segundo restaurante: el plano de Brasas es 1024x1536, y con la
   proporcion de Ciro se habria comido un 13% por los lados, que es justo donde
   viven las mesas de la pared. Un valor fijo que solo sirve para un cliente no
   es un valor por defecto, es una suposicion esperando. */
.salon{
  position:relative;width:100%;max-width:560px;aspect-ratio:945/1633;
  border-radius:16px;overflow:hidden;border:2px solid #e3d8c9;
  background:linear-gradient(160deg,#f6efe6,#f0e6da);
}
/* `contain` y no `cover`: con la proporcion ya ajustada al plano las dos dan lo
   mismo, pero si algun dia entra una imagen con otra forma —o falla el
   `onload`— `contain` deja barras y `cover` RECORTA MESAS sin avisar. Entre
   verse raro y perder informacion, se prefiere verse raro. */
.salon-fondo{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
/* Dos capas: las mesas se repintan; los que caminan NO. Si compartieran capa,
   cada repintado del reloj cortaría la caminata a la mitad. */
.salon-piezas,.salon-personas{position:absolute;inset:0}
.salon-personas{pointer-events:none;z-index:15}

.salon-elemento{
  position:absolute;transform:translate(-50%,-50%);
  background:rgba(255,255,255,.6);border:1.5px dashed #d8ccbb;border-radius:9px;
  color:#9c8f7d;font-weight:700;font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  padding:4px 10px;white-space:nowrap;
}

/* LA MESA ES UNA CAJA, NO UN PUNTO. Antes medía 0×0 y todo —sillas, reloj,
   contador— se colgaba a una distancia fija en píxeles del centro: quedaban
   unos encima de otros y tapando el número. Ahora la caja mide un 15% del
   ancho del lienzo y es cuadrada, así que cada cosa se coloca en PORCENTAJE
   de la caja y todas las mesas se ven igual, en cualquier pantalla. */
/* EL ANCHO LO PONE EL PLANO DE LA SEDE, no este archivo. `--mesa-ancho` lo
   escribe el JS con `restaurants.plano_mesa_pct`; el 15% de aquí es el respaldo
   si esa columna no existiera todavía, y es el valor del plano de Ciro BBQ.
   Ver la migración 20260903020000 para por qué dejó de ser fijo. */
.salon-mesa{
  position:absolute;transform:translate(-50%,-50%);cursor:pointer;
  width:var(--mesa-ancho,15%);aspect-ratio:1;border-radius:14px;z-index:3;
  transition:box-shadow .2s ease, background .25s ease;
}
.salon-mesa:hover{box-shadow:0 0 0 3px rgba(201,183,219,.9);z-index:6}
.salon-mesa.ocupada{background:rgba(179,53,43,.10)}
.salon-mesa.limpieza{background:rgba(28,95,158,.14)}

/* UNIDA E INHABILITADA SE VEN APAGADAS, y es lo que tienen que hacer: las dos
   dicen «aquí no sientes a nadie». Lo que las separa es a dónde te manda cada
   una — la unida tiene flecha y nombre de la principal; la inhabilitada, un
   motivo. Se distinguen por lo que DICEN, no por un color más que memorizar. */
.salon-mesa.unida{background:rgba(201,183,219,.20);opacity:.75}
.salon-mesa.unida .salon-num{border-color:var(--lavanda);border-style:dashed}
.salon-mesa.inhabilitada{background:repeating-linear-gradient(45deg,
  rgba(0,0,0,.05) 0 6px, transparent 6px 12px);opacity:.6}
.salon-mesa.inhabilitada .salon-num{border-color:var(--gris-500);color:var(--gris-500)}
/* La principal de un grupo sí se resalta: es la mesa que hay que tocar.
   Se llama `salon-principal`: `.principal` a secas es la columna de contenido
   del panel (margin-left:224px). Cuando la mesa se llamaba así, se iba 224px
   a la derecha y se montaba sobre la mesa vecina. */
.salon-mesa.salon-principal .salon-num{box-shadow:0 0 0 3px rgba(201,183,219,.75),0 2px 6px rgba(0,0,0,.25)}

/* La flecha se gira con el ángulo real hacia la principal, que calcula el JS
   con las dos posiciones del plano. El `➜` apunta a la derecha sin rotar, así
   que 0° ya es correcto y el ángulo entra tal cual. */
.salon-flecha{
  position:absolute;left:50%;top:50%;font-size:20px;color:var(--lavanda-hover);z-index:3;
  transform:translate(-50%,-50%) rotate(var(--ang,0deg)) translateX(20px);
  text-shadow:0 1px 2px rgba(255,253,250,.9);
}
.salon-fuera{position:absolute;right:-2px;top:-4px;font-size:13px;z-index:6;opacity:.8}

/* EL PUNTO DE PASILLO. Solo se ve calibrando —el JS ni lo pinta fuera de ese
   modo—, así que puede permitirse ser llamativo: aquí no compite con nada.
   Lavanda como el resto de lo que es «estructura del plano» y no «estado de una
   mesa», que son los colores que el host tiene que leer de un vistazo. */
.salon-paso{
  position:absolute;transform:translate(-50%,-50%);
  width:20px;height:20px;border-radius:50%;
  background:var(--lavanda-hover);border:2px solid rgba(255,253,250,.9);
  box-shadow:0 2px 6px rgba(0,0,0,.3);z-index:8;
}
.salon.calibrando .salon-paso{cursor:grab;touch-action:none}
.salon-paso-quitar{
  position:absolute;right:-9px;top:-9px;width:17px;height:17px;border-radius:50%;
  background:var(--ink);color:#fff;font-size:12px;font-style:normal;line-height:16px;
  text-align:center;cursor:pointer;z-index:9;
}
/* LAS UNIONES ENTRE PUNTOS. Se dibujan solo mientras se calibra, y son lo que
   evita una pantalla para definir la red: dos puntos se unen si se ven sin mesa
   en medio, y si una línea atraviesa un muro se ve y se corrige moviendo el
   punto. `vector-effect` mantiene el grosor aunque el viewBox se estire —el
   lienzo no es cuadrado y sin eso las líneas saldrían más gordas en un eje. */
.salon-enlaces{
  position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:7;
}
.salon-enlaces line{
  stroke:var(--lavanda-hover);stroke-width:2;stroke-dasharray:4 3;opacity:.85;
  vector-effect:non-scaling-stroke;
}
/* Cuántas mesas hay en el grupo, en la esquina de abajo: arriba a la derecha
   ya vive el «+N» de las personas que no caben en las cuatro sillas. */
.salon-grupo{
  position:absolute;left:-4px;bottom:-4px;z-index:6;
  background:var(--lavanda-hover);color:var(--ink);border-radius:12px;
  font-size:9.5px;font-weight:700;padding:1px 5px;
}

.salon-num{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:30px;height:30px;border-radius:50%;background:rgba(255,253,250,.94);
  border:3px solid var(--verde-fg);display:flex;align-items:center;justify-content:center;
  font-family:'Archivo Black',sans-serif;font-size:13px;z-index:4;
  box-shadow:0 2px 6px rgba(0,0,0,.25);transition:border-color .25s ease;
}
.salon-mesa.ocupada  .salon-num{border-color:var(--rojo-fg)}
.salon-mesa.limpieza .salon-num{border-color:var(--azul-fg)}

/* El reloj de la mesa cuelga POR DEBAJO de la caja, no dentro: dentro caía
   justo sobre la silla de abajo. Y «debajo» sólo despeja la silla mientras la
   silla esté DENTRO de la caja, así que el JS publica `--silla-y` —dónde acaba
   el mobiliario— y la etiqueta baja hasta pasarlo. El `max()` la deja donde
   estaba en los planos donde ya despejaba, como Ciro BBQ.

   ESTUVO UN RATO EN LA ESQUINA, y merece quedar escrito por qué volvió. Con el
   plano de Brasas apaisado las FILAS quedaban a 124 px y la caja medía 121:
   entre una mesa y la de abajo no cabía una etiqueta de 17 px, y en el Salón
   Cava no se leía ni un reloj. La esquina inferior derecha sí tenía sitio. Pero
   el mismo plano en vertical invierte el problema —las filas se van a 201 px y
   son las COLUMNAS las que se juntan, a 124— y ahí la esquina es justo el peor
   lado. Debajo vuelve a ser lo correcto.

   La lección: el hueco no está siempre en el mismo sitio, depende de si el
   plano es alto o ancho. Si algún día hay que decidirlo por plano, se mide la
   separación de filas y de columnas y se elige; no se elige de memoria. */
.salon-etiq{
  position:absolute;left:50%;
  top:max(100%, calc(var(--silla-y, 84%) + 13px));
  transform:translate(-50%,2px);
  /* NO SE TOCA. La etiqueta puede sobresalir de su caja, y como vive DENTRO del
     div de la mesa se tragaba el clic de la vecina: en Ciro BBQ, tocar la mesa
     12 dejó de abrir su ficha. Lo cazó `probar-salon-mesas`. Es información, no
     un botón. */
  pointer-events:none;
  background:var(--ink);color:#fff;font-size:9.5px;font-weight:700;border-radius:12px;
  padding:1px 7px;white-space:nowrap;z-index:5;box-shadow:0 2px 5px rgba(0,0,0,.3);
}
.salon-etiq.medio{background:var(--amber-fg)}
.salon-etiq.largo{background:var(--rojo-fg)}
/* MAS DE TRES HORAS. No es «un poco más de rojo»: el rojo ya estaba topado a
   los 90 minutos, así que una mesa de 91 minutos y una de seis horas se veían
   idénticas. Aquí el rojo late y se le añade un anillo, que es lo que el ojo
   caza barriendo un plano lleno. Es el único elemento del salón que se mueve
   sin que nadie lo toque, a propósito: si latieran varias cosas, no latiría
   ninguna. */
.salon-etiq.olvidada{
  background:var(--rojo-fg);
  animation:salon-olvidada 1.8s ease-in-out infinite;
}
@keyframes salon-olvidada{
  0%,100%{box-shadow:0 2px 5px rgba(0,0,0,.3), 0 0 0 0 rgba(179,53,43,.55)}
  50%    {box-shadow:0 2px 5px rgba(0,0,0,.3), 0 0 0 7px rgba(179,53,43,0)}
}
/* Quien haya pedido menos movimiento no ve el latido: se queda el anillo fijo,
   que sigue distinguiéndola de una mesa larga normal. */
@media (prefers-reduced-motion:reduce){
  .salon-etiq.olvidada{animation:none;box-shadow:0 2px 5px rgba(0,0,0,.3), 0 0 0 3px rgba(179,53,43,.45)}
}
/* «Con la mesa 12» y el motivo de una inhabilitada son más largos que «45 min»
   y no caben en el ancho de la mesa. `max-width` en vw en vez de nowrap: el
   texto se corta con puntos suspensivos en vez de empujar el plano. */
.salon-etiq.unida{background:var(--lavanda-hover);color:var(--ink);max-width:15vw;overflow:hidden;text-overflow:ellipsis}
.salon-etiq.fuera{background:var(--gris-500);max-width:15vw;overflow:hidden;text-overflow:ellipsis}
.salon-mas{
  position:absolute;right:-2px;top:-2px;z-index:6;
  background:var(--rojo-fg);color:#fff;border-radius:12px;font-size:9.5px;font-weight:700;padding:1px 5px;
}
.salon-nota{position:absolute;left:-2px;top:-4px;font-size:13px;z-index:6}

/* Comensales tipo pixel-art vistos desde arriba, girados para quedar mirando
   a la mesa. */
.pj{position:absolute;width:24px;height:24px;transform:translate(-50%,-50%) rotate(var(--rot,0deg));z-index:16}
.pj-hombros{position:absolute;left:2%;right:2%;top:34%;height:52%;border-radius:5px;
  background:var(--camisa,#7a4fb0);border:2px solid rgba(0,0,0,.35);
  box-shadow:inset -3px 0 0 rgba(0,0,0,.18)}
.pj-cab{position:absolute;left:24%;top:6%;width:52%;height:52%;
  background:var(--piel,#c99b71);border:2px solid rgba(0,0,0,.4);
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.15)}
.pj-pelo{position:absolute;left:24%;top:6%;width:52%;height:24%;
  background:var(--pelo,#3a2a1c);border:2px solid rgba(0,0,0,.4);border-bottom:none}
/* Caminando: el movimiento lo da la transición de left/top que pone el JS; el
   balanceo de hombros es lo que lo hace leer como pasos y no como deslizar. */
.pj-camina{transition-property:left,top;transition-timing-function:linear;z-index:17}
.pj-camina .pj-hombros{animation:pj-paso .38s ease-in-out infinite}
@keyframes pj-paso{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}
.pj-sentado{width:22px;height:22px}
/* Los SENTADOS no llevan animación de aparición, y es a propósito: la capa de
   mesas se repinta cada vez que corre el reloj, y una animación aquí volvería
   a empezar en cada repintado — los comensales quedaban parpadeando. */

/* ------------------------------------------------------------
   MODO CALIBRAR
   ------------------------------------------------------------ */
/* El plano se calibra arrastrando cada número hasta su mesa. Se ve DISTINTO a
   propósito: en este modo tocar una mesa la mueve en vez de sentar a alguien,
   y confundir los dos estados en hora pico sería caro. */
.salon.calibrando{cursor:grab;box-shadow:0 0 0 3px var(--lavanda)}
.salon.calibrando .salon-mesa,
.salon.calibrando .salon-elemento{cursor:grab;touch-action:none}
.salon.calibrando .salon-mesa:hover{box-shadow:0 0 0 3px var(--lavanda-hover)}
.salon.calibrando .salon-mesa.arrastrando,
.salon.calibrando .salon-elemento.arrastrando{
  cursor:grabbing;opacity:.85;z-index:30;
  box-shadow:0 0 0 3px var(--lavanda-hover),0 6px 18px rgba(0,0,0,.3);
}
.salon-calibrar{
  width:100%;max-width:560px;margin-top:12px;
  background:var(--blanco);border:1.5px solid var(--lavanda);
  border-radius:var(--radio);padding:14px;box-shadow:var(--sombra);
}
.cal-aviso{font-size:13px;color:var(--gris-700);line-height:1.5;margin-bottom:12px}
.cal-fila{display:flex;gap:18px;flex-wrap:wrap;margin-bottom:12px}
.cal-fila label{flex:1;min-width:190px;font-size:12.5px;font-weight:600;color:var(--gris-700)}
.cal-fila input[type=range]{width:100%;margin-top:6px;accent-color:var(--lavanda-hover)}
.cal-fila span{font-weight:700;color:var(--ink)}
.cal-pie{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cal-pie .ayuda{margin:0;font-variant-numeric:tabular-nums}

.salon-leyenda{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;font-size:12px;color:var(--gris-700)}
.salon-leyenda span{display:flex;align-items:center;gap:5px}
.salon-anillo{width:12px;height:12px;border-radius:50%;background:#fffdfa;border:3px solid}

/* ---------- Panel lateral: reservas por sentar ---------- */
/* LA COLUMNA SE QUEDA FIJA Y CADA LISTA SE DESPLAZA SOLA. Sin esto, un
   servicio con veinte grupos hacía crecer la columna derecha hacia abajo y
   estiraba la página: el plano quedaba arriba del todo y el host tenía que
   bajar para ver los avisos, que es justo lo contrario de lo que sirve
   durante el turno. Ahora las dos cosas se ven a la vez, siempre. */
.salon-lateral{position:sticky;top:82px}
@media (max-width:1080px){.salon-lateral{position:static;top:auto}}

.salon-panel{background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);padding:16px;margin-bottom:14px}
.salon-panel h3{font-size:14.5px;margin-bottom:10px}
.salon-panel h3 small{font-weight:400;color:var(--gris-500)}

/* El tope va en vh y no en píxeles: en un portátil de 13" y en el monitor del
   restaurante tiene que caber lo mismo en proporción. `overscroll-contain`
   evita que al llegar al final de la lista siga desplazándose la página. */
.salon-lista{overflow-y:auto;overscroll-behavior:contain;padding-right:2px}
.salon-lista.avisos{max-height:38vh}
.salon-lista.historial{max-height:32vh}
.salon-lista::-webkit-scrollbar{width:8px}
.salon-lista::-webkit-scrollbar-thumb{background:var(--gris-300);border-radius:8px}
.salon-lista::-webkit-scrollbar-track{background:transparent}

.salon-aviso{
  border-radius:11px;padding:10px 12px;font-size:13px;margin-bottom:8px;
  border:1.5px solid;display:flex;gap:9px;align-items:flex-start;text-align:left;
  width:100%;font-family:inherit;background:none;
}
.salon-aviso .ic{font-size:16px;line-height:1.1}
.salon-aviso b{display:block;font-size:13.5px}
.salon-aviso small{opacity:.85}
/* ESCALA DE RETRASO: ámbar → naranja → rojo → apagado.
   El color va subiendo solo con los minutos, para que el host sepa a qué
   atender sin leer ninguna hora. El naranja se define aquí y no en :root
   porque es propio de esta escala: no es un estado del sistema como los
   otros cinco, y meterlo en la paleta general invitaría a usarlo suelto. */
.salon-aviso.lejos{background:var(--blanco);border-color:var(--gris-200);color:var(--gris-700)}
.salon-aviso.pronto{background:var(--amber-bg);border-color:#e6d08a;color:var(--amber-fg);animation:salon-late 1.6s ease-in-out infinite}
.salon-aviso.tarde-poco{background:var(--amber-bg);border-color:#e6d08a;color:var(--amber-fg)}
.salon-aviso.tarde-medio{background:#fce6d2;border-color:#efbd8c;color:#a3550e}
.salon-aviso.tarde-mucho{background:var(--rojo-bg);border-color:#f0c9c9;color:var(--rojo-fg)}
/* Vencida: apagada a propósito. Sigue estando —hay que poder marcarla— pero
   deja de competir por la atención con lo que todavía se puede atender. */
.salon-aviso.vencida{background:var(--gris-100);border-color:var(--gris-200);color:var(--gris-500)}
.salon-aviso.sucia{background:var(--azul-bg);border-color:#b9d6ef;color:var(--azul-fg)}
.salon-aviso.larga{background:var(--rojo-bg);border-color:#f0c9c9;color:var(--rojo-fg)}
/* El aviso de la mesa olvidada usa el mismo latido que `.pronto`: en el panel
   lateral ya existía esa gramática —lo que late es lo que hay que atender
   ahora— y aquí se hereda en vez de inventar otra. */
.salon-aviso.olvidada{
  background:var(--rojo-bg);border-color:var(--rojo-fg);color:var(--rojo-fg);
  animation:salon-olvidada-aviso 1.8s ease-in-out infinite;
}
@keyframes salon-olvidada-aviso{
  0%,100%{box-shadow:0 0 0 0 rgba(179,53,43,.35)}
  50%    {box-shadow:0 0 0 6px rgba(179,53,43,0)}
}
@media (prefers-reduced-motion:reduce){ .salon-aviso.olvidada{animation:none} }
@keyframes salon-late{0%,100%{box-shadow:0 0 0 0 rgba(138,100,16,.35)}50%{box-shadow:0 0 0 6px rgba(138,100,16,0)}}

/* Rejilla de mesas del selector. Botones grandes: se usa de pie, con el
   cliente esperando delante, muchas veces en una tablet. */
.rejilla-mesas{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:8px;margin-bottom:8px}
/* MISMO LENGUAJE QUE EL SELECTOR DE PERSONAS de la ventana de mesa: caja
   blanca, borde gris, lavanda al pasar por encima. La primera versión pintaba
   cada mesa con el color de su estado —verde, rojo, azul— y quedaban dos
   ventanas del mismo flujo que parecían de dos productos distintos.
   El estado se sigue viendo, pero en la etiqueta pequeña y no llenando el
   botón: lo que el ojo tiene que encontrar aquí es el NÚMERO de la mesa. */
.mesa-op{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  min-height:56px;border-radius:11px;border:1.5px solid var(--gris-200);
  background:var(--blanco);color:var(--ink);font-family:inherit;
  transition:border-color .12s ease, background .12s ease;
}
.mesa-op b{font-family:'Archivo Black',sans-serif;font-size:16px}
.mesa-op small{font-size:10.5px;color:var(--gris-500);text-align:center;line-height:1.15;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mesa-op:hover:not(:disabled){background:var(--lavanda-suave);border-color:var(--lavanda)}
.mesa-op:disabled{background:var(--gris-100);color:var(--gris-500);cursor:default}
.mesa-op:disabled b{color:var(--gris-500)}
/* Un punto de color, no un relleno: dice el estado sin gritar. */
.mesa-op.ocupada small{color:var(--rojo-fg)}
.mesa-op.limpieza small{color:var(--azul-fg)}
.mesa-op.unida small{color:var(--lavanda-hover)}
.mesa-op.inhabilitada small{color:var(--gris-500)}
/* La mesa larga ya armada se resalta: es justo la que el host busca cuando
   está sentando a un grupo grande, y sin marca queda perdida entre las demás. */
.mesa-op.larga{border-color:var(--lavanda);background:var(--lavanda-suave)}
.mesa-op.larga small{color:var(--lavanda-hover);font-weight:700}

/* ---- Acciones de un aviso: SIEMPRE en su propia fila, siempre igual ----
   El botón no puede colgar del final del texto: según lo largo que sea la
   frase quedaba a la derecha o saltaba abajo, y cada tarjeta se veía
   distinta. Fila propia, misma altura y misma alineación en las cuatro
   esquinas de la lista — el ojo lo encuentra sin buscarlo. */
.salon-aviso-cuerpo{display:flex;flex-direction:column;min-width:0;flex:1}
.salon-acciones{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
.salon-acciones > button{height:30px;display:inline-flex;align-items:center;gap:4px;white-space:nowrap}

.salon-sentar{
  border:none;border-radius:9px;
  background:var(--ink);color:#fff;padding:0 13px;font-size:12.5px;font-weight:700;
}
.salon-sentar:hover{background:var(--ink-3)}
.salon-sentar:disabled{opacity:.5}

.salon-noshow{
  border:1.5px solid var(--gris-300);background:var(--blanco);
  color:var(--gris-700);border-radius:9px;padding:0 11px;font-size:12px;font-weight:600;
}
.salon-noshow:hover{border-color:var(--rojo-fg);color:var(--rojo-fg)}
.salon-noshow:disabled{opacity:.5}

.salon-hist{
  font-size:12.5px;border-left:3px solid var(--lavanda);background:var(--lavanda-suave);
  border-radius:0 9px 9px 0;padding:7px 10px;margin-bottom:6px;
}
.salon-hist .m{font-family:'Archivo Black',sans-serif;color:#6b4f8a}
.salon-hist.cerrada{background:var(--gris-100);border-left-color:var(--gris-300)}
/* La sentada deshecha va TACHADA. Es la única forma de que el turno siguiente,
   leyendo el registro de reojo, no cuente esa fila como una visita más — el
   texto explica que no se quedaron, pero nadie lee el texto de todas. */
.salon-hist.anulada{background:transparent;border-left-color:var(--gris-200);opacity:.65}
.salon-hist.anulada > b, .salon-hist.anulada .m{text-decoration:line-through}

/* ---------- Selector de personas (modal de la mesa) ---------- */
/* Existía en el prototipo y no se pasó: sin estas reglas los números salían
   pegados, sin caja y sin marcar cuál está elegido. */
.pax-sel{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:6px}
.pax-sel button{
  width:38px;height:38px;border-radius:10px;border:1.5px solid var(--gris-200);
  background:var(--blanco);font-weight:700;transition:border-color .12s ease, background .12s ease;
}
.pax-sel button:hover{border-color:var(--lavanda)}
.pax-sel button.on{background:var(--lavanda);border-color:var(--lavanda)}

/* OPCIONES DE TEXTO. Son primas de `.pax-sel` pero NO pueden compartirlo: allí
   el botón mide 38×38 fijos porque contiene un número de uno o dos dígitos.
   Metiendo «No les gustó la mesa» en esa caja, el texto se parte palabra a
   palabra y las cuatro opciones se montan unas encima de otras — se vio en el
   modal de «No se quedaron». Aquí el ancho lo pone el contenido. */
.chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:6px}
.chips button{
  border-radius:999px;border:1.5px solid var(--gris-200);background:var(--blanco);
  padding:7px 13px;font-family:inherit;font-size:13px;font-weight:600;
  color:var(--gris-700);line-height:1.25;text-align:center;max-width:100%;
  transition:border-color .12s ease, background .12s ease, color .12s ease;
}
.chips button:hover{border-color:var(--lavanda);background:var(--lavanda-suave)}
.chips button.on{background:var(--lavanda);border-color:var(--lavanda);color:var(--ink)}

/* Opciones grandes del modal de mesa: cada una es una decisión distinta
   (¿esta reserva? ¿un walk-in?), no un botón de formulario. */
.salon-op{
  display:block;width:100%;text-align:left;border:1.5px solid var(--gris-200);background:var(--blanco);
  border-radius:11px;padding:11px 13px;margin-bottom:7px;font-family:inherit;font-size:14px;font-weight:600;
}
.salon-op:hover{border-color:var(--lavanda);background:var(--lavanda-suave)}
.salon-op small{display:block;font-weight:400;color:var(--gris-500)}
.salon-op.res{border-color:#e6d08a;background:var(--amber-bg)}
.salon-op.res:hover{border-color:var(--amber-fg)}
/* Unir e inhabilitar son de otra categoría: no sientan a nadie, preparan la
   mesa. Se ven más pequeñas y detrás de un separador para que el botón grande
   de sentar siga siendo el único obvio del modal. */
.salon-op.menor{font-size:13px;font-weight:600;padding:9px 12px;color:var(--gris-700)}
.salon-op-sep{
  display:flex;align-items:center;gap:8px;margin:14px 0 8px;
  font-size:11.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--gris-500);
}
.salon-op-sep::before,.salon-op-sep::after{content:'';flex:1;height:1px;background:var(--gris-200)}

/* Aviso de informe truncado. Va arriba del todo y en rojo a propósito: si los
   números de abajo están mal, eso es lo primero que hay que saber. */
.aviso-trunco{
  background:var(--rojo-bg);border:1.5px solid #f0c9c9;color:var(--rojo-fg);
  border-radius:var(--radio);padding:12px 14px;margin-bottom:14px;font-size:13.5px;line-height:1.5;
}

/* ============================================================
   SIN CERRAR — reservas de fecha pasada que nadie marcó
   ============================================================ */
/* UNA SOLA CAJA AMBAR PARA LOS DOS SITIOS, a propósito: en Informes es un
   <div> que declara cuántas quedaron fuera de la tasa de no-show, y en Reservas
   un <details> con la lista para cerrarlas. Es el mismo hecho contado en dos
   pantallas, así que se ve igual en las dos — el host y el dueño hablan del
   mismo número sin traducirlo.

   AMBAR Y NO ROJO: rojo es «esto está mal» (`.aviso-trunco`, cuando los números
   de la pantalla son falsos). Esto es «falta hacer algo», que es distinto. */
.aviso-sin-cerrar{
  background:var(--amber-bg);border:1.5px solid #ecd9a4;color:var(--amber-fg);
  border-radius:var(--radio);padding:12px 14px;margin-bottom:16px;
  font-size:13.5px;line-height:1.5;
}
.aviso-sin-cerrar > summary{
  cursor:pointer;list-style:none;display:flex;gap:9px;align-items:baseline;flex-wrap:wrap;
}
.aviso-sin-cerrar > summary::-webkit-details-marker{display:none}
.aviso-sin-cerrar > summary::after{
  content:'▸';margin-left:auto;font-size:12px;transition:transform .18s ease;
}
.aviso-sin-cerrar[open] > summary::after{transform:rotate(90deg)}
.aviso-sin-cerrar .sc-sub{font-weight:500;color:var(--gris-700)}
.aviso-sin-cerrar .sc-cuerpo{margin-top:12px}
.aviso-sin-cerrar .sc-texto{color:var(--gris-700);font-size:13px;margin-bottom:10px}
.aviso-sin-cerrar .sc-sep{
  display:flex;align-items:center;gap:8px;margin:14px 0 8px;
  font-size:11.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--amber-fg);font-weight:700;
}
.aviso-sin-cerrar .sc-sep::before,.aviso-sin-cerrar .sc-sep::after{
  content:'';flex:1;height:1px;background:#ecd9a4;
}
/* Las tarjetas son las MISMAS de la agenda (.tarjeta-reserva). Aquí solo se
   apilan, igual que dentro de un bloque de hora del timeline. */
.aviso-sin-cerrar .sc-tarjetas{display:flex;flex-direction:column;gap:10px}
/* Cuánto lleva abierta / cuánto le queda. Va dentro de .meta, que es gris:
   en ámbar y negrita porque es el dato que decide si el host se acuerda o no. */
.tarjeta-reserva .meta .sc-edad{color:var(--amber-fg);font-weight:700}
.tarjeta-reserva .meta .sc-edad.sc-urge,.aviso-sin-cerrar .sc-texto.sc-urge{
  color:var(--rojo-fg);font-weight:700;
}

/* «N sin cerrar» debajo de la tasa de no-show, en Informes. Mismo sitio y mismo
   tamaño que la flecha de comparación (.delta): quitar reservas del cálculo sin
   decir cuántas sería mentir al revés. */
.kpi .sin-cerrar{font-size:12px;font-weight:700;margin-top:3px;color:var(--amber-fg)}

/* El estado «Sin cerrar» (`expired`). Tinta oscura y no ámbar: en la barra
   apilada de Informes tiene que distinguirse de «Pendiente», que ya es ámbar, y
   de «Completada»/«Cancelada», que son los dos grises. */
.badge-expired{background:var(--ink-3);color:var(--blanco)}
.punto-estado.expired{background:var(--ink-3)}

/* ============================================================
   DOCUMENTACIÓN
   ============================================================ */
/* Cada artículo es un <details>: abrir y cerrar sale gratis del navegador,
   con teclado incluido. Mismo criterio que el panel de ayuda — y comparte
   `.ay-detalle` para el cuerpo, así el texto se ve igual en los dos sitios
   y no hay dos estilos de prosa que mantener. */
.doc-art{
  background:var(--blanco);border-radius:var(--radio);box-shadow:var(--sombra);
  margin-bottom:10px;overflow:hidden;
}
.doc-art summary{
  padding:14px 18px;cursor:pointer;list-style:none;
  display:flex;flex-direction:column;gap:2px;
}
.doc-art summary::-webkit-details-marker{display:none}
.doc-art summary:hover .doc-t{color:#7c5f99}
.doc-t{font-weight:700;font-size:15px;display:flex;align-items:center;gap:9px}
.doc-t::before{
  content:'▸';color:var(--gris-500);font-size:12px;
  transition:transform .18s ease;flex:0 0 auto;
}
.doc-art[open] .doc-t::before{transform:rotate(90deg)}
.doc-r{color:var(--gris-500);font-size:13px;padding-left:21px}
.doc-cuerpo{padding:0 18px 18px 39px;font-size:14px}
@media (max-width:640px){.doc-cuerpo{padding-left:18px}}

.doc-pie{
  margin-top:22px;padding:16px 18px;text-align:center;
  color:var(--gris-500);font-size:13px;
  background:var(--gris-100);border-radius:var(--radio);
}

/* ============================================================
   PAGINADOR
   ============================================================ */
/* Lleva SIEMPRE el rango y el total («51–100 de 340»), no solo las flechas:
   sin el total, quien busca a alguien no sabe si le faltan dos páginas o
   veinte, y termina desistiendo. */
.paginador{
  display:flex;align-items:center;justify-content:center;gap:14px;
  flex-wrap:wrap;margin-top:16px;
}
.paginador-info{font-size:13px;color:var(--gris-500)}
.paginador .btn[disabled]{opacity:.4;cursor:default}

/* ============================================================
   CHECKLIST DE ALTA DE SEDE
   ============================================================ */
/* Dar de alta una sede son varios pasos manuales y ninguno da error si se
   omite: la sede funciona, acepta reservas y se ve bien. Esto los hace
   visibles. Ver js/lib/altaSede.js. */
.alta-caja{border:1.5px solid var(--gris-200);border-radius:var(--radio);padding:14px;background:var(--gris-100)}
.alta-caja.critica{border-color:var(--amber-fg);background:var(--amber-bg)}
.alta-tit{font-weight:700;font-size:14px;margin-bottom:10px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.alta-badge{background:var(--rojo-fg);color:#fff;border-radius:20px;font-size:11px;padding:2px 9px;font-weight:600}
.alta-item{background:var(--blanco);border-radius:10px;padding:10px 12px;margin-bottom:8px;font-size:13px;border-left:3px solid var(--gris-300)}
.alta-item.critico{border-left-color:var(--rojo-fg)}
.alta-item:last-child{margin-bottom:0}
.alta-item b{display:block;font-size:13.5px;margin-bottom:2px}
.alta-item div{color:var(--gris-700);line-height:1.45}
.alta-item small{display:block;margin-top:5px;color:var(--gris-500);font-size:11.5px;font-weight:600}
.alta-ok{background:var(--verde-bg);color:var(--verde-fg);border-radius:var(--radio);padding:12px 14px;font-size:13.5px;font-weight:600}

/* ============================================================
   AYUDA CONTEXTUAL — el «?» de cada vista y su panel lateral
   ============================================================ */
/* El botón vive junto al <h1> de la vista, dentro de .titulo-con-ayuda. */
.titulo-con-ayuda{display:flex;align-items:center;gap:9px}
.btn-ayuda{
  flex:0 0 auto;
  width:22px;height:22px;border-radius:50%;border:none;
  background:var(--gris-200);color:var(--gris-700);
  font-weight:700;font-size:13px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .18s ease, color .18s ease;
}
.btn-ayuda:hover{background:var(--lavanda);color:var(--ink)}

/* El panel. z-index 140: por encima de la vista y de la barra superior (40),
   por debajo del overlay de los modales (150) — si alguien abre un modal
   teniendo la ayuda abierta, el modal manda. */
.panel-ayuda{
  position:fixed;top:0;bottom:0;right:0;z-index:140;
  width:400px;max-width:92vw;
  background:var(--blanco);
  box-shadow:var(--sombra-alta);
  display:flex;flex-direction:column;
  animation:ayuda-entra .22s ease;
}
@keyframes ayuda-entra{from{transform:translateX(24px);opacity:0}to{transform:none;opacity:1}}
/* Quien haya pedido menos movimiento en su sistema, no lo recibe. */
@media (prefers-reduced-motion:reduce){
  .panel-ayuda{animation:none}
}

.ay-cabecera{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:18px 20px;border-bottom:1.5px solid var(--gris-200);flex:0 0 auto;
}
.ay-cabecera h2{font-family:'Archivo Black',sans-serif;font-size:16px;letter-spacing:.01em}

.ay-cuerpo{padding:18px 20px 32px;overflow-y:auto;flex:1 1 auto;font-size:14px}
.ay-intro{color:var(--gris-700);margin-bottom:16px;line-height:1.55}

/* Cada apartado es un <details>: abrir y cerrar sale gratis del navegador,
   con teclado incluido. */
.ay-seccion{border-bottom:1px solid var(--gris-200)}
.ay-seccion summary{
  padding:11px 0;font-weight:600;cursor:pointer;list-style:none;
  display:flex;align-items:center;gap:9px;
}
.ay-seccion summary::-webkit-details-marker{display:none}
.ay-seccion summary::before{
  content:'▸';color:var(--gris-500);font-size:12px;
  transition:transform .18s ease;flex:0 0 auto;
}
.ay-seccion[open] summary::before{transform:rotate(90deg)}
.ay-seccion summary:hover{color:#7c5f99}

.ay-detalle{padding:2px 0 16px 21px;color:var(--gris-700);line-height:1.6}
.ay-detalle p{margin-bottom:10px}
.ay-detalle p:last-child{margin-bottom:0}
.ay-detalle ul,.ay-detalle ol{margin:0 0 10px 18px}
.ay-detalle li{margin-bottom:5px}
.ay-detalle b{color:var(--ink)}
.ay-detalle code{
  background:var(--gris-100);border-radius:5px;padding:1px 5px;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12.5px;color:var(--ink);
}
/* Ejemplo concreto y aviso: se distinguen del cuerpo sin gritar. */
.ay-detalle .ay-ej{
  background:var(--lavanda-suave);border-radius:var(--radio);
  padding:10px 12px;font-size:13.5px;
}
.ay-detalle .ay-aviso{
  background:var(--amber-bg);color:var(--amber-fg);
  border-radius:var(--radio);padding:10px 12px;font-size:13.5px;
}
.ay-detalle .ay-aviso b{color:var(--amber-fg)}
.ay-ciclo{
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  margin-bottom:10px;color:var(--gris-500);font-size:12px;
}
.ay-pie{margin-top:20px;color:var(--gris-500);font-size:12.5px;text-align:center}

/* ------------------------------------------------------------
   Tablas → tarjetas apiladas en pantallas angostas.
   En móvil las tablas de datos se desbordaban hacia el lado y las
   columnas de la derecha (comentario, teléfono, estado...) quedaban
   escondidas tras un scroll horizontal que nadie descubre. Mismo
   patrón visual que la agenda del día de Reservas: la fila se vuelve
   una tarjeta y cada celda una línea "etiqueta: valor". La etiqueta
   sale de data-etiqueta en cada <td> (el thead se oculta).
   ------------------------------------------------------------ */
@media (max-width:640px){
  /* !important: varias de estas tablas traen min-width/white-space en
     estilo inline (para verse bien en escritorio); en stylesheet, un
     !important le gana al estilo inline y aquí es exactamente lo que
     se necesita. */
  .tabla-tarjetas{min-width:0 !important}
  .tabla-tarjetas thead{display:none}
  .tabla-tarjetas, .tabla-tarjetas tbody, .tabla-tarjetas tr, .tabla-tarjetas td{display:block;width:100%}
  .tabla-tarjetas tr{padding:12px 14px;border-bottom:1px solid var(--gris-200)}
  .tabla-tarjetas tr:last-child{border-bottom:none}
  .tabla-tarjetas td{
    padding:3px 0 !important;border:none !important;
    max-width:none !important;min-width:0 !important;white-space:normal !important;
    display:flex;gap:10px;align-items:baseline;
  }
  .tabla-tarjetas td::before{
    content:attr(data-etiqueta);
    flex:0 0 92px;color:var(--gris-500);
    font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.03em;
  }
  .tabla-tarjetas td:not([data-etiqueta])::before,
  .tabla-tarjetas td[data-etiqueta=""]::before{content:none}
  /* Gráficas: encoger al ancho del teléfono en vez de scroll lateral
     (el viewBox del svg mantiene las proporciones). */
  .chart-scroll svg{max-width:100%;height:auto}
}
