/* ==========================================================================
   BRASA — sistema de diseño de Rafa Hot Dog
   El calor de la plancha: rojo brasa, oro mostaza, carbón tibio y crema.
   Un solo lenguaje para el mostrador, la cocina, la oficina y el teléfono.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Tipografía — Figtree variable, servida desde este servidor.
   Geométrica y humanista a la vez: pesada sin gritar, redonda sin ser blanda.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/figtree-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/figtree-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* --- Superficies: crema tibia, nunca gris azulado -------------------- */
  --paper:   #ffffff;   /* tarjeta */
  --cream:   #fdf7f1;   /* fondo de página */
  --cream-2: #f6ece2;   /* zona hundida, cabecera de tabla */
  --cream-3: #ecdfd2;   /* borde suave */
  --line:    #ead9c9;   /* línea divisoria */
  --line-2:  #f4e8dc;   /* línea tenue */

  /* --- Carbón: el chasis oscuro, tibio ---------------------------------- */
  --coal-900: #191310;
  --coal-800: #221a16;
  --coal-700: #2f251f;
  --coal-600: #43352c;
  --coal-500: #9c8674;
  --coal-ink:   #fff6ec;
  --coal-ink-2: #c3ac97;

  /* --- Tinta ------------------------------------------------------------ */
  --ink:   #1a1512;
  --ink-2: #5c4e45;
  --ink-3: #78685d;

  /* --- LEY DE PALETA ----------------------------------------------------
     Siete colores. Cada uno tiene un trabajo y no hace ningún otro.
       brasa   → la marca, la acción principal, lo urgente
       oro     → lo que se destaca: oferta, favorito, novedad
       verde   → listo · disponible · pagado · conforme
       naranja → en curso: preparando, en ruta, pendiente
       azul    → información y enlaces
       uva     → combos y promociones
       grafito → inactivo · agotado · cerrado
     Ningún color decorativo. Si aparece un octavo, es un error.
     ---------------------------------------------------------------------- */
  --brasa:      #df121c;  --brasa-deep: #b30d15;  --brasa-soft: #fde8e9;  --brasa-on: #ffffff;  --brasa-lit: #ff6257;
  --oro:        #ffcd00;  --oro-deep:   #8a5c05;  --oro-soft:   #fff5cc;  --oro-on:   #241703;  --oro-lit:   #ffdb4d;
  --verde:      #12833a;  --verde-deep: #0f6e2f;  --verde-soft: #e4f6ea;  --verde-on: #ffffff;  --verde-lit: #45cf76;
  --naranja:    #e8720c;  --naranja-deep:#a24c05; --naranja-soft:#fdeedd; --naranja-on:#26150a; --naranja-lit:#ff9a44;
  --azul:       #1668d9;  --azul-deep:  #0f4ea6;  --azul-soft:  #e6f0fd;  --azul-on:  #ffffff;  --azul-lit:  #62a5ff;
  --uva:        #7b3fa0;  --uva-deep:   #5f2f7d;  --uva-soft:   #f3e9f9;  --uva-on:   #ffffff;  --uva-lit:   #b57bd8;
  --grafito:    #7d6d62;  --grafito-deep:#5c4e45; --grafito-soft:#f2ebe4; --grafito-lit:#a89689;

  /* --- Geometría generosa ------------------------------------------------
     La comida se sirve redonda. Nada de cantos vivos. */
  --r-xs:   8px;
  --r-sm:   12px;
  --r-md:   18px;
  --r-lg:   26px;
  --r-xl:   34px;
  --r-pill: 999px;

  /* --- Profundidad: sombra tibia y difusa, nunca gris -------------------- */
  --sh-1: 0 1px 2px rgba(26, 21, 18, .05), 0 2px 6px rgba(26, 21, 18, .04);
  --sh-2: 0 2px 6px rgba(26, 21, 18, .06), 0 10px 22px -8px rgba(26, 21, 18, .12);
  --sh-3: 0 6px 16px rgba(26, 21, 18, .08), 0 22px 48px -14px rgba(26, 21, 18, .2);
  --sh-4: 0 12px 32px rgba(26, 21, 18, .12), 0 40px 80px -20px rgba(26, 21, 18, .28);
  --sh-brasa: 0 6px 18px -4px rgba(223, 18, 28, .42);
  --sh-oro:   0 6px 18px -4px rgba(255, 205, 0, .5);
  --sh-verde: 0 6px 18px -4px rgba(18, 131, 58, .38);

  /* --- Medidas ---------------------------------------------------------- */
  --rail-w:     252px;
  --rail-w-min: 76px;
  --bar-h:      68px;
  --tap:        48px;   /* objetivo táctil mínimo */
  --tap-lg:     56px;   /* objetivo de mostrador y de calle */

  /* --- Movimiento: con rebote, como debe ser una app ---------------------- */
  --ease:  cubic-bezier(.4, 0, .2, 1);
  /* El rebote es para lo que se toca, no para lo que aparece. */
  --pop:   cubic-bezier(.32, 1.28, .6, 1);
  --fast:  150ms;
  --med:   240ms;
  --slow:  420ms;

  --font: 'Figtree', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, 'SFMono-Regular', 'Cascadia Mono', Menlo, monospace;
}

/* La pared de cocina invierte el material: mismo calor, sin luz.
   Se lee de pie, a tres metros, bajo campana. */
.night {
  --paper:   #221a16;
  --cream:   #191310;
  --cream-2: #2f251f;
  --cream-3: #43352c;
  --line:    rgba(255, 246, 236, .12);
  --line-2:  rgba(255, 246, 236, .07);
  --ink:   #fff6ec;
  --ink-2: #c3ac97;
  --ink-3: #9b8877;
  --brasa: var(--brasa-lit); --oro: var(--oro-lit); --verde: var(--verde-lit);
  --naranja: var(--naranja-lit); --azul: var(--azul-lit); --uva: var(--uva-lit);
  --grafito: var(--grafito-lit);
  --brasa-deep: var(--brasa-lit); --oro-deep: var(--oro-lit); --verde-deep: var(--verde-lit);
  --naranja-deep: var(--naranja-lit); --azul-deep: var(--azul-lit); --uva-deep: var(--uva-lit);
  --grafito-deep: var(--grafito-lit);
  --brasa-soft: rgba(255, 98, 87, .16);  --oro-soft: rgba(255, 219, 77, .16);
  --verde-soft: rgba(69, 207, 118, .16);  --naranja-soft: rgba(255, 154, 68, .16);
  --azul-soft: rgba(98, 165, 255, .16);   --uva-soft: rgba(181, 123, 216, .16);
  --grafito-soft: rgba(168, 150, 137, .14);
  --brasa-on: #2a0906; --oro-on: #241703; --verde-on: #04180a;
  --naranja-on: #26150a; --azul-on: #04101f; --uva-on: #1a0824;
  --sh-1: none;
  --sh-2: 0 4px 14px rgba(0, 0, 0, .4);
  --sh-3: 0 10px 30px rgba(0, 0, 0, .5);
  --sh-4: 0 20px 60px rgba(0, 0, 0, .6);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { -webkit-tap-highlight-color: transparent; }

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--cream-3) transparent;
  accent-color: var(--brasa);
  caret-color: var(--brasa);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: .9375rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'ss01' 1, 'cv11' 1;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 800; letter-spacing: -.022em; line-height: 1.18; color: var(--ink); }
p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; margin: 0; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
table { border-collapse: collapse; width: 100%; }
hr { border: 0; border-top: 1px solid var(--line); margin: 0; }
::selection { background: var(--brasa); color: #fff; }

/* Al saltar a un ancla o al enfocar un campo cerca del borde, el destino
   quedaba debajo de la barra fija. Se reserva su altura. */
html { scroll-padding-top: calc(var(--bar-h) + .75rem); }

:focus-visible {
  outline: 3px solid var(--azul);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--cream-3);
  border: 3px solid transparent;
  border-radius: var(--r-pill);
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); background-clip: content-box; }
.no-bar { scrollbar-width: none; }
.no-bar::-webkit-scrollbar { display: none; }

/* --------------------------------------------------------------------------
   3. Escala tipográfica
   Grande y segura. Un precio se lee de reojo; un titular convence.
   -------------------------------------------------------------------------- */
.t-display { font-size: clamp(2rem, 1.4rem + 2.6vw, 3.25rem); font-weight: 900; letter-spacing: -.04em; line-height: 1.02; }
.t-hero    { font-size: clamp(1.625rem, 1.2rem + 1.7vw, 2.375rem); font-weight: 800; letter-spacing: -.032em; line-height: 1.08; }
.t-title   { font-size: 1.375rem; font-weight: 800; letter-spacing: -.024em; }
.t-head    { font-size: 1.0625rem; font-weight: 700; letter-spacing: -.016em; }
.t-body    { font-size: .9375rem; font-weight: 500; }
.t-small   { font-size: .8125rem; font-weight: 500; color: var(--ink-2); }
.t-tiny    { font-size: .75rem; font-weight: 500; color: var(--ink-3); }

/* La voz de rótulo: nombra una zona, nunca titula. */
.t-label {
  font-size: .6875rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* El precio siempre alineado y siempre firme. */
.t-price { font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.tabular, .num { font-variant-numeric: tabular-nums; }

.muted { color: var(--ink-3); }
.dim   { color: var(--ink-2); }

/* --------------------------------------------------------------------------
   4. Primitivas de disposición
   -------------------------------------------------------------------------- */
.row   { display: flex; align-items: center; }
.col   { display: flex; flex-direction: column; }
.grow  { flex: 1 1 auto; min-width: 0; }
.fixed-w { flex: none; }

/* Las utilidades de alineación, después de `.row`.
 *
 * `.row` trae `align-items: center` y vive en este archivo, que se carga
 * DESPUÉS de `layout.css`. Con la misma especificidad gana el último, así que
 * `class="row items-start"` se quedaba centrado: la utilidad estaba escrita, se
 * leía en el marcado y no hacía nada.
 *
 * Pasaba en cinco sitios —la cabecera de la carta del QR, el ticket de cocina,
 * la tarjeta del despacho y la tira de favoritos del portal— y no se veía
 * porque «centrado» casi nunca se ve mal del todo: solo se ve raro. En la tira
 * de favoritos, las tarjetas de nombre corto quedaban diez píxeles más abajo
 * que las de nombre largo.
 *
 * Una utilidad que no gana no es una utilidad. */
.row.items-start    { align-items: flex-start; }
.row.items-end      { align-items: flex-end; }
.row.items-center   { align-items: center; }
.row.items-stretch  { align-items: stretch; }
.row.items-baseline { align-items: baseline; }
.clip  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clip-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.clip-3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.scroll-x { overflow-x: auto; scrollbar-width: none; }
.scroll-x::-webkit-scrollbar { display: none; }

/* --------------------------------------------------------------------------
   5. LA TARJETA — el objeto básico del sistema
   Todo el contenido vive en una tarjeta redonda sobre crema.
   -------------------------------------------------------------------------- */
.card {
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
}
.card--flat  { box-shadow: none; border: 1px solid var(--line-2); }
.card--raise { box-shadow: var(--sh-2); }
.card--big   { border-radius: var(--r-lg); }
.card--tap {
  cursor: pointer;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.card--tap:hover  { transform: translateY(-2px); box-shadow: var(--sh-2); }
.card--tap:active { transform: scale(.985); box-shadow: var(--sh-1); }

.card-head {
  display: flex; align-items: center; gap: .75rem;
  padding: 1rem 1.25rem .75rem;
}
.card-body { padding: 1.25rem; }
.card-foot {
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--line-2);
  display: flex; align-items: center; gap: .625rem;
}

/* --------------------------------------------------------------------------
   6. EL BOTÓN — pastilla. La firma del sistema.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 44px;
  padding: 0 1.25rem;
  border-radius: var(--r-pill);
  font-family: inherit;
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: -.01em;
  white-space: nowrap;
  cursor: pointer;
  color: var(--btn-fg, var(--ink));
  background: var(--btn-bg, var(--cream-2));
  border: 0;
  box-shadow: var(--btn-sh, none);
  transition: transform var(--fast) var(--pop), background-color var(--fast) var(--ease),
              box-shadow var(--fast) var(--ease), color var(--fast) var(--ease);
}
.btn:hover:not(:disabled)  { background: var(--btn-bg-h, var(--cream-3)); }
.btn:active:not(:disabled) { transform: scale(.955); }
.btn:disabled, .btn[disabled] { opacity: .4; cursor: not-allowed; }
.btn svg { width: 19px; height: 19px; flex: none; }

.btn--brasa  { --btn-bg: var(--brasa);   --btn-fg: var(--brasa-on);   --btn-bg-h: var(--brasa-deep);   --btn-sh: var(--sh-brasa); }
.btn--oro    { --btn-bg: var(--oro);     --btn-fg: var(--oro-on);     --btn-bg-h: var(--oro-lit);      --btn-sh: var(--sh-oro); }
.btn--verde  { --btn-bg: var(--verde);   --btn-fg: var(--verde-on);   --btn-bg-h: var(--verde-deep);   --btn-sh: var(--sh-verde); }
.btn--naranja{ --btn-bg: var(--naranja); --btn-fg: var(--naranja-on); --btn-bg-h: var(--naranja-deep); }
.btn--azul   { --btn-bg: var(--azul);    --btn-fg: var(--azul-on);    --btn-bg-h: var(--azul-deep); }
.btn--coal   { --btn-bg: var(--coal-800);--btn-fg: var(--coal-ink);   --btn-bg-h: var(--coal-700); }
.btn--line   { --btn-bg: transparent;    --btn-fg: var(--ink);        --btn-bg-h: var(--cream-2); box-shadow: inset 0 0 0 2px var(--cream-3); }
.btn--ghost  { --btn-bg: transparent;    --btn-fg: var(--ink-2);      --btn-bg-h: var(--cream-2); }
.btn--white  { --btn-bg: var(--paper);   --btn-fg: var(--ink);        --btn-bg-h: var(--cream); --btn-sh: var(--sh-1); }

.btn--xs { min-height: 32px; padding: 0 .75rem; font-size: .8125rem; gap: .3125rem; }
.btn--xs svg { width: 15px; height: 15px; }
.btn--sm { min-height: 38px; padding: 0 1rem; font-size: .875rem; }
.btn--sm svg { width: 17px; height: 17px; }
.btn--lg { min-height: var(--tap-lg); padding: 0 1.75rem; font-size: 1rem; }
.btn--lg svg { width: 21px; height: 21px; }
.btn--xl { min-height: 60px; padding: 0 2rem; font-size: 1.0625rem; }
.btn--block { display: flex; width: 100%; }
.btn--round { padding: 0; width: 44px; }
.btn--round.btn--xs { width: 32px; }
.btn--round.btn--sm { width: 38px; }
.btn--round.btn--lg { width: 52px; }
.btn--round.btn--xl { width: 60px; }

/* El botón que suma: círculo brasa, la interacción más repetida del sistema. */
.btn-add {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--brasa); color: #fff;
  box-shadow: var(--sh-brasa);
  cursor: pointer;
  transition: transform var(--fast) var(--pop), background-color var(--fast) var(--ease);
}
.btn-add svg { width: 20px; height: 20px; }
.btn-add:hover  { background: var(--brasa-deep); }
.btn-add:active { transform: scale(.86); }
.btn-add--lg { width: 46px; height: 46px; }

/* --------------------------------------------------------------------------
   7. CAMPOS
   -------------------------------------------------------------------------- */
.field, .select, .textarea {
  width: 100%;
  min-height: var(--tap);
  padding: .6875rem 1rem;
  font-family: inherit;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--cream-3);
  border-radius: var(--r-sm);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.field::placeholder, .textarea::placeholder { color: var(--ink-3); font-weight: 500; }
.field:hover, .select:hover, .textarea:hover { border-color: var(--ink-3); }
.field:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--brasa);
  box-shadow: 0 0 0 4px var(--brasa-soft);
}
.field:disabled, .select:disabled, .textarea:disabled {
  background: var(--cream-2); color: var(--ink-3); cursor: not-allowed; border-color: var(--cream-2);
}
.field[aria-invalid="true"], .field--bad { border-color: var(--brasa); }
.textarea { min-height: 96px; resize: vertical; line-height: 1.55; }
.field--sm, .select--sm { min-height: 40px; padding: .4375rem .75rem; font-size: .875rem; border-radius: var(--r-xs); }
.field--lg { min-height: 56px; font-size: 1.0625rem; }
.field--num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 800; }

.select {
  appearance: none;
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' fill='none' stroke='%238b7a6d' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 7 9 11.5 13.5 7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .875rem center;
}
/* Las variantes pequeñas fijan el relleno en atajo y, al hacerlo, borran el
   hueco que el desplegable reserva para su flecha: el texto largo se le monta
   encima. Se devuelve con más especificidad, para que no dependa del orden de
   las hojas. */
.select.field--sm, .select.select--sm, .select.input-sm { padding-right: 2.5rem; }
/* Y si aun así no cabe, que se corte con puntos suspensivos antes de chocar. */
.select { text-overflow: ellipsis; }

.field-set { display: flex; flex-direction: column; gap: .4375rem; }
.field-lab { font-size: .8125rem; font-weight: 700; color: var(--ink-2); }
.field-hint { font-size: .8125rem; color: var(--ink-3); }
.field-bad  { font-size: .8125rem; color: var(--brasa-deep); font-weight: 600; }

/* El campo que trae algo mal.

   `app.js` y el punto de venta llevan tiempo poniendo esta clase —al dejar un
   campo obligatorio vacío, al escribir un RNC que no cuadra— y ninguna regla la
   definía: se marcaba el campo y el campo seguía igual. El texto de abajo
   avisaba solo, sin que nada señalara cuál de los campos era.

   Contorno y no solo color: quien no distingue el rojo tiene que poder ver
   igual cuál es el campo. */
.field--invalid,
.input.field--invalid,
.select.field--invalid {
  border-color: var(--brasa);
  box-shadow: 0 0 0 3px var(--brasa-soft);
}
.field--invalid:focus,
.input.field--invalid:focus {
  border-color: var(--brasa-deep);
  box-shadow: 0 0 0 3px var(--brasa-soft);
}

/* Campo con marca al inicio */
.field-slot { position: relative; display: flex; align-items: center; }
.field-slot > svg {
  position: absolute; left: 1rem; width: 19px; height: 19px;
  color: var(--ink-3); pointer-events: none; z-index: 1;
}
.field-slot .field { padding-left: 2.875rem; }
.field-tail {
  position: absolute; right: .5rem;
  width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: var(--r-pill); color: var(--ink-3);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.field-tail:hover { background: var(--cream-2); color: var(--ink); }

/* Casilla, radio e interruptor */
.check, .radio {
  appearance: none;
  width: 22px; height: 22px; flex: none;
  border: 2px solid var(--cream-3);
  background: var(--paper);
  cursor: pointer; position: relative;
  transition: background-color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.check { border-radius: var(--r-xs); }
.radio { border-radius: 50%; }
.check:checked, .radio:checked { background: var(--brasa); border-color: var(--brasa); }
.check:checked::after {
  content: ""; position: absolute; left: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid #fff; border-width: 0 2.5px 2.5px 0;
  border-radius: 1px; transform: rotate(43deg);
}
.radio:checked::after { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: #fff; }

.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-rail {
  width: 50px; height: 30px; flex: none;
  border-radius: var(--r-pill);
  background: var(--cream-3);
  position: relative;
  transition: background-color var(--med) var(--ease);
}
.switch-rail::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px; border-radius: 50%;
  background: #fff; box-shadow: var(--sh-1);
  transition: transform var(--med) var(--pop);
}
.switch input:checked + .switch-rail { background: var(--verde); }
.switch input:checked + .switch-rail::after { transform: translateX(20px); }
.switch input:focus-visible + .switch-rail { outline: 3px solid var(--azul); outline-offset: 2px; }

/* --------------------------------------------------------------------------
   8. MARCAS DE ESTADO — pastillas rellenas, nunca filetes de borde
   -------------------------------------------------------------------------- */
.tag {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .25rem .625rem;
  border-radius: var(--r-pill);
  font-size: .75rem; font-weight: 700; letter-spacing: -.005em;
  white-space: nowrap;
  background: var(--grafito-soft); color: var(--grafito-deep);
}
.tag svg { width: 14px; height: 14px; flex: none; }
.tag--brasa   { background: var(--brasa-soft);   color: var(--brasa-deep); }
.tag--oro     { background: var(--oro-soft);     color: var(--oro-deep); }
.tag--verde   { background: var(--verde-soft);   color: var(--verde-deep); }
.tag--naranja { background: var(--naranja-soft); color: var(--naranja-deep); }
.tag--azul    { background: var(--azul-soft);    color: var(--azul-deep); }
.tag--uva     { background: var(--uva-soft);     color: var(--uva-deep); }

.tag--solid            { background: var(--grafito); color: #fff; }
.tag--solid.tag--brasa  { background: var(--brasa);   color: var(--brasa-on); }
.tag--solid.tag--oro    { background: var(--oro);     color: var(--oro-on); }
.tag--solid.tag--verde  { background: var(--verde);   color: var(--verde-on); }
.tag--solid.tag--naranja{ background: var(--naranja); color: var(--naranja-on); }
.tag--solid.tag--azul   { background: var(--azul);    color: var(--azul-on); }
.tag--solid.tag--uva    { background: var(--uva);     color: var(--uva-on); }
.tag--lg { padding: .375rem .875rem; font-size: .8125rem; }

/* Punto de aviso sobre un icono */
.dot {
  position: absolute; top: 6px; right: 6px;
  min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--brasa); color: #fff;
  font-size: .625rem; font-weight: 800; line-height: 1;
  box-shadow: 0 0 0 2px var(--paper);
}

/* --------------------------------------------------------------------------
   9. PASTILLA DE FILTRO — la fila de categorías
   -------------------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 42px;
  padding: 0 1rem;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--cream-3);
  font-family: inherit; font-size: .875rem; font-weight: 700;
  color: var(--ink-2);
  white-space: nowrap; cursor: pointer;
  transition: transform var(--fast) var(--pop), background-color var(--fast) var(--ease),
              color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.chip:hover  { box-shadow: inset 0 0 0 2px var(--ink-3); color: var(--ink); }
.chip:active { transform: scale(.95); }
.chip.is-on, .chip[aria-pressed="true"] {
  background: var(--coal-900); color: #fff; box-shadow: none;
}
.chip svg { width: 18px; height: 18px; flex: none; }
.chip-mark {
  width: 30px; height: 30px; flex: none; margin-left: -.4375rem;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--cream-2); color: var(--ink-2);
}
.chip.is-on .chip-mark { background: rgba(255, 255, 255, .16); color: #fff; }
.chip-count {
  min-width: 22px; padding: 0 .375rem;
  border-radius: var(--r-pill);
  background: var(--cream-2); color: var(--ink-2);
  font-size: .75rem; font-weight: 800; text-align: center; line-height: 20px;
  font-variant-numeric: tabular-nums;
}
.chip.is-on .chip-count { background: rgba(255, 255, 255, .18); color: #fff; }

/* --------------------------------------------------------------------------
   10. PESTAÑAS
   -------------------------------------------------------------------------- */
.tabs {
  display: inline-flex; gap: .25rem; padding: .3125rem;
  background: var(--cream-2); border-radius: var(--r-pill);
}
.tab {
  min-height: 38px; padding: 0 1rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .4375rem;
  border-radius: var(--r-pill);
  font-family: inherit; font-size: .875rem; font-weight: 700;
  color: var(--ink-2); white-space: nowrap; cursor: pointer;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.tab svg { width: 17px; height: 17px; }
.tab:hover { color: var(--ink); }
.tab.is-on, .tab[aria-selected="true"] {
  background: var(--paper); color: var(--ink); box-shadow: var(--sh-1);
}


/* --------------------------------------------------------------------------
   11. TABLAS
   -------------------------------------------------------------------------- */
.grid-table { width: 100%; font-size: .875rem; }
.grid-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--cream-2);
  padding: .75rem 1rem;
  text-align: left; white-space: nowrap;
  font-size: .6875rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3);
}
.grid-table thead th:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.grid-table thead th:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.grid-table tbody td {
  padding: .875rem 1rem;
  border-bottom: 1px solid var(--line-2);
  color: var(--ink-2);
  vertical-align: middle;
}
.grid-table tbody tr:last-child td { border-bottom: 0; }
.grid-table tbody tr { transition: background-color var(--fast) var(--ease); }
.grid-table tbody tr:hover { background: var(--cream); }
.grid-table .strong { color: var(--ink); font-weight: 700; }
.grid-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.grid-table--tight tbody td { padding: .5625rem .75rem; }
.table-scroll { overflow-x: auto; }

/* --------------------------------------------------------------------------
   12. INSTRUMENTOS — la lectura de una cifra
   -------------------------------------------------------------------------- */
.stat {
  background: var(--paper);
  border-radius: var(--r-md);
  padding: 1.125rem 1.25rem;
  box-shadow: var(--sh-1);
  display: flex; flex-direction: column; gap: .25rem;
  position: relative; overflow: hidden;
}
.stat-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem; }
.stat-val {
  font-size: 1.875rem; font-weight: 900; letter-spacing: -.035em; line-height: 1.05;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.stat-delta { display: inline-flex; align-items: center; gap: .3125rem; font-size: .8125rem; font-weight: 700; }
.stat-delta svg { width: 15px; height: 15px; }
.stat-delta.up   { color: var(--verde-deep); }
.stat-delta.down { color: var(--brasa-deep); }
.stat-mark {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--cream-2); color: var(--ink-2);
}
.stat-mark svg { width: 21px; height: 21px; }
.stat-mark--brasa   { background: var(--brasa-soft);   color: var(--brasa-deep); }
.stat-mark--oro     { background: var(--oro-soft);     color: var(--oro-deep); }
.stat-mark--verde   { background: var(--verde-soft);   color: var(--verde-deep); }
.stat-mark--naranja { background: var(--naranja-soft); color: var(--naranja-deep); }
.stat-mark--azul    { background: var(--azul-soft);    color: var(--azul-deep); }
.stat-mark--uva     { background: var(--uva-soft);     color: var(--uva-deep); }

/* Barra de nivel */
.meter { height: 8px; background: var(--cream-2); border-radius: var(--r-pill); overflow: hidden; }
.meter > i {
  display: block; height: 100%; width: 100%;
  background: var(--verde); border-radius: var(--r-pill);
  transform-origin: left center; transform: scaleX(var(--level, 0));
  transition: transform var(--slow) var(--ease);
}
.meter--brasa > i   { background: var(--brasa); }
.meter--oro > i     { background: var(--oro); }
.meter--naranja > i { background: var(--naranja); }
.meter--azul > i    { background: var(--azul); }
.meter--uva > i     { background: var(--uva); }
.meter--grafito > i { background: var(--grafito); }

/* --------------------------------------------------------------------------
   13. RETRATO
   -------------------------------------------------------------------------- */
.face {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--coal-800); color: #fff;
  font-size: .8125rem; font-weight: 800;
  overflow: hidden; letter-spacing: -.01em;
}
.face img { width: 100%; height: 100%; object-fit: cover; }
.face--sm { width: 32px; height: 32px; font-size: .6875rem; }
.face--lg { width: 56px; height: 56px; font-size: 1.0625rem; }
.face--brasa { background: var(--brasa); }
.face--oro   { background: var(--oro); color: var(--oro-on); }

/* --------------------------------------------------------------------------
   14. CONTADOR DE CANTIDAD
   -------------------------------------------------------------------------- */
.counter {
  display: inline-flex; align-items: center;
  background: var(--cream-2);
  border-radius: var(--r-pill);
  padding: .25rem;
}
.counter button {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--paper); color: var(--ink);
  box-shadow: var(--sh-1);
  transition: transform var(--fast) var(--pop), background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.counter button svg { width: 17px; height: 17px; }
.counter button:hover:not(:disabled) { background: var(--brasa); color: #fff; }
.counter button:active:not(:disabled) { transform: scale(.88); }
.counter button:disabled { opacity: .35; cursor: not-allowed; box-shadow: none; }
.counter-val {
  min-width: 40px; padding: 0 .375rem; text-align: center;
  font-size: .9375rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.counter--lg button { width: 42px; height: 42px; }
.counter--lg .counter-val { min-width: 48px; font-size: 1.0625rem; }

/* --------------------------------------------------------------------------
   15. OPCIÓN ESCOGIBLE — modificadores, repartidores, métodos de pago
   -------------------------------------------------------------------------- */
.pick {
  display: flex; align-items: center; gap: .875rem;
  width: 100%; min-height: 60px;
  padding: .75rem 1rem;
  background: var(--paper);
  border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 2px var(--cream-3);
  cursor: pointer; text-align: left;
  transition: box-shadow var(--fast) var(--ease), background-color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.pick:hover  { box-shadow: inset 0 0 0 2px var(--ink-3); }
.pick:active { transform: scale(.99); }
.pick.is-on, .pick[aria-pressed="true"] {
  background: var(--brasa-soft);
  box-shadow: inset 0 0 0 2.5px var(--brasa);
}
.pick[disabled] { opacity: .45; cursor: not-allowed; }
.pick-mark {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-sm);
  background: var(--cream-2); color: var(--ink-2);
}
.pick.is-on .pick-mark { background: var(--brasa); color: #fff; }

/* --------------------------------------------------------------------------
   16. CAPAS FLOTANTES
   -------------------------------------------------------------------------- */
.veil {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: rgba(26, 21, 18, .5);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--med) var(--ease);
}
.veil.is-open { opacity: 1; pointer-events: auto; }
.panel {
  width: 100%; max-width: 34rem; max-height: calc(100vh - 2rem);
  display: flex; flex-direction: column;
  background: var(--paper);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-4);
  transform: translateY(16px) scale(.97); opacity: 0;
  transition: transform var(--med) var(--ease), opacity var(--fast) var(--ease);
}
.veil.is-open .panel { transform: none; opacity: 1; }
.panel--sm { max-width: 26rem; }
.panel--lg { max-width: 48rem; }
.panel--xl { max-width: 68rem; }
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.25rem 1.5rem 1rem; flex: none;
}
/* `overscroll-behavior: contain` corta el arrastre. Sin él, al llegar al
   final de una lista dentro de un cuadro el dedo sigue empujando y lo que se
   mueve es la página de detrás: se cierra el cuadro y uno ya no sabe dónde
   estaba. En un ratón no se nota; en un teléfono pasa todo el rato. */
.panel-body { padding: 0 1.5rem 1.5rem; overflow-y: auto; overscroll-behavior: contain; flex: 1; }
.panel-foot {
  display: flex; align-items: center; gap: .625rem; justify-content: flex-end;
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--line-2);
  background: var(--cream);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  flex: none;
}

/* Bandeja inferior — la capa del teléfono */
.tray {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(26, 21, 18, .5);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--med) var(--ease);
}
.tray.is-open { opacity: 1; pointer-events: auto; }
.tray-panel {
  width: 100%; max-width: 34rem; max-height: 92vh;
  display: flex; flex-direction: column;
  background: var(--paper);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--sh-4);
  transform: translateY(100%);
  transition: transform var(--med) var(--ease);
}
.tray.is-open .tray-panel { transform: none; }
.tray-grip {
  width: 44px; height: 5px; flex: none;
  border-radius: var(--r-pill);
  background: var(--cream-3);
  margin: .75rem auto .25rem;
}
@media (min-width: 640px) {
  .tray { align-items: center; padding: 1rem; }
  .tray-panel { border-radius: var(--r-lg); transform: translateY(16px) scale(.97); }
  .tray.is-open .tray-panel { transform: none; }
}

/* Cajón lateral */
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 91;
  width: min(28rem, 100%);
  display: flex; flex-direction: column;
  background: var(--paper);
  box-shadow: var(--sh-4);
  transform: translateX(100%);
  transition: transform var(--med) var(--ease);
}
.drawer.is-open { transform: none; }

/* Menú emergente */
.pop {
  position: absolute; z-index: 80;
  min-width: 12rem; padding: .4375rem;
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);
  animation: pop-in var(--fast) var(--ease);
}
@keyframes pop-in { from { opacity: 0; transform: translateY(-6px) scale(.97); } to { opacity: 1; transform: none; } }
.pop a, .pop button {
  display: flex; align-items: center; gap: .625rem; width: 100%;
  padding: .625rem .75rem;
  border-radius: var(--r-xs);
  font-size: .875rem; font-weight: 600; color: var(--ink-2);
  text-align: left; cursor: pointer;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.pop a:hover, .pop button:hover { background: var(--cream-2); color: var(--ink); }
.pop a svg, .pop button svg { width: 18px; height: 18px; flex: none; }
.pop hr { margin: .3125rem .25rem; }

/* --------------------------------------------------------------------------
   17. AVISOS
   -------------------------------------------------------------------------- */
#notices {
  /* Por debajo de la barra: arriba del todo, un aviso se plantaba encima de la
     cuenta y de la campana, y durante sus cuatro segundos no se podían pulsar. */
  position: fixed; top: calc(var(--bar-h) + .75rem); right: 1rem; z-index: 100;
  display: flex; flex-direction: column; gap: .625rem;
  pointer-events: none;
  max-width: min(24rem, calc(100vw - 2rem));
}
.notice {
  display: flex; align-items: flex-start; gap: .75rem;
  padding: .875rem 1rem;
  border-radius: var(--r-md);
  background: var(--coal-900); color: var(--coal-ink);
  box-shadow: var(--sh-3);
  font-size: .875rem; font-weight: 500;
  pointer-events: auto;
  animation: notice-in var(--med) var(--ease);
}
@keyframes notice-in { from { opacity: 0; transform: translateX(24px) scale(.95); } to { opacity: 1; transform: none; } }
.notice.is-leaving { animation: notice-out var(--fast) var(--ease) forwards; }
@keyframes notice-out { to { opacity: 0; transform: translateX(24px) scale(.95); } }
.notice svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }
.notice-title { font-weight: 800; color: #fff; }
.notice--ok   svg { color: var(--verde-lit); }
.notice--no   svg { color: var(--brasa-lit); }
.notice--warn svg { color: var(--oro-lit); }
.notice--info svg { color: var(--azul-lit); }

/* Aviso en línea, pegado al dato que corrige */
.hint-line {
  display: flex; align-items: flex-start; gap: .5rem;
  padding: .5rem .75rem;
  border-radius: var(--r-xs);
  background: var(--oro-soft); color: var(--oro-deep);
  font-size: .8125rem; font-weight: 600; line-height: 1.4;
}
.hint-line svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.hint-line--brasa { background: var(--brasa-soft); color: var(--brasa-deep); }
.hint-line--verde { background: var(--verde-soft); color: var(--verde-deep); }
.hint-line--azul  { background: var(--azul-soft);  color: var(--azul-deep); }

/* --------------------------------------------------------------------------
   18. VACÍO Y ESPERA
   -------------------------------------------------------------------------- */
.blank {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .625rem; padding: 3rem 1.5rem; text-align: center;
}
.blank-mark {
  width: 72px; height: 72px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--cream-2); color: var(--ink-3);
  margin-bottom: .25rem;
}
.blank-mark svg { width: 32px; height: 32px; }
.blank-title { font-size: 1.0625rem; font-weight: 800; color: var(--ink); }
.blank-note  { font-size: .875rem; color: var(--ink-3); max-width: 34ch; }

.wait {
  background: linear-gradient(90deg, var(--cream-2) 25%, var(--cream-3) 37%, var(--cream-2) 63%);
  background-size: 300% 100%;
  border-radius: var(--r-sm);
  animation: wait-pan 1.4s ease-in-out infinite;
}
@keyframes wait-pan { from { background-position: 100% 0; } to { background-position: 0 0; } }

.spin {
  width: 18px; height: 18px; flex: none;
  border: 2.5px solid currentColor; border-top-color: transparent;
  border-radius: 50%;
  animation: spin 640ms linear infinite;
  opacity: .85;
}
@keyframes spin { to { transform: rotate(360deg); } }


/* --------------------------------------------------------------------------
   EL PLANO DEL SALÓN

   Una cuadrícula ordena las mesas por nombre; un plano las pone donde están.
   No es lo mismo: el mesero que mira la pantalla ya sabe dónde queda la mesa 7
   en el local, y buscarla entre veinticuatro nombres alfabéticos es traducir
   dos veces. Las posiciones viven en la base desde el primer día -pos_x y
   pos_y- y nadie las escribia.

   Se guardan en diezmilésimas del ancho, no en píxeles: el salón se ve igual
   en el monitor del encargado y en la tableta del mesero.
   -------------------------------------------------------------------------- */
.plano {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 320px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-2);
  background: var(--paper);
  /* Una retícula tenue: da referencia para alinear sin competir con las mesas. */
  background-image: radial-gradient(circle, var(--cream-3) 1.2px, transparent 1.2px);
  background-size: 32px 32px;
  overflow: hidden;
  /* Sin esto, arrastrar una mesa con el dedo desplaza la página. */
  touch-action: none;
}

.plano .table-card {
  position: absolute;
  --ancho: clamp(78px, 21%, 118px);
  /* La tarjeta es cuadrada: el alto sale del ancho y no de un número puesto a
     ojo. Con 92px inventados, quince mesas asomaban por el borde del plano. */
  --alto: var(--ancho);
  /* Las pone el marcado, una por mesa. Se declaran aquí para que la hoja se
     sostenga sola: sin esto, una mesa sin posición no tendría dónde caerse. */
  --px: 50%;
  --py: 50%;
  width: var(--ancho);
  min-height: 0;
  margin: 0;
  /* La posición llega en `--px` y `--py`, y aquí se ata: una mesa no puede
     salirse de su plano por muy adentro que esté guardada. El mismo salón se
     mira en un monitor de 27 pulgadas y en un teléfono de 320 px, y lo que en
     el monitor queda holgado, en el teléfono se sale por el borde —la tarjeta
     ocupa proporcionalmente el triple—. Atarlo aquí, con el tamaño real de la
     tarjeta, vale para los dos sin guardar dos planos. */
  left: clamp(calc(var(--ancho) / 2 + 4px), var(--px, 50%), calc(100% - var(--ancho) / 2 - 4px));
  top:  clamp(calc(var(--alto) / 2 + 4px),  var(--py, 50%), calc(100% - var(--alto) / 2 - 4px));
  transform: translate(-50%, -50%);
  transition: box-shadow var(--fast) var(--ease), transform var(--fast) var(--ease);
}

/* Mientras se acomoda el salón. */
.plano--editable .table-card { cursor: grab; }
.plano--editable .table-card:active { cursor: grabbing; }
.plano .table-card.se-arrastra {
  z-index: 5;
  cursor: grabbing;
  transform: translate(-50%, -50%) scale(1.06);
  box-shadow: var(--sh-3);
}

/* La mesa que aún no se ha colocado nunca. Se avisa en vez de dejarla caer en
   una esquina sin decir nada. */
.plano .table-card.sin-sitio { outline: 2px dashed var(--oro); outline-offset: 2px; }

.plano-aviso {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  text-align: center; color: var(--ink-3); font-size: .8125rem; font-weight: 600;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   SELECCIÓN DE VARIAS MESAS
   -------------------------------------------------------------------------- */
.table-card { position: relative; }

.tick {
  position: absolute; top: .375rem; left: .375rem;
  width: 22px; height: 22px; flex: none;
  display: none; place-items: center;
  border-radius: 999px;
  border: 2px solid var(--line);
  background: var(--paper);
  color: transparent;
}
.eligiendo .tick { display: grid; }
.eligiendo .table-card.elegida { outline: 3px solid var(--brasa); outline-offset: 2px; }
.table-card.elegida .tick { background: var(--brasa); border-color: var(--brasa); color: #fff; }
.tick svg { width: 14px; height: 14px; }

/* La barra de lo seleccionado: se queda a la vista mientras haya algo elegido,
   porque la selección se hace recorriendo y el botón no puede quedar arriba. */
.barra-lote {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin-top: 1rem; padding: .75rem 1rem;
  border-radius: var(--r-md);
  background: var(--coal-900); color: #fff;
  box-shadow: var(--sh-3);
}
.barra-lote .cuantas { font-weight: 800; margin-right: .25rem; }
.barra-lote .btn { border-color: var(--coal-600); color: #fff; }
.barra-lote .btn:hover { background: var(--coal-700); }

/* --------------------------------------------------------------------------
   LOS ESTADOS QUE SE PONEN A MANO
   -------------------------------------------------------------------------- */
.estados { display: flex; flex-wrap: wrap; gap: .5rem; }
.estados .btn.is-on { background: var(--coal-900); border-color: var(--coal-900); color: #fff; }

/* --------------------------------------------------------------------------
   19. HERRAMIENTA EMERGENTE
   -------------------------------------------------------------------------- */
/* Una sola etiqueta colgada del documento: no la recorta ningún ancestro con
   overflow, se coloca arriba o abajo según quepa, y no exige clase alguna en
   el elemento —basta el atributo `data-tip`—. */
.tip-pop {
  position: fixed; top: 0; left: 0; z-index: 200;
  max-width: 18rem;
  padding: .375rem .625rem;
  border-radius: var(--r-xs);
  background: var(--coal-900); color: #fff;
  font-size: .75rem; font-weight: 600; line-height: 1.35;
  box-shadow: var(--sh-2);
  opacity: 0; pointer-events: none;
  transition: opacity var(--fast) var(--ease);
}
.tip-pop.is-on { opacity: 1; }

/* --------------------------------------------------------------------------
   20. MOVIMIENTO COMPARTIDO
   -------------------------------------------------------------------------- */
.fade-in  { animation: fade-in var(--med) var(--ease); }
.rise     { animation: rise var(--med) var(--ease); }
.stagger > * { animation: rise 320ms var(--ease) backwards; }
.stagger > *:nth-child(2) { animation-delay: 40ms }
.stagger > *:nth-child(3) { animation-delay: 80ms }
.stagger > *:nth-child(4) { animation-delay: 120ms }
.stagger > *:nth-child(5) { animation-delay: 160ms }
.stagger > *:nth-child(6) { animation-delay: 200ms }
.stagger > *:nth-child(7) { animation-delay: 240ms }
.stagger > *:nth-child(8) { animation-delay: 280ms }
@keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }
@keyframes rise { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

.no-print { }
/* --------------------------------------------------------------------------
   EL PAPEL DE LA PANTALLA

   Los cinco documentos formales salen en PDF, pero alguien va a pulsar Ctrl+P
   sobre una lista de productos y el resultado también es la cara del negocio.
   El riel se oculta con `.no-print`, pero el cuerpo conservaba su margen de
   252 px y dejaba una banda vacía en cada hoja; la barra pegajosa se repetía;
   y las tarjetas se partían entre dos páginas por la mitad.
   -------------------------------------------------------------------------- */
@media print {
  .no-print { display: none !important; }
  body { background: #fff; }

  .shell { display: block; min-height: 0; }
  .body  { margin-left: 0 !important; }
  .bar   { position: static !important; background: transparent; padding-left: 0; padding-right: 0; }
  .deck  { padding: 0 !important; }

  /* Lo que solo existe para tocarse no tiene sentido en papel. */
  #notices, .cart-fab, .tray, .veil, .modal-backdrop, .pop, .menu-pop { display: none !important; }

  /* Una tarjeta partida entre dos hojas es ilegible; y la sombra, sobre papel,
     es una mancha gris. */
  .card, .stat, .order-card, .qr-card, .dish {
    box-shadow: none !important;
    border: 1px solid #ddd;
    break-inside: avoid; page-break-inside: avoid;
  }
  .grid-table thead { display: table-header-group; }
  tr, li { break-inside: avoid; page-break-inside: avoid; }
}

/* ==========================================================================
   21. EL CHASIS — un solo esqueleto para todas las pantallas de trabajo
   ========================================================================== */
.shell { display: flex; min-height: 100vh; min-height: 100dvh; background: var(--cream); }

/* El chasis clavado a la ventana, para las pantallas de trabajo.

   `dvh` y no `vh`: en un teléfono `100vh` mide la ventana con la barra del
   navegador escondida, o sea más de lo que se ve, y el último renglón queda
   siempre por debajo de esa barra. `dvh` mide lo que de verdad hay. Se deja
   `vh` delante como respaldo para navegadores viejos.

   Y en el teléfono no se clava: ahí el chasis se apila en columna y no cabe,
   así que se deja crecer y que la página se desplace. */
.shell--pantalla { height: 100vh; height: 100dvh; }
@media (max-width: 767px) {
  .shell--pantalla { height: auto; min-height: 100vh; min-height: 100dvh; }
}

/* --- EL RIEL: navegación persistente, carbón tibio ------------------------ */
.rail {
  width: var(--rail-w); flex: none;
  background: var(--coal-900);
  color: var(--coal-ink);
  display: flex; flex-direction: column;
  position: fixed; inset: 0 auto 0 0; z-index: 60;
  transition: transform var(--med) var(--ease);
}
.rail-brand {
  height: var(--bar-h); flex: none;
  display: flex; align-items: center; gap: .75rem;
  padding: 0 1.125rem;
}
/* El sello cuadrado. Trae su propio color y su propio contorno, así que la
   caja solo pone el tamaño y la sombra. */
.logo-marca {
  width: 40px; height: 40px; flex: none;
  border-radius: var(--r-sm);
  box-shadow: var(--sh-brasa);
}
/* El rótulo completo. Se mide por el alto, que es lo que manda en una barra;
   el ancho lo pone la proporción del original. */
.logo-ancho {
  display: block; width: auto; height: 44px; flex: none;
}
.logo-ancho--xl { height: clamp(76px, 12vw, 118px); }
.logo-ancho--lg { height: clamp(62px, 9vw, 86px); }
.rail-nav { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: .5rem .75rem 2rem; scrollbar-width: thin; scrollbar-color: var(--coal-600) transparent; }
.rail-nav::-webkit-scrollbar { width: 6px; }
.rail-nav::-webkit-scrollbar-thumb { background: var(--coal-600); border-radius: var(--r-pill); }

.rail-group {
  padding: 1.125rem .625rem .4375rem;
  font-size: .6875rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--coal-ink-2);
}
.rail-link {
  display: flex; align-items: center; gap: .75rem;
  min-height: 44px; padding: 0 .75rem;
  border-radius: var(--r-sm);
  font-size: .9375rem; font-weight: 600;
  color: var(--coal-ink-2);
  position: relative;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.rail-link svg { width: 21px; height: 21px; flex: none; }
.rail-link:hover { background: var(--coal-700); color: var(--coal-ink); }
.rail-link[aria-current="page"] {
  background: var(--brasa); color: #fff; font-weight: 700;
  box-shadow: var(--sh-brasa);
}
.rail-count {
  margin-left: auto;
  min-width: 22px; padding: 0 .375rem;
  border-radius: var(--r-pill);
  background: var(--brasa); color: #fff;
  font-size: .6875rem; font-weight: 800; text-align: center; line-height: 20px;
  font-variant-numeric: tabular-nums;
}
/* La fila activa del riel ya es roja: un velo blanco encima deja el número
   casi del mismo tono que su fondo. Se invierte —chapa blanca, tinta roja—
   que además la despega de la fila. */
.rail-link[aria-current="page"] .rail-count { background: #fff; color: var(--brasa-deep); }

/* --- El cuerpo ----------------------------------------------------------- */
.body { flex: 1; min-width: 0; margin-left: var(--rail-w); display: flex; flex-direction: column; }

/* --- LA BARRA: identidad de la pantalla y acciones ------------------------ */
.bar {
  min-height: var(--bar-h); flex: none;
  display: flex; align-items: center; gap: 1rem;
  padding: .625rem 1.5rem;
  background: var(--cream);
  position: sticky; top: 0; z-index: 50;
}
.bar::after {
  content: ""; position: absolute; left: 1.5rem; right: 1.5rem; bottom: 0;
  height: 1px; background: var(--line-2);
}
.bar-title { font-size: 1.375rem; font-weight: 800; letter-spacing: -.028em; line-height: 1.15; }
.bar-sub   { font-size: .8125rem; font-weight: 500; color: var(--ink-3); line-height: 1.3; }
.bar-acts  { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

.deck { flex: 1; padding: 1.5rem; }
.deck--wide { max-width: none; }
.deck--held { max-width: 84rem; margin: 0 auto; width: 100%; }

/* --- Riel plegado -------------------------------------------------------- */
.shell--folded .rail { width: var(--rail-w-min); }
.shell--folded .body { margin-left: var(--rail-w-min); }
.shell--folded .rail-label,
.shell--folded .rail-group,
.shell--folded .rail-brand-text,
.shell--folded .rail-count { display: none; }
.shell--folded .rail-link { justify-content: center; padding: 0; }
.shell--folded .rail-brand { justify-content: center; padding: 0; }
.shell--folded .rail-link::after {
  content: attr(data-label);
  position: absolute; left: calc(100% + 10px); top: 50%; transform: translateY(-50%);
  padding: .375rem .625rem; border-radius: var(--r-xs);
  background: var(--coal-900); color: #fff;
  font-size: .8125rem; font-weight: 600; white-space: nowrap;
  opacity: 0; pointer-events: none; z-index: 70;
  box-shadow: var(--sh-2);
  transition: opacity var(--fast) var(--ease);
}
.shell--folded .rail-link:hover::after { opacity: 1; }

@media (max-width: 1023px) {
  .rail { transform: translateX(-100%); box-shadow: var(--sh-4); }
  .shell--open .rail { transform: none; }
  .body { margin-left: 0 !important; }
  .deck { padding: 1rem; }
  .bar { padding: .625rem 1rem; }
  .bar::after { left: 1rem; right: 1rem; }
  .rail-veil {
    position: fixed; inset: 0; z-index: 55;
    background: rgba(26, 21, 18, .5);
    backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none;
    transition: opacity var(--med) var(--ease);
  }
  .shell--open .rail-veil { opacity: 1; pointer-events: auto; }
}

/* ==========================================================================
   22. EL MOSTRADOR — punto de venta
   Pantalla táctil, de pie, con las manos ocupadas. Todo grande.
   ========================================================================== */
.pos-body { flex: 1; display: flex; min-height: 0; gap: 1rem; padding: 1rem; }
.pos-menu { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1rem; }
.pos-order { width: 25rem; flex: none; display: flex; }

@media (max-width: 1439px) { .pos-order { width: 22rem; } }
@media (max-width: 1023px) {
  .pos-body { flex-direction: column; padding: .75rem; }
  .pos-order { width: 100%; height: 46vh; }
  .pos-menu { min-height: 44vh; }
}

/* --- La rejilla de producto --------------------------------------------- */
.menu-grid {
  display: grid; gap: .875rem;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  align-content: start;
  grid-auto-rows: max-content;
}

/* --- LA FICHA DE PRODUCTO — el objeto que más se toca ------------------- */
.dish {
  display: flex; flex-direction: column;
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  overflow: hidden;
  cursor: pointer; text-align: left;
  position: relative;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.dish:hover  { transform: translateY(-3px); box-shadow: var(--sh-2); }
.dish:active { transform: scale(.975); box-shadow: var(--sh-1); }
.dish.is-out { opacity: .5; pointer-events: none; }

.dish-pic {
  aspect-ratio: 4 / 3; flex: none; position: relative; overflow: hidden;
  background: var(--cream-2);
  display: grid; place-items: center;
}
.dish-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dish-body { flex: 1 0 auto; padding: .75rem .875rem .875rem; display: flex; flex-direction: column; gap: .1875rem; }
.dish-cat  { font-size: .6875rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.dish-name {
  font-size: .9375rem; font-weight: 700; line-height: 1.25; color: var(--ink);
  letter-spacing: -.012em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.dish-foot { margin-top: auto; padding-top: .5rem; display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.dish-price { font-size: 1.0625rem; font-weight: 900; letter-spacing: -.03em; color: var(--ink); font-variant-numeric: tabular-nums; }

.dish-flags { position: absolute; top: .5rem; left: .5rem; display: flex; flex-direction: column; gap: .3125rem; align-items: flex-start; z-index: 1; }
/* Sin fotografía no hay sobre qué flotar: los distintivos entran en el flujo,
   arriba de la tarjeta. */
.dish-flags--plain {
  position: static; flex-direction: row; flex-wrap: wrap;
  padding: .875rem 1rem 0;
}
.flag {
  padding: .1875rem .5rem;
  border-radius: var(--r-pill);
  font-size: .6875rem; font-weight: 900; letter-spacing: .04em; text-transform: uppercase;
  background: var(--coal-900); color: #fff;
  box-shadow: var(--sh-1);
}
.flag--oro     { background: var(--oro);     color: var(--oro-on); }
.flag--azul    { background: var(--azul);    color: var(--azul-on); }
.flag--uva     { background: var(--uva);     color: var(--uva-on); }
.flag--brasa   { background: var(--brasa);   color: var(--brasa-on); }
.flag--grafito { background: var(--grafito); color: #fff; }
/* Un distintivo que informa sin reclamar color: «A su gusto» dice que el plato
   se personaliza, no que esté en oferta. */
.flag--line    { background: var(--cream-2); color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--line); }

.dish-diet {
  position: absolute; top: .5rem; right: .5rem; z-index: 1;
  width: 18px; height: 18px;
  border-radius: var(--r-xs);
  background: var(--paper);
  display: grid; place-items: center;
  box-shadow: var(--sh-1);
}
.dish-diet::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: currentColor; }
.dish-diet.veg     { color: var(--verde); }
.dish-diet.non_veg { color: var(--brasa); }

/* --- El bloc de la orden ------------------------------------------------- */
.ticket {
  display: flex; flex-direction: column; min-height: 0; width: 100%;
  background: var(--paper);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
  overflow: hidden;
}
.ticket-head { padding: 1rem 1.125rem .875rem; flex: none; }
.ticket-lines { flex: 1; overflow-y: auto; overscroll-behavior: contain; min-height: 0; padding: .25rem .375rem; }

.line {
  display: flex; gap: .75rem; padding: .75rem;
  border-radius: var(--r-sm);
  position: relative;
  animation: rise 220ms var(--ease);
  transition: background-color var(--fast) var(--ease);
}
.line:hover { background: var(--cream); }
.line-pic {
  width: 46px; height: 46px; flex: none;
  border-radius: var(--r-xs);
  background: var(--cream-2);
  overflow: hidden; display: grid; place-items: center;
}
.line-pic img { width: 100%; height: 100%; object-fit: cover; }
.line-kill {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  color: var(--ink-3);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.line-kill:hover { background: var(--brasa-soft); color: var(--brasa-deep); }

/* El resumen: la zona de la cifra que decide */
.ticket-sum {
  flex: none; padding: 1rem 1.125rem 1.125rem;
  background: var(--cream);
  border-top: 1px solid var(--line-2);
}
.sum-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .25rem 0; font-size: .875rem; color: var(--ink-2);
}
.sum-row .num { font-weight: 700; color: var(--ink); }
.sum-row.total {
  margin-top: .5rem; padding-top: .75rem;
  border-top: 2px dashed var(--cream-3);
  font-size: 1rem; font-weight: 800; color: var(--ink);
}
.sum-row.total .num { font-size: 1.5rem; font-weight: 900; letter-spacing: -.035em; }

/* --- Tipo de orden: cuatro modos ---------------------------------------- */
.mode-row { display: flex; gap: .375rem; padding: .3125rem; background: var(--cream-2); border-radius: var(--r-pill); }
.mode {
  flex: 1; min-height: 46px; padding: .25rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .0625rem;
  border-radius: var(--r-pill); cursor: pointer;
  font-family: inherit; font-size: .6875rem; font-weight: 700; color: var(--ink-2);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), box-shadow var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.mode svg { width: 19px; height: 19px; }
.mode:hover  { color: var(--ink); }
.mode:active { transform: scale(.94); }
.mode.is-on  { background: var(--brasa); color: #fff; box-shadow: var(--sh-brasa); }

/* --- Acciones secundarias ------------------------------------------------ */
.mini {
  display: flex; align-items: center; justify-content: center; gap: .375rem;
  min-height: 42px; padding: 0 .5rem;
  border-radius: var(--r-sm); cursor: pointer;
  background: var(--cream-2);
  font-family: inherit; font-size: .75rem; font-weight: 700; color: var(--ink-2);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.mini svg { width: 16px; height: 16px; flex: none; }
.mini:hover:not(:disabled)  { background: var(--cream-3); color: var(--ink); }
.mini:active:not(:disabled) { transform: scale(.95); }
.mini:disabled { opacity: .38; cursor: not-allowed; }
.mini--danger:hover:not(:disabled) { background: var(--brasa-soft); color: var(--brasa-deep); }

/* --- Pedidos recientes --------------------------------------------------- */
.recent {
  min-width: 11rem; flex: none; position: relative; overflow: hidden;
  padding: .75rem .875rem; cursor: pointer; text-align: left;
  background: var(--paper); border-radius: var(--r-sm);
  box-shadow: var(--sh-1);
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.recent:hover { transform: translateY(-2px); box-shadow: var(--sh-2); }
.recent-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; background: var(--grafito); transform-origin: left center; transform: scaleX(0); transition: transform var(--slow) var(--ease); }

/* ==========================================================================
   23. LA PARED — pantalla de cocina
   Se lee de pie, a tres metros, bajo campana.
   ========================================================================== */
.wall { height: 100vh; height: 100dvh; display: flex; flex-direction: column; background: var(--coal-900); }
@media (max-width: 767px) { .wall { height: auto; min-height: 100dvh; } }
.wall-bar {
  min-height: 72px; flex: none;
  display: flex; align-items: center; gap: 1rem;
  padding: 0 1.125rem;
  background: var(--coal-800);
}
/* El desplegable de estación traía su ancho y sus colores escritos en el
   marcado, y un ancho fijo en línea no se puede encoger: a 320 px empujaba la
   barra hasta 589. Ahora es una clase, y en pantalla estrecha ocupa su
   propia línea. */
.wall-station {
  width: 12rem;
  background: var(--coal-700);
  border-color: var(--coal-600);
  color: var(--coal-ink);
}
@media (max-width: 720px) {
  .wall-bar { flex-wrap: wrap; row-gap: .625rem; padding: .625rem 1rem; }
  .wall-bar > .ml-auto { margin-left: 0; width: 100%; }
  .wall-station { width: 100%; }
}
.wall-board { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 1rem; }
.wall-grid { display: grid; gap: 1rem; align-items: start; grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); }

.wall-tab {
  min-height: 46px; padding: 0 1.125rem;
  display: inline-flex; align-items: center; gap: .5rem;
  border-radius: var(--r-pill); cursor: pointer; white-space: nowrap;
  font-family: inherit; font-size: .9375rem; font-weight: 700;
  color: var(--coal-ink-2); background: transparent;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.wall-tab:hover  { background: var(--coal-700); color: var(--coal-ink); }
.wall-tab:active { transform: scale(.96); }
.wall-tab.is-on  { background: #fff; color: var(--coal-900); }
.wall-tab .n {
  min-width: 24px; padding: 0 .4375rem; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .16); font-size: .8125rem; font-weight: 800;
  text-align: center; line-height: 22px; font-variant-numeric: tabular-nums;
}
/* La pestaña activa es una chapa blanca, y su contador hereda la tinta
   oscura. El velo de fondo tiene que salir de esa misma tinta: con un token
   de crema el número quedaba negro sobre negro, porque en la pared los
   tokens claros se invierten. */
.wall-tab.is-on .n { background: rgba(25, 19, 16, .12); }

/* --- LA COMANDA: chapa clara sobre carbón ------------------------------- */
.order-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: #fff;
  border-radius: var(--r-lg);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
  animation: rise 280ms var(--ease);
  /* La comanda no se invierte nunca: el contraste con el carbón del fondo es
     lo que la hace visible desde la plancha. */
  --ink: #1a1512; --ink-2: #5c4e45; --ink-3: #78685d;
  --paper: #fff; --cream: #fdf7f1; --cream-2: #f6ece2; --cream-3: #ecdfd2;
  --line-2: #f4e8dc;
  --brasa: #df121c; --brasa-deep: #b30d15; --brasa-soft: #fde8e9;
  --oro: #ffcd00; --oro-deep: #8a5c05; --oro-soft: #fff5cc;
  --verde: #12833a; --verde-deep: #0f6e2f; --verde-soft: #e4f6ea;
  --naranja: #e8720c; --naranja-deep: #a24c05; --naranja-soft: #fdeedd;
  --azul: #1668d9; --azul-deep: #0f4ea6; --azul-soft: #e6f0fd;
  --uva: #7b3fa0; --uva-deep: #5f2f7d; --uva-soft: #f3e9f9;
  --grafito: #7d6d62; --grafito-deep: #5c4e45; --grafito-soft: #f2ebe4;
  --brasa-on: #fff; --verde-on: #fff; --azul-on: #fff; --uva-on: #fff;
  --naranja-on: #fff; --oro-on: #241703;
  color: var(--ink);
}

/* La cabecera ES el estado: región llena. */
.order-top {
  padding: .875rem 1rem;
  display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem;
  transition: background-color var(--med) var(--ease);
}
.order-code  { font-size: 1.5rem; font-weight: 900; letter-spacing: -.035em; line-height: 1.05; }
.order-meta  { font-size: .875rem; font-weight: 600; opacity: .82; line-height: 1.3; }
.order-timer { font-size: 1.375rem; font-weight: 900; font-variant-numeric: tabular-nums; line-height: 1.05; letter-spacing: -.03em; }

.order-card.u-new   .order-top { background: var(--azul);    color: #fff; }
.order-card.u-warn  .order-top { background: var(--naranja); color: #fff; }
.order-card.u-late  .order-top { background: var(--brasa);   color: #fff; }
.order-card.u-ready .order-top { background: var(--verde);   color: #fff; }

.order-card.u-late { box-shadow: 0 0 0 4px var(--brasa), 0 8px 24px rgba(0, 0, 0, .4); }
.order-card.u-late .order-timer { animation: blink 1.2s steps(2, jump-none) infinite; }
@keyframes blink { 50% { opacity: .4; } }

.order-items { flex: 1; padding: .375rem 1rem .625rem; }
.order-foot  { padding: .875rem 1rem; border-top: 1px solid var(--line-2); }

.oi { padding: .625rem 0; cursor: pointer; border-bottom: 1px solid var(--line-2); transition: opacity var(--fast) var(--ease); }
.oi:last-child { border-bottom: 0; }
.oi.done { opacity: .35; }
.oi.done .oi-name { text-decoration: line-through; }
.oi-qty {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-xs);
  background: var(--coal-900); color: #fff;
  font-size: 1.0625rem; font-weight: 900; font-variant-numeric: tabular-nums;
}
.oi-name { font-size: 1.125rem; font-weight: 700; line-height: 1.25; letter-spacing: -.018em; }
.oi-var  { font-size: .875rem; font-weight: 500; color: var(--ink-3); }
.oi-mod {
  display: flex; align-items: center; gap: .375rem;
  margin-left: 2.625rem; font-size: .9375rem; font-weight: 700; line-height: 1.45;
}
.oi-mod svg { width: 16px; height: 16px; flex: none; }
.oi-mod.out { color: var(--brasa-deep); }
.oi-mod.add { color: var(--verde-deep); }
.oi-kid { margin-left: 2.625rem; font-size: .9375rem; font-weight: 600; color: var(--azul-deep); }
.oi-note {
  display: flex; align-items: flex-start; gap: .4375rem;
  margin: .375rem 0 0 2.625rem; padding: .375rem .625rem;
  border-radius: var(--r-xs);
  background: var(--oro-soft); color: var(--oro-deep);
  font-size: .9375rem; font-weight: 700; line-height: 1.35;
}
.oi-note svg { width: 16px; height: 16px; flex: none; margin-top: 2px; }
.oi-note--all { margin-left: 0; }

/* EL MOMENTO: el avance de comanda.
   Al marcar un paso, la comanda salta del riel y vuelve a asentarse. */
.order-card--go { animation: card-go 260ms var(--pop); }
@keyframes card-go {
  40%  { transform: translateY(-10px) scale(1.02); box-shadow: 0 18px 40px rgba(0, 0, 0, .5); }
  100% { transform: none; }
}

.wall-blank {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .75rem; padding: 6rem 1rem; text-align: center;
  color: var(--coal-ink-2);
}
.wall-blank .blank-mark { background: var(--coal-700); color: var(--coal-ink-2); }
.wall-blank h3 { font-size: 1.5rem; font-weight: 800; color: var(--coal-ink); }
.wall-blank p  { font-size: 1rem; color: var(--coal-500); }

/* ==========================================================================
   24. EL DESPACHO
   ========================================================================== */
.dis-body { flex: 1; display: flex; min-height: 0; }
.dis-main { flex: 1; min-width: 0; overflow-y: auto; padding: 1.25rem; }
.dis-side { width: 20rem; flex: none; overflow-y: auto; background: var(--paper); border-left: 1px solid var(--line-2); }
@media (max-width: 1023px) { .dis-side { display: none; } }
.dis-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); align-items: start; }

.parcel {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--paper); border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  transition: box-shadow var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.parcel:hover { box-shadow: var(--sh-2); transform: translateY(-2px); }
.parcel-top {
  padding: .875rem 1rem;
  display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem;
  background: var(--grafito-soft);
}
.parcel-code { font-size: 1.125rem; font-weight: 900; letter-spacing: -.028em; color: var(--ink); }
.parcel.s-ready      .parcel-top { background: var(--verde-soft); }
.parcel.s-dispatched .parcel-top { background: var(--azul-soft); }
.parcel.s-assigned   .parcel-top,
.parcel.s-picked_up  .parcel-top,
.parcel.s-on_route   .parcel-top { background: var(--uva-soft); }
.parcel.is-late      .parcel-top { background: var(--brasa-soft); }
.parcel.is-late { box-shadow: 0 0 0 3px var(--brasa), var(--sh-1); }

.parcel-items { padding: .75rem 1rem; max-height: 11rem; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: .375rem; }
.parcel-qty {
  width: 26px; height: 26px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-xs); background: var(--cream-2); color: var(--ink-2);
  font-size: .75rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.parcel-drop {
  padding: .75rem 1rem; border-top: 1px solid var(--line-2);
  background: var(--uva-soft); color: var(--uva-deep);
  font-size: .8125rem; font-weight: 600; line-height: 1.5;
  display: flex; flex-direction: column; gap: .25rem;
}
.parcel-drop svg { width: 15px; height: 15px; flex: none; }
.parcel-foot { padding: .75rem; border-top: 1px solid var(--line-2); display: flex; gap: .5rem; align-items: center; }

.rider {
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem; border-bottom: 1px solid var(--line-2);
}
.rider-dot { width: 10px; height: 10px; flex: none; border-radius: 50%; background: var(--grafito-lit); }
.rider-dot.available  { background: var(--verde); box-shadow: 0 0 0 3px var(--verde-soft); }
.rider-dot.delivering { background: var(--naranja); box-shadow: 0 0 0 3px var(--naranja-soft); }
.rider-dot.offline    { background: var(--cream-3); }

.call-row {
  padding: .875rem 1rem; border-bottom: 1px solid var(--line-2);
  background: var(--brasa-soft);
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
}

/* ==========================================================================
   25. EL SALÓN — mapa de mesas
   ========================================================================== */
.floor-grid { display: grid; gap: .875rem; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); }
.seat {
  aspect-ratio: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .1875rem;
  padding: .75rem; text-align: center; cursor: pointer; position: relative;
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  overflow: hidden;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.seat:hover  { transform: translateY(-3px); box-shadow: var(--sh-2); }
.seat:active { transform: scale(.97); }
.seat-name { font-size: 1.0625rem; font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.seat-meta { font-size: .75rem; font-weight: 600; color: var(--ink-3); }
.seat-sum  { font-size: .875rem; font-weight: 800; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.seat-call {
  position: absolute; top: .5rem; right: .5rem;
  padding: .125rem .4375rem; border-radius: var(--r-pill);
  background: var(--brasa); color: #fff;
  font-size: .625rem; font-weight: 900; letter-spacing: .04em;
  animation: blink 1.1s steps(2, jump-none) infinite;
}
.seat.st-available { background: var(--verde-soft); }
.seat.st-available .seat-sum { color: var(--verde-deep); }
.seat.st-occupied  { background: var(--azul-soft); }
.seat.st-ordered,
.seat.st-preparing { background: var(--naranja-soft); }
.seat.st-ready     { background: var(--verde); box-shadow: var(--sh-verde); }
.seat.st-ready .seat-name,
.seat.st-ready .seat-meta,
.seat.st-ready .seat-sum { color: #fff; }
.seat.st-billing   { background: var(--uva-soft); }
.seat.st-reserved  { background: var(--grafito-soft); }
.seat.st-disabled  { background: var(--cream-2); opacity: .5; cursor: not-allowed; }

/* ==========================================================================
   26. EL BOLSILLO — carta QR, portal y app del repartidor
   ========================================================================== */
body.pocket { background: var(--cream); padding-bottom: 6rem; }

/* La cabecera de marca: brasa plena, generosa. */
.hero {
  position: relative; overflow: hidden;
  padding: 1.25rem 1.25rem 1.5rem;
  background: var(--brasa);
  color: #fff;
}
.hero::after {
  content: ""; position: absolute; right: -3rem; top: -5rem;
  width: 16rem; height: 16rem; border-radius: 50%;
  background: rgba(0, 0, 0, .07);
}
.hero::before {
  content: ""; position: absolute; right: 3rem; bottom: -7rem;
  width: 12rem; height: 12rem; border-radius: 50%;
  background: rgba(255, 205, 0, .16);
}
.hero > * { position: relative; z-index: 1; }
.hero h1 { color: #fff; }
.hero .t-label { color: #fff; }
.hero-tag {
  display: inline-flex; align-items: center; gap: .375rem;
  padding: .375rem .75rem;
  border-radius: var(--r-pill);
  /* Velo oscuro, no claro: subir el fondo con blanco arruina el texto. */
  background: rgba(0, 0, 0, .17);
  font-size: .8125rem; font-weight: 700; color: #fff;
}
.hero-tag svg { width: 15px; height: 15px; }
.hero-tag--open { background: var(--verde); }
.hero-tag--shut { background: var(--coal-900); }
.hero-round {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, .17); color: #fff;
  transition: background-color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.hero-round:active { transform: scale(.9); }
.hero .field { background: #fff; border-color: transparent; box-shadow: var(--sh-2); }

/* La fila de categorías pegada arriba */
/* La tira de categorías se queda arriba mientras se recorre la carta: con 23
   categorías y 111 platos, volver al principio para cambiar de sección sería
   el gesto más repetido de la pantalla.

   El velo del borde derecho avisa de que la tira sigue: sin él, una tira que
   se desplaza parece una tira que se acabó. */
.cat-bar {
  position: sticky; top: 0; z-index: 30;
  display: flex; gap: .5rem; overflow-x: auto;
  padding: .75rem 1rem;
  background: var(--cream);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  box-shadow: 0 1px 0 var(--line-2), 0 10px 14px -14px rgba(26, 21, 18, .5);
}
.cat-bar::-webkit-scrollbar { display: none; }
.cat-bar > .chip { scroll-snap-align: start; }

/* El rótulo de la sección se queda debajo de la tira: recorriendo «Toda la
   carta» son veintitrés secciones seguidas, y sin él se pierde de vista en
   cuál se está. */
.cat-head {
  /* Se pega justo debajo de la tira, sin holgura: cuatro píxeles de hueco
     bastaban para que asomara la tarjeta de atrás. Y el fondo es crema plena,
     no un degradado a transparente, por la misma razón. */
  position: sticky; top: 62px; z-index: 20;
  margin: 1.25rem 0 .5rem;
  padding: .5rem 0 .5rem .25rem;
  background: var(--cream);
  font-size: .6875rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-3);
}
.cat-head:first-child { margin-top: .25rem; }

/* El renglón de plato en el teléfono */
/* --------------------------------------------------------------------------
   LA FILA DEL PLATO

   La carta se diseñó suponiendo fotografía y no hay ninguna: un cuadro de
   84 px que no muestra comida no gana su sitio, y con 111 platos convertía la
   carta en dieciséis pantallas de desplazamiento. Sin foto manda la
   tipografía, como en una carta impresa: el nombre a la izquierda, el precio
   alineado a la derecha en la misma línea, y el resto es aire.

   Cuando lleguen las fotografías, la fila con imagen vuelve sola: es el mismo
   componente y el dato decide cuál se pinta.
   -------------------------------------------------------------------------- */
.dish-row {
  display: flex; gap: .875rem; align-items: center;
  padding: .875rem;
  background: var(--paper);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  cursor: pointer;
  transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.dish-row:active { transform: scale(.985); }
.dish-row.out { opacity: .5; pointer-events: none; }
.dish-row img {
  width: 5.25rem; height: 5.25rem; flex: none;
  border-radius: var(--r-sm); object-fit: cover; background: var(--cream-2);
}

/* Sin fotografía: más apretada y con el precio en la línea del nombre. */
.dish-row--plain { padding: .8125rem .875rem .8125rem 1rem; }
.dish-row .dish-main { min-width: 0; flex: 1; }
.dish-row .dish-head { display: flex; align-items: baseline; gap: .75rem; }
.dish-row .dish-name {
  flex: 1; min-width: 0;
  font-size: .9375rem; font-weight: 800; line-height: 1.3;
  letter-spacing: -.018em; color: var(--ink);
}
.dish-row .dish-cost {
  flex: none;
  /* Un paso por debajo del nombre: dos negritas del mismo tamaño compiten y
     la fila se lee dos veces. */
  font-size: .875rem; font-weight: 800;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.dish-row .dish-note {
  margin-top: .1875rem;
  font-size: .8125rem; line-height: 1.4; color: var(--ink-3);
}
.dish-row .dish-tags { display: flex; gap: .375rem; margin-top: .375rem; }

/* El signo de más, no otra pastilla roja. Con 111 filas, 111 botones rellenos
   apagan el rojo y tapan el plato, que es lo que se viene a leer. */
.dish-add {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border: 2px solid var(--cream-3);
  border-radius: var(--r-pill);
  background: var(--paper); color: var(--brasa-deep);
  transition: background-color var(--fast) var(--ease), border-color var(--fast) var(--ease),
              transform var(--fast) var(--pop);
}
.dish-add svg { width: 20px; height: 20px; }
.dish-add:hover { border-color: var(--brasa); background: var(--brasa-soft); }
.dish-add:active { transform: scale(.9); }
.dish-row.out .dish-add { display: none; }

/* El mismo botón, en el mostrador y solo en el teléfono. De tableta para
   arriba el pedido está a la vista en su propia columna y un botón flotante
   encima sobraría. */
.pos-fab { display: none; }
/* Y fuera mientras haya un cuadro delante: por encima de un cobro, un botón
   rojo flotante es el sitio donde se toca sin querer.

   Se mira la capa abierta, no una clase que ponga el JavaScript. Con la clase
   sola, el botón reaparecía en cuanto un cuadro se abría por otro camino —una
   prueba que le pone `is-open` a mano, un cuadro creado al vuelo—, y la hoja
   dependía de que alguien se acordara de avisarla. Aquí la condición es la que
   de verdad importa: hay algo delante. */
body:has(.modal-backdrop.is-open) .cart-fab,
body:has(.veil.is-open) .cart-fab,
body:has(.tray.is-open) .cart-fab,
.con-capa .cart-fab { display: none !important; }
@media (max-width: 767px) {
  .pos-fab:not([hidden]) { display: flex; }
}

/* EL BOTÓN DEL PEDIDO — siempre a la mano, siempre visible */
.cart-fab {
  /* El teléfono reserva una franja abajo para su indicador de inicio: sin
     contarla, el botón queda medio debajo justo en la pantalla que más se
     usa, el teléfono del comensal en la mesa. */
  position: fixed; left: 50%; bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px)); z-index: 60;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: .875rem;
  width: calc(100% - 2rem); max-width: 30rem;
  min-height: 60px; padding: 0 1.25rem;
  border-radius: var(--r-pill);
  background: var(--brasa); color: #fff;
  font-size: 1rem; font-weight: 800;
  box-shadow: 0 10px 30px -6px rgba(223, 18, 28, .6), var(--sh-3);
  transition: transform var(--med) var(--pop), opacity var(--fast) var(--ease);
}
.cart-fab:active { transform: translateX(-50%) scale(.97); }
.cart-fab.is-away { transform: translateX(-50%) translateY(140px); opacity: 0; pointer-events: none; }
.cart-fab .n {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .22);
  font-size: .9375rem; font-weight: 900; font-variant-numeric: tabular-nums;
}
/* El rebote cuando entra algo al pedido */
.cart-fab.is-bump { animation: bump 400ms var(--pop); }
@keyframes bump {
  30% { transform: translateX(-50%) scale(1.07); }
  60% { transform: translateX(-50%) scale(.98); }
  100% { transform: translateX(-50%); }
}

/* El seguimiento del pedido: una escalera */
.track { display: flex; flex-direction: column; }
.track-step { display: flex; gap: .875rem; position: relative; padding-bottom: 1.25rem; }
.track-step:last-child { padding-bottom: 0; }
.track-step::before {
  content: ""; position: absolute; left: 17px; top: 38px; bottom: 0;
  width: 3px; border-radius: var(--r-pill); background: var(--cream-2);
}
.track-step:last-child::before { display: none; }
.track-dot {
  width: 36px; height: 36px; flex: none; z-index: 1;
  display: grid; place-items: center; border-radius: var(--r-pill);
  background: var(--cream-2); color: var(--ink-3);
  font-size: .875rem; font-weight: 800; font-variant-numeric: tabular-nums;
  position: relative;
}
.track-dot svg { width: 18px; height: 18px; }
.track-step.done .track-dot { background: var(--verde); color: #fff; }
.track-step.done::before { background: var(--verde); }
.track-step.current .track-dot { background: var(--brasa); color: #fff; box-shadow: var(--sh-brasa); }
.track-step.current .track-dot::after {
  content: ""; position: absolute; inset: -5px; border-radius: var(--r-pill);
  border: 3px solid var(--brasa); opacity: .35;
  animation: ping 1.8s var(--ease) infinite;
}
@keyframes ping { 0%, 100% { opacity: .35; transform: scale(1); } 50% { opacity: 0; transform: scale(1.25); } }

/* --- El portal en escritorio -------------------------------------------- */
.portal-nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
  box-shadow: var(--sh-1);
}
.shop-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); }

/* --- La app del repartidor ---------------------------------------------- */
.ride-tabs { position: sticky; top: 0; z-index: 30; display: flex; gap: .375rem; padding: .75rem 1rem; background: var(--cream); }
.ride-tab {
  flex: 1; min-height: 46px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; justify-content: center; gap: .4375rem;
  font-family: inherit; font-size: .875rem; font-weight: 700; color: var(--ink-2);
  background: var(--paper); box-shadow: var(--sh-1);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.ride-tab:active { transform: scale(.96); }
.ride-tab.is-on { background: var(--coal-900); color: #fff; }
.ride-tab .n {
  min-width: 22px; padding: 0 .375rem; border-radius: var(--r-pill);
  background: var(--cream-2); color: var(--ink-2);
  font-size: .75rem; font-weight: 800; line-height: 20px; text-align: center;
}
.ride-tab.is-on .n { background: rgba(255, 255, 255, .2); color: #fff; }

/* ==========================================================================
   27. LA PUERTA — inicio de sesión
   ========================================================================== */
.gate { min-height: 100vh; display: grid; grid-template-columns: 1fr; }
@media (min-width: 1024px) { .gate { grid-template-columns: 1.05fr .95fr; } }

.gate-show {
  display: none; flex-direction: column; justify-content: space-between;
  padding: 3rem; position: relative; overflow: hidden;
  background: var(--brasa); color: #fff;
}
@media (min-width: 1024px) { .gate-show { display: flex; } }
.gate-show::after {
  content: ""; position: absolute; right: -8rem; top: -8rem;
  width: 32rem; height: 32rem; border-radius: 50%;
  background: rgba(0, 0, 0, .07);
}
.gate-show::before {
  content: ""; position: absolute; left: -6rem; bottom: -10rem;
  width: 26rem; height: 26rem; border-radius: 50%;
  background: rgba(255, 205, 0, .18);
}
.gate-show > * { position: relative; z-index: 1; }
.gate-claim { margin-top: 3rem; font-size: clamp(2rem, 1.2rem + 2.4vw, 3.125rem); font-weight: 900; letter-spacing: -.04em; line-height: 1.03; color: #fff; }
.gate-sub { margin-top: 1.125rem; max-width: 32rem; font-size: 1rem; font-weight: 500; line-height: 1.6; color: rgba(255, 255, 255, .95); }
.gate-list { margin-top: 2.5rem; display: flex; flex-direction: column; gap: .625rem; max-width: 32rem; }
.gate-item {
  display: flex; gap: .875rem; align-items: center;
  padding: .875rem 1rem;
  border-radius: var(--r-md);
  background: rgba(0, 0, 0, .15);
}
.gate-mark {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center; border-radius: var(--r-sm);
  background: var(--oro); color: var(--oro-on);
}
.gate-form { display: flex; align-items: center; justify-content: center; padding: 1.5rem; background: var(--paper); }

/* El teclado del PIN */
.pin-row { display: flex; gap: .625rem; justify-content: center; }
.pin-slot {
  width: 52px; height: 60px;
  border-radius: var(--r-sm);
  background: var(--cream-2);
  position: relative;
  transition: background-color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.pin-slot.is-set { background: var(--brasa); transform: scale(1.04); }
.pin-slot.is-set::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; background: #fff;
}
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.keypad button {
  min-height: 60px; border-radius: var(--r-md);
  background: var(--cream-2); color: var(--ink);
  font-family: inherit; font-size: 1.375rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  display: grid; place-items: center;
  transition: background-color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.keypad button:hover  { background: var(--cream-3); }
.keypad button:active { transform: scale(.93); background: var(--brasa); color: #fff; }
.keypad button svg { width: 22px; height: 22px; }

.demo-key {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; min-height: 42px; padding: 0 .875rem;
  border-radius: var(--r-pill);
  background: var(--cream-2);
  font-family: inherit; font-size: .8125rem; font-weight: 700; color: var(--ink-2);
  cursor: pointer;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.demo-key:hover  { background: var(--brasa-soft); color: var(--brasa-deep); }
.demo-key:active { transform: scale(.97); }

/* ==========================================================================
   28. LA HOJA DE CÓDIGOS QR
   ========================================================================== */
.qr-sheet { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1rem; }
.qr-card {
  background: #fff; border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: 1.5rem 1.25rem; text-align: center;
  page-break-inside: avoid; break-inside: avoid;
  display: flex; flex-direction: column; align-items: center; gap: .625rem;
}
/* La tarjeta de mesa es lo que el comensal tiene delante: ahí manda el
   logotipo, no el nombre escrito. */
.qr-card .brand .logo-ancho { height: 52px; }
.qr-card .seat-no { font-size: 2rem; font-weight: 900; letter-spacing: -.045em; line-height: 1; color: var(--brasa); }
.qr-card .qr { padding: .5rem; background: #fff; border-radius: var(--r-sm); }
.qr-card .hint { font-size: .8125rem; font-weight: 600; color: var(--ink-2); line-height: 1.4; }
.qr-card .steps { width: 100%; text-align: left; font-size: .75rem; color: var(--ink-3); line-height: 1.7; }
.qr-card .token { font-family: var(--mono); font-size: .6875rem; letter-spacing: .08em; color: var(--ink-3); }
@media print {
  body { background: #fff; }
  .qr-sheet { grid-template-columns: repeat(3, 1fr); gap: 8mm; }
  .qr-card { box-shadow: none; border: 1px solid #ddd; }
}

/* --------------------------------------------------------------------------
   29. El mostrador en pantalla estrecha
   El POS se diseñó para una pantalla táctil de mostrador. En un teléfono sigue
   siendo usable, pero cede lo accesorio: los pedidos recientes desaparecen y
   la barra se queda con lo que de verdad se toca.
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .pos-body { flex-direction: column; padding: .75rem; gap: .75rem; }
  .pos-menu { min-height: 58vh; }
  .pos-order { width: 100%; height: auto; min-height: 22rem; }
  .pos-recent { display: none; }
  .bar .tag { display: none; }
}
@media (max-width: 767px) {
  .bar { gap: .5rem; padding: .5rem .75rem; }
  .bar-title { font-size: 1.0625rem; }
  .bar-sub { display: none; }
  .bar-acts { gap: .25rem; }
  .pos-order { min-height: 26rem; }
  .menu-grid { grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); gap: .625rem; }
  .deck { padding: .75rem; }
}

/* En el teléfono, el buscador y el orden dejan de competir por la misma fila. */
@media (max-width: 767px) {
  .pos-search { width: 100%; margin-left: 0 !important; }
  .pos-search .field-slot { width: 100% !important; }
  .pos-search select { width: 100% !important; }
}
@media (max-width: 767px) {
  .pos-search { flex-wrap: wrap; }
}

/* --------------------------------------------------------------------------
   30. Piso de objetivo táctil
   Ninguna cosa que se pulse baja de 24 px de alto, y las casillas llegan a 24
   para poder marcarse con el dedo sin apuntar. El enlace de texto dentro de una
   tabla gana altura por relleno, no por tamaño de letra.
   -------------------------------------------------------------------------- */
.check, .radio { width: 24px; height: 24px; }
.check:checked::after { left: 7px; top: 3px; }

.btn--xs, .btn.btn-xs { min-height: 34px; }
.btn.btn-icon.btn-xs, .btn--round.btn--xs { width: 34px; }

/* Un teléfono o un código enlazado dentro de una tabla es un objetivo real. */
.grid-table a[href^="tel:"], .table a[href^="tel:"],
.grid-table a:not(.btn), .table a:not(.btn) {
  display: inline-flex; align-items: center; min-height: 24px;
}
.recent { display: block; }

/* --------------------------------------------------------------------------
   EDITORES DE RENGLÓN

   Compras, recetas, modificadores y combos alinean sus renglones en columnas
   fijas para que los números cuadren unos debajo de otros. En pantalla
   estrecha no se apilan —apilados, cada campo pierde la relación con su
   encabezado y hay que adivinar qué es cada número—: la caja rueda a lo ancho
   con las columnas intactas, que es como se lee una tabla en un teléfono.
   -------------------------------------------------------------------------- */
.rengs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rengs > * { min-width: 32rem; }

/* --------------------------------------------------------------------------
   LA CABECERA DEL PORTAL

   Lo que se viene a hacer aquí es pedir comida. La cabecera tiene que
   convencer en una mirada y apartarse: en un teléfono, cada centímetro que
   ocupa es un centímetro que la carta baja.
   -------------------------------------------------------------------------- */
.portal-hero { padding: 2.5rem 1rem 3rem; }
.portal-claim { max-width: 38rem; }
.portal-sub {
  margin-top: 1rem; max-width: 34rem;
  font-size: 1rem; line-height: 1.6; color: rgba(255, 255, 255, .95);
}
@media (max-width: 767px) {
  .portal-hero { padding: 1.75rem 1rem 2rem; }
  .portal-sub { margin-top: .75rem; font-size: .9375rem; }
}

/* Sin fotografía la tarjeta pierde su cuadro y se aprieta: una rejilla de
   recuadros vacíos ocupa la pantalla entera para no enseñar nada, y con 111
   platos son diez pantallas de cajas beige. El nombre pasa a mandar y la
   rejilla cabe a más columnas. */
.dish--plain .dish-body { padding: .875rem 1rem; gap: .25rem; }
.dish--plain .dish-flags--plain + .dish-body { padding-top: .5rem; }
.dish--plain .dish-name { font-size: 1rem; font-weight: 800; -webkit-line-clamp: 3; }
.dish--plain .dish-foot { margin-top: .5rem; }
.shop-grid--plain { grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr)); }

/* La rejilla de la caja, sin fotografía.
   Sin el cuadro cada ficha mide un tercio de lo que medía, así que caben más
   por pantalla; y como el nombre pasa a mandar, la columna se ensancha un poco
   para que «Hot Dog a la plancha» no se parta en tres líneas. Con 111 platos
   esto es la diferencia entre tres pantallas y diez, y el cajero atiende de
   pie con gente esperando. */
.menu-grid--plain { grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr)); gap: .75rem; }

/* El distintivo, ahora dentro del cuerpo y debajo del nombre. Antes iba encima
   y empujaba el nombre: en una fila de cuatro fichas, las que lo llevaban
   arrancaban treinta píxeles más abajo que sus vecinas. Se lee mal aunque nadie
   sepa decir por qué. */
.dish--plain .dish-body > .dish-flags--plain { padding: 0; margin-top: .375rem; }

/* La dieta, sin cuadro donde flotar, entra en la línea de la categoría. */
.dish--plain .dish-cat { display: flex; align-items: center; gap: .375rem; }
.dish--plain .dish-diet { position: static; width: 14px; height: 14px; box-shadow: none; background: none; }
.dish--plain .dish-diet::after { width: 8px; height: 8px; }

/* La tira de favoritos: tarjetas de ancho fijo que se recorren de lado. El
   ancho vivía escrito en el marcado y por eso no podía encogerse. */
.fav-card { width: 12.5rem; flex: none; }
/* En la tira, las tarjetas miden todas lo mismo, así que el precio se va abajo
   y queda a la misma altura en todas. En la rejilla no: allí el precio sigue al
   nombre, porque separarlos media tarjeta solo alarga la página. */
.dish--plain.fav-card .dish-foot { margin-top: auto; }
@media (max-width: 400px) { .fav-card { width: 11rem; } }

/* --------------------------------------------------------------------------
   LA CARTA DEL PORTAL, SIN FOTOGRAFÍA

   Tres correcciones que solo se ven en escritorio, donde la rejilla se abre a
   cuatro columnas y el vacío se nota.
   -------------------------------------------------------------------------- */

/* 1. La tira de categorías se pegaba a cero y quedaba debajo de la barra de
      marca, que también está pegada: por el hueco entre ambas asomaba lo que
      pasaba rodando. Se pega debajo de la barra, no debajo del borde. */
.cat-bar--portal { top: 68px; padding-top: 1.25rem; }

/* 2. Sin fotografía la tarjeta no necesita tanto aire: el nombre y el precio
      son lo único que hay, y separarlos media tarjeta no los jerarquiza, solo
      alarga la página. */
.dish--plain .dish-foot { margin-top: .625rem; padding-top: 0; }
.dish--plain .dish-price { font-size: 1rem; }

/* 3. El signo de más, en contorno como en la carta de mesa. Un disco rojo
      relleno por tarjeta convierte la rejilla en una pared de botones y apaga
      el rojo, que en este sistema significa «la acción principal». */
.dish--plain .btn-add {
  background: var(--paper); color: var(--brasa-deep);
  border: 2px solid var(--cream-3);
  box-shadow: none;
}
.dish--plain:hover .btn-add { border-color: var(--brasa); background: var(--brasa-soft); }

/* --------------------------------------------------------------------------
   EL CAJÓN DEL PEDIDO

   El portal declaraba `.cart-drawer` y `.cart-overlay` desde el diseño
   anterior, y la reconstrucción nunca las portó: eran clases sin una sola
   regla. El guion ponía `is-open` obedientemente, la clase no existía, y el
   panel se quedaba al final del documento, en flujo normal. Pulsar «Mi
   pedido» no abría nada: llevaba al pie de la página.

   No dio error, ni en consola ni en ningún arnés —la clase se ponía, el botón
   respondía, nada se desbordaba—. Solo se ve mirando la pantalla.

   En escritorio es un panel lateral, que deja ver la carta detrás mientras se
   revisa el pedido. En el teléfono es una hoja que sube desde abajo, que es el
   gesto que ya conoce el pulgar.
   -------------------------------------------------------------------------- */
.cart-overlay {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(26, 21, 18, .5);
  backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transition: opacity var(--med) var(--ease);
}
.cart-overlay.is-open { opacity: 1; pointer-events: auto; }

.cart-drawer {
  position: fixed; z-index: 81;
  top: 0; right: 0; bottom: 0;
  width: min(30rem, 100%);
  display: flex; flex-direction: column;
  background: var(--paper);
  box-shadow: var(--sh-4);
  transform: translateX(100%);
  transition: transform var(--med) var(--ease);
  overscroll-behavior: contain;
}
/* Cerrado no se toca. Sin esto, el panel apartado con una transformación
   sigue ocupando su caja para el navegador y se come los clics de lo que
   tiene debajo: a 320 px se tragaba la tira de categorías. */
.cart-drawer { pointer-events: none; visibility: hidden; }
.cart-drawer.is-open { transform: none; pointer-events: auto; visibility: visible; }
/* La cabecera y el pie se quedan; lo del medio rueda. */
.cart-drawer > .grow { min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }

@media (max-width: 640px) {
  .cart-drawer {
    /* Anclado abajo: sin `bottom` el navegador usa su posición en el flujo y
       el panel acaba donde nadie lo puso. */
    top: auto; bottom: 0; left: 0; right: 0;
    width: 100%; max-height: 92vh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    /* El teléfono reserva una franja abajo para su indicador de inicio. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transform: translateY(100%);
  }
}

/* Cómo quiere recibir el pedido: tres opciones que se eligen, no tres iconos
   sueltos. `.type-card` y `.ic` venían del diseño anterior y tampoco tenían
   una sola regla, así que el cliente no veía cuál estaba elegida. */
.type-card {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: .375rem;
  min-height: var(--tap-lg); padding: .75rem .5rem;
  border-radius: var(--r-md);
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--cream-3);
  color: var(--ink-2);
  font-family: inherit; cursor: pointer;
  transition: box-shadow var(--fast) var(--ease), background-color var(--fast) var(--ease),
              color var(--fast) var(--ease), transform var(--fast) var(--pop);
}
.type-card .ic { display: grid; place-items: center; }
.type-card .ic svg { width: 22px; height: 22px; }
.type-card:hover { box-shadow: inset 0 0 0 2px var(--ink-3); }
.type-card:active { transform: scale(.97); }
.type-card.is-active {
  background: var(--brasa-soft);
  box-shadow: inset 0 0 0 2.5px var(--brasa);
  color: var(--brasa-deep);
}

/* Un dato pequeño al lado de un nombre: el tiempo de preparación, un código.
   No es un distintivo —no reclama nada— pero tampoco es texto corrido. */
.code {
  display: inline-flex; align-items: center; gap: .3125rem;
  padding: .1875rem .5rem;
  border-radius: var(--r-xs);
  background: var(--cream-2); color: var(--ink-2);
  font-size: .75rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.code svg { width: 13px; height: 13px; flex: none; }

/* Cada renglón de un gráfico de barras: rótulo arriba, barra debajo. */
.chart-row { padding: .375rem 0; }
.chart-row + .chart-row { border-top: 1px solid var(--line-2); }

/* El nombre del repartidor. Sin antetítulo —la pantalla entera es la suya y no
   hace falta decirle que es el repartidor— y sin recorte: «Jonatha…» en la
   pantalla de uno mismo se lee como un descuido. Si no cabe en una línea, baja
   de tamaño antes que cortarse. */
.ride-name {
  font-size: clamp(1.0625rem, 5.2vw, 1.5rem);
  font-weight: 900; letter-spacing: -.03em; line-height: 1.15;
  color: #fff;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   LA PARED, EN UNA PANTALLA GRANDE

   El tamaño de la comanda estaba pensado para un monitor de escritorio, y en
   la cocina la pantalla suele ser más grande y estar más lejos. A partir de
   1600 px las tarjetas se ensanchan y el texto crece con ellas: menos comandas
   a la vista, pero legibles desde la plancha, que es para lo que está.
   -------------------------------------------------------------------------- */
@media (min-width: 1600px) {
  .wall-grid { grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr)); gap: 1.25rem; }
  .oi-name { font-size: 1.375rem; }
  .oi-var  { font-size: 1rem; }
  .oi-mod, .oi-kid { font-size: 1.0625rem; }
  .oi-qty { width: 40px; height: 40px; font-size: 1.25rem; }
  .wall-tab { font-size: 1.0625rem; min-height: 52px; }
}

/* Una pestaña con cambios sin guardar lleva un punto: con ocho pestañas y un
   solo botón de guardar, hay que poder ver dónde quedó lo que se escribió. */
.tab--dirty { position: relative; }
.tab--dirty::after {
  content: ""; position: absolute; top: .375rem; right: .375rem;
  width: 7px; height: 7px; border-radius: var(--r-pill);
  background: var(--brasa);
}
