/* =====================================================================
   RestaGes Cloud — sistema visual
   ===================================================================== */

:root {
  color-scheme: dark;

  --bg:        #0b0f16;
  --bg-2:      #0f1520;
  --surface:   #131a26;
  --surface-2: #182131;
  --surface-3: #1e2938;
  --line:      #253044;
  --line-soft: #1c2534;

  --text:      #e8edf5;
  --text-2:    #a3b0c4;
  --text-3:    #6b7a93;

  --accent:      #f59e0b;
  --accent-2:    #fbbf24;
  --accent-soft: rgba(245, 158, 11, .14);
  --accent-line: rgba(245, 158, 11, .35);

  /* El ámbar de la marca no vale para escribir sobre fondo claro: sobre
     blanco se queda en 1,6:1. De ahí que el ámbar esté partido en dos, y la
     línea entre ellos es para qué se usa, no cómo de claro es:

       --accent y --accent-2  rellenan  (fondos, degradados, barras)
       --accent-texto         escribe   (texto e iconos)

     Los dos primeros son el color de la marca y valen igual en los dos
     temas, porque debajo llevan su propio fondo. El tercero se pinta sobre
     el fondo de la página, así que cada tema lo fija contra el suyo. Si
     algún día un precio vuelve a salir descolorido sobre blanco, es que se
     escribió con uno de los de rellenar. */
  --accent-texto: #fbbf24;

  --ok:      #34d399;
  --ok-soft: rgba(52, 211, 153, .14);
  --warn:    #fbbf24;
  --danger:  #f87171;
  --danger-soft: rgba(248, 113, 113, .14);
  --info:    #60a5fa;
  --info-soft: rgba(96, 165, 250, .14);

  --r-sm: 8px;  --r: 12px;  --r-lg: 18px;  --r-xl: 26px;
  --sh-1: 0 1px 2px rgba(0,0,0,.4);
  /* La sombra que asoma en una tabla con columnas fuera de la vista. */
  --sombra-tabla: rgba(0,0,0,.5);
  --sh-2: 0 8px 24px -8px rgba(0,0,0,.6);
  --sh-3: 0 24px 60px -16px rgba(0,0,0,.7);

  /* El suelo del comedor y el relieve de las mesas. Son cuatro valores que
     antes estaban dentro de las reglas, escritos contra el fondo oscuro; al
     salir aquí, el modo claro puede tener los suyos en vez de heredar un
     negro al 45 % que sobre blanco sale sucio. */
  /* El cuarto indicador. Los otros tres salen de colores que ya existían
     por otro motivo —la marca, el informativo y el de acierto— y para el
     cuarto no quedaba ninguno libre: tirar del azul de las gráficas dejaba
     dos tarjetas casi del mismo azul. Sólo se usa de filo y de pastilla,
     nunca de texto, así que le basta con separarse del fondo. */
  --kpi-4: #a78bfa;

  --suelo:        var(--surface);
  --suelo-punto:  var(--line);
  --suelo-vineta: rgb(0 0 0 / .16);
  /* La tarima: dos tonos de tabla, la junta entre ellas y la veta. */
  --tabla-1:      #3a2618;
  --tabla-2:      #46301e;
  --junta:        rgb(0 0 0 / .35);
  --veta:         rgb(255 255 255 / .02);
  /* Baldosa y piedra, oscuros. */
  --baldosa-1:    #1a2230;
  --baldosa-2:    #202a3a;
  --piedra:       #2a2d33;
  --mesa-sombra:  0 2px 6px -2px rgb(0 0 0 / .45);
  --mesa-brillo:  rgb(255 255 255 / .07);

  --sidebar-w: 286px;
  --topbar-h: 60px;
  --nav-h: 0px;       /* alto de la barra del modo comandero; lo fija app.js */

  /* Colores de serie de las gráficas.
     No son los del interfaz: se eligieron pasando el validador de paletas
     (banda de luminosidad, suelo de croma, separación bajo daltonismo y
     contraste sobre el fondo). Cada modo tiene su propio escalón elegido
     contra su propio fondo, no es un volteo automático del otro.
     Oscuro: ΔE 27,4 protan, dentro de la banda L 0,48–0,67, >= 3:1. */
  --serie-1: #c97d09;
  --serie-2: #3d8ae8;

  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace;
}

[data-theme="light"] {
  color-scheme: light;

  /* El lienzo va gris y los paneles blancos: con los dos casi blancos, como
     estaban, las tarjetas no se despegaban del fondo y todo parecía una
     misma lámina. */
  --bg:        #eef1f6;
  --bg-2:      #ffffff;
  --surface:   #ffffff;
  --surface-2: #f4f6fa;
  --surface-3: #e9edf4;
  --line:      #d7dde8;
  --line-soft: #e4e9f1;
  --text:      #0f172a;
  --text-2:    #45536a;

  /* Los apagados también se leen. El gris anterior (#67748a) se quedaba en
     4,3:1 sobre blanco y en 4,1:1 sobre el gris del lienzo, por debajo del
     4,5:1 que pide un texto de 13 px: la fecha del panel y los subtítulos
     costaban a pleno sol. Éste da 5,5:1 sobre blanco y 4,8:1 sobre el
     lienzo. */
  --text-3:    #5b6880;

  /* Sobre su propio tinte (--accent-soft) el ámbar anterior daba 4,50:1,
     justo en el límite; éste deja margen (5,4:1) para los chips y las
     observaciones de cocina, que van a 11-13 px. */
  --accent-texto: #a04a08;
  --accent-soft: rgba(245, 158, 11, .15);
  --accent-line: rgba(180, 83, 9, .30);

  /* Los semánticos, oscurecidos para el fondo claro: el verde y el rojo de
     modo oscuro se quedaban por debajo de 4,5:1 y son texto pequeño. El
     22/09/2026 se oscurecieron otra vez: sobre su propio tinte —que es como
     se usan, en las insignias «todo al día» o «anulada»— el verde daba
     4,3:1 y el rojo 4,3:1. Ahora 5,4:1 y 5,5:1. */
  --ok:        #0a6f4a;
  --ok-soft:   rgba(10, 128, 85, .12);
  --warn:      #a04a08;
  --danger:    #b02f2d;
  --danger-soft: rgba(194, 65, 63, .12);
  --info:      #1f63c4;
  --info-soft: rgba(31, 99, 196, .12);

  /* Un comedor con la luz dada: el suelo se separa del papel de la ficha,
     los puntos se quedan en marca de baldosa y la sombra pasa de tinta a
     azul de sombra real, que es lo que hace que la mesa parezca apoyada en
     vez de recortada. */
  --kpi-4: #6d28d9;

  --suelo:        #f7f8fb;
  --suelo-punto:  #dfe5ef;
  --suelo-vineta: rgb(31, 45, 74, .07);
  --tabla-1:      #d8b58c;
  --tabla-2:      #e2c39e;
  --junta:        rgb(90 55 20 / .28);
  --veta:         rgb(255 255 255 / .18);
  --baldosa-1:    #e4e8ee;
  --baldosa-2:    #eef1f5;
  --piedra:       #d9d7d2;
  --mesa-sombra:  0 1px 1px rgb(15 23 42 / .05), 0 4px 10px -4px rgb(15 23 42 / .22);
  --mesa-brillo:  rgb(255 255 255 / .75);

  --sh-1: 0 1px 2px rgba(15,23,42,.05);
  --sombra-tabla: rgba(15,23,42,.16);
  /* Claro: ΔE 26,8 protan, banda L 0,43–0,77, contraste >= 3:1 sobre blanco. */
  --serie-1: #a85f06;
  --serie-2: #2a78d6;
  --sh-2: 0 8px 24px -10px rgba(15,23,42,.18);
  --sh-3: 0 24px 60px -18px rgba(15,23,42,.24);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -.012em; }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-texto); }
::selection { background: var(--accent-soft); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 20px; border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--text-3); background-clip: content-box; }

.muted { color: var(--text-2); }
.dim   { color: var(--text-3); }
.mono  { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.num   { font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.center{ text-align: center; }
.nowrap{ white-space: nowrap; }
.grow  { flex: 1; }
[hidden] { display: none !important; }

/* icono inline (se rellena por JS con un <svg>) */
i[data-icon] { display: inline-flex; width: 1.15em; height: 1.15em; flex: none; }
i[data-icon] svg { width: 100%; height: 100%; stroke: currentColor; fill: none;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* ------------------------------------------------------------- login */
.login {
  display: grid; grid-template-columns: 1.05fr .95fr;
  min-height: 100dvh;
}
.login-art {
  position: relative; overflow: hidden;
  padding: clamp(32px, 5vw, 72px);
  display: flex; flex-direction: column; justify-content: center; gap: 40px;
  background:
    radial-gradient(1000px 620px at 8% 5%, rgba(245,158,11,.20), transparent 60%),
    radial-gradient(760px 520px at 92% 92%, rgba(96,165,250,.16), transparent 62%),
    linear-gradient(150deg, #0a0e15, #131c2c 55%, #0d1420);
  color: #eef3fb;
}
.login-art::after {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background-image:
    linear-gradient(rgba(255,255,255,.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.028) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(900px 600px at 30% 40%, #000, transparent 75%);
}
.login-brand { position: relative; z-index: 1; display: flex; align-items: center; gap: 20px; }
.login-brand h1 { font-size: clamp(28px, 3.4vw, 42px); letter-spacing: -.03em; }
.login-brand h1 em {
  font-style: normal; font-weight: 400;
  background: linear-gradient(92deg, var(--accent-2), #fde68a);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.login-brand p { color: #9fb0c9; margin-top: 4px; }
.login-features { position: relative; z-index: 1; list-style: none; margin: 0; padding: 0;
  display: grid; gap: 16px; max-width: 480px; }
.login-features li { display: flex; gap: 14px; align-items: flex-start; color: #c6d3e6; }
.login-features i { color: var(--accent-texto); margin-top: 3px; }
.login-foot { position: relative; z-index: 1; color: #6f8099; font-size: 13px; }

.login-form-wrap { display: grid; place-items: center; padding: 32px; background: var(--bg); }
.login-form { width: min(400px, 100%); display: grid; gap: 15px; }
.login-form h2 { font-size: 24px; }
.login-form > .muted { margin-bottom: 6px; }
.login-form label { display: grid; gap: 7px; font-size: 13px; font-weight: 550; color: var(--text-2); }
.login-form input {
  padding: 12px 14px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  transition: border-color .15s, box-shadow .15s;
}
.login-form input:focus { outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.login-sep { display: flex; align-items: center; gap: 12px; color: var(--text-3); font-size: 12px; }
.login-sep::before, .login-sep::after { content: ''; height: 1px; background: var(--line); flex: 1; }
.login-demo { font-size: 12px; color: var(--text-3); text-align: center; line-height: 1.9; }
.login-demo code { background: var(--surface-2); padding: 2px 6px; border-radius: 6px; font-family: var(--mono); font-size: 11px; }
.form-error {
  background: var(--danger-soft); color: var(--danger); padding: 10px 13px;
  border-radius: var(--r-sm); font-size: 13px; border: 1px solid rgba(248,113,113,.3);
}

/* El logo de la marca (plato con cuchara y tenedor), PNG con fondo
   transparente. La «R» naranja de antes se fue el 15 de septiembre. */
.logo { width: 42px; height: 42px; flex: none; object-fit: contain;
  filter: drop-shadow(0 5px 12px rgba(0,0,0,.45)); }

/* --------------------------------------------------------------- app */
#app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; height: 100dvh; }

.sidebar {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--bg-2); border-right: 1px solid var(--line-soft);
}
.sidebar-head { display: flex; align-items: center; gap: 12px; padding: 15px 16px; }
.sidebar-inicio { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1; color: inherit; text-decoration: none; border-radius: 10px; }
.sidebar-inicio:hover .sidebar-title strong { color: var(--accent-texto); }
.sidebar-title { display: grid; line-height: 1.25; min-width: 0; }
.sidebar-title strong { font-size: 15px; letter-spacing: -.01em; white-space: nowrap; }
/* «Cloud» en ámbar y fina, como en la pantalla de entrada. */
.sidebar-title strong em {
  font-style: normal; font-weight: 400;
  background: linear-gradient(92deg, var(--accent-2), #fde68a);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.sidebar-title small { color: var(--text-3); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar .sidebar-close { display: none; margin-left: auto; }

.sidebar-search { position: relative; margin: 0 12px 10px; }
.sidebar-search i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-3); }
.sidebar-search kbd {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  font-family: var(--mono); font-size: 10.5px; color: var(--text-3);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px;
}
.sidebar-search input {
  width: 100%; padding: 9px 34px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text); font-size: 13px;
}
.sidebar-search input:focus { outline: 0; border-color: var(--accent-line); }

.nav { flex: 1; overflow-y: auto; padding: 2px 10px 10px; min-height: 0; }
.nav-group + .nav-group { margin-top: 2px; }
/* --------------------------------------------------------- atajos
   Lo que más usa cada persona, arriba del árbol. Se separa del menú con
   un fondo propio para que se lea como «tus accesos» y no como una rama
   más del menú original. */
.atajos {
  margin: 0 12px 10px; padding: 8px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--line-soft);
  display: grid; gap: 2px;
}
.atajos-tit {
  display: flex; align-items: center; gap: 7px; padding: 2px 6px 6px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3);
}
.atajos-tit svg { width: 13px; height: 13px; color: var(--accent); }
.atajos-editar {
  margin-left: auto; width: 22px; height: 22px; opacity: 0; transition: opacity .14s;
}
.atajos-editar svg { color: var(--text-3); width: 14px; height: 14px; }
.atajos:hover .atajos-editar, .atajos-editar:focus-visible { opacity: 1; }
.atajos .atajos-vacio { color: var(--text-3); font-style: italic; }
.atajos .atajo { padding: 7px 8px; font-size: 12.8px; }
.atajos .atajo.activo { background: var(--accent-soft); color: var(--accent-texto); }

.nav-link, .nav-branch {
  width: 100%; display: flex; align-items: center; justify-content: flex-start; gap: 10px;
  padding: 8px 10px; border-radius: 9px; border: 0; background: none;
  color: var(--text-2); text-align: left; cursor: pointer; font-size: 13.5px;
  transition: background .12s, color .12s;
}
/* El icono ocupa siempre lo mismo y el rótulo empieza siempre en la misma
   columna: es lo que hace que un nivel se lea como una lista y no como
   palabras sueltas. El rótulo se lleva el ancho que quede y no parte. */
.nav-link > i[data-icon], .nav-branch > i[data-icon] { width: 17px; height: 17px; flex: none; }
.nav-link > span:not(.cloud-dot):not(.nav-hueco), .nav-branch > span { flex: 1 1 auto; min-width: 0; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-branch { font-weight: 600; color: var(--text); }
/* Sin icono, un punto discreto en su sitio: los informes, sobre todo. */
.nav-link .nav-hueco { width: 17px; height: 17px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.nav-link .nav-hueco::before { content: ""; width: 4px; height: 4px; border-radius: 50%; background: var(--text-3); }
.nav-link:hover, .nav-branch:hover { background: var(--surface-2); color: var(--text); }
.nav-branch .chev { margin-left: auto; transition: transform .18s; color: var(--text-3); }
.nav-branch[aria-expanded="true"] .chev { transform: rotate(90deg); }
.nav-children { display: none; margin: 1px 0 3px 9px; padding-left: 7px; border-left: 1px solid var(--line); }
.nav-children .nav-link, .nav-children .nav-branch { font-size: 13px; padding: 7px 8px; }
.nav-children .nav-children .nav-link { font-size: 12.5px; }
.nav-children.open { display: block; }
.nav-link.active {
  background: var(--accent-soft); color: var(--accent-texto); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent);
}

/* --------------------------------------------- las ramas principales
   Ventas, Caja, Archivos… se leen como cabeceras y no como una opción más:
   más cuerpo, el icono en su cajita, y al desplegarse sus opciones van
   más pequeñas y más claras, colgando de una línea de color. Así se ve de
   un vistazo qué es área y qué es opción. */
.nav > .nav-group > .nav-branch {
  font-size: 14px; font-weight: 700; color: var(--text); padding: 7px 8px; gap: 11px;
  letter-spacing: -.005em;
}
.nav > .nav-group > .nav-branch > i[data-icon] {
  width: 28px; height: 28px; border-radius: 8px; padding: 6px;
  background: var(--surface-2); color: var(--text-2);
  transition: background .12s, color .12s;
}
.nav > .nav-group > .nav-branch:hover > i[data-icon],
.nav > .nav-group > .nav-branch[aria-expanded="true"] > i[data-icon] {
  background: var(--accent-soft); color: var(--accent-texto);
}
.nav > .nav-group > .nav-branch[aria-expanded="true"] { color: var(--accent-texto); }
/* Sin fondo bajo el grupo abierto (probado con él el 21/09 y Alonso lo
   prefirió sin): el área desplegada se distingue por su color, la cajita
   del icono y la línea de las opciones, no por un bloque gris. */
.nav > .nav-group:has(> .nav-branch[aria-expanded="true"]) { margin: 4px 0 6px; }
.nav > .nav-group > .nav-children { margin: 0 0 0 20px; padding-left: 10px; border-left: 2px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.nav > .nav-group > .nav-children .nav-link, .nav > .nav-group > .nav-children .nav-branch { font-size: 12.8px; padding: 6px 8px; color: var(--text-2); }
.nav > .nav-group > .nav-children .nav-branch { font-weight: 600; }
.nav > .nav-group > .nav-children .nav-link:hover, .nav > .nav-group > .nav-children .nav-branch:hover { background: var(--surface-2); color: var(--text); }
.nav > .nav-group > .nav-children .nav-link.active { color: var(--accent-texto); background: var(--accent-soft); }
/* Lo pendiente de cobro, al lado de su opción: el número en la hoja. */
.nav-aviso {
  flex: none; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; background: var(--accent); color: #fff;
}
/* Los platos en cocina, en rojo: es trabajo esperando, no dinero pendiente. */
.nav-aviso.cocina { background: var(--danger); }
.atajo-btn .nav-aviso { margin-left: 2px; min-width: 17px; height: 17px; font-size: 10px; }
.nav-link .cloud-dot {
  width: 5px; height: 5px; border-radius: 50%; background: var(--info); margin-left: auto; flex: none;
}
.nav-empty { padding: 22px 12px; text-align: center; color: var(--text-3); font-size: 13px; }

.sidebar-foot { border-top: 1px solid var(--line-soft); padding: 10px; display: grid; gap: 8px; }
.user-chip { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 11px; background: var(--surface); }
.avatar {
  width: 32px; height: 32px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: linear-gradient(140deg, var(--accent), #ea580c); color: #1a1207; font-weight: 700; font-size: 13px;
}
.user-meta { display: grid; line-height: 1.3; min-width: 0; flex: 1; }
.user-meta strong { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-meta small { color: var(--text-3); font-size: 11px; text-transform: capitalize; }

.main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.topbar {
  height: var(--topbar-h); flex: none; display: flex; align-items: center; gap: 12px;
  padding: 0 20px; border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(12px); position: sticky; top: 0; z-index: 20;
}
.crumbs { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text-3); min-width: 0; overflow: hidden; }
.crumbs span { white-space: nowrap; }
.crumbs span:last-child { color: var(--text); font-weight: 600; }
.crumbs .sep { color: var(--line); }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.clock { font-family: var(--mono); font-size: 12.5px; color: var(--text-3); padding-right: 6px; }
/* Latencia con el servidor: un punto y los milisegundos. */
.latencia { display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono); font-size: 11.5px; color: var(--text-3); padding-right: 8px; }
.latencia::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); }
.latencia[data-nivel="verde"]::before { background: var(--ok); }
.latencia[data-nivel="ambar"]::before { background: var(--accent); }
.latencia[data-nivel="rojo"]::before { background: var(--danger); }
.latencia[data-nivel="rojo"] { color: var(--danger); font-weight: 600; }
.latencia:empty { display: none; }

.icon-btn {
  width: 34px; height: 34px; display: grid; place-items: center; flex: none;
  border-radius: 9px; border: 1px solid transparent; background: none;
  color: var(--text-2); cursor: pointer; transition: background .12s, color .12s;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.only-mobile { display: none; }

.view { flex: 1; overflow-y: auto; padding: 22px 24px 60px; min-height: 0; }
.view:focus { outline: none; }

/* ------------------------------------------------- estado del sistema */
/* Un punto de color por señal: verde va bien, ámbar hay que mirarlo, rojo
   hay que atenderlo. El color no va solo: al lado está siempre el texto. */
.salud-resumen { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.salud-resumen svg { width: 26px; height: 26px; flex: none; }
.salud-resumen.bien svg { color: var(--ok, #16a34a); }
.salud-resumen.aviso svg { color: var(--warn, #d97706); }
.salud-resumen.mal svg { color: var(--danger, #dc2626); }
.salud-senales { display: grid; gap: 8px; }
.salud-senal { display: flex; align-items: baseline; gap: 10px; font-size: 13px; }
.salud-senal .que { min-width: 160px; font-weight: 600; }
.punto { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; background: var(--text-3); }
.bien > .punto, .punto.bien { background: var(--ok, #16a34a); }
.aviso > .punto, .punto.aviso { background: var(--warn, #d97706); }
.mal > .punto, .punto.mal { background: var(--danger, #dc2626); }
.card-head h3 .punto { margin-right: 7px; }

/* ------------------------------------------------------------ bloques */
.page-head { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
.page-head h2 { font-size: 21px; letter-spacing: -.02em; }
.page-head .sub { color: var(--text-3); font-size: 13px; margin-top: 3px; }
.page-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.card {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
/* En claro el panel y el lienzo casi comparten luminosidad, así que lo que
   separa la tarjeta del fondo es su sombra, no su color. */
[data-theme="light"] .card { box-shadow: 0 1px 2px rgba(15,23,42,.04), 0 6px 16px -12px rgba(15,23,42,.22); }
[data-theme="light"] .sidebar { box-shadow: 1px 0 0 var(--line-soft); border-right: 0; }
.card-pad { padding: 18px; }
.card-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid var(--line-soft);
}
.card-head h3 { font-size: 14px; }
.card-head .card-actions { margin-left: auto; display: flex; gap: 6px; align-items: center; }

/* Configuración: la página de inicio con sus opciones en tarjetas, y la
   tira para saltar entre ellas desde dentro de cualquiera. */
.config-grupo { margin-bottom: 18px; }
.config-grupo h3 { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); margin: 0 0 8px 2px; }
.config-opciones { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.config-opcion {
  display: flex; gap: 12px; align-items: flex-start; text-align: left; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); cursor: pointer;
  color: inherit; font-family: inherit; transition: border-color .12s, box-shadow .12s;
}
.config-opcion:hover { border-color: var(--accent); box-shadow: 0 4px 14px rgba(0,0,0,.06); }
.config-opcion i[data-icon] { width: 22px; height: 22px; color: var(--accent-texto); flex: none; margin-top: 2px; }
.config-opcion strong { display: block; font-size: 14px; margin-bottom: 3px; }
.config-opcion span { font-size: 12.5px; color: var(--text-3); line-height: 1.35; }
.config-tira { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 14px; }
.config-tira .volver { margin-right: 6px; }
.config-tira .chip.on { border-color: transparent; background: var(--accent-soft); color: var(--accent-texto); }

.grid { display: grid; gap: 16px; }
.g-kpi { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.g-2 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.kpi { padding: 16px 18px; display: grid; gap: 6px; position: relative; overflow: hidden; }
.kpi .k-label { font-size: 12px; color: var(--text-3); font-weight: 550; display: flex; align-items: center; gap: 7px; }
.kpi .k-value { font-size: 26px; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.kpi .k-foot { font-size: 12px; color: var(--text-3); display: flex; align-items: center; gap: 6px; }
.kpi .k-accent { color: var(--accent-texto); }
.delta { font-weight: 600; display: inline-flex; align-items: center; gap: 3px; }
.delta.up { color: var(--ok); } .delta.down { color: var(--danger); }

.badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; background: var(--surface-3); color: var(--text-2);
  border: 1px solid var(--line);
}
.badge.ok { background: var(--ok-soft); color: var(--ok); border-color: transparent; }
.badge.warn { background: var(--accent-soft); color: var(--accent-texto); border-color: transparent; }
.badge.danger { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.badge.info { background: var(--info-soft); color: var(--info); border-color: transparent; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 9px 15px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text); cursor: pointer; font-size: 13.5px;
  font-weight: 550; white-space: nowrap; transition: background .13s, border-color .13s, transform .06s;
}
.btn:hover { background: var(--surface-3); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-primary {
  background: linear-gradient(140deg, var(--accent), #ea8a06); border-color: transparent; color: #1a1207;
  font-weight: 650; box-shadow: 0 4px 14px -6px rgba(245,158,11,.7);
}
.btn-primary:hover { background: linear-gradient(140deg, var(--accent-2), var(--accent)); }
.btn-ghost { background: none; }
.btn-danger { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.btn-ok { background: var(--ok-soft); color: var(--ok); border-color: transparent; }
.btn-sm { padding: 6px 11px; font-size: 12.5px; border-radius: 8px; }
.btn-lg { padding: 13px 22px; font-size: 15px; border-radius: 12px; }
.btn-block { width: 100%; }

/* `align-content: start` evita que una pista larga estire la fila y
   desalinee los campos vecinos del formulario. */
.field { display: grid; gap: 6px; align-content: start; }
.field > label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.field .hint { font-size: 11.5px; color: var(--text-3); }
input, select, textarea {
  padding: 9px 12px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text); width: 100%;
  transition: border-color .14s, box-shadow .14s;
}
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
input[readonly] { background: var(--surface-3); color: var(--text-2); cursor: default; }
/* Lo que no cuadra con otra casilla (la contraseña repetida), en rojo. */
input.invalid, input.invalid:focus { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }
textarea { resize: vertical; min-height: 68px; }
select { cursor: pointer; }
input[type="checkbox"] { width: auto; accent-color: var(--accent); width: 17px; height: 17px; }
.check { display: flex; align-items: center; gap: 9px; padding-top: 22px; font-size: 13px; }

.toolbar { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }

/* Desplegable de coincidencias bajo un buscador (artículos en documentos) */
.sugerencias {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 30; margin-top: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: 0 10px 30px rgba(0,0,0,.18); overflow: hidden; max-height: 320px; overflow-y: auto;
}
.sugerencia {
  display: flex; justify-content: space-between; gap: 12px; width: 100%; text-align: left;
  padding: 9px 12px; border: 0; background: transparent; color: var(--text); font: inherit; cursor: pointer;
  border-bottom: 1px solid var(--line-soft);
}
.sugerencia:last-child { border-bottom: 0; }
.sugerencia:hover, .sugerencia:focus { background: var(--surface-2); outline: 0; }
.sugerencia code { color: var(--text-3); margin-right: 6px; }
.search-box { position: relative; flex: 1; min-width: 200px; max-width: 380px; }
.search-box i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-3); }
.search-box input { padding-left: 34px; }

/* -------------------------------------------------------------- tabla */
/* Con más columnas de las que caben, la tabla se desplaza a lo ancho. Que
   se pueda no basta: hay que verlo, o el importe de la derecha parece que
   no está. Las dos sombras de los lados aparecen solas cuando hay algo
   fuera y se van al llegar al borde (fondos `local` contra `scroll`). */
.table-wrap {
  overflow-x: auto; border-radius: var(--r-lg);
  border: 1px solid var(--line-soft);
  background:
    linear-gradient(to right, var(--surface) 30%, transparent) left center / 28px 100% no-repeat local,
    linear-gradient(to left, var(--surface) 30%, transparent) right center / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, var(--sombra-tabla), transparent) left center / 16px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, var(--sombra-tabla), transparent) right center / 16px 100% no-repeat scroll,
    var(--surface);
}

/* La papelera de cada fila: discreta con el ratón —sale al pasar por la
   fila— y ausente con el dedo. */
.borrar-fila { opacity: 0; transition: opacity .12s; }
tr:hover .borrar-fila, .borrar-fila:focus-visible, tr:focus-within .borrar-fila { opacity: 1; }
@media (pointer: coarse) {
  .col-borrar { display: none; }
}
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th {
  position: sticky; top: 0; z-index: 1; text-align: left; padding: 11px 14px;
  background: var(--surface-2); color: var(--text-3); font-size: 11.5px;
  font-weight: 650; text-transform: uppercase; letter-spacing: .05em;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
tbody td { padding: 10px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
/* Bandas alternas muy sutiles: en una tabla de diez columnas es lo que
   permite seguir la fila con la vista hasta el importe de la derecha. */
tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover td,
tbody tr.clickable:nth-child(even):hover td { background: var(--surface-2); }
/* Y una guía de color al pasar por encima, para no perder la fila al ir a
   pulsar el botón de acciones del extremo. */
tbody tr.clickable:hover td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

.si-no { color: var(--text-3); }
.si-no.si { color: var(--ok); font-weight: 700; }
tfoot td { padding: 11px 14px; font-weight: 700; background: var(--surface-2); border-top: 1px solid var(--line); }
td.n, th.n { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); }
.row-actions { display: flex; gap: 4px; justify-content: flex-end; }

.empty { padding: 52px 20px; text-align: center; color: var(--text-3); }
.empty i { display: block; width: 34px; height: 34px; margin: 0 auto 12px; opacity: .5; }
.empty strong { display: block; color: var(--text-2); margin-bottom: 4px; font-size: 14px; }

.skeleton { background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%; animation: shimmer 1.3s infinite; border-radius: var(--r-sm); }
@keyframes shimmer { to { background-position: -200% 0; } }

/* -------------------------------------------------------------- plano */
.salon-tabs { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 14px; }
.salon-tab {
  padding: 8px 15px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--surface); color: var(--text-2); cursor: pointer; font-size: 13px; font-weight: 550;
}
.salon-tab.active { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-texto); }

/* ------------------------------------------------------------- plano
   El plano de sala es la pantalla que más mira un camarero, así que se
   dibuja como lo que representa: un suelo con mesas encima, no una lista
   de cajas. La rejilla marca el suelo, la viñeta da profundidad y cada
   mesa lleva sus sillas. */
.plano {
  /* La altura la fija `encajar()` con el hueco real de la pantalla; este
     mínimo sólo cubre el instante anterior al primer ajuste. */
  position: relative; min-height: 260px; border-radius: var(--r-lg);
  border: 1px solid var(--line-soft); overflow: auto;
  background:
    /* Viñeta suave: hunde los bordes y centra la atención en las mesas. */
    radial-gradient(120% 100% at 50% 0%, transparent 55%, var(--suelo-vineta) 100%),
    radial-gradient(circle at 1px 1px, var(--suelo-punto) 1px, transparent 0) 0 0 / 26px 26px,
    var(--suelo);
}
.plano-inner { position: relative; }

/* --- suelos ------------------------------------------------------------
   El suelo va en el lienzo (.plano-inner), que es lo que se escala: así la
   tabla de la tarima crece y encoge con las mesas y no se ve el corte. */
.plano-inner.suelo-liso { background: none; }
/* Tarima: tablas horizontales de 34 px con junta, y una veta muy tenue en
   diagonal para que no parezca una rejilla. */
.plano-inner.suelo-madera {
  background:
    repeating-linear-gradient(100deg, transparent 0 58px, var(--veta) 58px 61px),
    repeating-linear-gradient(180deg, rgb(255 255 255 / .04) 0 2px, transparent 2px 34px, rgb(0 0 0 / .08) 34px 35px),
    repeating-linear-gradient(180deg, var(--tabla-1) 0 35px, var(--tabla-2) 35px 70px);
}
/* Baldosa a damero de 52 px. */
.plano-inner.suelo-baldosa {
  background:
    repeating-conic-gradient(var(--baldosa-1) 0 25%, var(--baldosa-2) 0 50%) 0 0 / 104px 104px,
    var(--baldosa-1);
}
/* Piedra: manchas irregulares sobre gris. */
.plano-inner.suelo-piedra {
  background:
    radial-gradient(60px 40px at 20% 30%, rgb(255 255 255 / .05), transparent 70%),
    radial-gradient(90px 60px at 70% 60%, rgb(0 0 0 / .12), transparent 70%),
    radial-gradient(50px 50px at 45% 85%, rgb(255 255 255 / .04), transparent 70%),
    radial-gradient(70px 45px at 85% 15%, rgb(0 0 0 / .10), transparent 70%),
    var(--piedra);
  background-size: 360px 260px, 420px 300px, 300px 240px, 380px 280px, auto;
}
/* Imagen del local: la pone el estilo en línea; se estira al lienzo. */
.plano-inner.suelo-imagen { background-size: 100% 100%; background-repeat: no-repeat; }

/* --- elementos: paredes, barra, zonas y rótulos ------------------------ */
.elemento {
  position: absolute; box-sizing: border-box; display: grid; place-content: center;
  text-align: center; pointer-events: none; user-select: none; z-index: 0;
}
.elemento .e-txt { font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; opacity: .8; padding: 4px; }
.elemento.e-pared { background: color-mix(in srgb, var(--text) 55%, transparent); border-radius: 3px; box-shadow: 0 2px 6px rgb(0 0 0 / .35); }
.elemento.e-barra {
  border-radius: 10px; border: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 28%, var(--surface-2)), color-mix(in srgb, var(--accent) 14%, var(--surface-2)));
  box-shadow: 0 6px 16px -8px rgb(0 0 0 / .6);
}
.elemento.e-barra .e-txt { color: var(--accent-texto); }
.elemento.e-zona {
  border-radius: 12px; border: 1.5px dashed color-mix(in srgb, var(--text) 30%, transparent);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
}
.elemento.e-zona .e-txt { color: var(--text-2); }
.elemento.e-texto .e-txt { font-size: 15px; color: var(--text-2); text-transform: none; letter-spacing: 0; }

/* En el editor sí se tocan: se arrastran y se estiran por el asa. */
.plano-inner.editor .elemento { pointer-events: auto; cursor: grab; }
.plano-inner.editor .elemento.arrastrando, .plano-inner.editor .mesa.arrastrando { cursor: grabbing; opacity: .8; z-index: 10; }
.plano-inner.editor .asa {
  position: absolute; right: -6px; bottom: -6px; width: 14px; height: 14px; border-radius: 4px;
  background: var(--accent); border: 2px solid var(--bg); cursor: nwse-resize; opacity: 0; transition: opacity .12s;
}
.plano-inner.editor .elemento:hover .asa, .plano-inner.editor .elemento.arrastrando .asa { opacity: 1; }

.mesa {
  position: absolute; border-radius: 14px; border: 2px solid var(--line);
  background: var(--surface-2); cursor: pointer; display: grid; place-content: center;
  text-align: center; gap: 2px; padding: 6px; user-select: none;
  transition: transform .14s cubic-bezier(.2,.9,.3,1.1), box-shadow .14s, border-color .14s;
  /* Sombra de contacto: separa la mesa del suelo. Va por token porque un
     negro al 45 % es lo que hace falta sobre un suelo oscuro y lo que
     ensucia un suelo claro. */
  box-shadow: var(--mesa-sombra);
  /* Un reflejo tenue arriba da volumen al tablero sin tapar el color del
     estado, que se pinta debajo con `background-color`. */
  background-image: linear-gradient(180deg, var(--mesa-brillo), transparent 45%);
}
.mesa:hover { transform: translateY(-3px) scale(1.02); box-shadow: var(--sh-2); z-index: 3; }
.mesa:active { transform: translateY(-1px) scale(.99); }
.mesa.round { border-radius: 50%; }
.mesa .m-num { font-weight: 700; font-size: 15px; }
.mesa .m-pax { font-size: 10.5px; color: var(--text-3); }
.mesa .m-total { font-size: 12px; font-weight: 700; font-family: var(--mono); white-space: nowrap; }

/* --- sillas: una por plaza, del color del estado de la mesa --- */
.sillas { position: absolute; inset: 0; pointer-events: none; }
.silla {
  position: absolute; display: block; background: currentColor;
  opacity: .45; border-radius: 4px;
}
.silla.s-arriba, .silla.s-abajo { width: 24%; max-width: 20px; height: 4px; left: var(--pos); transform: translateX(-50%); }
.silla.s-izq, .silla.s-der { height: 24%; max-height: 20px; width: 4px; top: var(--pos); transform: translateY(-50%); }
.silla.s-arriba { top: -9px; }
.silla.s-abajo { bottom: -9px; }
.silla.s-izq { left: -9px; }
.silla.s-der { right: -9px; }
.mesa:hover .silla { opacity: .7; }
/* En mesa redonda se reparten por la circunferencia.

   El taburete no se desplaza: se gira. Cada uno es un marco invisible del
   tamaño de la mesa entera que rota sobre el centro, y el trazo va pintado
   en su borde superior. Así el radio sale solo del tamaño de la mesa, sea
   el que sea.

   Lo anterior intentaba empujar el trazo hacia fuera con un `translate` en
   porcentaje, y los porcentajes de `translate` se miden sobre el propio
   elemento —5 × 13 px—, no sobre la mesa: el taburete se quedaba a 13 px
   del centro, encima del número, y el texto se leía tachado. */
.round .silla {
  inset: 0; width: auto; height: auto;
  background: none; opacity: 1; border-radius: 0;
  transform: rotate(var(--giro)); transform-origin: 50% 50%;
}
.round .silla::before {
  content: ""; position: absolute; left: 50%; top: -9px;
  width: 14px; height: 4px; margin-left: -7px;
  background: currentColor; opacity: .45; border-radius: 4px;
}
.mesa.round:hover .silla { opacity: 1; }
.mesa.round:hover .silla::before { opacity: .7; }

/* El borde sale del mismo token que el texto y el relleno. Antes llevaba
   escrito a mano el verde y el rojo del modo oscuro, y en claro la mesa
   quedaba con un filo menta que no era el verde del tema. */
/* El relleno del estado va sobre la superficie y no traslúcido: sobre la
   tarima o una foto, un verde al 14 % no se lee. */
.mesa.libre { border-color: color-mix(in srgb, var(--ok) 45%, transparent); background-color: color-mix(in srgb, var(--ok) 16%, var(--surface)); color: var(--ok); }
.mesa.libre .m-num { color: var(--ok); }
.mesa.ocupada { border-color: color-mix(in srgb, var(--danger) 50%, transparent); background-color: color-mix(in srgb, var(--danger) 18%, var(--surface)); color: var(--danger); }
.mesa.ocupada .m-num, .mesa.ocupada .m-total { color: var(--danger); }
.mesa.reservada { border-color: var(--accent-line); background-color: color-mix(in srgb, var(--accent) 18%, var(--surface)); color: var(--accent-texto); }
.mesa.reservada .m-num { color: var(--accent-texto); }
/* «Reservada» va en el sitio del importe, con el mismo peso: es lo que el
   camarero tiene que ver antes de sentar a nadie. La hora debajo. */
.mesa.reservada .m-total { color: var(--accent-texto); font-family: var(--font); font-size: 11px; letter-spacing: .02em; text-transform: uppercase; }
.mesa.reservada .m-pax { color: var(--accent-texto); opacity: .85; }
.mesa.dragging { opacity: .75; z-index: 10; cursor: grabbing; box-shadow: var(--sh-3); }

/* Cuenta abierta desde hace más de dos horas: casi siempre es una mesa que
   se quedó sin cobrar. El punto late despacio para que llame sin agobiar. */
.m-aviso {
  position: absolute; top: 6px; right: 6px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 0 rgb(245 158 11 / .55);
  animation: late 2.4s ease-out infinite;
}
@keyframes late {
  0% { box-shadow: 0 0 0 0 rgb(245 158 11 / .5); }
  70% { box-shadow: 0 0 0 9px rgb(245 158 11 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(245 158 11 / 0); }
}
@media (prefers-reduced-motion: reduce) { .m-aviso { animation: none; } }
.plano-mini .m-aviso { width: 14px; height: 14px; top: 4px; right: 4px; }

/* Plano reducido para que quepa entero: el número de mesa se agranda para
   compensar la escala, y lo accesorio —texto menudo y sillas— desaparece
   porque a ese tamaño sólo emborrona. */
.plano-mini .mesa { border-radius: 10px; padding: 4px; border-width: 3px; }
.plano-mini .mesa .m-num { font-size: 26px; }
.plano-mini .mesa .m-pax { display: none; }
.plano-mini .mesa .m-total { font-size: 19px; }
.plano-mini .sillas { display: none; }

.plano-leyenda { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; font-size: 12px; color: var(--text-3); }
.plano-leyenda span { display: inline-flex; align-items: center; gap: 7px; }
.dot { width: 10px; height: 10px; border-radius: 3px; }
.dot.libre { background: var(--ok); } .dot.ocupada { background: var(--danger); } .dot.reservada { background: var(--accent); }

/* ---------------------------------------------------------------- TPV */
/* El TPV ocupa el alto que le deja la pantalla sin calcularlo: la vista se
   vuelve columna y la cuadrícula estira lo que sobra. Antes se restaban
   píxeles a 100dvh y la barra de cuentas, que va debajo en el mismo flujo,
   no entraba en la cuenta: el botón de cobrar quedaba tapado por ella. */
.view:has(> .tpv) { display: flex; flex-direction: column; padding-bottom: 22px; overflow: hidden; }
.view:has(> .tpv) > .tpv { flex: 1; min-height: 0; }
.view:has(> .tpv) > .tpv-conmutador { flex: none; }
#app.comandero .view:has(> .tpv) { padding-bottom: 12px; }
.tpv { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 16px; }
.tpv > * { min-width: 0; }
.tpv-carta { display: flex; flex-direction: column; min-height: 0; min-width: 0; gap: 12px; }
.tpv-buscar { display: flex; gap: 10px; align-items: center; flex: none; }
.tpv-buscar .search-box { flex: 1; min-width: 0; }

/* Los pases del servicio: el que está encendido se lleva lo que se pulse
   después. Van entre el buscador y la carta, donde está el dedo. */
.tpv-pases { display: flex; gap: 8px; flex-wrap: wrap; flex: none; }
.tpv-pases .chip { font-weight: 600; }
/* Cada pase lleva su tono, apagado: un punto y, encendido, un tinte suave
   del mismo color. El color fuerte es para las familias. */
.pase-punto { width: 9px; height: 9px; border-radius: 50%; background: var(--pase); flex: none; }
/* «Pase» delante de los chips: sin él parecen un filtro de la carta. Cuando
   hay uno puesto pasa a «Van a», que es lo que está haciendo. */
.pases-rotulo {
  align-self: center; font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-3); margin-right: 2px;
}
.tpv-pases.con-pase .pases-rotulo { color: var(--accent-texto); }
.pase-quitar { color: var(--text-3); }
.chip .pase-punto { margin-right: -1px; }
.chip.on .pase-punto { box-shadow: 0 0 0 3px color-mix(in srgb, var(--pase) 30%, transparent); }
.tpv-pases .chip.on, .chips .chip.on:has(.pase-punto) {
  background: color-mix(in srgb, var(--pase) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--pase) 55%, transparent);
  color: var(--text);
}

/* En pantalla ancha las familias van en columna, como en un TPV de toda la
   vida: se ven todas de un vistazo y no le quitan alto a la carta. */
@media (min-width: 1150px) {
  .tpv-carta {
    display: grid; gap: 12px;
    grid-template-columns: 190px minmax(0, 1fr);
    grid-template-areas: "buscar buscar" "pases pases" "fam arts";
    grid-template-rows: auto auto minmax(0, 1fr);
  }
  .tpv-carta .tpv-buscar { grid-area: buscar; }
  .tpv-carta .tpv-pases { grid-area: pases; }
  .tpv-carta > .fam-grid {
    grid-area: fam; grid-template-columns: 1fr;
    align-content: start; overflow-y: auto; padding-right: 2px;
  }
  .tpv-carta > .art-grid { grid-area: arts; }
}
/* Entre tablet apaisada y pantalla mediana: rejilla arriba, con tope de
   alto para que no se coma la carta. */
@media (min-width: 900px) and (max-width: 1149px) {
  .tpv-carta > .fam-grid {
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    max-height: 150px; overflow-y: auto;
  }
}
/* ------------------------------------------- familias en dos planos
   Con carta y comanda alternándose (móvil, o modo comandero), las familias
   no caben en rejilla sin dejar los platos fuera de la pantalla: se enseña
   la que está puesta y las demás se despliegan encima de la carta. */
.fam-actual {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 12px 14px; border-radius: 12px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  font-size: 15px; font-weight: 650; text-align: left;
  box-shadow: inset 4px 0 0 var(--fam);
}
.fam-actual .fam-nom {
  flex: 1; min-width: 0; display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fam-actual .chev { transition: transform .18s; flex: none; }
.fam-actual.abierta .chev { transform: rotate(180deg); }
.fam-actual.abierta { border-color: var(--fam); }

/* Tapa la carta mientras se elige, en vez de empujarla: así no salta el
   contenido bajo el dedo. */
.fam-desplegable {
  display: none; position: absolute; left: 0; right: 0; z-index: 5;
  max-height: 62%; overflow-y: auto; padding: 10px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface); box-shadow: var(--sh-3);
}
.fam-desplegable.abierta { display: block; }
.fam-desplegable .fam-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.fam-desplegable .fam-card { padding: 12px 11px 12px 13px; font-size: 13.5px; min-height: 54px; }

/* ---------------------------------------------------- familias del TPV
   Cada familia lleva su color (el de su ficha, o uno estable derivado del
   nombre): el camarero las localiza por color antes de leer el rótulo. */
.fam-grid {
  display: grid; gap: 8px; flex: none;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.fam-card {
  display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 10px 12px; border-radius: 11px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-2);
  font-size: 13px; font-weight: 550; min-width: 0;
  transition: border-color .12s, background .12s, transform .08s;
  /* Franja del color de la familia en el borde de arranque. */
  box-shadow: inset 3px 0 0 var(--fam);
}
.fam-card:hover:not(:disabled) { border-color: var(--fam); background: var(--surface-2); }
.fam-card:active:not(:disabled) { transform: scale(.98); }
.fam-card:disabled { opacity: .45; cursor: default; }
.fam-card.active {
  border-color: var(--fam); background: var(--surface-2); color: var(--text);
  box-shadow: inset 3px 0 0 var(--fam), 0 0 0 1px var(--fam);
}
.fam-punto { width: 10px; height: 10px; border-radius: 50%; background: var(--fam); flex: none; }
.fam-grid .fam-punto { display: none; }
.fam-card { padding-left: 13px; }
/* El nombre puede ocupar dos líneas: recortar «ENSALADAS» a «ENSALA…» hace
   la rejilla inservible, que es justo lo que se venía a arreglar. */
.fam-nom {
  flex: 1; min-width: 0; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
}
.fam-n {
  font-family: var(--mono); font-size: 11px; color: var(--text-3);
  background: var(--surface-3); border-radius: 20px; padding: 1px 7px; flex: none;
}
.fam-card.active .fam-n { background: var(--fam); color: #10131a; font-weight: 700; }
.art-grid {
  flex: 1; overflow-y: auto; display: grid; gap: 10px; align-content: start;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
}
.art-btn {
  padding: 13px 12px; border-radius: var(--r); border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; text-align: left; min-height: 84px;
  display: flex; flex-direction: column; justify-content: space-between; gap: 8px;
  transition: border-color .12s, transform .08s, background .12s;
}
/* El botón se tiñe de su familia. La raya de arriba sola no bastaba: con
   ocho familias en pantalla, la carta se veía como una pared de fichas
   blancas y había que leer cada nombre para orientarse. Teñido, el camarero
   va al bloque de color antes de leer nada, que es de lo que vive un TPV.
   La mezcla es floja a propósito —el nombre y el precio mandan— y va sobre
   --surface, así que el mismo porcentaje sirve en los dos temas. */
.art-btn {
  position: relative;
  box-shadow: inset 0 3px 0 var(--fam, transparent);
  background: color-mix(in srgb, var(--fam, transparent) 7%, var(--surface));
  border-color: color-mix(in srgb, var(--fam, transparent) 22%, var(--line-soft));
}
.art-btn:hover {
  border-color: color-mix(in srgb, var(--fam, var(--accent)) 55%, transparent);
  background: color-mix(in srgb, var(--fam, transparent) 15%, var(--surface));
}
.art-btn:active { transform: scale(.975); }
/* Unidades que ya lleva la comanda de este artículo. La primera línea del
   nombre le deja sitio, o la insignia se le come el final. */
.art-btn[data-cuenta] .a-nom { padding-right: 30px; }
.art-btn[data-cuenta]::after {
  content: attr(data-cuenta);
  position: absolute; top: 6px; right: 6px; min-width: 20px; height: 20px;
  display: grid; place-items: center; padding: 0 5px;
  border-radius: 20px; background: var(--accent); color: #1a1204;
  font-family: var(--mono); font-size: 11px; font-weight: 800;
}
@keyframes art-recien { 0% { transform: scale(1); } 45% { transform: scale(1.06); } 100% { transform: scale(1); } }
.art-btn.recien { animation: art-recien .26s ease; border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .art-btn.recien { animation: none; } }
.art-btn .a-nom { font-size: 12.8px; font-weight: 600; line-height: 1.3; color: var(--text); }
.art-btn .a-pvp { font-family: var(--mono); font-size: 13.5px; font-weight: 700; color: var(--accent-texto); }

.ticket { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.ticket-head { padding: 10px 14px; border-bottom: 1px solid var(--line-soft); display: grid; gap: 2px; }
.ticket-head .t-mesa { font-size: 15px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.ticket-head .t-min { width: 28px; height: 28px; margin-right: -4px; }
.ticket-head .t-min:hover { background: var(--accent-soft); color: var(--accent-texto); }
.ticket-head .t-meta { font-size: 11.5px; color: var(--text-3); display: flex; gap: 9px;
  flex-wrap: wrap; align-items: center; }
.ticket-lineas { flex: 1; overflow-y: auto; padding: 3px 0; min-height: 0; }
.tl {
  display: grid; grid-template-columns: 42px 1fr auto auto; gap: 10px; align-items: center;
  padding: 7px 14px; border-bottom: 1px solid var(--line-soft); cursor: pointer;
}
/* Sumar y quitar unidades desde la propia linea. En el original habia que
   abrir un editor para cambiar una unidad, y es de las cosas que mas veces
   se hacen en un servicio. */
.tl .tl-mas { display: flex; gap: 2px; }
.tl .tl-mas .icon-btn { width: 27px; height: 27px; border-radius: 7px; }
.tl .tl-mas .icon-btn svg { width: 15px; height: 15px; }
.tl:hover { background: var(--surface-2); }
.tl.sel { background: var(--accent-soft); }
.tl .tl-ctdad { font-family: var(--mono); font-weight: 700; text-align: center; background: var(--surface-3);
  border-radius: 7px; padding: 3px 0; font-size: 13px; }
.tl .tl-nom { font-size: 13px; line-height: 1.3; }
.tl .tl-obs { font-size: 11px; color: var(--accent-texto); }
/* Cabecera de cada pase en la comanda: una línea fina del color del pase y
   su nombre en pequeño. Separa los apartados sin robarle sitio a las líneas. */
.tl-grupo {
  display: flex; align-items: center; gap: 7px; padding: 9px 14px 3px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: color-mix(in srgb, var(--pase) 70%, var(--text-2));
}
.tl-grupo::after { content: ""; flex: 1; height: 1px; background: color-mix(in srgb, var(--pase) 40%, var(--line-soft)); }
.tl .tl-imp { font-family: var(--mono); font-weight: 600; font-size: 13px; }
.tl.nueva .tl-ctdad { background: var(--accent-soft); color: var(--accent-texto); }
/* El pie del ticket, al mínimo: cada píxel que se le quita es una línea más
   de comanda visible, que es lo que se está mirando mientras se pide. */
.ticket-tot { border-top: 1px solid var(--line); padding: 9px 16px; display: grid; gap: 4px; }
.tot-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--text-2); }
.tot-row.big { font-size: 21px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
/* La línea de puntos sólo hace falta si hay algo encima de lo que separar. */
.tot-row + .tot-row.big { padding-top: 5px; border-top: 1px dashed var(--line); margin-top: 3px; }
/* La fila del total: a la izquierda los dos botones de cada rato, a la
   derecha el total pegado a su importe. */
.tot-fila { display: flex; align-items: center; gap: 6px; }
.tot-fila .btn-sm { padding: 6px 9px; font-size: 11.5px; }
.tot-total { margin-left: auto; display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.tot-total .tot-rotulo { font-size: 15px; font-weight: 700; color: var(--text); }
.tot-total .tot-imp { font-size: 21px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.tot-row + .tot-fila { padding-top: 5px; border-top: 1px dashed var(--line); margin-top: 3px; }
.ticket-acciones { padding: 9px 12px 11px; border-top: 1px solid var(--line-soft); display: grid; gap: 6px; }
.ticket-acciones .cobrar { flex-direction: row; padding: 12px; font-size: 15px; gap: 8px; }

.numpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.numpad button { padding: 16px 0; font-size: 19px; font-weight: 600; border-radius: 11px;
  border: 1px solid var(--line); background: var(--surface-2); cursor: pointer; }
.numpad button:hover { background: var(--surface-3); }
.numpad .wide { grid-column: span 2; }
/* El fondo de arriba gana por especificidad al de .btn-primary, y el botón de
   aceptar se quedaba con su letra oscura sobre el tile oscuro: presente pero
   ilegible, y quien va a marcar su PIN no encuentra dónde aceptar. */
.numpad button.btn-primary {
  background: linear-gradient(140deg, var(--accent), #ea8a06);
  border-color: transparent; color: #1a1207;
}
.numpad button.btn-primary:hover { background: linear-gradient(140deg, var(--accent-2), var(--accent)); }

/* ------------------------------------------------------------ gráfica */
.chart { width: 100%; display: block; overflow: visible; }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .grid-l { stroke: var(--line-soft); stroke-width: 1; stroke-dasharray: 3 4; }
.chart .lbl { fill: var(--text-3); font-size: 10.5px; font-family: var(--font); }
.chart .bar { fill: var(--serie-1); rx: 3; transition: opacity .12s; }
.chart .bar:hover { opacity: .75; }
.chart .line { fill: none; stroke: var(--serie-1); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { fill: url(#gArea); }
.chart .pt { fill: var(--serie-1); }
.chart .bar2 { fill: var(--serie-2); rx: 3; }

.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--text-2); margin-top: 10px; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend .sw { width: 11px; height: 11px; border-radius: 3px; }

.bars-h { display: grid; gap: 9px; }
.bar-h { display: grid; grid-template-columns: 1fr auto; gap: 4px; font-size: 12.5px;
  padding: 3px 6px; margin: 0 -6px; border-radius: 7px; transition: background .12s; }
.bar-h:hover { background: var(--surface-2); }
.bar-h .bh-etq { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-h .bh-track { grid-column: 1 / -1; height: 7px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.bar-h .bh-fill { height: 100%; border-radius: 0 4px 4px 0; background: var(--serie-1); }
.bar-h .bh-val { font-family: var(--mono); font-weight: 600; }

/* ------------------------------------------------- cuentas abiertas */
/* Franja inferior con las ventas en curso: permite salir a cualquier
   pantalla sin perder de vista las cuentas ni el camino de vuelta. */
.dock {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 6px 14px; border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(14px);
  box-shadow: 0 -8px 24px -14px rgba(0, 0, 0, .5);
}
.dock-tit {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-3); white-space: nowrap; padding-right: 2px;
}
.dock-lista { display: flex; gap: 7px; overflow-x: auto; flex: 1; padding: 2px; min-width: 0; }
.dock-item {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 5px 8px 5px 10px; border-radius: 9px; cursor: pointer; text-align: left;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  transition: border-color .12s, transform .08s, background .12s;
}
.dock-item:hover { border-color: var(--accent-line); transform: translateY(-1px); }
.dock-item.activa { border-color: var(--accent); background: var(--accent-soft); }
.dock-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); flex: none; }
.dock-item.activa .dock-punto { background: var(--accent); }
.dock-item.vacia .dock-punto { background: var(--text-3); }
.dock-txt { display: flex; align-items: baseline; gap: 5px; line-height: 1.3; min-width: 0; }
.dock-txt strong { font-size: 13px; white-space: nowrap; }
.dock-txt small { font-size: 11px; color: var(--text-3); white-space: nowrap; }
.dock-txt small::before { content: "· "; }
.dock-imp { font-family: var(--mono); font-weight: 700; font-size: 13px; color: var(--accent-texto); margin-left: 2px; }
.dock-x {
  width: 20px; height: 20px; display: grid; place-items: center; flex: none;
  border-radius: 6px; border: 0; background: none; color: var(--text-3); cursor: pointer;
}
.dock-x:hover { background: var(--surface-3); color: var(--danger); }

@media (max-width: 700px) {
  .dock { padding: 8px 10px; gap: 8px; }
  .dock-tit { display: none; }
  .dock-txt small { display: none; }
}

/* -------------------------------------------------------------- modal */
.modal-back {
  position: fixed; inset: 0; z-index: 100; background: rgba(3, 6, 12, .68);
  backdrop-filter: blur(4px); display: grid; place-items: center; padding: 20px;
  animation: fade .16s ease;
}
@keyframes fade { from { opacity: 0; } }
.modal {
  width: min(var(--mw, 560px), 100%); max-height: 88dvh; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-xl);
  box-shadow: var(--sh-3); overflow: hidden; animation: pop .18s cubic-bezier(.2,.9,.3,1.1);
}
@keyframes pop { from { transform: translateY(14px) scale(.98); opacity: 0; } }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line-soft); }
.modal-head h3 { font-size: 16px; }
.modal-head .icon-btn { margin-left: auto; }
.modal-body { padding: 20px; overflow-y: auto; flex: 1; }
.modal-foot { padding: 14px 20px; border-top: 1px solid var(--line-soft); display: flex; gap: 9px; justify-content: flex-end; }

/* ---------------------------------------------------- fichas maestras
   Las secciones llevan icono y una línea de qué van, y el artículo lleva
   al lado el resumen de cómo queda (el botón del TPV, el margen, avisos),
   fijo mientras se baja por la ficha. */
.ficha-cuerpo.con-resumen { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; align-items: start; }
@media (max-width: 1100px) { .ficha-cuerpo.con-resumen { grid-template-columns: minmax(0, 1fr); } .ficha-resumen { order: -1; } }
.ficha-resumen { position: sticky; top: 0; }
.ficha-seccion { gap: 10px; }
.ficha-seccion .muted { font-size: 12px; margin-left: 2px; }
.ficha-seccion-icono {
  width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-texto); flex: none;
}
.ficha-seccion-icono i[data-icon] { width: 15px; height: 15px; }
.resumen-boton {
  display: flex; flex-direction: column; justify-content: space-between; gap: 10px; min-height: 84px;
  padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line);
  border-left: 5px solid var(--fam, var(--accent)); background: var(--surface-2);
}
.resumen-boton .a-nom { font-weight: 700; font-size: 15px; line-height: 1.25; overflow-wrap: anywhere; }
.resumen-boton .a-pvp { font-size: 22px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--fam, var(--accent-texto)); }
.resumen-datos { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin: 14px 0 0; font-size: 13px; }
.resumen-datos dt { color: var(--text-3); }
.resumen-datos dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.resumen-datos dd.ok { color: var(--ok); }
.resumen-datos dd.warn { color: var(--accent-texto); }
.resumen-datos dd.danger { color: var(--danger); }
.resumen-aviso {
  display: flex; gap: 8px; align-items: flex-start; margin-top: 10px; padding: 8px 10px; border-radius: 9px;
  background: var(--accent-soft); color: var(--accent-texto); font-size: 12.5px; line-height: 1.4;
}
.resumen-aviso i[data-icon] { width: 15px; height: 15px; flex: none; margin-top: 1px; }

.form-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px; }
.form-grid .field { grid-column: span var(--w, 12); }

/* La rejilla de 12 columnas se estrecha por tramos en vez de mantenerse
   fija: en un móvil, un campo de 3 columnas medía 70 px y no se leía ni la
   fecha que contenía. Al bajar el número de columnas, los campos anchos
   pasan a ocupar la fila entera y los estrechos se emparejan de dos en dos. */
@media (max-width: 900px) {
  .form-grid { grid-template-columns: repeat(8, 1fr); gap: 12px; }
  .form-grid .field { grid-column: span min(var(--w, 8), 8); }
}
@media (max-width: 620px) {
  .form-grid { grid-template-columns: repeat(4, 1fr); }
  .form-grid .field { grid-column: span min(var(--w, 4), 4); }
}
@media (max-width: 420px) {
  /* Aquí ya no cabe nada en paralelo: cada campo, su fila. */
  .form-grid { grid-template-columns: 1fr; gap: 11px; }
  .form-grid .field { grid-column: 1 / -1; }
}
.form-section { grid-column: 1 / -1; margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line-soft);
  font-size: 11.5px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .06em; }
.form-section:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* --------------------------------------------- pantallas informativas
   Las que explican cómo funciona algo en cloud. Con el icono en un disco
   de color y el texto al lado se leen como una guía y no como una lista
   de párrafos sueltos. */
.info-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
}
.info-card {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 18px; border-radius: var(--r-lg);
  border: 1px solid var(--line); background: var(--surface);
  transition: border-color .14s, transform .14s;
}
.info-card:hover { border-color: var(--accent-line); transform: translateY(-1px); }
.info-ico {
  flex: none; width: 42px; height: 42px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-texto);
}
.info-ico svg { width: 21px; height: 21px; }
.info-txt { min-width: 0; }
.info-txt h3 { font-size: 14.5px; font-weight: 650; margin-bottom: 5px; }
.info-txt p { font-size: 13px; line-height: 1.65; color: var(--text-2); }
.info-txt p em { color: var(--text); font-style: normal; font-weight: 550; }

.info-nota {
  display: flex; gap: 12px; align-items: flex-start; margin-top: 16px;
  padding: 15px 18px; border-radius: var(--r-lg);
  border: 1px solid var(--accent-line); background: var(--accent-soft);
}
.info-nota svg { width: 19px; height: 19px; flex: none; color: var(--accent-texto); margin-top: 1px; }
.info-nota p { font-size: 13px; line-height: 1.65; }

@media (max-width: 560px) {
  .info-grid { grid-template-columns: 1fr; }
  .info-card { padding: 15px; gap: 12px; }
  .info-ico { width: 36px; height: 36px; border-radius: 10px; }
}

/* ------------------------------------------------------------- toasts */
.toasts { position: fixed; bottom: 20px; right: 20px; z-index: 200; display: grid; gap: 9px; max-width: 380px; }
.toast {
  display: flex; align-items: flex-start; gap: 11px; padding: 12px 15px; border-radius: var(--r);
  background: var(--surface-3); border: 1px solid var(--line); box-shadow: var(--sh-2);
  font-size: 13px; animation: slide .2s cubic-bezier(.2,.9,.3,1.1);
}
@keyframes slide { from { transform: translateX(20px); opacity: 0; } }
.toast.ok i { color: var(--ok); } .toast.err i { color: var(--danger); } .toast.info i { color: var(--info); }
.toast i { margin-top: 1px; flex: none; }

/* ------------------------------------------------------------ ticket impreso */
.recibo {
  font-family: var(--mono); font-size: 12px; background: #fff; color: #111;
  padding: 18px; border-radius: var(--r); max-width: 340px; margin: 0 auto; line-height: 1.55;
}
.recibo hr { border: 0; border-top: 1px dashed #999; margin: 8px 0; }
.recibo .r-cab { text-align: center; }
.recibo .r-cab strong { font-size: 14px; }
.recibo table { font-size: 11.5px; }
.recibo td { padding: 1px 0; border: 0; color: #111; }
.recibo .r-tot { display: flex; justify-content: space-between; font-size: 15px; font-weight: 700; }

/* ------------------------------------------------------------ responsive */
@media (max-width: 1180px) {
  .tpv { grid-template-columns: minmax(0, 1fr) 340px; }
  .art-grid { grid-template-columns: repeat(auto-fill, minmax(126px, 1fr)); }
}
@media (max-width: 980px) {
  .login { grid-template-columns: 1fr; }
  .login-art { display: none; }
  #app { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; inset: 0 auto 0 0; width: var(--sidebar-w); z-index: 60;
    transform: translateX(-100%); transition: transform .22s cubic-bezier(.3,.8,.3,1);
    box-shadow: var(--sh-3);
  }
  .sidebar.abierta { transform: none; }
  .sidebar .sidebar-close { display: grid; }
  .only-mobile { display: grid; }
  .view { padding: 16px 14px 60px; }
}

/* =====================================================================
   TPV en pantalla estrecha (móvil y tablet en vertical)
   ---------------------------------------------------------------------
   Apilar carta y comanda deja las dos inservibles: la carta enseña dos
   productos y la comanda ni una línea. Se muestran como dos planos a
   pantalla completa y se alterna con la barra de abajo, que lleva
   siempre el importe a la vista.
   ===================================================================== */
@media (max-width: 899px) {
  .tpv-paneles { display: block; position: relative; }
  .tpv-paneles > .tpv-carta,
  .tpv-paneles > .ticket { height: 100%; }
  /* Sólo se muestra el plano activo; el otro no ocupa ni se puede tabular. */
  .tpv-paneles[data-panel="carta"] > .ticket,
  .tpv-paneles[data-panel="comanda"] > .tpv-carta { display: none; }

  .tpv-paneles .art-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px; padding-bottom: 6px;
  }
  .tpv-paneles .art-btn { min-height: 76px; padding: 12px 11px; }
  .tpv-paneles .art-btn .a-nom { font-size: 13.5px; }

  /* La comanda a pantalla completa: es lo que se pidió ver mejor. */
  .tpv-paneles .ticket-lineas { padding: 4px 0; }
  .tpv-paneles .tl { padding: 12px 14px; grid-template-columns: 46px 1fr auto auto; }
  .tpv-paneles .tl .tl-nom { font-size: 14.5px; }
  .tpv-paneles .tl .tl-ctdad { font-size: 15px; padding: 5px 0; }
  .tpv-paneles .tl .tl-imp { font-size: 14.5px; }
  /* Cobrar ya está en la barra de abajo: aquí sobra y roba sitio. */
  .tpv-paneles .ticket-acciones { display: none; }
  .tpv-paneles .ticket-tot { padding: 10px 14px; }
  .tpv-paneles .tot-fila .btn-sm { padding: 9px 11px; font-size: 12.5px; }

  /* Buscador y familias */
  .tpv-buscar { display: flex; gap: 8px; align-items: center; }
  .tpv-buscar .search-box { flex: 1; min-width: 0; }

  .tpv-buscar .btn { flex: none; }
  .solo-ancho { display: none; }

  /* Barra que alterna carta y comanda */
  .tpv-conmutador {
    display: flex; gap: 8px; align-items: stretch;
    padding: 8px 0 0;
  }
  .conm-btn {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 9px;
    min-height: 54px; padding: 0 16px; border-radius: 13px; cursor: pointer;
    border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
    font-size: 14.5px; font-weight: 650;
  }
  .conm-btn:disabled { opacity: .5; cursor: default; }
  .conm-btn .conm-txt { flex: 1; text-align: left; }
  .conm-btn .conm-imp { font-family: var(--mono); font-weight: 800; font-size: 16px; }
  .conm-ver { border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent-texto); }
  .conm-cobrar {
    flex: 0 0 46%; justify-content: center;
    background: var(--accent); border-color: var(--accent); color: #1a1204;
  }
  .conm-cobrar .conm-imp { font-size: 18px; }
  .conm-cobrar .solo-ancho { display: none; }
}
@media (min-width: 400px) and (max-width: 899px) {
  .conm-cobrar .solo-ancho { display: inline; }
}

/* Tablet en vertical: caben más columnas que en un móvil. */
@media (min-width: 600px) and (max-width: 899px) {
  .tpv-paneles .art-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
  .fam-desplegable .fam-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
  .solo-ancho { display: inline; }
}

/* La barra superior no puede desbordarse en pantallas estrechas. */
@media (max-width: 700px) {
  .topbar { padding: 0 12px; }
  .clock { display: none; }
  .crumbs span:not(:last-child), .crumbs .sep { display: none; }
  .crumbs span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 560px) {
  .page-actions { width: 100%; }
  .kpi .k-value { font-size: 22px; }
  .modal { border-radius: var(--r-lg); }
}

@media print {
  .sidebar, .topbar, .page-actions, .toolbar, .toasts { display: none !important; }
  #app { display: block; }
  .view { overflow: visible; padding: 0; }
  body { background: #fff; }
  .card { break-inside: avoid; border-color: #ccc; box-shadow: none; }
}

/* --------------------------------------------- vista previa del ticket
   El papel se pinta siempre en claro aunque la aplicación esté en oscuro:
   lo que se está juzgando es cómo saldrá impreso, no cómo se ve en pantalla. */
.ticket-previa {
  --tk-w: 320px;
  width: var(--tk-w);
  padding: 16px 14px;
  border-radius: var(--r-lg);
  background: #fff;
  color: #000;
  box-shadow: 0 10px 30px rgb(0 0 0 / .18);
  /* Borde dentado del papel térmico, arriba y abajo. */
  clip-path: polygon(0 6px, 4% 0, 8% 6px, 12% 0, 16% 6px, 20% 0, 24% 6px, 28% 0, 32% 6px,
    36% 0, 40% 6px, 44% 0, 48% 6px, 52% 0, 56% 6px, 60% 0, 64% 6px, 68% 0, 72% 6px, 76% 0,
    80% 6px, 84% 0, 88% 6px, 92% 0, 96% 6px, 100% 0, 100% 100%, 0 100%);
  overflow: hidden;
}
.ticket-papel {
  font-family: ui-monospace, 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.45;
}
.ticket-papel hr { border: 0; border-top: 1px dashed #999; margin: 7px 0; }
.ticket-papel table { width: 100%; border-collapse: collapse; }
.ticket-papel td { padding: 1px 0; vertical-align: top; }
.ticket-papel .c { text-align: center; }
.ticket-papel .r { text-align: right; }
.ticket-papel .b { font-weight: 700; }
.ticket-papel .big { font-size: 15px; }

/* Formulario a la izquierda y papel a la derecha; en pantalla estrecha,
   el papel baja debajo en vez de estrujar los campos. */
.ticket-editor {
  grid-template-columns: minmax(340px, 1fr) auto;
  gap: 16px;
  align-items: start;
}
@media (max-width: 900px) {
  .ticket-editor { grid-template-columns: 1fr; }
  .ticket-previa { margin-inline: auto; }
}

/* ------------------------------------------------------ modo comandero
   Interfaz reducida para el móvil del camarero: fuera el árbol de menús y
   los accesos donde llega el pulgar, no arriba del todo. */
/* La clase va en el propio #app, no en un antecesor: las reglas se escriben
   con `#app.comandero`. Las de antes iban con `.comandero #app` y no
   aplicaban nunca. */
#app.comandero { grid-template-columns: 1fr; --nav-h: 66px; }
#app.comandero .sidebar {
  position: fixed; inset: 0 auto 0 0; z-index: 60; width: var(--sidebar-w);
  transform: translateX(-100%); transition: transform .18s ease;
}
#app.comandero .sidebar.abierta { transform: none; }
#app.comandero .only-ancho { display: none; }
#app.comandero .only-mobile { display: inline-flex; }
/* Arriba se queda lo justo: el reloj y el interruptor del tema. Los atajos
   y el resto de accesos viven en la barra de abajo. */
#app.comandero .atajos-barra { display: none; }
#app.comandero .topbar-actions .icon-btn[title="Ir al TPV"] { display: none; }
#app.comandero .topbar-actions .icon-btn[title="Modo comandero"] { color: var(--accent); background: var(--accent-soft); }
#app.comandero .view { padding-bottom: calc(var(--nav-h) + 16px); }

/* La barra de accesos del comandero. Botones de pulgar: 66 px de alto,
   icono grande y una palabra debajo, repartidos a lo ancho. */
.barra-comandero {
  position: sticky; bottom: 0; z-index: 25; flex: none;
  display: flex; align-items: stretch; height: var(--nav-h);
  background: var(--bg-2); border-top: 1px solid var(--line-soft);
  padding-bottom: env(safe-area-inset-bottom);
}
.bc-btn {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 0; background: transparent; color: var(--text-3); cursor: pointer; font-size: 11px; font-weight: 600;
  padding: 6px 2px; position: relative;
}
.bc-btn i, .bc-btn svg { width: 22px; height: 22px; }
.bc-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.bc-btn:active { background: var(--surface-2); }
.bc-btn.on { color: var(--accent-texto); }
.bc-btn.on::before {
  content: ""; position: absolute; top: 0; left: 22%; right: 22%; height: 3px;
  border-radius: 0 0 3px 3px; background: var(--accent);
}

/* En comandero, el dock de cuentas sobra en las pantallas que ya enseñan lo
   mismo: en el TPV la cuenta en curso está en la barra de abajo, y en el
   plano las mesas abiertas se ven de un vistazo. Dos franjas apiladas se
   comían media pantalla. */
#app.sin-dock .dock { display: none; }

/* En modo comandero el plano ocupa el hueco que queda y se reduce hasta
   caber entero: el camarero localiza la mesa de un vistazo, sin arrastrar.
   La altura la fija aquí el hueco disponible, y `encajar()` calcula la
   escala con ella. */
#app.comandero .plano { min-height: 0; overflow: hidden; }
/* La leyenda del plano sobra en una pantalla donde el color ya se entiende
   y cada píxel cuenta. */
#app.comandero .plano-leyenda { display: none; }

/* Cabecera al mínimo en el plano: cada línea que se quita aquí es una línea
   de mesas más grandes abajo, que es lo único que se mira. El título ya está
   en la barra superior y «Venta de barra» está en la barra inferior, así que
   los dos sobran; queda el recuento, que sí informa. */
#app.comandero.en-plano .page-head {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
}
#app.comandero.en-plano .page-head h2 { display: none; }
#app.comandero.en-plano .page-head > div:first-child { flex: 1; min-width: 0; }
#app.comandero.en-plano .page-head .sub { margin: 0; font-size: 12.5px; }
#app.comandero.en-plano .page-actions { width: auto; flex: none; gap: 6px; }
/* «Venta de barra» ya está en la barra de abajo, y «Actualizar» se queda en
   su icono: el rótulo no aporta y cada línea que se ahorra aquí son mesas
   más grandes. */
#app.comandero.en-plano #btn-barra { display: none; }
#app.comandero.en-plano #btn-refrescar { padding: 9px 10px; gap: 0; }
#app.comandero.en-plano #btn-refrescar .btn-txt { display: none; }
/* Sin el recuento de mesas, las pestañas de salón caben en una sola fila. */
#app.comandero.en-plano .salon-tab small { display: none; }
#app.comandero.en-plano .salon-tabs { flex-wrap: nowrap; overflow-x: auto; }
#app.comandero.en-plano .salon-tab { flex: none; }
/* El hueco inferior de la vista lo ocupan ya las barras fijas. */
#app.comandero.en-plano .view { padding-bottom: 10px; }

/* Pestañas de salón compactas. */
#app.comandero .salon-tabs { margin-bottom: 10px; gap: 6px; }
#app.comandero .salon-tab { padding: 7px 12px; font-size: 13px; }

/* Cuenta de barra abierta: va con las pestañas de salón porque la barra es
   un sitio más del local, y es lo único que el plano no puede enseñar. */
.barra-tab {
  border-color: var(--danger); color: var(--danger);
  background: var(--danger-soft);
}
.barra-tab:hover { border-color: var(--danger); background: var(--danger-soft); filter: brightness(1.12); }
.barra-tab svg { width: 15px; height: 15px; }

.comandero-nav {
  flex: none; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 6px; padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line); background: var(--surface);
}
.comandero-nav button {
  display: grid; justify-items: center; gap: 3px;
  padding: 9px 4px; border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--text-2);
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  /* Objetivo táctil cómodo con el móvil en una mano. */
  min-height: 56px;
}
.comandero-nav button svg { width: 22px; height: 22px; }
.comandero-nav button:hover { background: var(--surface-2); }
.comandero-nav button.activo { color: var(--accent); background: var(--accent-soft); }

/* Selector de opciones del modo comandero (Parámetros Generales). */
.comandero-picker {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 6px;
  max-height: 46dvh; overflow: auto; padding: 2px;
}
.comandero-op {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border: 1px solid var(--line); border-radius: var(--r-md);
  cursor: pointer; font-size: 13px;
}
.comandero-op:hover { border-color: var(--accent-line); }
.comandero-op.on { border-color: var(--accent); background: var(--accent-soft); }
.comandero-op small { display: block; font-size: 11px; }
.comandero-orden {
  flex: none; width: 22px; height: 22px; display: grid; place-items: center;
  border-radius: 50%; background: var(--accent); color: #1a1204;
  font-size: 11px; font-weight: 800;
}

/* --------------------------------------------------- documentos de venta */
/* Los campos heredan width:100%, que es lo que quieren dentro de un
   formulario y lo que estorba en una barra de filtros: ahí cada uno ocupa
   lo suyo y comparten fila. */
.toolbar .filtro { width: auto; flex: none; min-width: 148px; }

/* Dentro de la tabla el campo es la celda: sin marco propio, para que la
   linea se lea como una fila y no como un formulario apretado. */
.table .celda {
  padding: 5px 8px; font-size: 13px; background: transparent;
  border-color: transparent; border-radius: 7px;
}
.table .celda:hover { border-color: var(--line); background: var(--surface-2); }
.table .celda:focus { background: var(--surface-2); }
.table .celda.n { text-align: right; font-variant-numeric: tabular-nums; }

/* Sin las flechas del campo numerico: en una celda estrecha se comen la
   cifra, y aqui las cantidades se teclean, no se suben de una en una. */
.table .celda[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.table .celda[type="number"]::-webkit-outer-spin-button,
.table .celda[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}

.doc-totales {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

/* ------------------------------------------------------ configuracion */
/* La previa del ticket va al lado del formulario mientras quepa; por
   debajo de eso se pone encima, que es peor pero se sigue viendo. */
.cfg-ticket { display: grid; gap: 14px; grid-template-columns: minmax(0, 1fr) 340px; }
@media (max-width: 1000px) { .cfg-ticket { grid-template-columns: 1fr; } }
.cfg-impresoras { display: grid; gap: 14px; max-width: 900px; }

/* Papel blanco de verdad, tambien en tema oscuro: la previa tiene que
   parecerse al ticket que sale de la termica, no a la aplicacion. */
.ticket-previa {
  background: #fff; color: #000; padding: 14px; border-radius: 8px;
  font-family: ui-monospace, 'Courier New', monospace; font-size: 12px;
  max-height: 620px; overflow: auto;
}
.ticket-previa hr { border: 0; border-top: 1px dashed #888; margin: 7px 0; }
.ticket-previa table { width: 100%; border-collapse: collapse; }
.ticket-previa td { padding: 1px 0; }
.ticket-previa .c { text-align: center; }
.ticket-previa .r { text-align: right; }
.ticket-previa .b { font-weight: 700; }
.ticket-previa .big { font-size: 15px; }

/* Etiquetas que se encienden al pulsarlas: elegir varias cosas de una
   lista corta sin gastar una tabla con casillas. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 999px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text-2);
  transition: background .13s, border-color .13s, color .13s;
}
.chip:hover { background: var(--surface-3); }
.chip.on { border-color: transparent; background: var(--accent-soft); color: var(--accent-texto); }
.chip:disabled { opacity: .5; cursor: not-allowed; }
.chip svg { width: 15px; height: 15px; }

/* ---------------------------------------------------- editor de plano */
/* El cursor dice que la mesa se puede coger; sin eso nadie descubre que
   el plano se edita arrastrando. */
.plano-inner.editor .mesa { cursor: grab; user-select: none; }
.plano-inner.editor .mesa.arrastrando {
  cursor: grabbing; z-index: 20; opacity: .85;
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .55);
}
/* Rejilla de ayuda: colocar mesas a ojo sobre un liso sale torcido. Va en
   una capa por encima del suelo, no en su lugar: así se ve la tarima o la
   foto tal como quedará en el plano de ventas. */
.plano-inner.editor::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgb(255 255 255 / .06) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / .06) 1px, transparent 1px);
  background-size: 40px 40px;
}

/* --------------------------------------------------- dividir comanda */
.linea-elegible {
  display: flex; gap: 10px; align-items: center; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; cursor: pointer;
}
.linea-elegible:hover { background: var(--surface-2); }
.linea-elegible .grow { flex: 1; min-width: 0; }

/* La linea de la comanda se abre al pulsarla. */
.tl.clickable { cursor: pointer; }
.tl.clickable:hover { background: var(--surface-2); }

/* ------------------------------------------------------------- cobro */
/* Formas de pago como botones grandes: cobrar es lo que mas se repite en
   un servicio, y en una pantalla tactil un desplegable son tres gestos
   donde esto es uno. */
.fpagos { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); }
.fpago {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: 12px 8px; border-radius: 12px; cursor: pointer; font-size: 13px; font-weight: 550;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text-2);
  transition: background .12s, border-color .12s, color .12s, transform .06s;
  min-height: 68px; text-align: center;
}
.fpago span { line-height: 1.2; }
.fpago svg { width: 20px; height: 20px; }
.fpago:hover { background: var(--surface-3); color: var(--text); }
.fpago:active { transform: translateY(1px); }
/* La elegida se ve de un vistazo desde lejos, que es como se mira la
   pantalla al cobrar. */
.fpago.on {
  border-color: transparent; color: #1a1207; font-weight: 650;
  background: linear-gradient(140deg, var(--accent), #ea8a06);
  box-shadow: 0 4px 14px -6px rgba(245, 158, 11, .7);
}

/* ------------------------------------------- buscador de clientes */
.lista-clientes {
  display: grid; gap: 4px; margin-bottom: 14px;
  max-height: 40vh; overflow: auto;
}
.cliente-fila {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 11px; border-radius: 9px; cursor: pointer; text-align: left;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  transition: background .12s, border-color .12s;
}
.cliente-fila:hover { background: var(--surface-3); border-color: var(--accent-line); }
.cliente-fila .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* El cliente asignado, en la cabecera de la comanda. */
.t-cliente {
  display: flex; align-items: center; gap: 7px; width: 100%;
  margin-top: 8px; padding: 6px 9px; border-radius: 9px; cursor: pointer;
  font-size: 12.5px; text-align: left;
  border: 1px solid var(--accent-line); background: var(--accent-soft); color: var(--accent-texto);
}
.t-cliente:hover { background: var(--surface-3); }
.t-cliente span:first-of-type { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-cliente svg { width: 15px; height: 15px; flex: none; }

/* ------------------------------------------------- barra que se pliega */
/* La columna se cierra a cero en vez de esconderse con `display`, para que
   la transicion se vea y el contenido gane el ancho sin dar un salto. */
#app { transition: grid-template-columns .2s cubic-bezier(.3,.8,.3,1); }
#app.plegado { grid-template-columns: 0 1fr; }
#app.plegado .sidebar { overflow: hidden; border-right: 0; }
/* En comandero la barra lateral no ocupa columna (va flotando), así que el
   pliegue no pinta nada: con las dos clases, el contenido se metía en la
   columna de cero ancho y quedaba una tira de nada. */
#app.comandero.plegado { grid-template-columns: 1fr; }

.only-ancho { display: grid; }

/* ------------------------------------------- atajos en la barra de arriba */
.atajos-barra {
  display: flex; align-items: center; gap: 6px; min-width: 0;
  overflow-x: auto; scrollbar-width: none;
}
.atajos-barra::-webkit-scrollbar { display: none; }

.atajo-btn {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 6px 11px; border-radius: 999px; cursor: pointer; font-size: 13px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text-2);
  transition: background .12s, border-color .12s, color .12s;
  white-space: nowrap;
}
.atajo-btn:hover { background: var(--surface-3); color: var(--text); }
.atajo-btn svg { width: 15px; height: 15px; flex: none; }
/* El atajo de la pantalla en la que se esta, encendido: asi la barra dice
   tambien donde estas, que es lo que hacian las migas de pan. */
.atajo-btn.on {
  border-color: transparent; background: var(--accent-soft);
  color: var(--accent-texto); font-weight: 600;
}
.atajo-editar { border-style: dashed; color: var(--text-3); }
.atajo-editar:hover { border-style: solid; }

.atajos-elegidos { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }
.lista-atajos { display: grid; gap: 4px; max-height: 46vh; overflow: auto; }
.lista-atajos .cliente-fila svg { width: 16px; height: 16px; flex: none; }

@media (max-width: 900px) {
  /* En estrecho manda el boton que saca el menu por encima, y los atajos
     ceden el sitio: en una barra de 360 px no caben con el reloj. */
  .only-ancho { display: none; }
  .atajos-barra .atajo-btn span { display: none; }
  .atajos-barra .atajo-btn { padding: 6px 9px; }
}

/* Los botones de accion de una fila, juntos y sin envolver. */
.acciones-fila { white-space: nowrap; }
.acciones-fila .btn + .btn { margin-left: 5px; }


/* =====================================================================
   Los cuatro indicadores del panel

   Eran cuatro rectángulos blancos iguales, y lo primero que se ve al
   entrar. Cada uno lleva ahora su color —el del dinero es el de la marca,
   los otros salen de los semánticos ya definidos— en dos sitios: un filo
   arriba y la pastilla del icono. Con eso se distinguen de un vistazo y la
   pantalla deja de parecer una hoja de cálculo.

   El color va sólo en el filo y el icono, nunca en la cifra ni en el
   fondo: la cifra tiene que leerse al máximo contraste y cuatro tarjetas
   de colores distintos serían un semáforo, no un panel.
   ===================================================================== */
.kpi { --k: var(--accent); padding-top: 17px; }
.kpi::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 3px;
  background: linear-gradient(90deg, var(--k), color-mix(in srgb, var(--k) 25%, transparent));
}
.g-kpi > .kpi:nth-child(2) { --k: var(--info); }
.g-kpi > .kpi:nth-child(3) { --k: var(--ok); }
.g-kpi > .kpi:nth-child(4) { --k: var(--kpi-4); }

/* El icono deja de ser un garabato gris al lado del rótulo y pasa a ser una
   pastilla del color de la tarjeta, que es lo que la ata a su filo. */
.kpi .k-label { gap: 9px; }
.kpi .k-label > i {
  width: 26px; height: 26px; flex: none; display: grid; place-items: center;
  border-radius: 8px; color: var(--k);
  background: color-mix(in srgb, var(--k) 13%, transparent);
}
.kpi .k-label > i svg { width: 15px; height: 15px; }
.kpi .k-value { font-size: 29px; margin-top: 2px; }

/* La cifra de dinero se escribe con el ámbar legible de cada tema; el resto
   con el color normal del texto, que es lo que más contrasta. */
.kpi .k-value.k-accent { color: var(--accent-texto); }


/* ----------------------------------------------- familias de la carta
   El color de una familia se elige con el selector nativo del navegador,
   que en un TPV táctil es lo que mejor funciona: abre la paleta del sistema.
   Se le quita el marco por defecto para que parezca una muestra y no un
   campo de formulario. */
.color-eleccion { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.color-eleccion input[type="color"] {
  width: 44px; height: 34px; padding: 2px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface);
}
.color-eleccion input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.color-eleccion input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 6px; }
.color-eleccion .muted { font-size: 12px; flex: 1; min-width: 180px; }

/* El punto de color en la tabla de familias: el mismo que lleva la botonera. */
.table .fam-punto { display: inline-block; vertical-align: middle; }

/* En pantalla estrecha las dos tarjetas van una bajo otra y sobran las
   columnas de interruptores: lo que importa es el nombre y cuántos artículos
   tiene. Los interruptores siguen en la ficha. */
@media (max-width: 1100px) {
  .familias .opc { display: none; }
}


/* ------------------------------------------------------ cierre y arqueo */
.ok-txt { color: var(--ok); font-weight: 700; }
.danger-txt { color: var(--danger); font-weight: 700; }

/* El aviso de cuentas sin cobrar va en ámbar y no en rojo: no es un error,
   es algo que hay que mirar antes de cerrar. */
.aviso-caja { margin-bottom: 16px; border-color: var(--accent-line); background: var(--accent-soft); }
.aviso-caja strong { display: flex; align-items: center; gap: 8px; color: var(--accent-texto); }

/* El recuento se hace de pie, con el cajón abierto y a menudo en una
   tableta: por eso cada fila lleva sus botones de más y menos, grandes, y
   el número queda en medio para quien prefiera teclearlo. */
.recuento { display: grid; gap: 6px; }
.recuento-fila {
  display: grid; grid-template-columns: 74px 38px 1fr 38px 100px; gap: 8px; align-items: center;
  padding: 4px 6px; border-radius: 10px;
}
.recuento-fila.con { background: var(--surface-2); }
.recuento-fila input { text-align: center; font-family: var(--mono); font-size: 15px; padding: 7px 4px; }
.recuento-fila .btn.btn-sm { justify-content: center; padding: 0; height: 36px; font-size: 18px; font-weight: 700; }
.recuento-fila .n { text-align: right; color: var(--text-2); }
.recuento-fila.con .n { color: var(--text); font-weight: 700; }
@media (max-width: 480px) {
  .recuento-fila { grid-template-columns: 60px 36px 1fr 36px 84px; gap: 5px; }
}


/* Fila que pide atención en un listado (un artículo bajo mínimo). */
tbody tr.fila-aviso td { background: color-mix(in srgb, var(--danger) 6%, transparent); }

/* El velo que oscurece la pantalla cuando el menú lateral se saca por
   encima (móvil y comandero); pulsarlo cierra el menú. */
.nav-velo { position: fixed; inset: 0; z-index: 55; background: rgb(0 0 0 / .45); }

/* La cuenta sin camarero se nota: es la que luego no cuadra en el reparto
   de propinas ni en el listado por camarero. */
.t-meta .btn.sin-camarero { color: var(--accent-texto); border-color: var(--accent-line); }
.t-meta .btn i, .t-meta .btn svg { width: 13px; height: 13px; }
/* Los dos botones de la cabecera (pax y camarero), juntos y a la derecha. */
.t-meta .t-meta-acciones { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }

/* ----------------------------------------------------- reconexión
   El cartel que Blazor enseña mientras intenta volver a conectar. Oculto
   salvo cuando lleva la clase que le pone el propio Blazor. */
#components-reconnect-modal { display: none; }
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
  display: grid; place-items: center; position: fixed; inset: 0; z-index: 10000;
  background: color-mix(in srgb, var(--bg) 75%, transparent); backdrop-filter: blur(4px);
}
.reconexion-caja {
  display: grid; justify-items: center; gap: 8px; text-align: center;
  padding: 26px 30px; border-radius: 16px; max-width: 360px;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-lg, 0 20px 50px rgba(0,0,0,.25));
  color: var(--text);
}
.reconexion-caja span { font-size: 13px; color: var(--text-3); }
.reconexion-rueda {
  width: 34px; height: 34px; border-radius: 50%; margin-bottom: 4px;
  border: 3px solid var(--line); border-top-color: var(--accent);
  animation: reconexion-giro .9s linear infinite;
}
@keyframes reconexion-giro { to { transform: rotate(360deg); } }

/* ------------------------------------------------- plano de reservas
   El salón en SVG, con cada mesa según lo que tiene reservado ese día:
   libre, con reservas (se ven las horas), ocupada a la hora elegida, o
   la elegida. Escala solo; no hay que arrastrar nada. */
.plano-reservas { width: 100%; max-height: 360px; display: block; background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; }
/* Dentro de la ficha caben menos alto: el plano es para señalar la mesa, no para leerlo. */
.mud-dialog .plano-reservas { max-height: 280px; }
/* Con cuatro botones (Quitar, Combinar, Cancelar, Guardar) el pie del
   diálogo se salía por los lados: los botones saltan de línea. */
.mud-dialog .mud-dialog-actions { flex-wrap: wrap; gap: 8px; row-gap: 8px; }
/* «Enviar · cobrar después», encima de Cobrar en un pedido a domicilio. */
.ticket-acciones .btn.enviar { width: 100%; justify-content: center; margin-bottom: 8px; }
.mud-dialog .mud-dialog-actions > .btn { margin: 0; }
.mesa-r rect, .mesa-r ellipse { fill: var(--surface); stroke: var(--line); stroke-width: 2; }
.mesa-r text { fill: var(--text); font-family: var(--sans, inherit); pointer-events: none; }
.mesa-r .num { font-size: 20px; font-weight: 700; }
.mesa-r .pax { font-size: 11px; fill: var(--text-3); }
.mesa-r .horas { font-size: 11px; font-weight: 600; fill: var(--accent-texto); }
.mesa-r.libre rect, .mesa-r.libre ellipse { stroke: var(--ok); }
.mesa-r.reservada rect, .mesa-r.reservada ellipse { stroke: var(--accent); fill: var(--accent-soft); }
.mesa-r.ocupada rect, .mesa-r.ocupada ellipse { stroke: var(--danger); fill: var(--danger-soft); }
.mesa-r.ocupada .num { fill: var(--danger); }
.mesa-r.elegida rect, .mesa-r.elegida ellipse { stroke: var(--accent); stroke-width: 4; fill: var(--accent); }
.mesa-r.elegida text { fill: #fff; }
.mesa-r.elegible { cursor: pointer; }
.mesa-r.elegible:hover rect, .mesa-r.elegible:hover ellipse { stroke-width: 4; }
.mesa-r.ocupada { cursor: not-allowed; }

/* Apartados de la carta por subfamilia, dentro de la rejilla de artículos:
   una línea del color de la familia con el nombre en pequeño, a todo el
   ancho, que separa sin robar sitio a los botones. */
.art-sub {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; margin-top: 4px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--fam, var(--text-2));
  /* Es un botón (pliega el apartado), pero se ve como el rótulo de siempre. */
  background: none; border: 0; padding: 4px 0; width: 100%; text-align: left; cursor: pointer; font-family: inherit;
}
.art-sub::after { content: ""; flex: 1; height: 1px; background: color-mix(in srgb, var(--fam, var(--line)) 45%, var(--line-soft)); }
.art-sub:first-child { margin-top: 0; }
.art-sub i[data-icon] { width: 14px; height: 14px; flex: none; }
.art-sub i[data-icon] svg { width: 14px; height: 14px; }
.art-sub.plegada { opacity: .85; }
.art-sub-n {
  font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--fam, var(--accent)) 16%, transparent); color: var(--fam, var(--text-2));
}

/* Las subfamilias de la familia elegida, entre las familias y la carta. */
.sub-chips { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }
.sub-chips .chip { padding: 5px 11px; font-size: 12.5px; }
.sub-chips .chip.on { background: var(--fam, var(--accent)); border-color: transparent; color: #fff; }
@media (min-width: 1150px) {
  .tpv-carta:has(> .sub-chips) { grid-template-areas: "buscar buscar" "pases pases" "fam subs" "fam arts"; grid-template-rows: auto auto auto minmax(0, 1fr); }
  .tpv-carta > .sub-chips { grid-area: subs; }
}

/* Líneas que cuelgan de otra (platos de un menú): sangradas y sin botones. */
.tl.tl-hija { padding-left: 18px; opacity: .92; }
.tl.tl-hija .tl-nom { font-weight: 400; }

/* ------------------------------------------------ pantalla de cocina */
.kds { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; align-items: start; }
.kds-mandos { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-left: auto; }
.kds-sep { width: 1px; height: 22px; background: var(--line); margin: 0 2px; }
.chip.aviso { border-color: var(--accent); color: var(--accent-texto); background: var(--accent-soft); animation: kds-parpadeo 1.2s ease-in-out infinite; }
.kds-mesa { border-top: 4px solid var(--ok); }
.kds-mesa.aviso { border-top-color: var(--accent); }
.kds-mesa.tarde { border-top-color: var(--danger); }
/* Una tarjeta con algo recién llegado llama la atención un minuto. */
.kds-mesa.nueva { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 55%, transparent); animation: kds-llegada 1.2s ease-in-out 3; }
@keyframes kds-llegada { 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 25%, transparent); } }
@keyframes kds-parpadeo { 50% { opacity: .55; } }
.kds-cab { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); font-size: 16px; }
.kds-reloj { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 700; font-size: 18px; }
.kds-mesa.aviso .kds-reloj { color: var(--accent-texto); }
.kds-mesa.tarde .kds-reloj { color: var(--danger); }
.kds-pase { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px 2px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-3); }
.kds-pase-btns { display: flex; gap: 2px; }
/* Cada plato: el botón de «al fuego» a la izquierda y el plato entero, que
   se pulsa cuando sale. */
.kds-linea { display: grid; grid-template-columns: 36px 1fr; border-bottom: 1px solid var(--border); }
.kds-linea.nueva { background: var(--accent-soft); }
.kds-linea.marchando { background: color-mix(in srgb, var(--ok-soft) 60%, transparent); }
.kds-fuego { display: grid; place-items: center; border: 0; border-right: 1px solid var(--border); background: transparent; color: var(--text-3); cursor: pointer; padding: 0; }
.kds-fuego svg { width: 18px; height: 18px; }
.kds-fuego:hover { color: var(--accent-texto); background: var(--accent-soft); }
.kds-linea.marchando .kds-fuego { color: var(--accent-texto); }
.kds-plato { display: grid; grid-template-columns: 34px 1fr auto; gap: 8px; width: 100%; text-align: left; padding: 9px 12px; border: 0; background: transparent; color: inherit; cursor: pointer; font: inherit; }
.kds-plato:hover { background: var(--ok-soft); }
.kds-plato:active { background: var(--ok-soft); opacity: .8; }
.kds-ctdad { font-weight: 800; font-size: 18px; }
.kds-txt { display: grid; gap: 2px; }
.kds-nom { font-weight: 600; font-size: 15px; }
.kds-obs { font-size: 13px; font-weight: 700; color: var(--accent-texto); }
.kds-min { display: grid; justify-items: end; gap: 3px; font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; align-self: start; }
.kds-etq { font-size: 10px; padding: 0 6px; }
.kds-pie { padding: 10px 12px; }

/* Letra grande: para un monitor a dos metros. Las tarjetas se ensanchan y
   todo crece un tercio. */
.kds-grande .kds { grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 18px; }
.kds-grande .kds-cab { font-size: 22px; padding: 14px 16px; }
.kds-grande .kds-reloj { font-size: 26px; }
.kds-grande .kds-pase { font-size: 15px; padding: 10px 16px 4px; }
.kds-grande .kds-linea { grid-template-columns: 48px 1fr; }
.kds-grande .kds-fuego svg { width: 24px; height: 24px; }
.kds-grande .kds-plato { grid-template-columns: 44px 1fr auto; padding: 14px 16px; }
.kds-grande .kds-ctdad { font-size: 26px; }
.kds-grande .kds-nom { font-size: 21px; }
.kds-grande .kds-obs { font-size: 17px; }
.kds-grande .kds-min { font-size: 15px; }
.kds-grande .kds-etq { font-size: 12px; }
.kds-grande .kds-pie .btn { font-size: 18px; padding: 14px; }

/* Pantalla completa desde la cocina: sin barra lateral ni cabecera. */
body.cocina-completa #app { grid-template-columns: 1fr; }
body.cocina-completa .sidebar, body.cocina-completa .topbar, body.cocina-completa .dock { display: none; }

/* Con la cocina abierta, «Reconectando…» es un aviso en una esquina y no un
   telón: lo que había en pantalla se sigue viendo y se sigue cocinando. Si
   la reconexión falla del todo, reconexion.js recarga igual. */
body.en-cocina #components-reconnect-modal.components-reconnect-show {
  inset: auto 12px 12px auto; place-items: end; background: transparent; backdrop-filter: none;
}
body.en-cocina #components-reconnect-modal.components-reconnect-show .reconexion-caja {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-color: var(--danger);
}
body.en-cocina #components-reconnect-modal.components-reconnect-show .reconexion-caja span { display: none; }
/* El enlace a la libreta de emergencia sigue saliendo (a los ocho segundos), pequeño y al lado. */
body.en-cocina #components-reconnect-modal.components-reconnect-show .reconexion-caja a.btn { margin: 0 0 0 4px !important; padding: 5px 10px; font-size: 12px; }
body.en-cocina #components-reconnect-modal.components-reconnect-show .reconexion-rueda { width: 18px; height: 18px; margin: 0; border-width: 2px; border-top-color: var(--danger); }

/* ------------------------------------------------ fichar y cuadrante */
.fichar-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.fichar-btn { display: grid; gap: 4px; padding: 18px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.fichar-btn.dentro { border-color: var(--ok); background: var(--ok-soft); }
.fichar-nom { font-size: 17px; font-weight: 700; }
.fichar-est { font-size: 12px; color: var(--text-3); }
.fichar-acc { display: inline-flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 13px; font-weight: 600; }

/* En el móvil la gráfica no se encoge hasta lo ilegible: se desliza. */
.chart-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 640px) {
  .chart-wrap .chart { min-width: 560px; }
}

/* El enlace a la libreta de emergencia dentro del cartel de reconexión. */
#components-reconnect-modal .btn { pointer-events: auto; }

/* --------------------------------------------------- consola SQL (proveedor) */
.sql-consola { display: grid; grid-template-columns: 220px 1fr; gap: 14px; align-items: start; }
.sql-tablas .sql-lista { max-height: 70vh; overflow: auto; padding: 6px; display: grid; gap: 2px; }
.sql-tablas .nav-link { padding: 6px 10px; font-size: 12px; }
.sql-editor { width: 100%; min-height: 120px; resize: vertical; font-size: 13px; line-height: 1.5; }
.sql-resultado { max-height: 60vh; overflow: auto; }
.sql-resultado td, .sql-resultado th { white-space: nowrap; }
@media (max-width: 900px) { .sql-consola { grid-template-columns: 1fr; } }


/* =====================================================================
   Tamaños táctiles
   ---------------------------------------------------------------------
   El programa se diseñó con ratón y en un TPV de 15" va bien; en una
   tableta de 10" o en el móvil del comandero, un dedo necesita 44 px de
   alto en todo lo que se pulsa (es la medida de Apple y de Google, y la
   que sale al medir dedos mojados en una barra). Se aplica sólo donde el
   puntero es un dedo (`pointer: coarse`: tabletas, móviles, monitores
   táctiles) y siempre en modo comandero; en un PC con ratón no cambia
   nada. Alonso lo pidió el 22/09/2026 tras la prueba de carga.
   ===================================================================== */
@media (pointer: coarse) {
  :root { --tactil: 44px; }
}
#app.comandero { --tactil: 44px; }

/* Botones, chips, iconos y campos: 44 px de alto como mínimo. */
.btn { min-height: var(--tactil, 0); }
.btn-sm { min-height: calc(var(--tactil, 0) - 6px); }
.icon-btn { min-width: var(--tactil, 34px); min-height: var(--tactil, 34px); }
.chip { min-height: calc(var(--tactil, 0) - 4px); }
input:not([type=checkbox]):not([type=radio]), select { min-height: var(--tactil, 0); }
/* La casilla, a la mitad del dedo: 22 px en táctil. El valor de reserva es
   34 —la mitad, 17, es el tamaño normal de la casilla— y no 18: con 18 se
   quedaban en 9 px en cualquier PC con ratón, que es lo que pasó del 22 al
   23/09/2026 en Parámetros Generales. */
.field.check input[type=checkbox] { width: calc(var(--tactil, 34px) / 2); height: calc(var(--tactil, 34px) / 2); flex: none; }
.mud-dialog .mud-dialog-actions .btn, .mud-dialog .mud-button-root { min-height: var(--tactil, 0); }

@media (pointer: coarse) {
  /* La carta: fichas de familia y artículo con sitio para el dedo, y sin
     el «hover», que en una pantalla táctil se queda pegado al último toque. */
  .fam-card { min-height: 48px; padding: 12px 14px; font-size: 14px; }
  .fam-card:hover:not(:disabled) { border-color: var(--line); background: var(--surface); }
  .fam-card.active { border-color: var(--fam); background: var(--surface-2); }
  .art-btn { min-height: 92px; padding: 14px 13px; }
  .art-btn:hover { border-color: color-mix(in srgb, var(--fam, transparent) 22%, var(--line-soft)); background: color-mix(in srgb, var(--fam, transparent) 7%, var(--surface)); }
  .art-btn .a-nom { font-size: 14px; }
  .art-btn .a-pvp { font-size: 14.5px; }
  .tpv-pases .chip { min-height: 42px; padding: 8px 14px; font-size: 14px; }

  /* La comanda: cada línea de 52 px, con el + y el − de 40 px, que son lo
     que más se pulsa después de la carta. */
  .tl { min-height: 52px; padding: 8px 12px; grid-template-columns: 46px 1fr auto auto; gap: 8px; }
  .tl:hover { background: transparent; }
  .tl.sel { background: var(--accent-soft); }
  .tl .tl-mas .icon-btn { width: 40px; height: 40px; min-width: 40px; min-height: 40px; border-radius: 9px; }
  .tl .tl-mas .icon-btn svg { width: 18px; height: 18px; }
  .tl .tl-nom { font-size: 14.5px; }
  .tl .tl-ctdad { font-size: 15px; padding: 6px 0; }
  .tl .tl-imp { font-size: 14px; }
  .tot-fila .btn-sm { padding: 8px 12px; font-size: 13px; }
  .ticket-head .t-min { width: 40px; height: 40px; }

  /* La barra de cuentas de abajo y el plano. */
  .dock-item { min-height: 44px; padding: 6px 10px 6px 12px; }
  .dock-x { min-width: 36px; min-height: 36px; display: grid; place-items: center; }
  .salon-tab { min-height: 44px; }

  /* La pantalla de cocina en una tableta: la llama y el plato, de dedo. */
  .kds-linea { grid-template-columns: 48px 1fr; }
  .kds-fuego svg { width: 22px; height: 22px; }
  .kds-fuego:hover { color: var(--text-3); background: transparent; }
  .kds-linea.marchando .kds-fuego { color: var(--accent-texto); }
  .kds-plato { min-height: 56px; padding: 12px 14px; }
  .kds-plato:hover { background: transparent; }
  .kds-pase .btn-sm { min-height: 36px; }

  /* Reloj de fichar, teclado de PIN y listas: filas que se pulsan. */
  .fichar-btn { min-height: 64px; }
  tr.clickable td { padding-top: 12px; padding-bottom: 12px; }
}

/* El comandero va en el móvil: además de lo de arriba, la carta y la
   comanda ya iban grandes; se igualan los tamaños de dedo aunque el móvil
   no declare `pointer: coarse` (algún navegador de PC en modo
   emulación). */
#app.comandero .tl .tl-mas .icon-btn { width: 40px; height: 40px; }
#app.comandero .tl { min-height: 52px; }
#app.comandero .tpv-pases .chip { min-height: 42px; }
#app.comandero .fam-card { min-height: 48px; }
#app.comandero .art-btn { min-height: 84px; }

/* Un TPV en pantalla estrecha sin modo comandero (un movil que entra sin
   activarlo): las dos columnas no caben y se pisaban. Se apilan, con la
   comanda arriba a media pantalla y la carta debajo; el modo comandero
   sigue siendo lo suyo, pero esto ya no se solapa. */
@media (max-width: 899px) {
  .tpv:not(.tpv-paneles) { grid-template-columns: minmax(0, 1fr); }
  .tpv:not(.tpv-paneles) > .ticket { order: -1; max-height: 42vh; }
  .tpv:not(.tpv-paneles) > .tpv-carta { min-height: 50vh; }
}

/* =====================================================================
   Los diálogos de confirmación, con los botones de la casa
   ---------------------------------------------------------------------
   Los avisos de «¿seguro?» los pinta MudBlazor (ShowMessageBox) y salían
   con sus botones planos y en MAYÚSCULAS, al lado de los botones de
   RestaGes en el mismo diálogo: dos programas distintos en la misma
   ventana. Se les da aquí el aspecto de `.btn`, que es más barato y más
   seguro que reescribir los dieciocho avisos que hay.
   ===================================================================== */
.mud-dialog .mud-dialog-actions .mud-button-root {
  text-transform: none; letter-spacing: 0; font-family: var(--font);
  font-size: 13.5px; font-weight: 550; padding: 9px 15px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  box-shadow: none; min-width: 0;
}
.mud-dialog .mud-dialog-actions .mud-button-root:hover { background: var(--surface-3); }
/* El botón que confirma (el de color, que MudBlazor pinta como primario o
   de error) manda: ámbar de la casa, o rojo si lo que confirma es borrar. */
.mud-dialog .mud-dialog-actions .mud-button-root.mud-button-filled-primary,
.mud-dialog .mud-dialog-actions .mud-button-root.mud-button-text-primary {
  background: linear-gradient(140deg, var(--accent), #ea8a06);
  border-color: transparent; color: #1a1207; font-weight: 650;
}
.mud-dialog .mud-dialog-actions .mud-button-root.mud-button-filled-error,
.mud-dialog .mud-dialog-actions .mud-button-root.mud-button-text-error {
  background: var(--danger-soft); color: var(--danger); border-color: transparent; font-weight: 650;
}
