/* ═══════════════════════════════════════════════════════════════════════════
   POS Bar Yesca · hoja de estilos
   ═══════════════════════════════════════════════════════════════════════════
   Esto NO se diseña para un celular. Vive en el aparato de la caja —un notebook
   o una tablet apoyada— que queda encendido todo el servicio, y se opera con el
   dedo, de pie y apurado. Lo que manda:

   · Objetivo de toque de 56 px o más en todo lo que se aprieta en el servicio.
   · Fondo oscuro: la pantalla queda encendida 12 horas frente a la gente.
   · Densidad alta en los reportes, densidad baja en la venta. Son dos modos de
     uso distintos y no se pueden diseñar igual.
   · Nada de animaciones de entrada. Un POS que "aparece con gracia" es un POS
     que se siente lento.

   ── Cómo se aplica la regla del toque (26-08-2026) ─────────────────────────
   "56 px o más" no puede significar lo mismo en la comanda que en la tabla de
   costos: si todo mide 56 px, un reporte de 33 filas no cabe en pantalla y se
   pierde la densidad que el mismo encabezado exige. La regla se escribió en
   tres escalones, y cada control cae en uno según CUÁNDO se aprieta:

     --toque      56 px · lo que se aprieta DE PIE, en pleno servicio, mirando
                          al cliente: platos, mesas, teclado del PIN, cobrar,
                          mandar a cocina, medios de pago.
     --toque-med  44 px · lo que se aprieta con el dedo pero sin la mesa
                          esperando: navegación, categorías, +/− de una línea,
                          avanzar un pedido de delivery, rangos del reporte.
     --toque-min  36 px · lo que se usa sentado y con puntero, fuera del
                          servicio: editar costos, dar de baja un usuario,
                          ajustar la comisión de una app.

   Antes de esto la barra de navegación medía 34 px y los +/− de la comanda
   30 px — los dos controles que más se aprietan en un turno eran los dos más
   chicos de la interfaz, en un archivo que declaraba 56 px en la primera línea.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Superficies ─────────────────────────────────────────────────────────
     Cinco escalones de profundidad, no dos. Es lo que permite que un panel
     dentro de otro panel se distinga sin dibujar un borde más. */
  --bg: #0e1214;
  --bg-2: #141a1d;
  --panel: #1a2226;
  --panel-2: #212b30;
  --panel-3: #2a3639;
  --line: #2b373d;
  --line-soft: rgba(232, 238, 240, 0.08);

  /* ── Texto · los tres niveles están medidos sobre --panel (#1a2226) ──────
     --tx 8,3:1 · --tx-2 8,3:1 · --muted 4,9:1. Los tres pasan AA para texto
     chico. --muted es el piso: no bajarlo más, que ahí se cae. */
  --tx: #e8eef0;
  --tx-2: #aebcc1;
  --muted: #8a9ca2;

  /* ── Marca y semántica ──────────────────────────────────────────────────
     El verde es identidad de Aurai y significa UNA sola cosa en el POS: plata
     que entra y acción principal. No se usa de adorno. */
  --acento: #20cd97;
  --acento-2: #16a87a;
  --acento-tx: #05221a;
  --acento-tenue: rgba(32, 205, 151, 0.14);
  --acento-linea: rgba(32, 205, 151, 0.42);
  --ok: #4ade80;
  --ojo: #f5c451;
  --ojo-tenue: rgba(245, 196, 81, 0.1);
  --ojo-linea: rgba(245, 196, 81, 0.32);
  --alerta: #f0785e;
  --alerta-tenue: rgba(240, 120, 94, 0.12);
  --alerta-linea: rgba(240, 120, 94, 0.42);
  --azul: #78a9e0;
  --azul-tenue: rgba(120, 169, 224, 0.14);
  --azul-linea: rgba(120, 169, 224, 0.42);

  /* ── Foco de teclado ────────────────────────────────────────────────────
     Un menta más claro que el acento, para que un control ENFOCADO no se
     confunda con uno SELECCIONADO (que se pinta con el acento). Va siempre
     con separación del elemento, así también se ve sobre el botón verde. */
  --foco: #9ff3d0;

  /* ── Espaciado · escala de 4 ───────────────────────────────────────────── */
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 24px;
  --e6: 32px;

  /* ── Tipografía · la base es 15 px y la escala sube en saltos de ~1,15 ─── */
  --t-micro: 0.7rem;
  --t-min: 0.78rem;
  --t-chico: 0.84rem;
  --t-base: 0.92rem;
  --t-med: 1rem;
  --t-tit: 1.12rem;
  --t-tit-2: 1.35rem;
  --t-cifra: 1.6rem;
  --t-cifra-2: 2.4rem;

  /* ── Toque · ver el encabezado ─────────────────────────────────────────── */
  --toque: 56px;
  --toque-med: 44px;
  --toque-min: 36px;

  /* ── Geometría ─────────────────────────────────────────────────────────── */
  --radio: 10px;
  --radio-chico: 7px;
  --rail: 116px;
  --barra: 44px;
  --cuenta: 348px;
  color-scheme: dark;
}

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

html, body { height: 100%; }

body {
  background: var(--bg);
  color: var(--tx);
  font-family: ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; }
h1, h2, h3 { font-weight: 600; line-height: 1.2; }
table { border-collapse: collapse; width: 100%; }

.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* El aviso de "sin JavaScript". Estaba escrito con un `style=""` en el marcado:
   con la CSP de producción de Aurai, que descarta los estilos en línea, la
   única pantalla que se ve cuando algo falla habría salido sin formato. */
.sin-js { padding: var(--e6) var(--e5); max-width: 38rem; margin: 0 auto; }
.sin-js h1 { font-size: var(--t-tit-2); margin-bottom: var(--e3); }
.sin-js p { color: var(--tx-2); }

/* ── Foco de teclado, una sola regla para toda la aplicación ──────────────
   No existía. En un POS casi todo se toca con el dedo, pero el aparato de la
   caja tiene teclado y el que cuadra la caja a las 2 de la mañana tabula; sin
   anillo visible no se sabe dónde está parado. Se usa :focus-visible para que
   el anillo NO aparezca al tocar con el dedo, que sería ruido. */
:where(button, a, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--foco);
  outline-offset: 2px;
  border-radius: var(--radio-chico);
}
/* Los controles pegados al borde de su contenedor llevan el anillo por dentro:
   con offset positivo lo recortaría el overflow del panel que scrollea. */
.rail button:focus-visible,
.lineas button:focus-visible,
.tabla button:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline-offset: -2px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Cáscara · rail lateral + columna principal
   ══════════════════════════════════════════════════════════════════════════
   La navegación estaba arriba, en una barra de 60 px, con NUEVE destinos
   peleando el ancho contra el nombre del local, dos chips de estado, el
   usuario y el reloj. A 1024 px —una tablet apoyada, que es medio parque
   instalado— la fila se partía en dos y "Negocio" caía FUERA de la barra,
   encima del contenido.

   El rail resuelve las tres cosas de una vez: los nueve destinos caben en
   vertical sin pelear, se pueden agrupar por para-qué-sirven (servicio arriba,
   gestión abajo), y devuelve al contenido los 48 px de alto que se llevaba la
   barra doble. En una pantalla de 800 px de alto eso es una fila más de platos.
   ══════════════════════════════════════════════════════════════════════════ */

.app {
  height: 100dvh;
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
}

.rail {
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  padding: var(--e3) var(--e2) var(--e2);
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  overflow-x: hidden;
}

.rail-marca { padding: 0 var(--e2) var(--e3); }
.rail-marca strong {
  display: block;
  font-size: var(--t-base);
  line-height: 1.2;
  letter-spacing: -0.01em;
}
.etq-demo {
  display: inline-block;
  margin-top: var(--e1);
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ojo);
  background: var(--ojo-tenue);
  border: 1px solid var(--ojo-linea);
}

/* El rótulo del grupo. Existe para que "Reportes" y "Venta" no se lean como
   dos cosas del mismo tipo: una se usa en el servicio y la otra después. */
.rail-titulo {
  padding: var(--e3) var(--e2) var(--e1);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
}
.rail-grupo:first-of-type .rail-titulo { padding-top: 0; }

.rail-b {
  display: flex;
  align-items: center;
  gap: var(--e1);
  width: 100%;
  min-height: var(--toque-med);
  padding: 0 var(--e2);
  border-radius: var(--radio-chico);
  color: var(--tx-2);
  font-weight: 600;
  font-size: var(--t-chico);
  text-align: left;
  transition: background 0.1s, color 0.1s;
}
.rail-b:hover { background: var(--panel-2); color: var(--tx); }
.rail-b[aria-current="page"] { background: var(--acento); color: var(--acento-tx); }
.rail-b .pip {
  margin-left: auto;
  min-width: 20px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--alerta);
  color: #16100e;
  font-size: var(--t-micro);
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.rail-b[aria-current="page"] .pip { background: var(--acento-tx); color: var(--acento); }

/* ── Quién está operando ─────────────────────────────────────────────────
   Va abajo del rail y no en un chip perdido a la derecha de la barra. Es la
   única pista de por qué a Ana le faltan siete pestañas, y el botón para
   cambiar de usuario al terminar el turno. El punto de color repite el mismo
   código que usa el resto del POS: verde = puede tocar la plata. */
.rail-yo {
  display: flex;
  align-items: center;
  gap: var(--e2);
  width: 100%;
  min-height: var(--toque-med);
  margin-top: auto;
  padding: var(--e2);
  border-radius: var(--radio-chico);
  border: 1px solid var(--line);
  background: var(--bg-2);
  text-align: left;
}
.rail-yo:hover { border-color: var(--panel-3); background: var(--panel-2); }
.rail-yo .punto { flex: 0 0 auto; background: var(--azul); }
.rail-yo[data-rol="admin"] .punto { background: var(--acento); }
.rail-yo b { display: block; font-size: var(--t-chico); font-weight: 600; line-height: 1.2; }
.rail-yo small { display: block; font-size: 0.66rem; color: var(--muted); line-height: 1.3; }

.principal { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }

/* ── Barra de estado ─────────────────────────────────────────────────────
   Lo que queda arriba después de mudar la navegación: el aviso de demo a la
   izquierda y el estado del aparato a la derecha. 44 px, una sola línea. */
.barra {
  flex: 0 0 auto;
  min-height: var(--barra);
  display: flex;
  align-items: center;
  gap: var(--e4);
  padding: 0 var(--e4);
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
}
.barra-estado { display: flex; align-items: center; gap: var(--e3); margin-left: auto; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: var(--t-min);
  font-weight: 600;
  border: 1px solid var(--line);
  color: var(--tx-2);
  white-space: nowrap;
}
.chip.on { border-color: var(--acento-linea); color: var(--acento); }
.chip.off { border-color: var(--alerta-linea); color: var(--alerta); }
.chip.sin-red { border-color: var(--ojo-linea); color: var(--ojo); background: var(--ojo-tenue); }
.punto { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.reloj { font-variant-numeric: tabular-nums; color: var(--muted); font-size: var(--t-min); }

.vista { flex: 1; min-height: 0; overflow: hidden; display: flex; }
.vista.scroll { overflow-y: auto; display: block; }

/* ── Aviso de demo ───────────────────────────────────────────────────────
   Antes era una banda amarilla de ancho completo, con fondo teñido y borde
   propio, que en toda pantalla era lo segundo más llamativo después del botón
   de cobrar. Un aviso permanente que grita deja de leerse a los diez minutos y
   mientras tanto le compite a la operación. Ahora es una línea sobria dentro
   de la barra: se lee cuando se busca, no cuando se cobra. Lo que sí tiene que
   saltar —"no emite boleta"— está gritado donde corresponde, en Boletas. */
.aviso-demo {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-width: 0;
  font-size: var(--t-min);
  color: var(--muted);
}
.aviso-demo b { color: var(--ojo); font-weight: 700; }
.aviso-demo span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.aviso-demo button {
  flex: 0 0 auto;
  min-height: var(--toque-min);
  padding: 0 var(--e2);
  border: 1px solid var(--line);
  border-radius: var(--radio-chico);
  color: var(--tx-2);
  font-size: var(--t-min);
  font-weight: 600;
}
.aviso-demo button:hover { color: var(--tx); background: var(--panel-2); }

/* Solo aparece en la copia publicada en vercarta.cl/demo-pos (ver `enVerCarta()`
   en app.js). Va con el MISMO tratamiento que "Reiniciar" y no como un botón de
   color: es una salida, no una acción del POS, y competir con los controles de
   la caja sería exactamente al revés de lo que se quiere mostrar. */
.volver-vercarta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--toque-min);
  padding: 0 var(--e2);
  border: 1px solid var(--line);
  border-radius: var(--radio-chico);
  color: var(--tx-2);
  font-size: var(--t-min);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.volver-vercarta:hover { color: var(--tx); background: var(--panel-2); }

/* ══════════════════════════════════════════════════════════════════════════
   Vista · VENTA
   ══════════════════════════════════════════════════════════════════════════ */

.venta { display: flex; width: 100%; min-height: 0; }
.venta-carta { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* El buscador se separa de las categorías en vez de ir a la cola de ellas.
   Antes quedaba enganchado en el segundo renglón, entre "Para el final" y el
   borde, y parecía una categoría más con el texto borrado. */
.cats {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
  padding: var(--e2) var(--e4);
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.cats-lista { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: var(--e1); }
.cats-lista button {
  min-height: var(--toque-med);
  padding: 0 0.85rem;
  border-radius: var(--radio-chico);
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--tx-2);
  font-weight: 600;
  font-size: var(--t-chico);
  white-space: nowrap;
}
.cats-lista button:hover { background: var(--panel-2); color: var(--tx); }
.cats-lista button[aria-pressed="true"] {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--acento-tx);
}
.buscador {
  flex: 0 0 190px;
  min-height: var(--toque-med);
  padding: 0 0.7rem;
  border-radius: var(--radio-chico);
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--tx);
  font-size: var(--t-chico);
}
.buscador::placeholder { color: var(--muted); }

/* La lista scrollea; la grilla vive adentro. Estaban fundidos en un solo
   elemento y por eso no se podían intercalar encabezados de categoría. */
.lista-platos { flex: 1; overflow-y: auto; padding: 0 var(--e4) var(--e4); }

/* El encabezado de categoría se queda pegado arriba mientras se scrollea y
   lleva una línea que cruza todo el ancho. Las dos cosas hacen el mismo
   trabajo: cerrar la sección. Una fila incompleta —cinco platos en una grilla
   de cuatro— dejaba un hueco que se leía como grilla rota; con la línea se lee
   como "hasta acá llegan las pizzas", que es lo que es. */
.grupo {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--e3);
  padding: var(--e4) 0 var(--e2);
  background: var(--bg);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.grupo::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.platos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(144px, 1fr));
  gap: var(--e2);
  align-content: start;
}
.plato {
  min-height: 76px;
  padding: 0.6rem 0.65rem;
  border-radius: var(--radio);
  background: var(--panel);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: left;
  gap: var(--e2);
  transition: background 0.1s, border-color 0.1s;
}
.plato:hover { background: var(--panel-2); border-color: var(--panel-3); }
.plato:active { background: var(--acento); border-color: var(--acento); }
.plato:active .plato-n, .plato:active b { color: var(--acento-tx); }
/* El nombre manda y el precio acompaña. Estaba al revés: el precio era más
   grande, más pesado y verde, así que la vista saltaba de precio en precio
   cuando lo que se busca es el plato. */
.plato-n { font-size: var(--t-chico); font-weight: 600; line-height: 1.25; color: var(--tx); }
.plato b { font-size: var(--t-min); font-weight: 700; color: var(--acento); font-variant-numeric: tabular-nums; }
.plato:disabled { cursor: default; }
.plato.agotado { background: var(--bg-2); border-style: dashed; }
.plato.agotado .plato-n { color: var(--muted); }
.plato.agotado b { color: var(--muted); }
.plato.agotado::after {
  content: "Agotado";
  align-self: flex-start;
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
  background: var(--alerta-tenue);
  color: var(--alerta);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ── Panel de la cuenta ─────────────────────────────────────────────────── */

.cuenta {
  flex: 0 0 var(--cuenta);
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border-left: 1px solid var(--line);
}
.cuenta-cab { padding: var(--e3) var(--e4); border-bottom: 1px solid var(--line); }
.cuenta-tit { display: flex; align-items: center; justify-content: space-between; gap: var(--e2); }
.cuenta-tit h2 { font-size: var(--t-tit); }
.cuenta-meta { display: flex; gap: var(--e1); margin-top: var(--e2); flex-wrap: wrap; }
.cuenta-meta select, .cuenta-meta input {
  flex: 1;
  min-width: 90px;
  min-height: var(--toque-min);
  padding: 0 0.45rem;
  border-radius: var(--radio-chico);
  background: var(--panel);
  border: 1px solid var(--line);
  font-size: var(--t-min);
}

.lineas { flex: 1; overflow-y: auto; padding: var(--e2); }
.linea {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--e1) var(--e2);
  padding: var(--e2) var(--e1);
  border-bottom: 1px solid var(--line-soft);
}
.linea-n { font-size: var(--t-chico); font-weight: 500; }
.linea-p { font-variant-numeric: tabular-nums; font-size: var(--t-chico); text-align: right; }
.linea-ctl { display: flex; align-items: center; gap: var(--e1); grid-column: 1 / -1; margin-top: var(--e1); }
/* 40 px y no 30: son los dos botones que más se aprietan en todo el turno. */
.linea-ctl button {
  width: 40px;
  height: 40px;
  border-radius: var(--radio-chico);
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--tx-2);
  font-weight: 700;
  font-size: var(--t-med);
  line-height: 1;
}
.linea-ctl button:hover { background: var(--panel-2); color: var(--tx); }
.linea-ctl .cant {
  min-width: 30px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: var(--t-base);
}
.linea-ctl .quitar {
  width: auto;
  height: 40px;
  margin-left: auto;
  padding: 0 0.6rem;
  border-color: transparent;
  color: var(--muted);
  font-size: var(--t-min);
  font-weight: 600;
}
.linea-ctl .quitar + .quitar { margin-left: 0; }
.linea-ctl .quitar:hover { color: var(--alerta); background: var(--alerta-tenue); }

.cuenta-vacia { padding: var(--e5) var(--e4); text-align: center; color: var(--muted); font-size: var(--t-chico); }

/* ── Sin venta abierta ───────────────────────────────────────────────────
   Eran 380 px de alto completo con dos renglones de texto pegados arriba: un
   tercio de la pantalla en blanco, en la vista donde el POS pasa la mitad del
   día. No se puede llenar con datos que no existen, pero sí se puede dejar de
   parecer un panel que no cargó: la ayuda va centrada, con las dos entradas
   reales al trabajo separadas y la de Mesas convertida en un botón de verdad. */
.cuenta-nada {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e3);
  padding: var(--e5) var(--e5) 15vh;
  text-align: center;
}
.cuenta-nada h3 { font-size: var(--t-med); color: var(--tx-2); font-weight: 600; }
.cuenta-nada p { font-size: var(--t-chico); color: var(--muted); max-width: 24ch; line-height: 1.5; }
.cuenta-nada .o {
  display: flex;
  align-items: center;
  gap: var(--e3);
  width: 100%;
  max-width: 200px;
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.cuenta-nada .o::before, .cuenta-nada .o::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.cuenta-pie {
  flex: 0 0 auto;
  padding: var(--e3) var(--e4) var(--e4);
  border-top: 1px solid var(--line);
  background: var(--panel);
}
.tot-fila { display: flex; justify-content: space-between; gap: var(--e3); font-size: var(--t-chico); color: var(--tx-2); padding: 0.1rem 0; }
.tot-fila.grande {
  font-size: var(--t-cifra);
  font-weight: 700;
  color: var(--tx);
  padding-top: var(--e2);
  margin-top: var(--e1);
  border-top: 1px solid var(--line-soft);
  align-items: baseline;
  letter-spacing: -0.02em;
}
.tot-fila.grande span:first-child { font-size: var(--t-chico); font-weight: 600; color: var(--tx-2); letter-spacing: 0; }
.tot-fila .num { font-variant-numeric: tabular-nums; }
.acciones { display: flex; gap: var(--e2); margin-top: var(--e3); }

/* ── Botones ─────────────────────────────────────────────────────────────
   Tres tamaños, uno por escalón de toque. `.btn-chico` dejó de medir 30 px:
   ese es el botón de "Aceptar" un pedido de delivery y el de "Anular" una
   venta, y los dos se aprietan con el dedo. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: var(--toque-med);
  padding: 0.5rem 0.9rem;
  border-radius: 9px;
  font-weight: 700;
  font-size: var(--t-base);
  line-height: 1.25;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--tx);
  text-align: center;
  transition: background 0.12s, border-color 0.12s;
}
.btn:hover { background: var(--panel-3); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn:disabled:hover { background: var(--panel-2); }
.btn-primario { background: var(--acento); border-color: var(--acento); color: var(--acento-tx); }
.btn-primario:hover { background: var(--acento-2); border-color: var(--acento-2); }
.btn-primario:disabled:hover { background: var(--acento); }
.btn-peligro { color: var(--alerta); }
/* Dentro de una tabla el rojo se guarda para el momento de apretar. Treinta y
   tres "Sacar" rojos en fila dejan de ser una advertencia y pasan a ser el
   color de fondo de la columna. */
.tabla .btn-peligro { color: var(--tx-2); }
.tabla .btn-peligro:hover, .tabla .btn-peligro:focus-visible { color: var(--alerta); }
.btn-peligro:hover { background: var(--alerta-tenue); border-color: var(--alerta-linea); }
.btn-grande { flex: 1; min-height: var(--toque); padding: 0.6rem 0.5rem; }
.btn-chico { min-height: var(--toque-min); padding: 0.3rem 0.7rem; font-size: var(--t-min); font-weight: 600; }
/* Los botones que avanzan un pedido en la bandeja se aprietan de pie: suben
   un escalón aunque compartan la clase con los de una tabla de reportes. */
.pedido-pie .btn { min-height: var(--toque-med); padding: 0.4rem 0.9rem; font-size: var(--t-chico); }

/* ══════════════════════════════════════════════════════════════════════════
   Vista · MESAS
   ══════════════════════════════════════════════════════════════════════════ */

.salon { padding: var(--e4) var(--e5); width: 100%; overflow-y: auto; }
.salon h2 { font-size: var(--t-tit-2); }
.salon-sub { color: var(--muted); font-size: var(--t-chico); margin: 0.15rem 0 var(--e4); }
.mesas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(144px, 1fr));
  gap: var(--e3);
}
/* Las mesas se miran de lejos y se tocan de paso: el número tiene que leerse
   cruzando el salón, no de cerca. */
.mesa {
  min-height: 148px;
  padding: var(--e3);
  border-radius: var(--radio);
  text-align: left;
  background: var(--panel);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  transition: background 0.1s, border-color 0.1s;
}
.mesa:hover { border-color: var(--panel-3); background: var(--panel-2); }
.mesa-n { font-size: 1.75rem; font-weight: 700; line-height: 1; letter-spacing: -0.02em; }
.mesa-sillas { font-size: var(--t-min); color: var(--muted); margin-top: var(--e1); }
.mesa-info { font-size: var(--t-min); color: var(--tx-2); }
.mesa-total {
  margin-top: auto;
  padding-top: var(--e2);
  font-size: var(--t-tit);
  font-weight: 700;
  color: var(--acento);
  font-variant-numeric: tabular-nums;
}
.mesa.ocupada { border-color: var(--acento-linea); background: rgba(32, 205, 151, 0.07); }
/* La mesa libre no es un estado de alerta ni de éxito: es una superficie vacía
   esperando. Se dibuja hueca —fondo del lienzo y borde punteado— y así el
   salón se lee de un vistazo por relleno, sin tener que leer una palabra. */
.mesa.libre { background: transparent; border-style: dashed; border-color: var(--line); }
.mesa.libre:hover { background: var(--panel); border-style: solid; }
.mesa.libre .mesa-n { color: var(--tx-2); }
.mesa.libre .mesa-total {
  color: var(--muted);
  font-weight: 600;
  font-size: var(--t-min);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ══════════════════════════════════════════════════════════════════════════
   Vista · DELIVERY
   ══════════════════════════════════════════════════════════════════════════ */

.delivery { display: flex; width: 100%; min-height: 0; }
.bandeja { flex: 1; min-width: 0; overflow-y: auto; padding: var(--e4) var(--e5); }
.conexiones {
  flex: 0 0 var(--cuenta);
  overflow-y: auto;
  padding: var(--e4);
  background: var(--bg-2);
  border-left: 1px solid var(--line);
}

.cab-seccion { display: flex; align-items: center; justify-content: space-between; gap: var(--e4); margin-bottom: var(--e3); }
.cab-seccion h2 { font-size: var(--t-tit-2); }
.cab-seccion h3 { font-size: var(--t-med); }
.cab-seccion .sub { margin: 0.1rem 0 0; }
.sub-seccion {
  margin: var(--e5) 0 var(--e3);
  font-size: var(--t-min);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ── Tarjeta de pedido ───────────────────────────────────────────────────
   El estado venía codificado SOLO en el color de un filete de 4 px a la
   izquierda —ámbar, azul, verde— y en cuál botón aparecía. Quien no distingue
   esos tres colores, o quien mira la bandeja de reojo, tenía que deducir el
   estado del verbo del botón. Ahora el estado está escrito con todas sus
   letras arriba, y el color acompaña en vez de cargar solo. */
.pedido {
  padding: var(--e3) var(--e4);
  border-radius: var(--radio);
  background: var(--panel);
  border: 1px solid var(--line);
  margin-bottom: var(--e2);
}
.pedido.nuevo { border-color: var(--alerta-linea); background: rgba(240, 120, 94, 0.06); }
.pedido.despachado, .pedido.rechazado { opacity: 0.55; }
.pedido-cab { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }
.pedido-app {
  padding: 0.18rem 0.5rem;
  border-radius: 5px;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--c, var(--muted)) 15%, transparent);
  color: var(--c, var(--muted));
}
.pedido-ref { font-weight: 700; font-variant-numeric: tabular-nums; }
.pedido-hora { margin-left: auto; font-size: var(--t-min); color: var(--muted); font-variant-numeric: tabular-nums; }
.pedido-estado {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--tx-2);
}
.pedido-estado::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pedido.nuevo .pedido-estado { border-color: var(--alerta-linea); color: var(--alerta); }
.pedido.aceptado .pedido-estado { border-color: var(--ojo-linea); color: var(--ojo); }
.pedido.cocina .pedido-estado { border-color: var(--azul-linea); color: var(--azul); }
.pedido.listo .pedido-estado { border-color: var(--acento-linea); color: var(--acento); }

.pedido-lineas { margin: var(--e2) 0; font-size: var(--t-chico); color: var(--tx-2); }
.pedido-lineas li { list-style: none; display: flex; justify-content: space-between; gap: var(--e4); padding: 0.1rem 0; }
.pedido-pie { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; padding-top: var(--e2); border-top: 1px solid var(--line-soft); }
/* "Te quedan" es la tesis entera del producto —el número que la app no te
   muestra—, así que se pinta con el color de la plata que entra en vez de ir
   en gris de nota al pie. */
.pedido-total { font-weight: 700; font-size: var(--t-base); font-variant-numeric: tabular-nums; margin-right: auto; }
.pedido-total .queda { color: var(--acento); font-weight: 600; font-size: var(--t-min); }

.tarjeta {
  padding: var(--e3) var(--e4);
  border-radius: var(--radio);
  background: var(--panel);
  border: 1px solid var(--line);
  margin-bottom: var(--e3);
}
.tarjeta h3 { font-size: var(--t-base); display: flex; align-items: center; gap: var(--e2); }
.tarjeta p { font-size: var(--t-min); color: var(--tx-2); margin-top: var(--e2); }
.tarjeta ul { margin: var(--e2) 0 0 var(--e4); font-size: var(--t-micro); color: var(--muted); }
.tarjeta li { margin-bottom: 0.15rem; }
.estado-conexion {
  margin-left: auto;
  font-size: var(--t-micro);
  font-weight: 700;
  padding: 0.15rem 0.5rem;
  border-radius: 5px;
  background: var(--alerta-tenue);
  color: var(--alerta);
  white-space: nowrap;
}
/* En la tarjeta de una app manda lo que se OPERA (la comisión y los dos
   botones); el listado de lo que pide la API es documentación y se lee una vez
   en la vida. Baja de tamaño y se separa con una línea, en vez de ocupar el
   centro de una pantalla de servicio. */
.tarjeta-app .requisitos {
  margin-top: var(--e3);
  padding-top: var(--e2);
  border-top: 1px solid var(--line-soft);
}
.tarjeta-app .requisitos p { margin-top: 0; font-size: var(--t-micro); color: var(--muted); }
.campo-comision {
  display: flex;
  align-items: center;
  gap: var(--e2);
  margin-top: var(--e3);
  font-size: var(--t-min);
  color: var(--tx-2);
}
.campo-comision label { flex: 1; }
.campo-comision input {
  width: 74px;
  min-height: var(--toque-min);
  padding: 0 0.5rem;
  border-radius: var(--radio-chico);
  background: var(--bg-2);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.acciones-app { display: flex; gap: var(--e2); margin-top: var(--e2); }
.acciones-app .btn { flex: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   Vista · REPORTES
   ══════════════════════════════════════════════════════════════════════════ */

.reportes { padding: var(--e4) var(--e5) var(--e6); }
.rep-cab { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--e4); flex-wrap: wrap; margin-bottom: var(--e4); }
.rep-cab h2 { font-size: var(--t-tit-2); }
.rep-cab p { color: var(--muted); font-size: var(--t-chico); }
.periodos { display: flex; gap: var(--e1); flex-wrap: wrap; }
.periodos button {
  min-height: var(--toque-med);
  padding: 0 0.85rem;
  border-radius: var(--radio-chico);
  font-size: var(--t-chico);
  font-weight: 600;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--tx-2);
}
.periodos button:hover { background: var(--panel-2); color: var(--tx); }
.periodos button[aria-pressed="true"] { background: var(--acento); border-color: var(--acento); color: var(--acento-tx); }
/* Exportar no filtra nada: es una acción y no puede parecer un rango más. */
.periodos .exportar { margin-left: var(--e3); background: transparent; color: var(--tx-2); }
.periodos .exportar:hover { background: var(--panel); color: var(--tx); }

/* ── Los indicadores, en dos pesos ───────────────────────────────────────
   Eran ocho tarjetas idénticas en una grilla que dejaba dos huérfanas en la
   segunda fila. Ocho números del mismo tamaño no tienen jerarquía: obligan a
   leerlos todos para descubrir cuál importaba. Ahora hay dos alturas.

   Arriba, los dos que explican el negocio: cuánto se vendió y cuánto de eso
   quedó después de la comisión de las apps. Es la pregunta que trae al dueño a
   esta pantalla.

   Abajo, los otros seis en una regleta de celdas iguales separadas por
   hairlines, no en tarjetas sueltas. La regleta se reparte el ancho exacto, así
   que no puede quedar huérfana ninguna, y se lee como un instrumento en vez de
   como seis avisos. */
.kpis-cab {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--e3);
  margin-bottom: var(--e3);
}
.kpi-hero {
  padding: var(--e4) var(--e5);
  border-radius: var(--radio);
  background: var(--panel);
  border: 1px solid var(--line);
}
.kpi-hero .kpi-t { font-size: var(--t-min); }
.kpi-hero .kpi-v { font-size: var(--t-cifra-2); line-height: 1.05; margin-top: var(--e2); }
.kpi-hero .kpi-p { font-size: var(--t-chico); margin-top: var(--e2); }
.kpi-hero.destacado {
  background: linear-gradient(160deg, rgba(32, 205, 151, 0.12), var(--panel) 60%);
  border-color: var(--acento-linea);
}
.kpi-hero.destacado .kpi-v { color: var(--acento); }

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  border-radius: var(--radio);
  background: var(--panel);
  border: 1px solid var(--line);
  overflow: hidden;
  margin-bottom: var(--e4);
}
.kpi {
  padding: var(--e3) var(--e4);
  border-left: 1px solid var(--line);
  min-width: 0;
}
.kpi:first-child { border-left: none; }
.kpi.destacado { background: var(--acento-tenue); }
.kpi.destacado .kpi-v { color: var(--acento); }
.kpi-t { font-size: var(--t-micro); font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted); }
.kpi-v { font-size: var(--t-cifra); font-weight: 700; font-variant-numeric: tabular-nums; margin-top: var(--e1); letter-spacing: -0.02em; line-height: 1.15; }
.kpi-p { font-size: var(--t-min); color: var(--tx-2); margin-top: 0.1rem; }
.kpi-d { font-size: var(--t-min); font-weight: 700; font-variant-numeric: tabular-nums; }
.kpi-d.sube { color: var(--ok); }
.kpi-d.baja { color: var(--alerta); }

/* align-items: start · sin esto los paneles de una fila se estiran al más alto,
   y la "Curva del día" quedaba con medio panel vacío debajo del gráfico. */
.rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(370px, 1fr));
  gap: var(--e3);
  margin-bottom: var(--e3);
  align-items: start;
}
.panel { padding: var(--e4); border-radius: var(--radio); background: var(--panel); border: 1px solid var(--line); min-width: 0; }
.panel h3 { font-size: var(--t-base); }
.panel .sub { font-size: var(--t-min); color: var(--muted); margin: 0.1rem 0 var(--e3); }
.panel.ancho { grid-column: 1 / -1; }

.grafico { width: 100%; height: auto; display: block; overflow: visible; }
.grafico .barra-g { fill: var(--acento); }
.grafico .barra-g.tenue { fill: var(--panel-3); }
.grafico .eje { stroke: var(--line); stroke-width: 1; }
.grafico .prom { stroke: var(--ojo); stroke-width: 1.5; stroke-dasharray: 5 4; }
.grafico text { fill: var(--muted); font-size: 10px; font-family: inherit; }
.grafico text.valor { fill: var(--tx-2); font-size: 10px; }

/* ── Tablas ──────────────────────────────────────────────────────────────
   Densidad alta: acá se mira, no se toca. El encabezado se queda pegado al
   scrollear —la carta tiene 33 filas y en la fila 20 ya nadie se acuerda de
   cuál columna era el costo y cuál el margen. */
.tabla { font-size: var(--t-chico); }
.tabla th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--panel);
  padding: var(--e2) var(--e2);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.tabla td { padding: 0.42rem var(--e2); border-bottom: 1px solid var(--line-soft); }
.tabla tbody tr:hover td { background: rgba(232, 238, 240, 0.03); }
.tabla tr:last-child td { border-bottom: none; }
.tabla .n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla .bien { color: var(--ok); }
.tabla .mal { color: var(--alerta); }
/* width + max-width:0 es el truco para que una celda de tabla respete el
   ellipsis: sin el width la columna se encoge al mínimo y corta a la tercera letra. */
.tabla .nombre { width: 45%; max-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Una tabla de cuatro columnas cortas estirada a 1.200 px deja medio metro de
   nada entre el nombre y el PIN, y hay que seguir la fila con el dedo en la
   pantalla. Estas se dejan hugging su contenido en vez de ocupar todo. */
.tabla-ajustada { width: auto; min-width: min(540px, 100%); }
.carta-editor .tabla .nombre { width: 26%; }
/* El formulario de alta se alinea con la tabla que completa, en vez de cruzar
   el panel entero mientras la tabla mide la mitad. */
.tabla-ajustada ~ .fila-form { max-width: min(540px, 100%); }
.fila-cat td {
  padding-top: var(--e4);
  font-weight: 700;
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.tabla-nota { font-size: var(--t-min); color: var(--muted); margin-top: var(--e3); }

.barra-share { height: 6px; border-radius: 4px; background: var(--panel-3); overflow: hidden; margin-top: var(--e1); }
.barra-share i { display: block; height: 100%; border-radius: 4px; background: var(--acento); }
.tabla .cel-share { display: block; font-size: var(--t-micro); color: var(--muted); }

/* ── Las lecturas ────────────────────────────────────────────────────────
   Llevaban un filete de color de 4 px a la izquierda, en once tarjetas
   seguidas: el tell más reconocible de una interfaz generada, y además
   codificaba la urgencia SOLO con color. El tono ahora va en un punto al lado
   del título, que es más chico, se lee igual y deja la tarjeta limpia. */
.lecturas { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--e3); }
.lectura { padding: var(--e3) var(--e4); border-radius: var(--radio); background: var(--panel); border: 1px solid var(--line); }
.lectura h4 { display: flex; align-items: baseline; gap: var(--e2); font-size: var(--t-base); margin-bottom: var(--e1); }
.lectura h4::before {
  content: "";
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
  transform: translateY(-1px);
}
.lectura.ok h4::before { background: var(--ok); }
.lectura.ojo h4::before { background: var(--ojo); }
.lectura.alerta h4::before { background: var(--alerta); }
.lectura.alerta { border-color: var(--alerta-linea); }
.lectura p { font-size: var(--t-min); color: var(--tx-2); line-height: 1.5; }

/* ══════════════════════════════════════════════════════════════════════════
   Vistas · CAJA, BOLETAS, CARTA y NEGOCIO
   ══════════════════════════════════════════════════════════════════════════ */

.hoja { padding: var(--e4) var(--e5) var(--e6); width: 100%; overflow-y: auto; }
/* 760 px dejaba la tabla de ventas del turno —siete columnas— apretada en el
   centro de una pantalla de 1.280, con 260 px de negro a cada lado. */
.hoja-centro { max-width: 1040px; margin: 0 auto; }
.hoja h2 { font-size: var(--t-tit-2); }
.hoja > .sub, .hoja-centro > .sub { color: var(--muted); font-size: var(--t-chico); margin: 0.15rem 0 var(--e5); max-width: 78ch; }

.campo { display: block; margin-bottom: var(--e3); }
.campo span { display: block; font-size: var(--t-min); font-weight: 600; color: var(--tx-2); margin-bottom: var(--e1); }
.campo input, .campo select {
  width: 100%;
  min-height: var(--toque-med);
  padding: 0 0.7rem;
  border-radius: 9px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  font-size: var(--t-med);
  font-variant-numeric: tabular-nums;
}
/* Un campo de cinco dígitos no necesita 1.000 px de ancho. */
.campo.corto { max-width: 15rem; }
.campo.medio { max-width: 24rem; }

/* Los dos botones de la bandeja de pedidos: el de WhatsApp y el de las apps. */
.acciones-bandeja { display: flex; gap: var(--e2); flex-wrap: wrap; }

/* El verde de WhatsApp, que es la señal que se reconoce sin leer. No se cambia
   por el acento del POS: es el canal que el dueño quiere distinguir de un
   vistazo entre las tres apps, porque es el único que no le cobra comisión. */
.btn-wsp {
  background: #25d366;
  border-color: #25d366;
  color: #06301b;
  font-weight: 700;
}
.btn-wsp:hover { background: #1fbb59; border-color: #1fbb59; }

/* Los dos campos del despacho, uno al lado del otro: los kilómetros y lo que se
   cobra. Van juntos porque el segundo sale del primero. */
.wsp-despacho { display: flex; gap: var(--e3); flex-wrap: wrap; }
.wsp-despacho .campo { margin-bottom: var(--e2); }

/* Campo numérico que se ESCRIBE, no que se elige (28-08-2026: reemplazó la fila
   de botones rápidos al abrir una mesa). El ancho va sobre el input y no sobre
   el `.campo`, porque acotar la etiqueta partiría "¿Cuántas personas se
   sentaron?" en cuatro líneas. Selector de dos clases para ganarle al
   `width: 100%` de `.campo input`, que es más específico que una clase sola.
   ⚠️ Se le quitan las flechitas del `type=number`: en una tablet no se pueden
   tocar, y en escritorio invitan a subir de a uno — justo el gesto que se
   eliminó al sacar los botones. */
.campo input.campo-numero {
  width: 8rem;
  font-weight: 600;
  -moz-appearance: textfield;
  appearance: textfield;
}
.campo input.campo-numero::-webkit-outer-spin-button,
.campo input.campo-numero::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* El aviso bajo el campo. Reserva su alto para que el modal no dé un salto
   cuando el texto aparece y desaparece mientras alguien escribe. */
.campo-aviso {
  min-height: 1.15em;
  margin: calc(var(--e2) * -1) 0 var(--e3);
  font-size: var(--t-min);
  color: var(--tx-2);
}

.arqueo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e3); margin: var(--e4) 0; }
.arqueo div { padding: var(--e3); border-radius: var(--radio); background: var(--bg-2); border: 1px solid var(--line); }
.arqueo dt { font-size: var(--t-micro); color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
.arqueo dd { font-size: var(--t-tit-2); font-weight: 700; font-variant-numeric: tabular-nums; margin-top: var(--e1); }
.arqueo .cuadra { color: var(--ok); }
.arqueo .falta { color: var(--alerta); }

/* min-width y no solo width:100%: con la tabla en `auto`, un input elástico
   aporta cero al ancho mínimo de su columna y la columna se encoge hasta que
   el número queda cortado en dos dígitos.

   El :not() excluye la casilla de disponibilidad, que también es un `input`
   dentro de un `td` de esta tabla: sin la exclusión heredaba estos 86 px de
   ancho y 36 de alto, y las 33 casillas se convertían en la franja verde que
   la regla de más abajo dice estar apagando. El blanco de toque lo pone la
   etiqueta `.interruptor`, no la casilla. */
.carta-editor td input:not([type="checkbox"]) {
  width: 100%;
  min-width: 86px;
  max-width: 108px;
  min-height: var(--toque-min);
  padding: 0 0.45rem;
  border-radius: 6px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  text-align: right;
  font-size: var(--t-chico);
}
/* El interruptor de disponibilidad medía 17 px: por debajo del mínimo de 24 y
   sin ninguna chance de acertarle con el dedo. Ahora la etiqueta entera es el
   blanco, con 36 px de alto. */
.interruptor {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  gap: var(--e2);
  min-height: var(--toque-min);
  padding: 0 var(--e2) 0 var(--e1);
  border-radius: var(--radio-chico);
  font-size: var(--t-min);
  cursor: pointer;
}
.interruptor:hover { background: var(--panel-2); }
/* Verde apagado y no el de marca: en la carta hay 33 filas y "está en carta"
   es el estado normal de todas. Con el acento a full la columna se convertía
   en una franja verde que le robaba la vista al food cost, que es para lo que
   se abre esta pantalla. Lo que tiene que gritar es la excepción. */
.interruptor input {
  width: 18px; height: 18px; margin: 0;
  accent-color: var(--acento-2); cursor: pointer;
}
.interruptor span { color: var(--muted); }
.interruptor input:not(:checked) + span { color: var(--alerta); font-weight: 700; }

.titulo-seccion { font-size: var(--t-tit); margin: var(--e6) 0 var(--e3); }
.fila-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
  margin-top: var(--e3);
  padding-top: var(--e3);
  border-top: 1px solid var(--line);
}
.fila-form input, .fila-form select {
  flex: 1 1 130px;
  min-width: 110px;
  min-height: var(--toque-min);
  padding: 0 0.6rem;
  border-radius: var(--radio-chico);
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--tx);
  font-size: var(--t-chico);
}
.fila-form .btn { flex: 0 0 auto; }
.pin-input {
  width: 78px;
  min-height: var(--toque-min);
  padding: 0 0.45rem;
  border-radius: 6px;
  text-align: right;
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--tx);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-chico);
}
.tabla select {
  min-height: var(--toque-min);
  padding: 0 0.4rem;
  border-radius: 6px;
  font-size: var(--t-min);
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--tx);
}
.panel code {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 0.05rem 0.35rem;
  font-size: 0.92em;
}
.area {
  width: 100%;
  padding: 0.7rem;
  border-radius: 9px;
  resize: vertical;
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--tx);
  font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: var(--t-chico);
  line-height: 1.5;
}
/* El input de archivo va oculto y se opera desde su <label>, que sí se puede
   estilar como botón. `display:none` lo sacaría del árbol de accesibilidad. */
label.btn { display: inline-flex; align-items: center; justify-content: center; }

/* ── Ritmo vertical y tonos ──────────────────────────────────────────────
   Estas clases reemplazan 31 atributos `style=""` que había repartidos por el
   marcado. No es purismo: la CSP de producción de Aurai descarta los estilos
   en línea, así que el día que esto se publique los márgenes y los colores de
   aviso desaparecerían de golpe — y en localhost, sin cabeceras, no se nota.
   De paso, los saltos vuelven a la escala: eran 1.4rem, .7rem, .9rem, .6rem y
   .5rem elegidos de a uno. */
.hoja > .panel,
.hoja-centro > .panel { margin-bottom: var(--e4); }
.sub.mt { margin-top: var(--e3); margin-bottom: 0; }
.campo.rotulo { display: block; margin: var(--e3) 0 var(--e1); }
.campo.mt { margin-top: var(--e2); }
.interruptor.mb { margin-bottom: var(--e1); }
.acciones.envuelve { flex-wrap: wrap; }
.tit-bloque { font-size: var(--t-base); margin: var(--e4) 0 var(--e2); }
.nota-cel { display: inline-block; font-size: var(--t-micro); color: var(--muted); }
.tabla td.nota-cel { display: table-cell; }

.aviso-ojo { border-color: var(--ojo-linea); background: var(--ojo-tenue); }
.aviso-ojo p, .aviso-ojo h3 { color: var(--ojo); }
.panel.tono-alerta { border-color: var(--alerta-linea); }
.panel.tono-alerta > h3 { color: var(--alerta); }
.panel.tono-ojo { border-color: var(--ojo-linea); }
.panel.tono-ojo > h3 { color: var(--ojo); }

/* ══════════════════════════════════════════════════════════════════════════
   Modales
   ══════════════════════════════════════════════════════════════════════════ */

.velo {
  position: fixed;
  inset: 0;
  background: rgba(6, 9, 10, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e4);
  z-index: 100;
}
.modal {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  width: min(560px, 100%);
  max-height: 90dvh;
  overflow-y: auto;
  /* Sin padding abajo: lo pone el pie, que es sticky y tiene que poder tapar
     el borde inferior del modal cuando el contenido lo desborda. Los diez
     modales del POS llevan pie, así que no queda ninguno sin cerrar. */
  padding: var(--e5) var(--e5) 0;
  /* Dos sombras apiladas: una corta y densa que asienta el borde, otra larga y
     difusa que separa del fondo. Una sola sombra pesada se ve como un sticker. */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45), 0 24px 64px rgba(0, 0, 0, 0.55);
}
.modal.ancho { width: min(820px, 100%); }
.modal-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--e4); margin-bottom: var(--e4); }
.modal-cab h2 { font-size: var(--t-tit); }
.modal-cab p { font-size: var(--t-min); color: var(--muted); margin-top: var(--e1); }
.modal-cab button {
  flex: 0 0 auto;
  width: var(--toque-min);
  height: var(--toque-min);
  border-radius: var(--radio-chico);
  font-size: 1.4rem;
  line-height: 1;
  color: var(--muted);
}
.modal-cab button:hover { color: var(--tx); background: var(--panel-2); }
/* El pie se queda pegado abajo del modal. En una pantalla de 800 px el modal
   de cobro no cabe entero —descuento, propina, cinco medios de pago— y "Cobrar"
   quedaba abajo de todo, fuera de la vista: había que scrollear dentro del
   modal, con el cliente esperando, para encontrar el botón que cierra la venta. */
.modal-pie {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: var(--e2);
  margin-top: var(--e5);
  padding: var(--e3) 0 var(--e5);
  background: linear-gradient(to bottom, transparent, var(--panel) 30%);
}
.modal-pie .btn { flex: 1; min-height: var(--toque); }

/* Los medios de pago y las propinas se aprietan de pie, con el cliente
   esperando el vuelto: van al escalón grande. */
.pagos-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--e2); }
.pagos-grid button {
  min-height: var(--toque);
  padding: 0.5rem;
  border-radius: 9px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  font-weight: 600;
  font-size: var(--t-chico);
}
.pagos-grid button:hover { background: var(--panel-3); }
.pagos-grid button[aria-pressed="true"] { border-color: var(--acento); background: var(--acento-tenue); color: var(--acento); }

.pago-lista { margin: var(--e3) 0; }
.pago-fila { display: flex; align-items: center; gap: var(--e2); padding: 0.2rem 0; font-size: var(--t-chico); }
.pago-fila .num { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
.pago-fila button { min-height: var(--toque-min); padding: 0 var(--e2); border-radius: var(--radio-chico); color: var(--muted); font-size: var(--t-min); }
.pago-fila button:hover { color: var(--alerta); background: var(--alerta-tenue); }

.propinas { display: flex; gap: var(--e1); flex-wrap: wrap; }
.propinas button {
  flex: 1;
  min-width: 66px;
  min-height: var(--toque-med);
  padding: 0.4rem;
  border-radius: var(--radio-chico);
  background: var(--panel-2);
  border: 1px solid var(--line);
  font-weight: 600;
  font-size: var(--t-chico);
}
.propinas button:hover { background: var(--panel-3); }
.propinas button[aria-pressed="true"] { border-color: var(--acento); background: var(--acento-tenue); color: var(--acento); }

.resta { padding: var(--e2) var(--e3); border-radius: 9px; background: var(--bg-2); border: 1px solid var(--line); margin-top: var(--e2); font-size: var(--t-chico); }
.resta.listo { border-color: var(--acento-linea); color: var(--acento); }
.resta.falta { border-color: var(--alerta-linea); color: var(--alerta); }

/* ── Ticket ─────────────────────────────────────────────────────────────── */
.ticket {
  background: #f4f1ea;
  color: #16110c;
  border-radius: 6px;
  padding: var(--e4);
  font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: var(--t-chico);
  line-height: 1.55;
}
.ticket h3 { text-align: center; font-size: var(--t-med); letter-spacing: 0.05em; }
.ticket .centro { text-align: center; }
.ticket hr { border: none; border-top: 1px dashed #b9b0a0; margin: var(--e2) 0; }
.ticket .fila { display: flex; justify-content: space-between; gap: var(--e4); }
.ticket .fila b { font-variant-numeric: tabular-nums; }
.ticket .grande { font-size: var(--t-med); font-weight: 700; }
.ticket .nota { margin-top: var(--e3); font-size: var(--t-micro); text-align: center; color: #5d5346; }
.ticket .nota-linea span { font-size: 0.92em; padding-left: 0.6rem; }

/* ══════════════════════════════════════════════════════════════════════════
   Detalles de la comanda
   ══════════════════════════════════════════════════════════════════════════ */

/* Ventas anuladas · se atenúan pero NO se ocultan: la lista de anulaciones es
   justamente lo que el dueño quiere mirar. Tachar el folio y el monto deja
   claro que no cuenta, sin sacar la fila de la vista. */
.tabla tr.fila-anulada td { opacity: 0.55; }
.tabla tr.fila-anulada td:first-child,
.tabla tr.fila-anulada td.n { text-decoration: line-through; }
.tabla tr.fila-anulada td:last-child { text-decoration: none; opacity: 1; }
.marca-anulada {
  display: inline-block;
  margin-left: var(--e1);
  padding: 0.05rem 0.4rem;
  border-radius: 4px;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--alerta-tenue);
  color: var(--alerta);
  text-decoration: none;
}
/* La celda de acciones lleva dos botones y no debe partirse en dos líneas. */
.tabla td:last-child { white-space: nowrap; }
.tabla td:last-child .btn + .btn { margin-left: var(--e1); }

/* Notas de cocina · se pinta en ámbar y bajo el plato, no al costado: en una
   comanda de veinte líneas la excepción tiene que saltar a la vista sin
   obligar a leer todo. */
.linea-nota { grid-column: 1 / -1; font-size: var(--t-min); color: var(--ojo); line-height: 1.3; }

/* Lo que ya está en cocina · atenuado, no oculto: el garzón tiene que ver la
   mesa completa para saber qué está esperando, y a la vez distinguir de un
   vistazo lo que todavía no mandó. */
.linea.enviada .linea-n,
.linea.enviada .linea-p { opacity: 0.6; }
.marca-cocina {
  display: inline-block;
  margin-left: var(--e1);
  padding: 0.05rem 0.38rem;
  border-radius: 4px;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: var(--azul-tenue);
  color: var(--azul);
}
/* Ancho completo y separado de los otros dos botones: mandar a cocina no es lo
   mismo que cobrar, y confundirlos a las 21:30 manda una mesa sin comer. */
.btn-cocina {
  display: flex;
  width: 100%;
  margin-top: var(--e3);
  background: var(--azul-tenue);
  border-color: var(--azul-linea);
  color: var(--azul);
  min-height: var(--toque);
}
.btn-cocina:hover { background: rgba(120, 169, 224, 0.24); }

/* Datos del cliente en la cuenta */
.cuenta-cliente {
  margin-top: var(--e2);
  padding: var(--e2);
  border-radius: var(--radio-chico);
  background: var(--panel);
  border: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: baseline;
  font-size: var(--t-min);
}
.cuenta-cliente span { color: var(--tx-2); }
.cuenta-cliente i { flex-basis: 100%; color: var(--ojo); font-style: normal; }

/* ── Cuentas separadas ─────────────────────────────────────────────────── */
.parte {
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--acento);
  background: var(--acento-tenue);
  padding: 0.1rem 0.45rem;
  border-radius: 5px;
  vertical-align: middle;
}
.personas-ctl { display: flex; align-items: center; gap: var(--e2); margin-bottom: var(--e4); font-size: var(--t-chico); }
.personas-ctl b { font-size: var(--t-tit-2); min-width: 1.6rem; text-align: center; font-variant-numeric: tabular-nums; }
.personas-ctl > button:not(.btn) {
  width: var(--toque-med);
  height: var(--toque-med);
  border-radius: var(--radio-chico);
  font-size: var(--t-tit);
  font-weight: 700;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--tx);
}
.personas-ctl > button:not(.btn):disabled { opacity: 0.3; cursor: not-allowed; }

.unidades {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--e1);
  max-height: 46dvh;
  overflow-y: auto;
  padding-right: var(--e1);
}
.unidad {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--toque-med);
  text-align: left;
  padding: var(--e2);
  border-radius: 9px;
  background: var(--panel-2);
  border: 1px solid var(--line);
}
.unidad:hover { border-color: var(--panel-3); }
.unidad-p {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: var(--t-min);
  background: var(--c, var(--panel-3));
  color: var(--bg);
}
.unidad-n { flex: 1; min-width: 0; font-size: var(--t-chico); line-height: 1.25; }
.unidad-n i { display: block; font-size: var(--t-micro); color: var(--ojo); font-style: normal; }
.unidad-precio { font-size: var(--t-min); color: var(--tx-2); font-variant-numeric: tabular-nums; }

.reparto-totales { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--e2); margin-top: var(--e3); }
.reparto-persona { padding: var(--e2) var(--e3); border-radius: var(--radio-chico); background: var(--bg-2); border: 1px solid var(--line); }
.reparto-persona span { display: flex; align-items: center; gap: var(--e1); font-size: var(--t-micro); color: var(--muted); }
.reparto-persona span::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--muted)); }
.reparto-persona b { display: block; font-size: var(--t-med); font-variant-numeric: tabular-nums; }
.reparto-persona small { display: block; font-size: var(--t-micro); color: var(--muted); }

/* ══════════════════════════════════════════════════════════════════════════
   Entrar con PIN
   ══════════════════════════════════════════════════════════════════════════
   Es la primera pantalla que ve un cliente cuando se le muestra el POS, y
   estaba flotando en negro sin ninguna superficie que la sostuviera. */

.entrar { min-height: 100dvh; display: grid; place-items: center; padding: var(--e5); }
.entrar-caja {
  width: min(400px, 100%);
  padding: var(--e6) var(--e5) var(--e5);
  border-radius: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4), 0 32px 80px rgba(0, 0, 0, 0.5);
  text-align: center;
}
.entrar-caja h1 { font-size: 1.7rem; letter-spacing: -0.02em; }
.entrar-caja .sub { color: var(--muted); font-size: var(--t-chico); margin: var(--e1) 0 var(--e6); }

.pin-puntos { display: flex; justify-content: center; gap: var(--e3); margin-bottom: var(--e3); }
.pin-puntos i {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--panel-3);
  background: transparent;
}
.pin-puntos i.lleno { background: var(--acento); border-color: var(--acento); }
.pin-error { color: var(--alerta); font-size: var(--t-chico); font-weight: 600; margin-bottom: var(--e2); }

.teclado { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--e2); margin-top: var(--e4); }
.teclado button {
  min-height: 64px;
  border-radius: 12px;
  font-size: 1.5rem;
  font-weight: 600;
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--tx);
  font-variant-numeric: tabular-nums;
}
.teclado button:hover { background: var(--panel-3); }
.teclado button:active { background: var(--acento); color: var(--acento-tx); }
.teclado .tecla-tenue, .teclado .tecla-ok { font-size: var(--t-base); font-weight: 700; }
.teclado .tecla-tenue { color: var(--tx-2); }
.teclado .tecla-ok { background: var(--acento); border-color: var(--acento); color: var(--acento-tx); }
.teclado .tecla-ok:hover { background: var(--acento-2); border-color: var(--acento-2); }

/* Los PIN a la vista son del demo y hay que sacarlos el día que esto entre a
   un local: se dibujan como una nota al margen, no como parte del producto. */
/* La grilla vive en el contenedor y las filas usan `display: contents`. Con la
   grilla en cada <b> las columnas se medían fila por fila, y el PIN de César
   quedaba corrido respecto al de Ana porque "Administrador" es más ancho que
   "Garzón" — cuatro números que hay que comparar de un vistazo, desalineados. */
.pin-demo {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--e1) var(--e2);
  margin-top: var(--e5);
  padding: var(--e3);
  border-radius: var(--radio);
  background: var(--ojo-tenue);
  border: 1px solid var(--ojo-linea);
  text-align: left;
}
.pin-demo > span {
  grid-column: 1 / -1;
  color: var(--ojo);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: var(--e1);
}
.pin-demo b {
  display: contents;
  font-weight: 600;
  font-size: var(--t-chico);
}
.pin-demo code {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 0.05rem 0.4rem;
  font-variant-numeric: tabular-nums;
}
.pin-demo small { color: var(--muted); font-size: var(--t-micro); min-width: 8ch; text-align: right; }

/* ══════════════════════════════════════════════════════════════════════════
   Sin conexión
   ══════════════════════════════════════════════════════════════════════════ */
.aviso-sin-red { border-color: var(--ojo-linea); background: rgba(245, 196, 81, 0.07); }
.aviso-sin-red h3 { color: var(--ojo); }
.aviso-sin-red p { color: var(--tx-2); font-size: var(--t-chico); }

/* ══════════════════════════════════════════════════════════════════════════
   Responsivo
   ══════════════════════════════════════════════════════════════════════════
   Dos quiebres reales, no una cascada de teléfonos: la tablet apoyada en
   horizontal (1180) y el caso de rescate (860), que es alguien mirando el POS
   desde un celular. El POS no se DISEÑA para el celular, pero tampoco puede
   quedar ilegible si el dueño lo abre en la micro. */

@media (max-width: 1180px) {
  :root { --rail: 104px; --cuenta: 312px; }
  .kpi-hero .kpi-v { font-size: 2rem; }
  /* La regleta mantiene sus seis celdas y encoge la cifra. Con 1,6rem un
     "$27.519.664" no cabe en una celda de 145 px y se metía encima de la
     celda vecina, que en una pantalla de plata es peor que ilegible. */
  .kpi { padding: var(--e2) var(--e3); }
  .kpi-v { font-size: 1.2rem; }
  .hoja, .reportes, .salon, .bandeja { padding-left: var(--e4); padding-right: var(--e4); }
  /* Ocho categorías más el buscador ocupaban tres renglones —144 px— antes del
     primer plato. Con la pastilla más compacta caben en dos. */
  .cats { padding: var(--e2) var(--e4); }
  .cats-lista button { min-height: 40px; padding: 0 0.6rem; font-size: var(--t-min); }
  .buscador { flex-basis: 150px; min-height: 40px; }
}

@media (max-width: 860px) {
  body { overflow: auto; }
  .app { display: block; height: auto; min-height: 100dvh; }
  /* El rail se acuesta y se vuelve una tira que scrollea. Los grupos y el
     bloque de usuario dejan de tener sentido en horizontal: se apilan igual y
     el usuario queda al final de la tira. */
  .rail {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e2);
    /* Envuelve en vez de scrollear: con la tira horizontal el bloque de
       usuario quedaba fuera de pantalla y había que arrastrar para ver quién
       está operando, que es justo el dato que no se puede esconder. */
    overflow: visible;
    border-right: none;
    border-bottom: 1px solid var(--line);
    padding: var(--e2);
  }
  .rail-marca { padding: 0 var(--e2) 0 0; white-space: nowrap; }
  .rail-titulo { display: none; }
  .rail-grupo { display: flex; gap: var(--e1); }
  .rail-b { width: auto; white-space: nowrap; padding: 0 0.7rem; }
  .rail-yo { width: auto; margin: 0 0 0 auto; white-space: nowrap; }
  .principal { overflow: visible; }
  .barra { flex-wrap: wrap; gap: var(--e2); padding: var(--e2) var(--e4); }
  /* ⚠️ `white-space: normal` SIN dejar envolver la banda no arreglaba nada: el
     span quedaba comprimido en una columna de ~50 px, partido en una elipsis
     por línea («…este nave…», «…ni fact…»), y la banda entera medía 199 px de
     alto en un teléfono de 360 px. Que el texto pueda cortar no sirve si no
     tiene dónde: la fila también tiene que envolver, y el texto tiene que
     tomarse su propio renglón entero. */
  .aviso-demo { flex-wrap: wrap; }
  .aviso-demo span { white-space: normal; flex: 1 1 100%; }
  /* Los dos botones de la banda se aprietan CON EL DEDO acá —el demo publicado
     se abre desde el celular—, no sentado y con puntero, que es para lo que
     `--toque-min` está definido. */
  .aviso-demo button,
  .volver-vercarta { min-height: var(--toque-med); }
  .barra-estado { margin-left: 0; }
  .vista { display: block; overflow: visible; }
  .venta, .delivery { display: block; }
  .cuenta, .conexiones { flex-basis: auto; border-left: none; border-top: 1px solid var(--line); }
  .cats { flex-wrap: wrap; }
  .buscador { flex: 1 1 100%; }
  .lineas { max-height: 340px; }
  .rejilla { grid-template-columns: 1fr; }
  .kpis { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .kpi { border-top: 1px solid var(--line); }
  .cuenta-nada { padding-bottom: var(--e5); }

  /* En un teléfono las tablas de reportes no caben, y sin esto quedaban
     CORTADAS: las columnas de la derecha —justo las de plata— eran
     inalcanzables. Con `display: block` la tabla scrollea dentro de su panel
     en vez de desbordarlo, y la página sigue sin scroll horizontal. */
  .panel .tabla,
  .carta-editor .tabla {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  /* El truco de `max-width: 0` para el ellipsis no sirve con la tabla en
     bloque: acá conviene que el nombre se lea entero y se scrollee. */
  .tabla .nombre { width: auto; max-width: none; overflow: visible; }
  .tabla th { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Impresión: solo sale el ticket
   ══════════════════════════════════════════════════════════════════════════
   El comprobante se imprime en una térmica de 80 mm. Todo lo demás —rail,
   barra, modal, botones— sobra en el papel, así que se esconde el árbol
   completo y se saca el ticket a flujo normal. */
@media print {
  body { background: #fff; overflow: visible; }
  .app, .modal-cab, .modal-pie, .velo > .modal > *:not(#ticket) { display: none !important; }
  .velo { position: static; background: none; padding: 0; display: block; }
  .modal { box-shadow: none; border: none; background: none; padding: 0; max-height: none; width: auto; }
  .ticket { background: #fff; color: #000; padding: 0; width: 72mm; font-size: 11px; }
  .ticket .nota { color: #000; }
  @page { margin: 4mm; }
}
