/**
 * Punto de venta táctil
 *
 * Esta pantalla se usa de pie, en tablet y con prisa: cada cosa que se toca
 * mide al menos 44 px, los números se leen a un brazo de distancia y nada
 * depende de pasar el ratón por encima.
 */

:root {
  --toque: 44px;      /* mínimo cómodo para un dedo */
  --toque-holgado: 52px;
}

/* —— Mesas dibujadas como mesas —— */
.salon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.6rem;
}

.mesa-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.5rem 0.6rem;
  min-height: 9.5rem;
  border: 2px solid var(--line);
  border-radius: 16px;
  background: var(--bg-elev);
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
.mesa-card:active { transform: scale(0.97); }
.mesa-card:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

.mesa-card-estado {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.mesa-figura {
  position: relative;
  width: 100%;
  max-width: 5.6rem;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.mesa-svg { width: 100%; height: 100%; display: block; }
.mesa-svg .tablero {
  fill: color-mix(in srgb, currentColor 16%, transparent);
  stroke: currentColor;
  stroke-width: 2.5;
}
.mesa-svg .silla {
  fill: color-mix(in srgb, currentColor 45%, transparent);
}
.mesa-card-cod {
  position: absolute;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

.mesa-card-pie {
  display: grid;
  gap: 0.1rem;
  width: 100%;
  line-height: 1.2;
}
.mesa-card-tiempo { font-size: 0.68rem; color: var(--muted); }
.mesa-card-importe { font-size: 0.95rem; font-weight: 700; }
.mesa-card-importe.libre { font-size: 0.8rem; color: var(--ok); font-weight: 600; }
.mesa-card-cam {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* Estado: el mismo código de color que el plano */
.mesa-card.FREE { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); color: var(--ok); }
.mesa-card.FREE .mesa-card-cod,
.mesa-card.FREE .mesa-card-pie { color: var(--ink); }
.mesa-card.FREE .mesa-card-estado { color: var(--ok); }

.mesa-card.OCCUPIED {
  border-color: var(--estado-ocupada);
  background: color-mix(in srgb, var(--estado-ocupada) 8%, var(--bg-elev));
  color: var(--estado-ocupada-ink);
}
.mesa-card.OCCUPIED .mesa-card-cod { color: var(--estado-ocupada-ink); }
.mesa-card.OCCUPIED .mesa-card-estado { color: var(--estado-ocupada-ink); }
.mesa-card.OCCUPIED .mesa-card-importe { color: var(--estado-ocupada-ink); }

.mesa-card.BILL {
  border-color: var(--info);
  background: color-mix(in srgb, var(--info) 10%, var(--bg-elev));
  color: var(--info);
}
.mesa-card.BILL .mesa-card-cod,
.mesa-card.BILL .mesa-card-importe { color: var(--info); }

.mesa-card.RESERVED { border-color: var(--premium); border-style: dashed; color: var(--premium); }
.mesa-card.RESERVED .mesa-card-cod { color: var(--ink); }

.mesa-card.DIRTY {
  border-color: var(--muted);
  color: var(--muted);
  background: repeating-linear-gradient(45deg, var(--bg-elev) 0 9px, var(--bg-soft) 9px 18px);
}
.mesa-card.DIRTY .mesa-card-cod { color: var(--ink); }

.mesa-card.BLOCKED { border-color: var(--danger); color: var(--danger); opacity: 0.65; }
.mesa-card.BLOCKED .mesa-card-cod { color: var(--ink); }

.mesa-card.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.mesa-card .plano-pins { top: 6px; right: 6px; }

/* —— Todo lo que se toca, con tamaño de dedo —— */
.pos-floor .kds-chip,
.pos-floor .zona-chip,
.pos-menu .kds-chip,
.pos-menu .cat-chip {
  min-height: var(--toque);
  padding: 0.5rem 0.9rem;
  font-size: 0.86rem;
  border-radius: 12px;
}
.pos-floor .panel-head-actions .btn,
.pos-comanda .btn {
  min-height: var(--toque);
  padding-inline: 1rem;
  font-size: 0.88rem;
}
.salon-vista .kds-chip { min-height: var(--toque); }

/* Buscador del menú: alto y con la lupa grande */
#menu-search {
  min-height: var(--toque-holgado);
  font-size: 1rem;
}

/* —— Tarjetas de plato —— */
.menu-grid { gap: 0.6rem; }
.menu-card {
  border-radius: 16px;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.menu-card:active { transform: scale(0.97); }
.menu-card .name { font-size: 0.95rem; line-height: 1.2; }
.menu-card .price { font-size: 1.05rem; font-weight: 700; }
.menu-card .add-btn {
  width: 42px;
  height: 42px;
  font-size: 1.5rem;
  line-height: 1;
  display: grid;
  place-items: center;
  /* En táctil no hay hover: el botón de añadir está siempre a la vista */
  opacity: 1;
}

/* —— Comanda: cantidades y acciones —— */
.qty-btn {
  min-width: var(--toque);
  min-height: var(--toque);
  font-size: 1.25rem;
  border-radius: 12px;
  touch-action: manipulation;
}
.pos-comanda .comanda-actions .btn,
.pos-comanda .comanda-foot .btn { min-height: var(--toque-holgado); }

/* Cobrar y enviar a cocina: los dos botones que más se pulsan */
#btn-cobrar,
#btn-fire {
  min-height: 3.5rem;
  font-size: 1.05rem;
  font-weight: 700;
  border-radius: 14px;
}

/* —— En tablet de verdad, todo un punto más grande —— */
@media (pointer: coarse) {
  :root { --toque: 48px; --toque-holgado: 56px; }
  .mesa-card { min-height: 10.5rem; }
  .mesa-card-cod { font-size: 1.5rem; }
  .menu-card .add-btn { width: 46px; height: 46px; }
  .salon-grid { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); }
}

/* El dedo tapa la mesa: el estado se confirma con un toque sostenido */
@media (hover: none) {
  .mesa-card:hover { transform: none; }
  .menu-card:hover { transform: none; }
}

/* ——————————————————————————————————————————————————————
   Pestañas
   Un grupo de opciones excluyentes se ve como pestañas —
   una barra continua con la activa subrayada—, no como
   píldoras sueltas que parecen botones de acción.
   —————————————————————————————————————————————————————— */
.gp-tabs {
  display: flex;
  align-items: stretch;
  gap: 0;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.gp-tabs::-webkit-scrollbar { display: none; }

.gp-tabs > button,
.gp-tabs .gp-tab,
.gp-tabs .kds-chip,
.gp-tabs .zona-chip,
.gp-tabs .admin-tab {
  position: relative;
  flex: 0 0 auto;
  min-height: var(--toque);
  padding: 0.55rem 0.95rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.12s ease;
}
.gp-tabs > button::after,
.gp-tabs .gp-tab::after,
.gp-tabs .kds-chip::after,
.gp-tabs .zona-chip::after,
.gp-tabs .admin-tab::after {
  content: '';
  position: absolute;
  left: 0.6rem;
  right: 0.6rem;
  bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: transparent;
  transition: background 0.12s ease;
}
.gp-tabs > button:hover,
.gp-tabs .gp-tab:hover,
.gp-tabs .kds-chip:hover,
.gp-tabs .zona-chip:hover,
.gp-tabs .admin-tab:hover { color: var(--ink); }

.gp-tabs > button.active,
.gp-tabs .gp-tab.active,
.gp-tabs .kds-chip.active,
.gp-tabs .zona-chip.active,
.gp-tabs .admin-tab.active {
  color: var(--accent-ink);
  background: transparent;
}
.gp-tabs > button.active::after,
.gp-tabs .gp-tab.active::after,
.gp-tabs .kds-chip.active::after,
.gp-tabs .zona-chip.active::after,
.gp-tabs .admin-tab.active::after { background: var(--accent); }

/* El contador de cada pestaña, en discreto */
.gp-tabs .zona-chip-count,
.gp-tabs .gp-tab-count {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 700;
}
.gp-tabs .active .zona-chip-count,
.gp-tabs .active .gp-tab-count {
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.gp-tabs .zona-chip-name { font: inherit; }

/* En el salón las pestañas van pegadas al panel */
.salon-toolbar { padding: 0 0.75rem; }
.salon-toolbar .gp-tabs { width: 100%; }

/* —— Administración: tablas que se editan —— */
.adm-editable tbody tr { cursor: pointer; }
.adm-editable tbody tr:hover { background: var(--accent-soft); }
.adm-editar {
  text-align: right;
  white-space: nowrap;
  color: var(--muted);
  font-size: 0.78rem;
}
.adm-editable tbody tr:hover .adm-editar { color: var(--accent-ink); font-weight: 600; }
.adm-rol {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--muted);
}
.adm-si { color: var(--ok); font-weight: 600; }
.adm-no { color: var(--muted); }

/* Un formulario en modo edición se distingue del de alta */
.form-card.editando {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-acciones { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }

/* —— Foto del plato, dentro de su formulario —— */
.plato-foto-caja {
  display: flex;
  gap: 0.9rem;
  align-items: center;
  margin: 0.8rem 0;
  padding: 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--bg-soft);
}
.plato-foto-previa {
  width: 6rem;
  height: 4.5rem;
  border-radius: 10px;
  overflow: hidden;
  flex: 0 0 auto;
  background: var(--bg-elev);
}
.plato-foto-previa img,
.plato-foto-previa .thumb-fallback { width: 100%; height: 100%; object-fit: cover; display: flex; align-items: center; justify-content: center; }
.plato-foto-acciones { display: grid; gap: 0.35rem; }
.plato-foto-acciones .muted { font-size: 0.76rem; }
.plato-foto-acciones > div { display: flex; gap: 0.4rem; }

/* El plano en Administración */
.admin-plano { margin-bottom: 1.2rem; }
.plano-zonas { margin-bottom: 0.6rem; }

/* ——————————————————————————————————————————————————————
   Lo que todavía va en camino
   El ítem entra en la comanda en cuanto se toca; mientras el
   servidor confirma, la fila respira despacio. Si algo falla,
   el aviso salta y la línea se va — no se queda una mentira
   en pantalla.
   —————————————————————————————————————————————————————— */
.line-row.en-vuelo { animation: gp-en-vuelo 1.1s ease-in-out infinite; }
.line-row.en-vuelo .amt { opacity: 0.75; }

@keyframes gp-en-vuelo {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.62; }
}

@media (prefers-reduced-motion: reduce) {
  .line-row.en-vuelo { animation: none; opacity: 0.8; }
}

/* ——————————————————————————————————————————————————————
   Cocina: la comanda nueva se ve entrar
   La columna ya no se rehace entera cada seis segundos, así que
   una tarjeta recién llegada sí puede llamar la atención sin que
   parpadeen las demás.
   —————————————————————————————————————————————————————— */
.kds-ticket.kds-nueva { animation: gp-kds-entra 2.4s ease-out 1; }

@keyframes gp-kds-entra {
  0% {
    transform: translateY(-6px) scale(0.99);
    box-shadow: 0 0 0 3px var(--estado-ocupada, #ff8a2a);
  }
  35% { box-shadow: 0 0 0 3px var(--estado-ocupada, #ff8a2a); }
  100% {
    transform: none;
    box-shadow: 0 0 0 0 transparent;
  }
}

/* La campana del aviso */
.kds-sonido {
  display: inline-grid;
  place-items: center;
  min-width: var(--toque, 44px);
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}
.kds-sonido svg { width: 18px; height: 18px; }
.kds-sonido.silenciado { opacity: 0.55; }

@media (prefers-reduced-motion: reduce) {
  .kds-ticket.kds-nueva { animation: none; outline: 2px solid var(--estado-ocupada, #ff8a2a); }
}

/* Administración: casillas y subtítulos de las fichas largas */
.adm-intro { margin: 0 0 0.9rem; font-size: 0.82rem; line-height: 1.45; }
.adm-sub { margin: 1.4rem 0 0.6rem; font-size: 0.92rem; font-weight: 600; }
.adm-checks { display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; }
.adm-check {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--toque, 44px);
  font-size: 0.84rem;
  cursor: pointer;
}
.adm-check input { width: 18px; height: 18px; accent-color: var(--accent); }

/* ——————————————————————————————————————————————————————
   El botón de mostrador manda en la barra
   Es el que más se usa cuando hay cola, y tiene que encontrarse
   sin mirar: por eso lleva icono, texto y el tamaño de toque.
   —————————————————————————————————————————————————————— */
.btn-mostrador {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: var(--toque, 44px);
  padding-left: 0.85rem;
  padding-right: 1rem;
  font-weight: 600;
}
.btn-mostrador svg { width: 18px; height: 18px; flex-shrink: 0; }

@media (max-width: 720px) {
  .btn-mostrador span { display: none; }
  .btn-mostrador { padding-left: 0.7rem; padding-right: 0.7rem; }
}

/* Cancelar no se pulsa por error: va aparte y en rojo al tocarlo */
.btn-cancelar-orden { margin-left: auto; }
.btn-cancelar-orden:not(:disabled):hover,
.btn-cancelar-orden:not(:disabled):active {
  color: var(--danger, #e5484d);
  border-color: rgba(229, 72, 77, 0.45);
}

/* ——————————————————————————————————————————————————————
   Un plato se marca solo
   Las papas están antes que el churrasco. Cada línea lleva su
   botón, con tamaño de dedo, y el de abajo sigue llevándose la
   comanda entera para cuando sale todo a la vez.
   —————————————————————————————————————————————————————— */
.kds-item {
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
}
.kds-item-note { grid-column: 2 / -1; }

.kds-item-paso {
  display: grid;
  place-items: center;
  width: var(--toque, 44px);
  height: var(--toque, 44px);
  margin: -0.35rem -0.35rem -0.35rem 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s, border-color 0.12s, transform 0.08s;
}
.kds-item-paso svg { width: 17px; height: 17px; }
.kds-item-paso:hover {
  color: var(--accent-ink, #1a1206);
  background: var(--accent);
  border-color: var(--accent);
}
.kds-item-paso:active { transform: scale(0.92); }

/* Sin ratón no hay hover: el botón tiene que verse desde el principio */
@media (pointer: coarse) {
  .kds-item-paso {
    color: var(--accent-ink);
    border-color: var(--accent);
  }
}

/* Un plato listo es una tarea para el camarero: que se vea desde lejos */
.line-badge.prod.listo {
  background: var(--ok-soft, rgba(111, 207, 123, 0.16));
  color: var(--ok, #6fcf7b);
  font-weight: 700;
}

/* ——————————————————————————————————————————————————————
   El POS en una pantalla de 14 pulgadas
   A 1280 px las tres zonas caben, pero lo de dentro no: los
   botones de la cabecera se salían del panel y «Cobrar» se iba
   fuera de la ventana. El problema no era el ancho de las
   columnas sino que nada de dentro podía encoger ni doblarse.
   —————————————————————————————————————————————————————— */

/* Cinco botones no caben en una columna de 250 px: que bajen. */
.panel-head-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* «1fr» no baja del ancho de su contenido, y «Enviar cocina/bar (3)»
   empujaba a «Cobrar» fuera de la pantalla. Con minmax(0, 1fr) el botón
   encoge y la etiqueta se dobla en dos líneas. */
.comanda-actions {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.comanda-actions .btn {
  min-height: var(--toque, 44px);
  padding: 0.7rem 0.45rem;
  white-space: normal;
  line-height: 1.15;
  /* break-word y no anywhere: «anywhere» parte a mitad de palabra aunque
     sobre sitio en la línea de abajo. */
  overflow-wrap: break-word;
}

/* El camarero tiene que poder leer el plato. Antes se cortaba con
   puntos suspensivos —«Camar…»— justo donde está la información. */
.line-name {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: break-word;
}

/* De 14 pulgadas para abajo se aprieta sin perder el tamaño de dedo.
   El mínimo de 721 px lo deja fuera del móvil, que va a una columna. */
@media (max-width: 1400px) and (min-width: 721px) {
  .pos-layout {
    grid-template-columns: minmax(196px, 0.9fr) minmax(250px, 1.3fr) minmax(244px, 1fr);
    gap: 0.6rem;
  }
  .panel-head { padding: 0.6rem 0.7rem; }
  .panel-head h2 { font-size: 1rem; }
  .menu-grid {
    padding: 0.6rem;
    gap: 0.6rem;
    grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  }
  .comanda-actions,
  .comanda-tools { padding: 0.6rem; }
  .comanda-totals { padding: 0.6rem 0.7rem; }
  .line-row { padding: 0.55rem 0.35rem; font-size: 0.86rem; }
}

/* Por debajo de 1280 la comanda deja de ser una columna y pasa abajo,
   a lo ancho: es mejor una comanda ancha y corta que tres columnas
   estranguladas. */
@media (max-width: 1240px) and (min-width: 721px) {
  .pos-layout {
    grid-template-columns: minmax(200px, 1fr) minmax(280px, 1.5fr);
    grid-template-rows: minmax(0, 1fr) auto;
  }
  .pos-comanda {
    grid-column: 1 / -1;
    max-height: 46vh;
  }
  .comanda-lines { max-height: 22vh; }
}

/* El bloque de 1100 px seguía contando con el alto de la ventana y no
   con el hueco real: el pie fijo le comía el final. */
@media (max-width: 1100px) {
  .pos-layout {
    height: 100%;
    min-height: 0;
  }
}

/* La cabecera del salón, en dos filas y no en tres.
   Cinco botones en una columna de 280 px se apilaban y se comían el alto,
   que en una pantalla de 14 pulgadas es lo que falta. */
@media (max-width: 1400px) {
  .pos-floor .panel-head-actions .btn-sm {
    padding: 0.35rem 0.55rem;
    font-size: 0.78rem;
  }
  .pos-floor .btn-mostrador {
    padding-left: 0.55rem;
    padding-right: 0.6rem;
    gap: 0.3rem;
  }
  .pos-floor .panel-head h2 { font-size: 0.95rem; }

  /* Dos mesas por fila aunque la columna se estreche: una por fila
     obliga a desplazarse para ver un salón de cinco mesas. */
  .salon-grid { grid-template-columns: repeat(auto-fill, minmax(6.6rem, 1fr)); gap: 0.5rem; }
}

/* La línea de comanda se parte en dos alturas cuando LA COMANDA se
   estrecha, no cuando se estrecha la ventana: lo que decide es el sitio
   que hay en esa columna. Los botones de cantidad miden lo que mide un
   dedo —127 px con el número— y en una fila de 274 px al nombre del plato
   le quedaban 50. Si la fila llega a 330, todo cabe en una altura y se ven
   casi el doble de ítems. */
.pos-comanda { container-type: inline-size; }

@container (max-width: 345px) {
  .line-row {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "info info"
      "qty  side";
    gap: 0.4rem 0.55rem;
    align-items: center;
  }
  .line-info { grid-area: info; }
  .line-qty { grid-area: qty; }
  .line-side {
    grid-area: side;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.6rem;
  }
}

/* Con sitio de sobra, todo en una altura: cantidad, nombre e importe. */
@container (min-width: 346px) {
  .pos-comanda .line-side {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 1px;
  }
}

/* ——————————————————————————————————————————————————————
   La cara de quien atiende la mesa
   De un vistazo al salón se reconoce antes una foto que un
   nombre en letra pequeña. Sin foto quedan las iniciales,
   que ya distinguen a dos camareros.
   —————————————————————————————————————————————————————— */
.mesa-card-cam {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
}
.mesa-card-cara {
  position: relative;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
}
.mesa-card-cara i {
  font-style: normal;
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.mesa-card-cara img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mesa-card-cam-nombre {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* En el plano, la cara sola: ahí no cabe el nombre */
.plano-mesa .mesa-card-cam-nombre { display: none; }
.plano-mesa .mesa-card-cara { width: 20px; height: 20px; }

/* ——————————————————————————————————————————————————————
   Menos aire vacío, en todas las pantallas
   Los rellenos de 1 rem venían de un diseño pensado para
   monitores grandes. En 14 pulgadas —y en la tablet— ese aire
   es sitio de trabajo que se pierde. Se recortan los rellenos
   de los contenedores; los botones no se tocan, que ahí el
   tamaño es el del dedo.
   —————————————————————————————————————————————————————— */
.app-main { padding: 0.5rem; }

.panel-head { padding: 0.5rem 0.65rem; }
.panel-head h2 { font-size: 1rem; }

.module-shell { padding: 0; }
.module-hero {
  padding: 0.85rem 1rem;
  margin-bottom: 0.7rem;
}
.module-hero h2 { margin: 0.1rem 0 0.15rem; }
.module-hero p { margin: 0; }

.form-card { padding: 0.85rem; }
.form-card.compact { padding: 0.7rem 0.8rem; }

.data-table th,
.data-table td { padding: 0.45rem 0.6rem; }

.analytics-card { padding: 0.8rem 0.9rem; }
.analytics-card-head { margin-bottom: 0.6rem; }

.kpi-premium-grid { gap: 0.55rem; }
.stat-grid { gap: 0.55rem; }

.comanda-totals { padding: 0.55rem 0.7rem; }
.comanda-cliente { padding: 0.5rem 0.6rem; }
.menu-grid { padding: 0.6rem; gap: 0.6rem; }
.zona-filters,
.cat-filters { padding-left: 0.6rem; padding-right: 0.6rem; }
.floor-legend { padding: 0.5rem 0.6rem; }

/* La cabecera del salón tenía media fila vacía a la derecha:
   los botones se van al borde y el título manda a la izquierda. */
.pos-floor .panel-head { align-items: center; }
.pos-floor .panel-head-actions { margin-left: auto; }

@media (min-width: 1500px) {
  /* En monitores grandes sí sobra sitio: se devuelve algo de aire. */
  .app-main { padding: 0.75rem; }
  .panel-head { padding: 0.7rem 0.9rem; }
  .module-hero { padding: 1.1rem 1.25rem; }
}

/* ——————————————————————————————————————————————————————
   Densidad, ahora medida en píxeles
   En rem cada valor depende del tamaño de fuente del navegador
   y no se sabe qué se está pidiendo. Aquí va en píxeles, que es
   lo que se ve: en una pantalla de 14 pulgadas el alto es el
   recurso escaso y cada bloque tiene que justificar el suyo.
   —————————————————————————————————————————————————————— */

/* La tarjeta de mesa medía 188 px de alto para 139 de ancho: más alta
   que ancha y sólo entraban cuatro. El dibujo de la mesa no necesita
   90 px para entenderse. */
.mesa-card {
  min-height: 118px;
  gap: 3px;
  padding: 6px 6px 7px;
  border-radius: 12px;
}
.mesa-figura { max-width: 62px; }
.mesa-card-estado { font-size: 9px; letter-spacing: 0.08em; }
.mesa-card-cod { font-size: 15px; }
.mesa-card-tiempo { font-size: 10px; }
.mesa-card-importe { font-size: 13px; }
.mesa-card-importe.libre { font-size: 11px; }
.mesa-card-cara { width: 18px; height: 18px; }
.mesa-card-cara i { font-size: 8px; }
.mesa-card-cam-nombre { font-size: 9px; }
.salon-grid { gap: 6px; }
.salon-zona-title { margin: 6px 0 4px; }

/* La leyenda ocupaba 96 px —más que dos mesas— para decir seis colores.
   En una fila y pequeña dice lo mismo. */
.floor-legend {
  gap: 4px 10px;
  padding: 5px 8px;
  font-size: 10px;
  line-height: 1.3;
}
.floor-legend .dot { width: 7px; height: 7px; margin-right: 3px; }
.floor-legend-hint { font-size: 9px; opacity: 0.75; }

/* La cabecera del salón: 137 px para un título y cinco botones.
   Se aprieta el relleno lateral para que quepan en menos filas sin
   bajar de los 44 px de alto, que eso es el dedo. */
.pos-floor .panel-head { padding: 6px 8px; gap: 6px; }
.pos-floor .panel-head h2 { font-size: 15px; }
.pos-floor .panel-head-actions { gap: 3px; }
.pos-floor .panel-head-actions .btn {
  padding-left: 6px;
  padding-right: 6px;
  font-size: 11.5px;
  letter-spacing: 0;
}
.pos-floor .btn-mostrador { padding-left: 6px; padding-right: 7px; gap: 3px; }
.pos-floor .btn-mostrador svg { width: 15px; height: 15px; }

/* Filtros y buscador, sin aire de sobra */
.zona-filters, .cat-filters { padding: 5px 8px 0; gap: 4px; }
.menu-pro-head { padding: 6px 8px; }
.menu-search-wrap input { padding-top: 8px; padding-bottom: 8px; }
.menu-grid { padding: 8px; gap: 8px; }
.salon-toolbar { padding: 0; }

/* La comanda */
.comanda-cliente { padding: 6px 8px; gap: 6px; }
.comanda-totals { padding: 7px 9px; }
.comanda-tools { padding: 7px 8px; gap: 5px; }
.comanda-actions { padding: 8px; gap: 6px; }
.line-row { padding: 6px 5px; }

/* Cabeceras y tarjetas del resto de pantallas */
.panel-head { padding: 6px 9px; }
.module-hero { padding: 10px 12px; margin-bottom: 8px; }
.form-card { padding: 10px; }
.form-card.compact { padding: 9px 10px; }
.data-table th, .data-table td { padding: 5px 8px; }
.analytics-card { padding: 10px 11px; }
.app-main { padding: 6px; }
.pos-layout { gap: 8px; }

@media (min-width: 1500px) {
  /* En un monitor grande sí sobra sitio: se devuelve algo de aire. */
  .app-main { padding: 10px; }
  .panel-head { padding: 10px 12px; }
  .module-hero { padding: 16px 18px; }
  .mesa-card { min-height: 132px; }
  .mesa-figura { max-width: 72px; }
}

/* Los cinco botones suman 317 px y en la fila del título les quedaban
   312: por cinco píxeles bajaba uno y la cabecera pasaba de 82 a 129.
   Se les da la fila entera, que ahí caben de sobra. */
@media (max-width: 1500px) {
  .pos-floor .panel-head { row-gap: 4px; }
  .pos-floor .panel-head h2 { flex: 1 1 100%; }
  .pos-floor .panel-head-actions {
    flex: 1 1 100%;
    margin-left: 0;
    justify-content: flex-start;
  }
}

/* ——————————————————————————————————————————————————————
   La comanda muestra más ítems
   De 856 px de columna, las líneas —que son el contenido— se
   quedaban con 373 y lo de abajo con 393. Y cada línea medía
   105 px, así que entraban tres.
   —————————————————————————————————————————————————————— */

/* `.tot-row { display: flex }` le ganaba al atributo `hidden` del
   navegador: «Descuento 0» y «Pagado 0» se veían igual aunque el
   código los marcara como ocultos. Dos filas de aire y dos ceros
   que no dicen nada. */
.tot-row[hidden] { display: none !important; }

.comanda-totals { padding: 6px 9px; }
.tot-row { padding: 1px 0; font-size: 12.5px; }
.tot-row.total { margin-top: 4px; padding-top: 6px; font-size: 15px; }

/* La línea: el nombre arriba y, debajo, cantidad e importe en la misma
   altura. Los botones mantienen sus 44 px. */
.pos-comanda .line-row { padding: 5px 4px; gap: 3px 6px; }
.pos-comanda .line-qty { padding: 0; gap: 0; border-radius: 9px; }
.pos-comanda .line-name { font-size: 13px; line-height: 1.2; }
.pos-comanda .line-meta { font-size: 10.5px; margin-top: 1px; }
.pos-comanda .line-mods { font-size: 10.5px; }
.pos-comanda .line-row .amt { font-size: 13px; }
.pos-comanda .line-void { font-size: 10.5px; }
.pos-comanda .line-badge { font-size: 8.5px; padding: 1px 4px; }

/* Las cinco herramientas en una fila más baja: son acciones de vez en
   cuando, no el camino de todos los días. */
.comanda-tools { padding: 6px 8px; gap: 4px; }
.comanda-tools .btn {
  min-height: 34px;
  padding: 4px 8px;
  font-size: 11.5px;
}

.comanda-cliente { padding: 5px 7px; }
.comanda-cliente .btn { min-height: 34px; font-size: 11.5px; }
.pos-comanda .panel-head { padding: 5px 9px; }

/* Lo que sobra es para las líneas, no para los totales */
.comanda-lines { flex: 1 1 auto; min-height: 0; }

/* ——————————————————————————————————————————————————————
   Cocina con diez mesas encima
   Una comanda de diez platos llenaba la columna entera y las
   demás quedaban debajo, sin verse. Aquí manda que se vean
   muchas a la vez y que se distinga de un vistazo cuál corre
   prisa: el color lo dice antes que el número.
   —————————————————————————————————————————————————————— */

/* Las cabeceras llevan el color de la casa, no gris de sistema */
.kds-col-head {
  padding: 7px 10px;
  border-radius: 10px 10px 0 0;
  border-bottom: 2px solid transparent;
}
.kds-col-head h3 {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.kds-col-count {
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  display: inline-grid;
  place-items: center;
}

/* En cola: lo que espera. Preparando: lo que está en el fuego.
   Listo: lo que hay que sacar ya. */
.kds-col[data-col="QUEUED"] .kds-col-head {
  background: var(--accent-soft);
  border-bottom-color: var(--accent);
  color: var(--accent-ink, var(--ink));
}
.kds-col[data-col="QUEUED"] .kds-col-count { background: var(--accent); color: #16210f; }

.kds-col[data-col="IN_PROGRESS"] .kds-col-head {
  background: var(--warn-soft);
  border-bottom-color: var(--warn);
  color: var(--warn);
}
.kds-col[data-col="IN_PROGRESS"] .kds-col-count { background: var(--warn); color: #201400; }

.kds-col[data-col="READY"] .kds-col-head {
  background: var(--ok-soft);
  border-bottom-color: var(--ok);
  color: var(--ok);
}
.kds-col[data-col="READY"] .kds-col-count { background: var(--ok); color: #04210b; }

/* La tarjeta: compacta, con la mesa grande y el reloj a la vista */
.kds-cards { gap: 7px; padding: 7px; }
.kds-ticket {
  padding: 0;
  border-radius: 10px;
  border-left-width: 5px;
  overflow: hidden;
}
.kds-ticket-head {
  padding: 6px 9px;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--line);
}
.kds-mesa { font-size: 17px; font-weight: 800; letter-spacing: 0.01em; }
.kds-est { font-size: 9px; letter-spacing: 0.08em; opacity: 0.75; }
.kds-timer {
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.kds-items { padding: 4px 6px; gap: 3px; }
.kds-item {
  padding: 3px 5px;
  border-radius: 7px;
  gap: 2px 7px;
}
.kds-item-qty { font-size: 14px; font-weight: 800; }
.kds-item-name { font-size: 13.5px; line-height: 1.2; }
.kds-item-note { font-size: 11px; font-weight: 600; }
.kds-item-paso { width: 38px; height: 38px; border-radius: 9px; }
.kds-item-paso svg { width: 15px; height: 15px; }

.kds-advance {
  width: auto;
  margin: 4px 6px 6px;
  min-height: 40px;
  font-size: 12.5px;
  font-weight: 700;
}

/* La urgencia se ve en el borde y en el reloj, no hay que leer nada */
.kds-ticket.tone-ok { border-left-color: var(--ok); }
.kds-ticket.tone-ok .kds-timer { color: var(--ok); }
.kds-ticket.tone-warn { border-left-color: var(--warn); }
.kds-ticket.tone-warn .kds-timer { color: var(--warn); }
.kds-ticket.tone-warn .kds-ticket-head { background: var(--warn-soft); }
.kds-ticket.tone-crit {
  border-left-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger);
}
.kds-ticket.tone-crit .kds-timer { color: var(--danger); }
.kds-ticket.tone-crit .kds-ticket-head { background: var(--danger-soft); }
.kds-ticket.tone-crit .kds-mesa { color: var(--danger); }

/* Con sitio de sobra, dos comandas por fila: con diez mesas la
   diferencia es verlas todas o ir buscando con el dedo. */
.kds-cards { display: grid; grid-template-columns: 1fr; align-content: start; }

@container (min-width: 620px) {
  .kds-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.kds-col { container-type: inline-size; }

/* La cabecera de la pantalla, sin aire de sobra */
.kds-head { padding: 6px 2px 8px; }
.kds-head h2 { font-size: 19px; margin: 0; }
.kds-sub { font-size: 11.5px; }
.kds-board { gap: 8px; }

/* ——————————————————————————————————————————————————————
   Mis mesas, entre las de diez compañeros
   Con tres pantallas para diez camareros, lo primero que hace
   uno al llegar es buscar las suyas. El contador va en el botón
   para no tener que pulsarlo y ver si hay algo.
   —————————————————————————————————————————————————————— */
.salon-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}
.mesa-vistas {
  display: flex;
  gap: 3px;
  padding: 0 8px 5px;
}
.mesa-vista {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.mesa-vista em {
  font-style: normal;
  min-width: 17px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--bg-soft);
  font-size: 10.5px;
  font-weight: 700;
}
.mesa-vista:hover { color: var(--ink); border-color: var(--muted); }
.mesa-vista.activa {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-ink, var(--accent));
}
.mesa-vista.activa em { background: var(--accent); color: #16210f; }

/* La mesa que atiende quien está mirando se distingue del resto */
.mesa-card.mia { box-shadow: inset 3px 0 0 var(--accent); }

/* ——————————————————————————————————————————————————————
   La forma de pago, de un toque
   Teclear el importe en la casilla de la tarjeta con la gente
   esperando era lo más lento del cobro. Cinco botones grandes,
   y el desglose solo cuando se paga de varias formas.
   —————————————————————————————————————————————————————— */
.pay-metodos {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: 10px;
}
.pay-metodo {
  min-height: var(--toque-holgado);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 3px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  color: var(--ink);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.1;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.pay-metodo svg { width: 20px; height: 20px; flex: 0 0 auto; }
.pay-metodo span { white-space: nowrap; }
.pay-metodo:hover { border-color: var(--accent); }
.pay-metodo.activo {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--accent-ink);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* «Cuánto» es una decisión secundaria: ocupa menos que el «cómo» */
.modal-pay .pay-modes { gap: 6px; margin-bottom: 10px; }
.modal-pay .pay-mode { min-height: var(--toque); font-size: 12px; }

.pay-last4 { max-width: 7.5rem; }

/* En pantalla estrecha caben mejor en dos filas que apretados en una */
@media (max-width: 460px) {
  .pay-metodos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* `hidden` es un atributo, no una regla: cualquier `display` de autor le
   gana. Ya pasó con las filas de totales; aquí con el desglose del cobro. */
.field-grid[hidden] { display: none !important; }

/* La lista de ventas viene del modal de devolución, que es más ancho: aquí
   se le da el mismo sitio para que el importe no parta en dos renglones. */
#modal-reimprimir .modal { max-width: 40rem; width: 100%; }
#modal-reimprimir .dev-venta { min-height: var(--toque); }
#reimp-ventas { display: grid; gap: 5px; max-height: 48vh; overflow: auto; }

/* ——————————————————————————————————————————————————————
   Numeración e-CF
   Un rango que se agota no puede enterarse uno leyendo un
   número: la barra y el color lo dicen antes.
   —————————————————————————————————————————————————————— */
.ecf-pendientes {
  border: 1px solid var(--warn);
  background: var(--warn-soft);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
}
.ecf-pend-head { margin: 0 0 4px; font-weight: 700; color: var(--warn); font-size: 13px; }
.ecf-pendientes ul { margin: 0; padding-left: 18px; font-size: 13px; }

.ecf-rangos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.ecf-rango {
  border: 1px solid var(--line);
  border-left: 4px solid var(--ok);
  border-radius: 10px;
  padding: 10px 12px;
  background: var(--bg-elev);
}
.ecf-rango.tono-warn { border-left-color: var(--warn); }
.ecf-rango.tono-danger { border-left-color: var(--danger); }
.ecf-rango.inactivo { opacity: 0.55; border-left-color: var(--line); }
.ecf-rango header { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.ecf-rango-tipo { font-weight: 800; font-size: 15px; letter-spacing: 0.02em; }
.ecf-rango-nombre { font-size: 12px; color: var(--muted); flex: 1; min-width: 0; }
.ecf-chip {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--muted);
}
.ecf-chip.warn { background: var(--warn-soft); color: var(--warn); }
.ecf-chip.danger { background: var(--danger-soft); color: var(--danger); }

.ecf-rango-barra {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-soft);
  overflow: hidden;
  margin-bottom: 7px;
}
.ecf-rango-barra i { display: block; height: 100%; background: var(--accent); }
.ecf-rango.tono-warn .ecf-rango-barra i { background: var(--warn); }
.ecf-rango.tono-danger .ecf-rango-barra i { background: var(--danger); }

.ecf-rango-datos {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 12px;
  color: var(--muted);
}
.ecf-rango-datos strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.ecf-rango footer { display: flex; gap: 6px; margin-top: 8px; }
.ecf-rango footer .btn { min-height: 34px; }

.ecf-resumen { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 10px; }
.ecf-resumen .ecf-chip { font-size: 11px; padding: 4px 10px; }
.ecf-chip.ok { background: var(--ok-soft); color: var(--ok); }
.ecf-chip.info { background: var(--accent-soft); color: var(--accent-ink, var(--accent)); }
.ecf-nota { font-size: 11px; color: var(--danger); margin-top: 3px; }
#ecf-docs code { font-size: 12px; letter-spacing: 0.02em; }

/* La contingencia se ve o no sirve: es una obligación con fecha */
.ecf-conting {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
  background: var(--bg-elev);
}
.ecf-conting.encendida {
  border-color: var(--warn);
  border-left-color: var(--warn);
  background: var(--warn-soft);
}
.ecf-conting h4 { margin: 0 0 3px; font-size: 14px; }
.ecf-conting p { margin: 0; font-size: 12.5px; }
.ecf-conting .vencido { color: var(--danger); }
.ecf-conting-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.ecf-conting-btns .btn { min-height: var(--toque); }

/* Con qué se factura hoy, arriba del todo: es lo primero que hay que saber */
.ecf-regimen {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--bg-elev);
}
.ecf-regimen h3 { margin: 0 0 3px; font-size: 15px; }
.ecf-regimen p { margin: 0; font-size: 12.5px; max-width: 46ch; }
.ecf-regimen-campos { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.ecf-regimen-campos .field { margin: 0; }
.ecf-regimen-campos .btn { min-height: var(--toque); }

.ecf-cuenta {
  border: 1px dashed var(--line);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 12px;
}
.ecf-cuenta.cerca { border-color: var(--warn); border-style: solid; background: var(--warn-soft); }
.ecf-cuenta h4 { margin: 0 0 3px; font-size: 14px; }
.ecf-cuenta p { margin: 0 0 3px; font-size: 12.5px; }
.ecf-cuenta ul { margin: 0; padding-left: 18px; font-size: 12.5px; }

/* Anular no es dar de baja: el botón lo dice con el color */
.ecf-rango footer .btn.peligro { color: var(--danger); }
.ecf-rango footer .btn.peligro:hover { border-color: var(--danger); background: var(--danger-soft); }
#ecf-anulaciones code { font-size: 11.5px; }

/* ——————————————————————————————————————————————————————
   El costo al lado del plato
   Un food cost que sólo se ve en un informe de fin de mes
   no cambia ninguna decisión. Aquí está donde se decide.
   —————————————————————————————————————————————————————— */
.costeo-panel {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  background: var(--bg-elev);
}
.costeo-cifras {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 8px;
  margin-bottom: 8px;
}
.costeo-cifras > div { display: flex; flex-direction: column; gap: 1px; }
.costeo-cifras span { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.costeo-cifras strong { font-size: 15px; font-variant-numeric: tabular-nums; }
.costeo-fc.bueno strong { color: var(--ok); }
.costeo-fc.justo strong { color: var(--warn); }
.costeo-fc.malo strong { color: var(--danger); }

/* La barra con la marca del objetivo: se ve de un vistazo si se pasó */
.costeo-barra {
  position: relative;
  height: 7px;
  border-radius: 999px;
  background: var(--bg-soft);
  overflow: visible;
  margin-bottom: 6px;
}
.costeo-barra i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--ok);
}
.costeo-barra.justo i { background: var(--warn); }
.costeo-barra.malo i { background: var(--danger); }
.costeo-barra em {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 13px;
  background: var(--ink);
  opacity: 0.6;
}
.costeo-objetivo { margin: 0 0 8px; font-size: 11.5px; color: var(--muted); }
.costeo-objetivo strong { color: var(--danger); }

.costeo-desglose { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11.5px; color: var(--muted); }
.costeo-desglose strong { color: var(--ink); }

.costeo-avisos {
  border: 1px solid var(--warn);
  background: var(--warn-soft);
  border-radius: 8px;
  padding: 7px 10px;
  margin-bottom: 10px;
  font-size: 12px;
}
.costeo-avisos p { margin: 0; }
.split-line em { font-style: normal; font-size: 11.5px; display: block; }

/* ——————————————————————————————————————————————————————
   Conteo físico
   Se cuenta de pie, con una tablet en una mano: las casillas
   tienen que ser grandes y la fila alta.
   —————————————————————————————————————————————————————— */
.conteo-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.conteo-head h3 { margin: 0 0 3px; font-size: 16px; }
.conteo-head p { margin: 0; font-size: 12.5px; max-width: 52ch; }
.conteo-abrir { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.conteo-abrir .field { margin: 0; }
.conteo-abrir .btn { min-height: var(--toque); }

.conteo-hoja {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  margin-top: 14px;
  background: var(--bg-elev);
}
.conteo-hoja-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.conteo-hoja-head h4 { margin: 0 0 2px; font-size: 15px; }
.conteo-hoja-head p { margin: 0; font-size: 12px; }
.conteo-hoja-btns { display: flex; gap: 6px; flex-wrap: wrap; }
.conteo-hoja-btns .btn { min-height: var(--toque); }

.conteo-tabla td { padding-block: 5px; }
.conteo-input {
  width: 100%;
  max-width: 8rem;
  min-height: var(--toque);
  text-align: right;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.conteo-input:focus { border-color: var(--accent); }

.conteo-variacion {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  margin-top: 12px;
}
.conteo-variacion h4 { margin: 0 0 3px; font-size: 15px; }
.conteo-variacion > p { margin: 0 0 10px; font-size: 12.5px; }

/* ——————————————————————————————————————————————————————
   Centro de costos
   Tres columnas: la carta, la receta y el dinero. El dinero
   manda, porque es lo que se viene a mirar.
   —————————————————————————————————————————————————————— */
.cc-layout {
  display: grid;
  grid-template-columns: minmax(0, 240px) minmax(0, 1fr) minmax(0, 300px);
  gap: 12px;
  align-items: start;
  margin-top: 12px;
}
@media (max-width: 1180px) {
  .cc-layout { grid-template-columns: minmax(0, 220px) minmax(0, 1fr); }
  .cc-dinero { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .cc-layout { grid-template-columns: 1fr; }
}

/* —— La carta —— */
.cc-lista {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px;
  background: var(--bg-elev);
}
.cc-buscador input { width: 100%; min-height: var(--toque); }
.cc-chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0; }
.cc-chip {
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--muted);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
}
.cc-chip.activo { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); }

.cc-platos { display: grid; gap: 4px; max-height: 58vh; overflow: auto; }
.cc-plato {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1px 8px;
  text-align: left;
  border: 1px solid transparent;
  border-left: 3px solid var(--line);
  border-radius: 8px;
  padding: 7px 9px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  min-height: var(--toque);
}
.cc-plato:hover { background: var(--bg-soft); }
.cc-plato.activo { border-color: var(--accent); background: var(--accent-soft); }
.cc-plato.bueno { border-left-color: var(--ok); }
.cc-plato.justo { border-left-color: var(--warn); }
.cc-plato.malo { border-left-color: var(--danger); }
.cc-plato.gris { border-left-color: var(--line); opacity: 0.75; }
.cc-plato-nombre { font-size: 13px; font-weight: 600; }
.cc-plato-cat { font-size: 10.5px; grid-column: 1; }
.cc-plato-fc {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.cc-plato.bueno .cc-plato-fc { color: var(--ok); }
.cc-plato.justo .cc-plato-fc { color: var(--warn); }
.cc-plato.malo .cc-plato-fc { color: var(--danger); }
.cc-plato.gris .cc-plato-fc { font-size: 10.5px; font-weight: 600; color: var(--muted); }

/* —— La receta —— */
.cc-detalle { min-width: 0; }
.cc-ficha {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  background: var(--bg-elev);
}
.cc-ficha-head { display: flex; gap: 12px; align-items: center; margin-bottom: 12px; }
.cc-ficha-head h3 { margin: 0 0 2px; font-size: 18px; }
.cc-ficha-head p { margin: 0; font-size: 12px; }
.cc-foto {
  width: 76px;
  height: 76px;
  border-radius: 12px;
  object-fit: cover;
  flex: 0 0 auto;
  background: var(--bg-soft);
}
.cc-foto-vacia { background: linear-gradient(135deg, var(--accent-soft), var(--bg-soft)); }

.cc-tabla td { padding-block: 6px; font-size: 13px; }
.cc-sub {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.cc-linea-mal { font-size: 11px; color: var(--danger); margin-top: 2px; }
.cc-peso {
  display: inline-block;
  width: 42px;
  height: 5px;
  border-radius: 999px;
  background: var(--bg-soft);
  margin-right: 6px;
  vertical-align: middle;
  overflow: hidden;
}
.cc-peso i { display: block; height: 100%; background: var(--accent); }
.cc-aviso {
  border: 1px solid var(--warn);
  background: var(--warn-soft);
  border-radius: 8px;
  padding: 8px 10px;
  margin: 0 0 10px;
  font-size: 12.5px;
}

/* —— El dinero —— */
.cc-dinero { display: grid; gap: 10px; align-content: start; }
.cc-panel, .cc-simulador, .cc-movidos {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px;
  background: var(--bg-elev);
}
.cc-movidos:empty { display: none; }
.cc-cifra { display: flex; align-items: baseline; justify-content: space-between; padding: 3px 0; }
.cc-cifra span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.cc-cifra strong { font-size: 17px; font-variant-numeric: tabular-nums; }
.cc-cifra.destacada strong { font-size: 21px; color: var(--ok); }

.cc-fc {
  display: grid;
  gap: 1px;
  margin: 10px 0 6px;
  padding: 10px;
  border-radius: 10px;
  background: var(--bg-soft);
  text-align: center;
}
.cc-fc span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.cc-fc strong { font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; }
.cc-fc em { font-size: 11px; font-style: normal; color: var(--muted); }
.cc-fc.bueno { background: var(--ok-soft); }
.cc-fc.bueno strong { color: var(--ok); }
.cc-fc.justo { background: var(--warn-soft); }
.cc-fc.justo strong { color: var(--warn); }
.cc-fc.malo { background: var(--danger-soft); }
.cc-fc.malo strong { color: var(--danger); }

.cc-barra { position: relative; height: 7px; border-radius: 999px; background: var(--bg-soft); margin-bottom: 8px; }
.cc-barra i { display: block; height: 100%; border-radius: 999px; background: var(--ok); }
.cc-barra.justo i { background: var(--warn); }
.cc-barra.malo i { background: var(--danger); }
.cc-barra b { position: absolute; top: -3px; width: 2px; height: 13px; background: var(--ink); opacity: 0.55; }

.cc-veredicto { margin: 0 0 10px; font-size: 12px; }
.cc-veredicto.malo { color: var(--danger); }
.cc-veredicto.bueno { color: var(--ok); }
.cc-desglose { display: grid; gap: 2px; font-size: 12px; border-top: 1px solid var(--line); padding-top: 8px; }
.cc-desglose div { display: flex; justify-content: space-between; }
.cc-desglose span { color: var(--muted); }
.cc-simular-btn { width: 100%; margin-top: 10px; min-height: var(--toque); }

.cc-simulador h4, .cc-movidos h4 { margin: 0 0 3px; font-size: 14px; }
.cc-simulador p, .cc-movidos p { margin: 0 0 8px; font-size: 11.5px; }
.cc-simulador .field { margin-bottom: 8px; }
.cc-simulador .btn { width: 100%; min-height: var(--toque); }
.cc-sim-salida { margin-top: 10px; font-size: 12.5px; }
.cc-sim-fila { display: flex; justify-content: space-between; padding: 3px 0; border-bottom: 1px solid var(--line); }
.cc-sim-sugerido { margin: 8px 0 0; font-size: 12px; }
.cc-movido { display: flex; justify-content: space-between; font-size: 12px; padding: 3px 0; }

/* —— Menu engineering —— */
.cc-menu-panel {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  margin-top: 14px;
  background: var(--bg-elev);
}
.cc-menu-panel h3 { margin: 0 0 3px; font-size: 17px; }
.cc-menu-panel > p { margin: 0 0 12px; font-size: 12.5px; }
.cc-cuadrantes { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.cc-cuadrante { border: 1px solid var(--line); border-top-width: 3px; border-radius: 10px; padding: 10px; }
.cc-cuadrante.ok { border-top-color: var(--ok); }
.cc-cuadrante.warn { border-top-color: var(--warn); }
.cc-cuadrante.info { border-top-color: var(--accent); }
.cc-cuadrante.danger { border-top-color: var(--danger); }
.cc-cuadrante h4 { margin: 0 0 2px; font-size: 14px; display: flex; justify-content: space-between; }
.cc-cuadrante h4 em { font-style: normal; font-variant-numeric: tabular-nums; }
.cc-cuadrante p { margin: 0 0 8px; font-size: 11.5px; }
.cc-cuad-fila { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; padding: 3px 0; }
.cc-cuad-fila em { font-style: normal; color: var(--muted); white-space: nowrap; }

/* ── Alertas ────────────────────────────────────────────────────
   La bandeja se lee de arriba abajo y por dinero. El color lo pone la
   severidad, que es paleta semántica y no marca: una alerta grave se ve
   igual de roja en claro que en oscuro. */

.gp-nav-btn { position: relative; }
.gp-nav-badge {
  position: absolute;
  top: 6px;
  right: 8px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--warn);
  color: #1b1200;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 17px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.gp-nav-badge.grave { background: var(--danger); color: #fff; }

.al-tabs { display: flex; gap: 4px; margin: 12px 0 10px; border-bottom: 1px solid var(--line); }
.al-tab {
  min-height: var(--toque);
  padding: 0 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
}
.al-tab.activo { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 600; }

.al-nota { font-size: 12.5px; max-width: 72ch; margin: 0 0 12px; }
.al-reglas-acciones { margin-bottom: 12px; }

.al-lista { display: flex; flex-direction: column; gap: 10px; }

.al-card {
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: 12px;
  padding: 12px 14px;
  background: var(--bg-elev);
}
.al-card.tone-bad { border-left-color: var(--danger); }
.al-card.tone-warn { border-left-color: var(--warn); }
.al-card.tone-info { border-left-color: var(--accent); }
.al-card.cerrada { opacity: 0.62; }

.al-card > header {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.al-card h4 { margin: 0; font-size: 14.5px; flex: 1 1 260px; }
.al-monto { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 14px; white-space: nowrap; }

.al-sev {
  flex: 0 0 auto;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.al-sev.tone-bad { background: var(--danger-soft); color: var(--danger); }
.al-sev.tone-warn { background: var(--warn-soft); color: var(--warn); }
.al-sev.tone-info { background: var(--accent-soft); color: var(--accent-ink); }

.al-detalle { margin: 7px 0 10px; font-size: 12.5px; line-height: 1.5; max-width: 86ch; }

.al-card > footer {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
  font-size: 11.5px;
}
.al-acciones { display: flex; gap: 6px; flex-wrap: wrap; }
.al-cierre {
  margin: 9px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 12px;
  color: var(--muted);
}

.al-grupo { margin-bottom: 16px; }
.al-grupo h4 { margin: 0 0 7px; font-size: 13.5px; }
.al-reglas { display: block; }
.al-regla {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--toque);
  margin-bottom: 6px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
  color: inherit;
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.al-regla:hover { border-color: var(--accent); }
.al-regla.apagada { opacity: 0.55; }
.al-regla-ambito { flex: 1 1 auto; }
.al-regla-cond { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.al-regla-off {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

#modal-alerta-regla .btn.peligro { margin-right: auto; color: var(--danger); }
#modal-alerta-regla .btn.peligro:hover { border-color: var(--danger); background: var(--danger-soft); }
.al-acciones .btn.peligro { color: var(--danger); }
.al-acciones .btn.peligro:hover { border-color: var(--danger); background: var(--danger-soft); }

@media (max-width: 720px) {
  .al-card > header { gap: 5px; }
  .al-monto { flex: 1 1 100%; }
  .al-card > footer { align-items: flex-start; flex-direction: column; }
}

/* ── Unidades del insumo ────────────────────────────────────────
   Se compra la caja, se guarda en mililitros y se sirve en onzas: son tres
   campos que sólo tienen sentido juntos, así que van dentro de un bloque. */
.uom-bloque {
  margin: 0 0 12px;
  padding: 11px 13px 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
}
.uom-bloque legend {
  padding: 0 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-ink);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.uom-nota { margin: 0 0 9px; font-size: 12px; max-width: 64ch; }

.field-hint {
  display: block;
  margin-top: 3px;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--muted);
}

/* ── Que quepa en un teléfono ────────────────────────────────────
   El fallo era siempre el mismo y no se veía venir: un hijo de grid o de
   flex **no se encoge por debajo de su contenido** salvo que se le diga.
   Una tabla de stock de 511 px estiraba su columna a 511, y la ficha del
   insumo que tiene al lado se iba con ella fuera de la pantalla. La tabla
   no era el problema —ésa ya sabe desplazarse dentro de su caja, para eso
   `.data-table-wrap` lleva overflow—: el problema era la columna.

   Con `min-width: 0` la columna vuelve a medir lo que mide la pantalla y
   cada cual se apaña dentro: la tabla se desplaza de lado, el formulario
   se apila. Se toca sólo lo que es rejilla de la página; en escritorio no
   cambia nada, porque allí la columna ya era más ancha que su contenido. */
.module-shell > *,
.analytics-shell > *,
.analytics-board > *,
.clientes-layout > *,
.caja-workbench > *,
.caja-side-col > *,
.cc-layout > *,
.al-shell > *,
.field-grid > * { min-width: 0; }

/* Un `select` mide por su opción más larga —«Onza líquida (OZ)»— y se
   niega a encoger aunque le pongas width: 100%. */
.field input,
.field select,
.field textarea { min-width: 0; max-width: 100%; }

/* ── Teléfono ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  /* Dos columnas de formulario en 390 px son dos columnas de nada */
  .field-grid { grid-template-columns: 1fr; }

  /* La cabecera de cada módulo es flex y no envolvía: el título y los
     botones se empujaban el uno al otro hasta salirse. */
  .module-hero {
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .module-hero > * { min-width: 0; }
  .module-hero-actions { width: 100%; }
  .module-hero h2 { font-size: 1.35rem; }
  .hub-hero-mod .hub-staff { margin-left: 0; }

  /* Las tablas anchas se desplazan dentro de su caja, no arrastran la
     página. El tirón lateral en el móvil es el de la tabla, no el del
     documento. */
  .data-table-wrap { -webkit-overflow-scrolling: touch; }

  /* Y nada de palabras largas partiendo la caja */
  .al-card h4,
  .al-detalle,
  .module-hero p { overflow-wrap: anywhere; }
}

/* La tarjeta del plato aprieta precio y estación en la misma línea, y en una
   tableta apaisada la rejilla las deja en 129 px: «800.00 COCINA» no cabía y
   se salía por el borde. Que envuelva. */
.menu-card .meta-row { flex-wrap: wrap; row-gap: 3px; }
.menu-card .meta-row > * { min-width: 0; }

/* Con el dedo, un campo de formulario también es un blanco que hay que
   acertar. Los de las ventanas ya cumplían el mínimo; los que viven en la
   página se habían quedado en 40 px, por debajo del propio `--toque` del
   proyecto. Aquí manda el puntero y no el ancho: un iPad apaisado es ancho
   y se usa con la mano igual que un teléfono. */
@media (pointer: coarse) {
  .field input,
  .field select,
  .field textarea,
  .form-card .btn { min-height: var(--toque); }
}

/* ── Pestañas del centro de costos y su barra de filtros ─────────
   Los filtros vivían apretados en la columna de 240 px: el buscador y ocho
   fichas apiladas de cuatro en cuatro, mientras al lado sobraba media
   pantalla. Suben a una barra de ancho completo, que es donde se leen de un
   vistazo, y la columna se queda para lo suyo: la lista de platos. */
.cc-tabs {
  display: flex;
  gap: 4px;
  margin: 12px 0 10px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.cc-tab {
  min-height: var(--toque);
  padding: 0 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
}
.cc-tab.activo { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 600; }

.cc-filtros-barra {
  display: flex;
  align-items: center;
  gap: 8px 14px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
}
.cc-filtros-barra .cc-buscador { flex: 1 1 240px; min-width: 0; }
.cc-filtros-barra .cc-buscador input { width: 100%; min-height: var(--toque); }
.cc-filtros-barra .cc-chips { margin: 0; flex: 0 1 auto; }
/* Una raya entre «de qué carta» y «cómo va»: son dos preguntas distintas */
.cc-filtros-barra .cc-chips-estado {
  padding-left: 14px;
  border-left: 1px solid var(--line);
}

@media (max-width: 720px) {
  .cc-filtros-barra { padding: 9px 10px; }
  .cc-filtros-barra .cc-chips-estado { padding-left: 0; border-left: 0; }
}

/* ── Avisos por correo ──────────────────────────────────────────── */
.al-correo-estado { margin-bottom: 14px; }
.al-aviso {
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: 10px;
  padding: 11px 13px;
  font-size: 12.5px;
  line-height: 1.55;
  background: var(--bg-elev);
}
.al-aviso.tone-ok { border-left-color: var(--ok); }
.al-aviso.tone-warn { border-left-color: var(--warn); }
.al-aviso.tone-bad { border-left-color: var(--danger); }
.al-aviso code {
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--bg-soft);
  font-size: 11.5px;
}
.al-dest-quien { flex: 1 1 auto; min-width: 0; }
.al-dest-quien strong { font-weight: 600; }

/* La lista se queda sola en su columna —los filtros subieron a la barra— así
   que le sobra sitio para que un nombre largo no se parta: «Camarones al
   ajillo» cabe entero. */
.cc-layout { grid-template-columns: minmax(0, 290px) minmax(0, 1fr) minmax(0, 320px); }
@media (max-width: 1180px) {
  .cc-layout { grid-template-columns: minmax(0, 260px) minmax(0, 1fr); }
}

/* ── La rejilla ──────────────────────────────────────────────────
   `.data-table` no tenía estilo propio: lo único que llevaba era el relleno
   de las celdas, y lo demás era el navegador —cabeceras centradas, sin líneas
   y con la letra de un documento—. Las tablas que «se veían bien» era porque
   alguien les había puesto color a las filas por otro lado.

   Va aquí y sin apellidos, así que lo arregla en todas a la vez: existencias,
   kardex, recetas, órdenes de compra y las que vengan. */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-soft);
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: left;
  white-space: nowrap;
}
.data-table tbody td {
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:hover { background: var(--bg-soft); }
/* Los números se leen por la derecha y con el mismo ancho de cifra: así una
   columna de precios se compara de un vistazo. */
.data-table th.num,
.data-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.data-table tbody tr[data-id] { cursor: pointer; }

/* ── El buscador del centro de costos ───────────────────────────
   Tampoco tenía estilo: era el recuadro gris del navegador, y encima se
   estiraba a media pantalla. Un buscador no necesita 500 px. */
.cc-buscador input {
  width: 100%;
  min-height: var(--toque);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg);
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
}
.cc-buscador input::placeholder { color: var(--muted); }
.cc-buscador input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.cc-filtros-barra .cc-buscador { flex: 0 1 300px; }

/* ── La pantalla de recetas ──────────────────────────────────────
   La carta es una tabla de cuatro columnas y la ficha una sola columna de
   campos: partir la pantalla por la mitad dejaba la tabla apretada y la ficha
   con aire de sobra. */
#cc-panel-recetas .clientes-layout { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }

/* La lista de ingredientes no lleva su propia barra de desplazamiento: una
   receta de seis líneas cabe entera, y para eso la página ya se desplaza. */
#cc-panel-recetas .split-lines { max-height: none; overflow: visible; }

/* Y el alta de una línea cabe en un renglón: insumo, cuánto, en qué unidad y
   cuánto se pierde. Son cuatro casillas cortas, no un formulario. */
#cc-panel-recetas .receta-alta {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 8px;
  align-items: end;
  margin-top: 10px;
}
#cc-panel-recetas .receta-alta .field { margin: 0; }
#cc-panel-recetas .receta-alta label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 2px;
}
@media (max-width: 900px) {
  #cc-panel-recetas .clientes-layout { grid-template-columns: 1fr; }
  #cc-panel-recetas .receta-alta { grid-template-columns: 1fr 1fr; }
}

/* Un food cost fuera de sitio se ve antes en color que leyendo la cifra */
.data-table td.num.tone-ok { color: var(--ok); font-weight: 600; }
.data-table td.num.tone-warn { color: var(--warn); font-weight: 600; }
.data-table td.num.tone-bad { color: var(--danger); font-weight: 700; }

/* La línea de la receta, en un renglón. Antes el nombre y la cantidad iban en
   dos, y seis ingredientes se comían media pantalla. */
.receta-linea {
  padding: 5px 10px;
  font-size: 12.5px;
  gap: 8px;
}
.receta-linea-que {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.receta-linea-que em { font-style: normal; font-size: 11.5px; }
.receta-linea-costo { min-width: 4.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.receta-linea .btn { padding: 2px 9px; font-size: 11.5px; min-height: 26px; }
@media (pointer: coarse) {
  /* Con el dedo el botón manda: vale más un renglón alto que fallar el toque */
  .receta-linea .btn { min-height: var(--toque); padding: 0 12px; }
}

/* `.form-card .btn` separa del formulario con un margen arriba, y aquí ese
   margen se multiplicaba por cada ingrediente. */
.receta-linea .btn { margin-top: 0; }

/* ── El hueco que se paga dos veces ──────────────────────────────
   `.module-shell` es una columna flex con `gap: 16px`, y encima cada bloque
   traía su propio margen: la cabecera 8 abajo, las pestañas 12 arriba y 10
   abajo. En flex los márgenes no se funden con el hueco, se suman — así que
   entre la cabecera y los KPIs había 24 px, entre los KPIs y las pestañas 28,
   y entre las pestañas y su contenido 26. De ahí las bandas vacías.

   El hueco lo pone el contenedor y nadie más. Vale para todos los módulos,
   que todos se montan igual. */
.module-shell > *,
.analytics-shell > *,
.compras-shell > * {
  margin-top: 0;
  margin-bottom: 0;
}

/* ── La tarjeta de KPI ───────────────────────────────────────────
   108 px de alto mínimo para una etiqueta, una cifra y un pie de siete
   palabras. Se le quita el aire de dentro sin tocar la letra: la cifra sigue
   leyéndose desde la puerta. */
.kpi-premium {
  min-height: 92px;
  padding: 11px 13px 10px;
}
.kpi-premium .kpi-value { margin-top: 6px; font-size: 1.45rem; }
.kpi-premium .kpi-foot { margin-top: 3px; }
.kpi-premium .kpi-icon { width: 30px; height: 30px; border-radius: 9px; }

@media (min-width: 1500px) {
  /* En un monitor grande sigue sobrando sitio, pero no tanto */
  .kpi-premium { min-height: 100px; padding: 13px 15px 12px; }
}

/* La cabecera del módulo: el subtítulo explica, no ocupa */
.module-hero h2 { line-height: 1.1; }
.module-hero .muted { margin-top: 2px; font-size: 12.5px; }
.module-kicker { margin-bottom: 1px; }

/* ── La carta y su ficha, en paralelo ────────────────────────────
   Estaban una encima de otra: para ver el plato que se estaba editando había
   que bajar la pantalla, y al volver arriba ya no se sabía cuál era. Ahora la
   carta manda a la izquierda —que es lo que se mira— y las fichas acompañan a
   la derecha, a la vista. */
.menu-admin-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: 14px;
  align-items: start;
}
.menu-admin-carta { min-width: 0; }
.menu-admin-fichas { min-width: 0; }

/* La primera cabecera no necesita el margen de arriba: ya está arriba */
.menu-admin-carta .adm-gallery-head { margin-top: 0; }
/* En una columna más estrecha caben tarjetas más pequeñas */
.menu-admin-carta .adm-gallery { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); }

/* La ficha se queda a la vista mientras se recorre una carta larga */
.menu-admin-fichas {
  position: sticky;
  top: 8px;
}
.menu-admin-fichas .form-card:last-child { margin-bottom: 0; }

@media (max-width: 1100px) {
  .menu-admin-layout { grid-template-columns: 1fr; }
  /* Sin dos columnas no hay nada a lo que quedarse pegado */
  .menu-admin-fichas { position: static; }
  /* Y la ficha vuelve arriba: es lo que se está haciendo */
  .menu-admin-carta { order: 2; }
  .menu-admin-fichas { order: 1; }
}

/* ── La salud del cliente en el BackOffice ───────────────────────
   Una columna más en la ficha de cada cliente: si va al día con las
   migraciones y cuánto usa de lo que paga. Con una base por cliente, el
   desfase es lo que se rompe sin que suene nada. */
.bo-cliente {
  grid-template-columns:
    minmax(0, 1.3fr) minmax(0, 0.9fr) minmax(0, 0.9fr)
    minmax(0, 1.1fr) minmax(0, 0.85fr) minmax(0, 1fr) auto;
}
.bo-cliente-salud { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }

.bo-salud-chip {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.bo-salud-chip.aldia { background: var(--ok-soft, rgba(111,207,123,0.16)); color: var(--ok); }
.bo-salud-chip.atrasado { background: var(--warn-soft); color: var(--warn); }
.bo-salud-chip.caido { background: var(--danger-soft); color: var(--danger); }
.bo-salud-chip.sin { background: var(--bg-soft); color: var(--muted); }

/* Lo que usa contra lo que da el plan. El que roza el techo se ve aquí antes
   de que llame porque no puede crear otra caja. */
.bo-topes { display: inline-flex; gap: 4px; }
.bo-tope {
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.bo-tope.justo { border-color: var(--warn); color: var(--warn); }
.bo-tope.lleno { border-color: var(--danger); color: var(--danger); font-weight: 700; }

@media (max-width: 1240px) {
  /* Cuando la ficha se apila, la salud va entera en su renglón */
  .bo-cliente-salud { grid-column: 1 / -1; }
}

/* ── La banda de soporte ─────────────────────────────────────────
   Entrar en casa ajena sin que se note es justo lo que no se hace: mientras
   dure, se ve en todas las pantallas y por encima de todo. Roja y fija, no
   porque sea un error, sino porque no se puede olvidar que se está dentro. */
.soporte-banda {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 14px;
  background: var(--danger);
  color: #fff;
  font-size: 12.5px;
  line-height: 1.35;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}

/* Sin esto la banda NO se va nunca.

   El JavaScript la esconde poniendole el atributo `hidden`, que funciona
   porque el navegador trae `[hidden] { display: none }`. Pero esa regla
   suya es de especificidad minima y la de arriba —`.soporte-banda`, una
   clase— le gana: el `display: flex` se impone y la banda sigue en
   pantalla con el atributo puesto. Tapando la barra, sin boton que la
   quite, y tambien en la pantalla de acceso.

   Es el fallo que dejaba la aplicacion inservible. Comprobarlo mirando
   `banda.hidden` decia que si estaba escondida; habia que mirar lo que
   se veia. */
.soporte-banda[hidden] { display: none; }

.soporte-texto { flex: 1 1 auto; min-width: 0; }
.soporte-texto strong { font-weight: 700; }
.soporte-reloj {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  white-space: nowrap;
}
.soporte-banda .btn {
  background: #fff;
  color: var(--danger);
  border-color: #fff;
  font-weight: 700;
  white-space: nowrap;
}
.soporte-banda .btn:hover { background: #ffecea; }

/* El punto que late: se ve de reojo desde el otro lado del mostrador */
.soporte-punto {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #fff;
  flex: 0 0 auto;
  animation: soporte-late 1.6s ease-in-out infinite;
}
@keyframes soporte-late {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
  .soporte-punto { animation: none; }
}

/* La aplicación se baja lo que ocupa la banda: la barra de arriba es fija y
   si no, la tapa. */
body.con-soporte .app-shell { padding-top: var(--soporte-alto, 38px); }

@media (max-width: 720px) {
  .soporte-banda { flex-wrap: wrap; padding: 6px 10px; gap: 6px 8px; }
  .soporte-texto { flex: 1 1 100%; font-size: 11.5px; }
  body.con-soporte .app-shell { padding-top: var(--soporte-alto, 66px); }
}

/* El bloque de «de dónde sale» dentro de la ficha del plato: la costura
   entre lo que se vende y lo que se almacena. */
.art-bloque {
  margin: 0 0 12px;
  padding: 11px 13px 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
}
.art-bloque legend {
  padding: 0 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-ink);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.art-nota { margin: 0 0 9px; font-size: 12px; }
.art-bloque .field { margin-bottom: 9px; }

/* En la carta, de un vistazo: qué descuenta cada plato */
.adm-plato-inv {
  display: inline-block;
  margin-top: 3px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.adm-plato-inv.receta { background: var(--accent-soft); color: var(--accent-ink); }
.adm-plato-inv.directo { background: var(--ok-soft, rgba(111,207,123,0.16)); color: var(--ok); }
.adm-plato-inv.ninguno { background: var(--bg-soft); color: var(--muted); }
.adm-plato-inv.falta { background: var(--warn-soft); color: var(--warn); }

/* ── El submenú del lateral ──────────────────────────────────────
   Lo que está a dos clics no existe: había que entrar a Inventario y
   descubrir que dentro hay conteo físico, recetas y kardex. Ahora se ven
   desde fuera, y cada uno es una dirección de verdad —`#inventario/conteo`—
   que se puede guardar en favoritos y compartir. */
.gp-nav-sub {
  display: none;
  flex-direction: column;
  gap: 1px;
  margin: 1px 0 4px 0;
  padding-left: 30px;
}
.gp-nav-sub.abierto { display: flex; }

.gp-nav-subbtn {
  position: relative;
  min-height: 30px;
  padding: 4px 10px 4px 12px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}
/* La guía vertical: se ve de qué módulo cuelgan sin tener que leerlos */
.gp-nav-subbtn::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line);
}
.gp-nav-subbtn:hover { background: var(--bg-soft); color: var(--ink); }
.gp-nav-subbtn.activo { color: var(--accent-ink); font-weight: 600; }
.gp-nav-subbtn.activo::before { background: var(--accent); width: 2px; }

@media (pointer: coarse) {
  .gp-nav-subbtn { min-height: 38px; font-size: 13px; }
}

/* Con la barra plegada no hay sitio para nombres: el submenú se guarda */
.app-shell.sidebar-mini .gp-nav-sub,
.gp-sidebar.mini .gp-nav-sub { display: none; }
