/* ============================================================
   Rediseño visual — misma paleta de marca, sin cambiar un hex.
   (Los valores son los de sitio-grupo/marca/marca.css.)

   Reglas de movimiento, por frecuencia de uso:
   - Pestañas y botones se pulsan cientos de veces al dia: SOLO
     respuesta al tacto (150ms o menos), nada decorativo.
   - Modales y toasts son ocasionales: entrada de 200-350ms.
   - El login se ve una vez al dia: ahi si hay entrada escalonada.
   Todo transform/opacity (GPU); nunca `transition: all`.
   ============================================================ */

:root {
  /* Que el navegador pinte en oscuro lo que dibuja el por su cuenta: las
     casillas sin marcar, el calendario de las fechas, la lista de un
     desplegable. Sin esto, en el telefono las casillas "Crítico" y "Ya pedido"
     salian como cuadros blancos sobre la ficha oscura. */
  color-scheme: dark;
  --bg: #14171A;
  --surface: #1E2226;
  --surface2: #262B30;
  --border: #2A2F33;
  --border2: #33383D;
  --gold: #D9A441;
  --sage: #6B9080;
  --rust: #C1543C;
  --slate: #5B7C99;
  /* EL ACENTO: el color de la marca de lo que se esta mirando (ver "Las
     marcas"). Fuera de un [data-marca], el del grupo. */
  --acento: var(--gold);
  --acento-claro: #E3B155;
  --acento-rgb: 217, 164, 65;
  --marca-franja: var(--gold);
  --marca-signo: var(--gold);
  --marca-fondo: #14171A;
  --text: #ECEFF1;
  --text-dim: #8B939A;
  /* El gris de las ayudas. Era #6B7176, que da 3,2:1 sobre las tarjetas: por
     debajo del 4,5:1 que pide el texto pequeño, y a 11px, de noche y en el
     telefono del local, no se leia. Este da 4,6:1 y sigue siendo mas tenue que
     --text-dim. No es un color de la marca (el kit solo define el #8B939A):
     sobre un fondo oscuro dos grises legibles no pueden estar lejos, asi que
     la jerarquia la pone el TAMAÑO, no un gris que no se lee. (24/10/2026) */
  --text-dimmer: #858B90;

  /* Curvas con intencion: las de CSS de serie son demasiado blandas. */
  /* LAS TRES VOCES DE LA MARCA, con los mismos nombres que
     sitio-grupo/marca/marca.css. Hasta el 24/10/2026 esta aplicacion escribia
     TODO en la mono —nombres de productos, etiquetas, botones— y la de texto
     ni se cargaba: la mono es para datos, y con 550 productos de nombres
     largos es justo donde peor se lee. Las cantidades se quedan en mono, que
     es su trabajo: alinean por la coma sin hacer nada mas. */
  --f-titulo: 'Space Grotesk', system-ui, sans-serif;
  --f-texto: 'IBM Plex Sans', system-ui, sans-serif;
  --f-datos: 'IBM Plex Mono', ui-monospace, monospace;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
}

* { box-sizing: border-box; }

/* Textura: grano fino sobre el carbon (como papel), mas un calor de laton
   arriba, muy tenue — la "luz" de la marca. El grano va como imagen de fondo
   en mosaico: barato de pintar, sin capas fijas que compositar en moviles. */
body {
  margin: 0;
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse 90% 40% at 50% -5%, rgba(217, 164, 65, 0.05), transparent 70%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  color: var(--text);
  font-family: var(--f-texto);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, .heading, .section-label { font-family: var(--f-titulo); }

button { font-family: var(--f-texto); font-weight: 600; cursor: pointer; border: none; }
input, select { font-family: var(--f-texto); }
/* Lo que se teclea son CANTIDADES: en mono se ve de un vistazo si sobra un cero. */
input[inputmode="decimal"], input[type="number"], input[type="date"], input[type="time"] { font-family: var(--f-datos); }

/* Un <select> mide por su opcion mas larga, y ese ancho minimo no lo baja ni un
   width:100%: hay que decir min-width:0 expresamente. Con 550 productos en el
   desplegable, "Sparkling Minalba Para Recetas (g)" estiraba la columna del
   contenido a 551px dentro de una pantalla de 375 y toda la pagina se iba de
   lado — no solo el desplegable: la cabecera, las pestañas y los botones.
   Se le pone a todo lo que se rellena, que es de donde salen los textos largos. */
input, select, textarea { min-width: 0; max-width: 100%; }

::selection { background: rgba(var(--acento-rgb), 0.35); }

/* Los iconos dibujados (ver ICONO_IMPRIMIR en nucleo.js): van con el texto del
   boton, a su altura y con su color. */
.icono { display: inline-block; vertical-align: -2px; margin-right: 6px; flex-shrink: 0; }
/* El cursor de texto tambien lo dibuja el navegador por su cuenta si nadie se
   lo dice: en laton se ve donde esta escribiendo quien cuenta el inventario. */
input, textarea, select { caret-color: var(--acento); }

/* Las cifras con digitos del mismo ancho, para que las columnas se alineen por
   la coma sin hacer nada mas. Antes salia gratis porque TODO era mono. */
/* Solo las CELDAS: una cabecera es una etiqueta, no una cifra. Con los th
   dentro, la misma fila de cabecera salia mitad en Sans y mitad en mono. */
.num, table td.text-right {
  font-family: var(--f-datos);
  font-variant-numeric: tabular-nums;
}

/* Anillo de foco para teclado, en laton. Solo :focus-visible: al tocar o
   pinchar no aparece, al tabular si. */
:focus-visible {
  outline: 2px solid rgba(var(--acento-rgb), 0.55);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Barras de desplazamiento discretas (tablas anchas, listas de modal) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--text-dimmer); }

/* 1500 y no fluido del todo: una tabla que cruza 1900px de monitor se vuelve
   dificil de seguir con la vista de fila en fila. Esto aprovecha la pantalla
   sin sacrificar la lectura. */
.container { max-width: 1500px; margin: 0 auto; padding: 0 24px; }
/* En una pantalla de 375px, los 24 del contenedor mas los 20 de cada tarjeta se
   comian 88px — casi una cuarta parte del ancho — antes de escribir nada. */
@media (max-width: 720px) { .container { padding: 0 16px; } }

/* ---- Barra lateral de navegacion (solo escritorio) ----
   Todo visible y agrupado con sus titulos: con 16 pestañas, verlas todas de un
   vistazo gana a las pildoras de grupos. En el telefono no hay sitio y se
   mantienen las pestañas de siempre — lo decide el ancho, no el codigo. */
.app-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 28px; align-items: start; }
.lateral-nav {
  position: sticky; top: 16px;
  display: flex; flex-direction: column; gap: 20px;
  max-height: calc(100dvh - 32px); overflow-y: auto;
  padding: 4px 4px 4px 0;
}
/* La categoria tiene que leerse como categoria y no como una opcion mas. Antes
   era mas pequeña Y mas apagada que sus propios elementos, asi que se hundia:
   la vista saltaba directa a los nombres y los grupos desaparecian.
   Ahora manda por contraste y por el filete que la subraya, mientras los
   elementos bajan de peso — la jerarquia se ve sin leer nada. */
.lateral-cabecera {
  display: flex; justify-content: space-between; align-items: center;
  width: 100%; background: none;
  padding: 0 10px 7px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
@media (hover: hover) and (pointer: fine) {
  .lateral-cabecera:hover .lateral-titulo { color: var(--text); }
}
.lateral-titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--text-dim);
  transition: color 120ms ease;
}
.lateral-flecha {
  color: var(--text-dimmer); font-size: 9px; line-height: 1;
  transition: transform 200ms var(--ease-out);
}
.lateral-flecha.plegada { transform: rotate(-90deg); }
/* El pliegue: el truco de 1fr -> 0fr anima una altura desconocida sin medirla.
   El interior necesita min-height:0 y overflow:hidden para poder encogerse. */
.lateral-items {
  display: grid; grid-template-rows: 1fr;
  transition: grid-template-rows 220ms var(--ease-out);
}
.lateral-items.plegado { grid-template-rows: 0fr; }
.lateral-items-interior { overflow: hidden; min-height: 0; }
.lateral-item {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  width: 100%; padding: 7px 10px; border-radius: 8px;
  background: none; color: var(--text-dim);
  font-size: 13px; font-weight: 500; text-align: left;
  transition: color 120ms ease, background-color 120ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .lateral-item:hover { color: var(--text); background: rgba(255, 255, 255, 0.03); }
}
.lateral-item.active {
  color: var(--text);
  font-weight: 700;
  background: rgba(var(--acento-rgb), 0.12);
  box-shadow: inset 2px 0 0 var(--acento);   /* el filete del activo, del color de la marca */
}
.lateral-badge {
  background: var(--rust); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1;
  border-radius: 10px; padding: 3px 7px;
  flex-shrink: 0;
}
/* minmax(0, 1fr) y no 1fr: "1fr" a secas deja que la columna crezca hasta el
   contenido mas ancho que haya dentro, asi que un solo elemento que no sepa
   encogerse (una tabla, un desplegable) se lleva la pagina entera de lado. Con
   el minimo en 0 la columna nunca pasa de la pantalla y quien tenga que
   desplazarse lo hace dentro de su propia caja. */
@media (max-width: 1100px) {
  .app-layout { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .lateral-nav { display: none; }
}
@media (min-width: 1101px) {
  .nav-movil { display: none; }
}

/* ---- Inventario: tabla + lateral de ultimos movimientos ----
   El lateral es cosa de escritorio: en el telefono la pestaña Historial ya
   cumple ese papel y aqui solo empujaria la tabla fuera de la vista. */
.inv-layout { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 20px; align-items: start; }
.inv-lado { display: flex; flex-direction: column; gap: 16px; position: sticky; top: 16px; }
.mov-row { display: flex; align-items: baseline; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 12px; }
.mov-row:last-child { border-bottom: none; }
.mov-producto { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mov-detalle { color: var(--text-dimmer); font-size: 11px; }
.mov-cantidad { font-weight: 600; white-space: nowrap; }
@media (max-width: 1100px) {
  .inv-layout { grid-template-columns: 1fr; }
  .inv-lado { display: none; }
}

/* ---- Login ---- */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.login-card {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent 40%), var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px;
  width: 100%;
  max-width: 380px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),   /* luz desde arriba */
    0 16px 48px rgba(0, 0, 0, 0.35);
}
/* Entrada del login: se ve una vez al dia, aqui si cabe el escalonado.
   Cada bloque sube 10px y aparece, en cascada corta (60ms entre pasos). */
.login-card { animation: entrada-suave 420ms var(--ease-out) both; }
.login-card .login-marca { animation: entrada-suave 420ms var(--ease-out) 40ms both; }
.login-card .field:nth-of-type(1) { animation: entrada-suave 420ms var(--ease-out) 100ms both; }
.login-card .field:nth-of-type(2) { animation: entrada-suave 420ms var(--ease-out) 160ms both; }
.login-card .btn-full { animation: entrada-suave 420ms var(--ease-out) 220ms both; }
@keyframes entrada-suave {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* El lockup de ADMOS SHOP va en curvas y trae sus propios colores, asi que no
   se recolorea desde aqui. El horizontal nunca por debajo de 24px de alto. */
.login-marca { text-align: center; margin-bottom: 24px; }
.logo-login { width: 220px; height: auto; display: block; margin: 0 auto 18px; }
/* EL ESTADO DE "ENTRANDO". Un punto que late, no una vuelta entera: el boton
   mantiene su sitio y su tamaño, y lo que cambia es que esta ocupado. */
.cargando-punto {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; margin-right: 8px; vertical-align: 1px;
  animation: latido 900ms var(--ease-in-out) infinite;
}
@keyframes latido {
  0%, 100% { opacity: 0.35; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1); }
}
/* El error del login no es una linea suelta: es lo unico que hay que leer. */
.error-login {
  background: rgba(193, 84, 60, 0.12);
  border: 1px solid rgba(193, 84, 60, 0.4);
  border-radius: 8px; padding: 10px 12px; margin-top: 4px;
  color: var(--text); font-size: 12px; line-height: 1.45;
}
.login-title { font-size: 16px; font-weight: 700; margin: 0 0 2px; }
.login-sub { color: var(--text-dim); font-size: 12px; margin: 0; }
.aviso-clave {
  background: rgba(217,164,65,0.08); border: 1px solid rgba(217,164,65,0.3);
  border-left: 3px solid var(--gold);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 18px;
  font-size: 12px; line-height: 1.5; color: var(--text-dim);
}

/* ---- Header ---- */
header.app-header {
  border-bottom: 1px solid var(--border);
  padding: 20px 0;
}
.header-row { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; }
/* El logotipo manda y el texto queda a su lado, separado por un filete. El
   min-width:0 es lo que permite que el texto se encoja en el telefono en vez de
   empujar los botones fuera de la pantalla. */
.header-marca { display: flex; align-items: center; gap: 16px; min-width: 0; }
.logo-app { height: 26px; width: auto; display: block; flex-shrink: 0; }
.header-marca-texto { padding-left: 16px; border-left: 1px solid var(--border); min-width: 0; }
.app-title { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--text); margin: 0; }
.app-sub { color: var(--text-dim); font-size: 12px; margin-top: 2px; }
/* En el telefono el logotipo se lleva la mitad del ancho y el texto de al lado
   partia en dos lineas cada uno: la cabecera ocupaba 290px antes de que
   empezara el contenido. Apilado, el texto va a todo lo ancho y cabe de una,
   con lo que la cabecera baja a menos de la mitad. El filete se quita porque
   solo tiene sentido separando dos cosas que van lado a lado. */
@media (max-width: 720px) {
  .header-marca { flex-direction: column; align-items: flex-start; gap: 8px; }
  .logo-app { height: 24px; }
  .header-marca-texto { padding-left: 0; border-left: none; }
  .app-title { font-size: 13px; }
  .app-sub { font-size: 11px; }
}
.header-actions { display: flex; gap: 8px; align-items: center; }

/* ---- Buttons ----
   Se pulsan cientos de veces al dia: la unica animacion es la respuesta al
   dedo (encogerse un 3% al presionar, 140ms). El relieve viene del degradado
   vertical y el brillo interior de 1px — luz desde arriba, como el resto. */
.btn {
  border-radius: 8px; padding: 10px 16px; font-size: 13px; font-weight: 700;
  transition: transform 140ms var(--ease-out), filter 140ms var(--ease-out), background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}
.btn:active { transform: scale(0.97); }
.btn-primary {
  background: linear-gradient(180deg, var(--acento-claro), var(--acento));
  color: #14171A;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), 0 1px 2px rgba(0, 0, 0, 0.35);
}
.btn-primary:active { filter: brightness(0.94); }
.btn-sage {
  background: linear-gradient(180deg, #779B8B, var(--sage));
  color: #14171A;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 1px 2px rgba(0, 0, 0, 0.35);
}
.btn-slate {
  background: linear-gradient(180deg, #6989A6, var(--slate));
  color: #14171A;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 1px 2px rgba(0, 0, 0, 0.35);
}
.btn-ghost { background: transparent; border: 1px solid var(--border2); color: var(--text-dim); }
@media (hover: hover) and (pointer: fine) {
  .btn-ghost:hover { color: var(--text); border-color: var(--text-dimmer); background: rgba(255, 255, 255, 0.03); }
}
.btn-ghost:hover { color: var(--text); } /* respaldo tactil: solo color, sin falsos hover */
.btn-sm { padding: 6px 12px; font-size: 12px; }
.btn-icon { display: inline-flex; align-items: center; gap: 6px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
.btn-full { width: 100%; }

/* ---- Tabs ----
   Se cambian decenas de veces al dia: 150ms de color y nada mas. */
.tabs { display: flex; gap: 20px; border-bottom: 1px solid var(--border); overflow-x: auto; margin: 24px 0; }
.tabs-grupo { margin-bottom: 10px; border-bottom: none; gap: 10px; }
.tabs-grupo .tab-btn {
  background: var(--surface2); border-radius: 20px; padding: 6px 14px; font-size: 12px;
  color: var(--text-dim); border-bottom: none;
  transition: background-color 150ms ease, color 150ms ease, transform 140ms var(--ease-out);
}
.tabs-grupo .tab-btn:active { transform: scale(0.96); }
.tabs-grupo .tab-btn.active {
  background: linear-gradient(180deg, var(--acento-claro), var(--acento));
  color: #14171A;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
.tab-btn {
  background: none; padding-bottom: 12px; font-size: 13px; font-weight: 600;
  color: var(--text-dimmer); border-bottom: 2px solid transparent; white-space: nowrap;
  transition: color 150ms ease, border-color 150ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .tab-btn:hover { color: var(--text-dim); }
}
.tab-btn.active { color: var(--text); border-bottom-color: var(--acento); }

/* ---- Cards / forms ---- */
.card {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent 32%), var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 20px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
@media (max-width: 720px) { .card { padding: 14px; } }
.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.field label { font-size: 12px; color: var(--text-dim); }
.field input, .field select {
  background: var(--bg); border: 1px solid var(--border2); border-radius: 8px;
  padding: 9px 11px; font-size: 13px; color: var(--text); width: 100%;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.field input:focus, .field select:focus {
  outline: none;
  border-color: rgba(var(--acento-rgb), 0.6);
  box-shadow: 0 0 0 3px rgba(var(--acento-rgb), 0.14);
}
.field input[type="checkbox"], .field input[type="radio"] {
  width: 16px; height: 16px; padding: 0; flex-shrink: 0; accent-color: var(--acento);
}
/* Los cuadros donde se pega lo copiado de Excel (importar ventas, conteo). Antes
   llevaban su aspecto escrito en el propio atributo style, y contra eso no hay
   media query que valga: se quedaban en 12-13px y iOS hacia zoom al tocarlos. */
.area-pegar {
  width: 100%; background: var(--bg); border: 1px solid var(--border2);
  border-radius: 6px; padding: 10px; color: var(--text);
  font-family: 'IBM Plex Mono', monospace; font-size: 13px; resize: vertical;
}
/* iOS hace zoom automático al enfocar un input con letra menor a 16px, y a veces no
   regresa el zoom después — con font-size >=16px en móvil, nunca se dispara.
   Cubre todo lo que se escribe, no solo lo que va dentro de .field: los
   casilleros del conteo de operativos se pintan sueltos dentro de una tabla y
   se quedaban en 13px.
   La lista es larga porque en CSS gana el selector que mas pesa: un "select" a
   secas pierde contra ".field select", y ".area-pegar" les gana a los dos. Por
   eso van nombrados los tres, y este bloque va DESPUES de las reglas que tiene
   que tumbar — entre dos que pesan igual, manda el que viene despues. */
@media (max-width: 720px) {
  input:not([type="checkbox"]):not([type="radio"]), select, textarea,
  .field input:not([type="checkbox"]):not([type="radio"]), .field select,
  .area-pegar {
    font-size: 16px;
  }
}
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-2 { display: grid; grid-template-columns: 3fr 2fr; gap: 24px; }
@media (max-width: 720px) { .grid-2, .field-row { grid-template-columns: 1fr; } }

/* ---- Tables ---- */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th {
  text-align: left; color: var(--text-dim); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.015);
}
tbody td { padding: 12px 14px; border-bottom: 1px solid #22262A; }
@media (hover: hover) and (pointer: fine) {
  tbody tr { transition: background-color 120ms ease; }
  tbody tr:hover { background: rgba(255, 255, 255, 0.02); }
}
.table-wrap {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent 24%), var(--surface);
  border: 1px solid var(--border); border-radius: 12px; overflow-x: auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.text-right { text-align: right; }
.empty-msg { text-align: center; color: var(--text-dimmer); padding: 40px; font-size: 13px; }

/* Tablas de seis o siete columnas (usuarios, activos). Con width:100% a secas,
   en el telefono la tabla se queda en el ancho de la pantalla y son las celdas
   las que ceden: cada una parte su texto en cinco lineas y una fila acaba
   midiendo 153px de alto, casi toda ella hueca. Es mejor que la tabla ocupe lo
   que necesita y se desplace de lado dentro de su caja — que para eso el marco
   ya tiene overflow-x. El min-width evita que una tabla corta quede coja.
   Solo estas dos: en las listas de uso diario el desplazamiento lateral seria
   peor que el texto partido, porque escondería la casilla del final. */
@media (max-width: 720px) {
  .table-wrap .tabla-ancha { width: max-content; min-width: 100%; }
}

/* ---- Conteo de insumos operativos ----
   Cuatro columnas y un casillero que rellenar en cada fila. En el escritorio es
   una tabla y se lee de corrido; en el telefono no caben cuatro columnas en
   375px sin dejar el nombre del producto partido en tres lineas y el casillero
   pegado al borde. Ahi cada fila pasa a ser una ficha: el nombre arriba, a todo
   lo ancho, y debajo las dos cifras de referencia junto al casillero. */
.conteo-caja { max-height: 420px; overflow-y: auto; margin: 10px 0; }
.conteo-operativo {
  width: 100px; text-align: right;
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px;
  padding: 6px 8px; color: var(--text);
}
@media (max-width: 720px) {
  /* Sin caja con desplazamiento propio: en el telefono el dedo no distingue
     entre mover la pagina y mover una caja de dentro, y contando 40 insumos
     seguidos eso se convierte en pelearse con la pantalla. Desplaza la pagina. */
  .conteo-caja { max-height: none; overflow-y: visible; }
  .tabla-conteo, .tabla-conteo tbody { display: block; }
  .tabla-conteo thead { display: none; }
  .tabla-conteo tr {
    display: grid;
    /* El casillero en una columna de ancho fijo, no en un 1fr: con "1fr" cada
       fila le daba lo que sobrara despues de sus cifras, asi que "mín 0.5" y
       "mín 1" dejaban los casilleros a distinta altura de borde y la columna
       salia dentada. Fijo, todos caen en la misma linea. */
    grid-template-columns: auto auto 120px;
    grid-template-areas:
      "nombre nombre nombre"
      "min    sis    entrada";
    align-items: center;
    gap: 8px 12px;
    border: 1px solid var(--border); border-radius: 10px;
    padding: 12px; margin-bottom: 8px;
  }
  .tabla-conteo td { display: block; border: none; padding: 0; text-align: left; }
  .tabla-conteo .c-nombre { grid-area: nombre; font-size: 14px; line-height: 1.4; }
  .tabla-conteo .c-min    { grid-area: min; font-size: 12px; }
  .tabla-conteo .c-sis    { grid-area: sis; font-size: 12px; }
  .tabla-conteo .c-inp    { grid-area: entrada; }
  /* Los titulos de columna se van con el thead, asi que cada cifra dice lo que es */
  /* Igual que en las alertas: el rotulo encima, en la voz del texto. */
  .tabla-conteo .c-min::before,
  .tabla-conteo .c-sis::before {
    display: block; font-family: var(--f-texto); font-size: 11px;
    color: var(--text-dimmer); margin-bottom: 2px;
  }
  .tabla-conteo .c-min::before { content: "mín"; }
  .tabla-conteo .c-sis::before { content: "sistema"; }
  .conteo-operativo { width: 100%; min-height: 44px; }
}

/* Casillas de marcar dentro de una fila de alerta ("Crítico", "Ya pedido").
   En el telefono el area de toque la agranda el bloque movil de mas abajo. */
.marca-alerta {
  display: flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11px; color: var(--text-dim); font-weight: 400; white-space: nowrap;
}
/* flex-shrink: 0 NO es un adorno.
   La etiqueta es un flex y su texto va con white-space: nowrap, asi que cuando
   la columna no da de si el unico que puede ceder es el <input>. La casilla de
   "Critico" acababa midiendo 4,8px de ancho por 13 de alto — aplastada, no
   pequeña — mientras "Ya pedido", que va en una columna mas ancha, se quedaba
   cuadrada en sus 13. Parecian dos controles distintos y costaba acertarle.
   El tamaño va declarado ademas para que no dependa del navegador, y el
   accent-color iguala el desktop con el telefono (alli ya era dorado). */
.marca-alerta input[type="checkbox"] {
  width: 15px; height: 15px; flex-shrink: 0; margin: 0;
  accent-color: var(--acento); cursor: pointer;
}

/* ---- Tabla de alertas de stock ----
   Siete columnas (producto, proveedor, stock, minimo, falta y las dos casillas)
   y varias tablas seguidas, una por local. Con el reparto automatico cada tabla
   mide sus columnas por su propio contenido: la de SLA ponia "Stock actual" en
   un sitio y la de BKL en otro, y la lista se leia dentada. `table-layout:fixed`
   con anchos declarados las cuadra todas iguales.

   Se cuentan DESDE LA DERECHA (nth-last-child) porque los subproductos van sin
   la columna de proveedor — se producen en cocina, no se le compran a nadie —
   y asi los mismos anchos valen para las tablas de seis y las de siete. El
   nombre del producto no lleva ancho: se queda con lo que sobre. */
@media (min-width: 721px) {
  .tabla-alertas { table-layout: fixed; min-width: 720px; }
  .tabla-alertas th:nth-last-child(1) { width: 116px; }
  .tabla-alertas th:nth-last-child(2) { width: 106px; }
  .tabla-alertas th:nth-last-child(3) { width: 104px; }
  .tabla-alertas th:nth-last-child(4) { width: 100px; }
  .tabla-alertas th:nth-last-child(5) { width: 114px; }
  .tabla-alertas.con-prov th:nth-last-child(6) { width: 210px; }
  .tabla-alertas.con-prov { min-width: 860px; }
}
/* Con anchos fijos un nombre largo de una sola palabra se sale de su celda en
   vez de partirse. */
.tabla-alertas .a-nombre, .tabla-alertas .a-prov { overflow-wrap: anywhere; }
.tabla-alertas .a-prov { color: var(--text-dim); font-size: 12px; }

/* En el telefono no caben siete columnas en 375px: cada fila pasa a ser una
   ficha, igual que en el conteo. El nombre arriba a todo lo ancho, debajo el
   proveedor, luego las tres cifras en columnas iguales y al final las dos
   casillas. Las cifras van en `1fr 1fr 1fr` y no en `auto`: asi caen a la misma
   altura en todas las fichas y la lista se lee en vertical. */
@media (max-width: 720px) {
  .wrap-alertas { background: none; border: none; box-shadow: none; overflow-x: visible; }
  .tabla-alertas, .tabla-alertas tbody { display: block; }
  .tabla-alertas thead { display: none; }
  .tabla-alertas tr {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-areas:
      "nombre nombre nombre"
      "prov   prov   prov"
      "stock  min    falta"
      "crit   crit   accion";
    gap: 8px 10px;
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--border); border-radius: 10px;
    padding: 12px; margin-bottom: 8px;
  }
  .tabla-alertas td { display: block; border: none; padding: 0; text-align: left; }
  .tabla-alertas .a-nombre { grid-area: nombre; font-size: 14px; line-height: 1.4; }
  .tabla-alertas .a-prov   { grid-area: prov; font-size: 11px; }
  .tabla-alertas .a-stock  { grid-area: stock; font-size: 12px; }
  .tabla-alertas .a-min    { grid-area: min; font-size: 12px; }
  .tabla-alertas .a-sugerida { grid-area: falta; font-size: 12px; }
  .tabla-alertas .a-crit   { grid-area: crit; }
  .tabla-alertas .a-accion { grid-area: accion; justify-self: end; }
  /* Los titulos de columna se van con el thead, asi que cada dato dice lo que es */
  .tabla-alertas .a-prov::before  { content: "proveedor "; color: var(--text-dimmer); }
  /* Los rotulos de las tres cifras, ENCIMA de cada una y en la voz del texto.
     En linea con la cifra, en un tercio de 375px, "pedir 13,200 g" dejaba la
     unidad sola en otro renglon; y como viven dentro de celdas de cifras, un
     ::before hereda la mono de su celda. */
  .tabla-alertas .a-stock::before,
  .tabla-alertas .a-min::before,
  .tabla-alertas .a-sugerida::before {
    display: block; font-family: var(--f-texto); font-size: 11px; font-weight: 400;
    color: var(--text-dimmer); margin-bottom: 2px;
  }
  .tabla-alertas .a-stock::before { content: "hay"; }
  .tabla-alertas .a-min::before   { content: "mín"; }
  .tabla-alertas .a-sugerida::before { content: "pedir"; }
  .tabla-alertas .a-stock, .tabla-alertas .a-min, .tabla-alertas .a-sugerida { white-space: nowrap; }
  /* Area de toque: en la ficha las dos casillas son lo unico que se pulsa */
  .tabla-alertas .marca-alerta { min-height: 32px; font-size: 12px; }
}

/* ---- Historial de movimientos ----
   Siete columnas, y la ultima lleva los botones de cada fila — incluido
   Reversar, que solo ven gerencia y administracion.

   En el telefono esa ultima celda es justo la que se pierde: la tabla mide
   803px, la pantalla 375, y el boton empezaba en x=728. Quedaba a 430px fuera
   de la pantalla, sin nada que indicara que la tabla se arrastra de lado. Es
   exactamente lo que avisaba el comentario de .tabla-ancha — desplazar de lado
   una lista de uso diario esconde la casilla del final — y aqui se cumplio.

   Asi que cada fila pasa a ser una ficha, igual que en Conteo y en Alertas:
   producto arriba, tipo y cantidad, fecha y almacen, la nota, y los botones al
   pie separados por una linea. Nada queda fuera de la pantalla. */
.tabla-historial .h-acciones { white-space: nowrap; }
.tabla-historial .h-acciones .link-btn + .link-btn { margin-left: 10px; }
.tabla-historial .btn-reversar { color: var(--rust); }
.tabla-historial .fila-reversa { background: rgba(176, 106, 74, 0.07); }

@media (max-width: 720px) {
  .wrap-historial { background: none; border: none; box-shadow: none; overflow-x: visible; }
  .tabla-historial, .tabla-historial tbody { display: block; }
  .tabla-historial thead { display: none; }
  .tabla-historial tr {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "producto producto"
      "tipo     cantidad"
      "fecha    almacen"
      "nota     nota"
      "acciones acciones";
    gap: 6px 10px;
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--border); border-radius: 10px;
    padding: 12px; margin-bottom: 8px;
  }
  .tabla-historial td { display: block; border: none; padding: 0; text-align: left; }
  .tabla-historial .h-producto { grid-area: producto; font-size: 14px; line-height: 1.4; }
  .tabla-historial .h-tipo     { grid-area: tipo; font-size: 12px; }
  .tabla-historial .h-cantidad { grid-area: cantidad; font-size: 13px; font-weight: 600; text-align: right; }
  .tabla-historial .h-fecha    { grid-area: fecha; font-size: 11px; }
  .tabla-historial .h-almacen  { grid-area: almacen; font-size: 11px; text-align: right; }
  .tabla-historial .h-nota     { grid-area: nota; font-size: 11px; line-height: 1.4; }
  /* Los titulos de columna se van con el thead, asi que el almacen se explica */
  .tabla-historial .h-almacen::before { content: "en "; color: var(--text-dimmer); }
  /* Los botones al pie, separados y con area de toque: en la ficha son lo unico
     que se pulsa. white-space vuelve a normal para que puedan bajar de linea. */
  .tabla-historial .h-acciones {
    grid-area: acciones; white-space: normal;
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px;
    border-top: 1px solid var(--border2); padding-top: 10px; margin-top: 2px;
  }
  .tabla-historial .h-acciones .link-btn { min-height: 32px; }
  .tabla-historial .h-acciones .link-btn + .link-btn { margin-left: 0; }
  /* El aviso de "sin movimientos" no es una ficha de datos: ocupa toda la fila */
  .tabla-historial td[colspan] { grid-column: 1 / -1; }
  /* El tinte de la reversa, APILADO sobre la superficie de la ficha. A secas
     se queda translucido sobre el fondo de la pagina y esa tarjeta parece un
     hueco en la lista en vez de una tarjeta teñida. */
  .tabla-historial .fila-reversa {
    background: linear-gradient(rgba(176, 106, 74, 0.12), rgba(176, 106, 74, 0.12)), var(--surface);
  }
}

/* ---- Una linea del carrito de compras ----
   Nombre, proveedor, cantidad y la equis. El proveedor va por linea y no uno
   para todo el carrito: recibir de dos proveedores el mismo dia dejaba la
   mitad de las compras atribuidas a quien no fue.

   El nombre en `minmax(0, 1fr)` y no en `1fr`: con "1fr" un nombre largo
   ("Salsa de Ajo Base Mayonesa Casera Grande") empuja la fila y se lleva por
   delante el desplegable. Y el <select> necesita su min-width:0 por lo de
   siempre — mide por su opcion mas larga. */
.carrito-fila {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px 90px auto;
  align-items: center;
  gap: 8px;
  background: #1A1D20; border: 1px dashed var(--border2); border-radius: 8px;
  padding: 8px 12px; margin-bottom: 6px; font-size: 12px;
}
.carrito-fila .cf-nombre { overflow-wrap: anywhere; }
.carrito-fila .cf-proveedor {
  min-width: 0; font-size: 12px; padding: 5px 8px;
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px; color: var(--text);
}
.carrito-fila .cf-cantidad {
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px;
  padding: 6px 8px; color: var(--text); width: 100%;
}
/* En una compra va una columna mas: el total pagado por la linea, en $ (de
   ahi sale el costo del producto). Opcional, y con su propio ancho fijo para
   que las cifras caigan en el mismo sitio en todas las filas. */
.carrito-fila.con-costo { grid-template-columns: minmax(0, 1fr) 160px 80px 170px auto; }
/* El total va con su moneda delante ($ o Bs): lo que se paga en Bs se pasa a
   dolares en el servidor con la tasa del dia de Finanzas. */
.cf-costo-wrap, .costo-con-moneda { display: grid; grid-template-columns: 82px minmax(0, 1fr); gap: 4px; min-width: 0; }
.carrito-fila .cf-costo, .costo-con-moneda input {
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px;
  padding: 6px 8px; color: var(--text); width: 100%; min-width: 0; font-family: var(--f-datos);
}
.cf-moneda {
  min-width: 0; font-size: 12px; padding: 5px 6px;
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px; color: var(--text);
}
/* El campo del proveedor nuevo cae debajo, a todo lo ancho de la fila */
.carrito-fila .cf-nuevo {
  grid-column: 1 / -1;
  background: var(--bg); border: 1px solid var(--acento); border-radius: 6px;
  padding: 6px 8px; color: var(--text); font-size: 12px; width: 100%;
}

/* En el telefono no caben cuatro columnas: el nombre arriba a todo lo ancho y
   debajo el proveedor con la cantidad y la equis. */
@media (max-width: 720px) {
  .carrito-fila {
    grid-template-columns: minmax(0, 1fr) 90px auto;
    grid-template-areas:
      "nombre nombre nombre"
      "prov   cant   quitar";
    gap: 8px;
  }
  .carrito-fila .cf-nombre    { grid-area: nombre; font-size: 13px; }
  .carrito-fila .cf-proveedor { grid-area: prov; min-height: 36px; }
  .carrito-fila .cf-cantidad  { grid-area: cant; min-height: 36px; }
  .carrito-fila .cf-quitar    { grid-area: quitar; }
  .carrito-fila.con-costo {
    grid-template-columns: minmax(0, 1fr) 84px auto;
    grid-template-areas:
      "nombre nombre nombre"
      "prov   cant   quitar"
      "costo  costo  costo";
  }
  .carrito-fila .cf-costo-wrap { grid-area: costo; }
  .carrito-fila .cf-costo, .carrito-fila .cf-moneda { min-height: 36px; }
}

/* ---- Pasar lista: la hora de llegada ----
   Cinco columnas en el escritorio. En el telefono no caben, y es justo donde
   se usa: el supervisor pasa lista con el movil en la mano. Cada persona pasa
   a ser una ficha, con la hora y la nota debajo del nombre.

   La casilla de hora en ancho fijo y no en `auto`: con `auto` cada fila le
   daba lo que sobrara despues del nombre, y las horas quedaban dentadas. */
.tabla-asistencia .as-hora input,
.tabla-asistencia .as-nota input {
  background: var(--bg); border: 1px solid var(--border2); border-radius: 6px;
  padding: 6px 8px; color: var(--text); font-family: inherit; font-size: 13px;
}
/* 150 y no 120: en español el <input type="time"> se dibuja en 12 horas y
   necesita sitio para el "a. m."; a 120 se cortaba a mitad de palabra. */
.tabla-asistencia .as-hora input { width: 150px; }
.tabla-asistencia .as-nota input { width: 100%; min-width: 0; }

@media (max-width: 720px) {
  .tabla-asistencia, .tabla-asistencia tbody { display: block; }
  .tabla-asistencia thead { display: none; }
  .tabla-asistencia tr {
    display: grid;
    grid-template-columns: 130px minmax(0, 1fr);
    grid-template-areas:
      "nombre nombre"
      "cargo  cargo"
      "hora   nota"
      "quien  quien";
    gap: 8px 10px;
    align-items: center;
    border: 1px solid var(--border); border-radius: 10px;
    padding: 12px; margin-bottom: 8px;
  }
  .tabla-asistencia td { display: block; border: none; padding: 0; text-align: left; }
  .tabla-asistencia .as-nombre { grid-area: nombre; font-size: 14px; }
  .tabla-asistencia .as-cargo  { grid-area: cargo; font-size: 11px; color: var(--text-dim); }
  .tabla-asistencia .as-hora   { grid-area: hora; }
  .tabla-asistencia .as-nota   { grid-area: nota; }
  .tabla-asistencia .as-quien  { grid-area: quien; }
  /* Vacia no ocupa: sin esto la ficha lleva una linea en blanco al pie */
  .tabla-asistencia .as-quien:empty { display: none; }
  .tabla-asistencia .as-hora input { width: 100%; min-height: 40px; }
  .tabla-asistencia .as-nota input { min-height: 40px; }
}

/* ---- Ticket-style rows ---- */
.ticket-row { background: #1A1D20; border: 1px dashed var(--border2); border-radius: 8px; padding: 8px 12px; display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; font-size: 12px; }

/* ---- Misc ---- */
.alert-box {
  background: rgba(193,84,60,0.1);
  border: 1px solid rgba(193,84,60,0.35);
  border-left: 3px solid var(--rust);
  border-radius: 8px; padding: 12px 16px; margin-bottom: 20px; font-size: 13px; display: flex; gap: 8px;
}
.alert-box b { color: var(--rust); }
/* El aviso del plan por vencer: laton, no ladrillo (no es un error todavia). */
.alert-box.suave { background: rgba(217,164,65,0.08); border-color: rgba(217,164,65,0.3); border-left-color: var(--gold); }
.alert-box.suave b { color: var(--gold); }
.pill { padding: 4px 12px; border-radius: 6px; font-size: 11px; font-weight: 700; }
.section-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 8px; font-weight: 700; }
.error-text { color: var(--rust); font-size: 12px; margin-top: 6px; }

/* El toast entra desde abajo al insertarse (@starting-style: sin JS). Es
   transition y no keyframes a proposito — si llega otro mensaje en mitad de la
   entrada, retoma desde donde va, no desde cero. */
.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translate(-50%, 0);
  background: var(--surface2); border: 1px solid var(--border2); padding: 10px 18px;
  border-radius: 10px; font-size: 13px; z-index: 999;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 8px 24px rgba(0, 0, 0, 0.4);
  transition: transform 320ms var(--ease-out), opacity 320ms var(--ease-out);
  opacity: 1;
}
@starting-style {
  .toast { transform: translate(-50%, 14px); opacity: 0; }
}

/* El dialogo tiene que poder desplazarse cuando no cabe en la pantalla.
   En el telefono el de Productos mide mas de 1100px y la pantalla ronda los
   800: centrado con `align-items:center` y sin desbordamiento, la cabecera se
   iba por encima del borde superior y el boton de guardar por debajo del
   inferior, los dos fuera de alcance — no se podia ni crear ni editar nada.

   `margin:auto` en vez de `align-items:center`: centra igual, pero al
   desbordar no recorta la parte de arriba, que es justo lo que hace el
   centrado por flex. */
.modal-overlay {
  /* 0.72 para que el fondo no compita aunque el navegador no sepa desenfocar */
  position: fixed; inset: 0; background: rgba(10, 12, 14, 0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: flex; justify-content: center; z-index: 998; padding: 16px;
  overflow-y: auto;
  overscroll-behavior: contain; /* al llegar al final no arrastra la pagina de detras */
  transition: opacity 200ms var(--ease-out);
  opacity: 1;
}
/* Entrada del modal: aparece desde el 97% — nada surge de la nada — con su
   velo fundiendose a la vez. transform-origin centrado a proposito: un modal
   no sale de ningun boton concreto, es una capa de la pantalla. */
.modal-box {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent 30%), var(--surface);
  border: 1px solid var(--border2); border-radius: 14px;
  padding: 20px; width: 100%; max-width: 400px;
  margin: auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 24px 64px rgba(0, 0, 0, 0.5);
  /* dvh descuenta la barra del navegador del movil, que vh no descuenta. La
     linea de vh queda antes como respaldo para quien no entienda dvh. */
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  transition: transform 220ms var(--ease-out), opacity 220ms var(--ease-out);
  transform: scale(1);
  opacity: 1;
}
@starting-style {
  .modal-overlay { opacity: 0; }
  .modal-box { transform: scale(0.97); opacity: 0; }
}
@media (max-width: 720px) {
  .modal-overlay { padding: 10px; }
  .modal-box { padding: 16px; max-height: calc(100dvh - 20px); }
}
/* Listas dentro de un dialogo (productos, almacenes). Tienen que llevar tope:
   son 550 productos. En el movil se acortan porque el dialogo ya se desplaza
   por su cuenta, y una zona de scroll dentro de otra deja el dedo atrapado en
   la lista sin poder llegar al formulario de abajo. */
.lista-modal { max-height: 220px; overflow-y: auto; }
@media (max-width: 720px) { .lista-modal { max-height: 150px; } }
.modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.close-x { background: none; color: var(--text-dim); font-size: 18px; line-height: 1; transition: color 140ms ease; }
.close-x:active { color: var(--text); }
.link-btn { background: none; color: var(--text-dim); font-size: 12px; text-decoration: underline; padding: 0; transition: color 140ms ease; }
.link-btn:hover { color: var(--text); }
/* En el telefono estos dos median 16 y 17px de alto, pegados el uno al otro, y
   el segundo borra. Se les da alto de dedo sin cambiar como se ven. */
@media (max-width: 720px) {
  .link-btn, .small-x { min-height: 38px; padding-left: 6px; padding-right: 6px; }
}

/* ---- El telefono, que es donde se usa esto de verdad ----
   El personal marca su checklist y la lista de compras de pie, con una mano y
   a veces con guantes. Lo que aqui se corrige salio de medir la pantalla real,
   no de mirarla. */
@media (max-width: 720px) {
  /* Las casillas venian con el tamaño por defecto del navegador: 13px. Es la
     mitad de lo que necesita un dedo, y son justo lo que mas se toca — 73 en el
     checklist diario y una por cada linea de la lista de compras. */
  /* Tiene que cubrir tambien `.marca-alerta input[type="checkbox"]`, que pesa
     mas (dos clases) y desde aqui NO se le gana por estar en una media query:
     las media queries no suman especificidad. Sin nombrarla, las casillas de
     "Critico" y "Ya pedido" se quedaban en 15px en el telefono — justo las dos
     que mas se tocan de pie y con guantes. */
  input[type="checkbox"], input[type="radio"],
  .field input[type="checkbox"], .field input[type="radio"],
  .marca-alerta input[type="checkbox"] {
    width: 24px; height: 24px;
    accent-color: var(--acento);
    flex-shrink: 0;
  }
  /* La etiqueta que envuelve la casilla ("Ya pedido") pasa a ser zona de toque:
     asi se acierta aunque el dedo caiga al lado. */
  label:has(input[type="checkbox"]) { min-height: 40px; }

  /* Los botones pequeños (filtros, "Imprimir") median 28-30px. 40 es lo que
     hace que no haya que apuntar. */
  .btn-sm { min-height: 40px; padding-top: 8px; padding-bottom: 8px; }

  /* El texto de 10px es legible en un escritorio a 40cm, no en una cocina.
     Se sube a 12 el de las anotaciones sueltas. Los estilos van en linea en el
     marcado, asi que hace falta ganarles la mano. */
  [style*="font-size:10px"], [style*="font-size: 10px"] { font-size: 12px !important; }
  [style*="font-size:11px"], [style*="font-size: 11px"] { font-size: 12px !important; }

  /* El aviso es flex, asi que la parte en negrita y el resto son dos bloques
     distintos y el texto se partia en escalera ("337 alerta(s) / de stock
     minimo"). En el telefono va como texto corrido, que es como se lee. */
  .alert-box { display: block; padding: 10px 12px; line-height: 1.45; }

  /* La cabecera se lleva 300px antes de que empiece nada. En una pantalla de
     812 eso es mas de un tercio, y esta en TODAS las pestañas. Se compacta:
     el logotipo y el titulo bastan para saber donde estas. */
  header.app-header { padding: 12px 0; }
  .header-row { gap: 8px; }
  .app-sub { display: none; }      /* el nombre del usuario ya sale al entrar */
}
.recipe-card {
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent 32%), var(--surface);
  border: 1px solid var(--border); border-radius: 12px; padding: 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
.recipe-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 720px) { .recipe-grid { grid-template-columns: 1fr; } }
.insumo-row { display: flex; gap: 8px; margin-bottom: 8px; }
.qty-input { width: 90px; flex-shrink: 0; }

/* Un aro girando rapido hace que la carga se sienta mas corta que un texto
   quieto — mismo tiempo real, otra percepcion. */
.spinner { text-align: center; padding: 60px; color: var(--text-dim); }
.spinner::before {
  content: "";
  display: block;
  width: 22px; height: 22px;
  margin: 0 auto 12px;
  border-radius: 50%;
  border: 2px solid var(--border2);
  border-top-color: var(--acento);
  animation: girar 650ms linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

.small-x { background: none; color: var(--text-dimmer); padding: 0 6px; transition: color 140ms ease; }
.small-x:hover { color: var(--rust); }

/* Menos movimiento para quien lo pide en su sistema: se conservan los fundidos
   (ayudan a entender) y se quita todo desplazamiento y escala. */
@media (prefers-reduced-motion: reduce) {
  .login-card, .login-card .login-marca, .login-card .field, .login-card .btn-full {
    animation-duration: 1ms;
  }
  .btn:active, .tabs-grupo .tab-btn:active { transform: none; }
  .toast, .modal-box { transition-duration: 60ms; }
  .lateral-items, .lateral-flecha { transition-duration: 60ms; }
  @starting-style {
    .toast { transform: translate(-50%, 0); }
    .modal-box { transform: scale(1); }
  }
  .spinner::before { animation-duration: 1.4s; }
}

/* ============================================================
   LAS MARCAS
   Cada almacen tiene su color (almacenes.color, o uno de la paleta de
   marcas.js) y el negocio entero firma con el laton. Lo que es de un almacen
   lo dice con data-marca ("grupo" | "a<id>") y, en la MISMA etiqueta, las
   variables de su color (atributosMarca, en render.js): de ahi salen el
   ACENTO (botones, pestaña activa, foco), la FRANJA de arriba y la SEÑAL que
   va delante del nombre de cada almacen. Aqui solo vive el grupo: los colores
   de los almacenes llegan con los datos, no con la hoja.

   Todo va por variables y no por selectores del tipo [data-marca="x"] .boton:
   una variable la hereda el elemento del data-marca MAS CERCANO, asi que la
   tarjeta de un almacen dentro de una pantalla del grupo se ve del almacen.
   El color de una marca nunca es un estado: los avisos siguen siendo
   ladrillo, laton y verde en cualquier pantalla.
   ============================================================ */
[data-marca="grupo"] {
  --acento: var(--gold); --acento-claro: #E3B155; --acento-rgb: 217, 164, 65;
  --marca-franja: var(--gold); --marca-signo: var(--gold); --marca-fondo: #14171A;
}

/* La señal: un cuadrito con los colores de la marca, delante de su nombre. */
.marca-signo {
  display: inline-block; width: 10px; height: 10px; border-radius: 3px;
  background: var(--marca-signo); flex-shrink: 0;
}
.marca-chip { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }

/* De que marca es la pantalla, antes de leer nada: la franja de arriba, la
   luz que cae desde ella (la del body es la del grupo; esta la tapa con la de
   la marca) y el rotulo junto a "Salir". */
.marco {
  min-height: 100vh;
  background: radial-gradient(ellipse 80% 420px at 50% -120px, rgba(var(--acento-rgb), 0.09), transparent 72%) no-repeat;
}
header.app-header { position: relative; }
.franja-marca { position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--marca-franja); }
.contexto-marca {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid rgba(var(--acento-rgb), 0.45);
  background: rgba(var(--acento-rgb), 0.08);
  color: var(--text); font-size: 12px; font-weight: 700; letter-spacing: 0.04em;
}

/* Cada almacen de la lista de alertas lleva una raya de su marca bajo el
   nombre, y los botones para elegir almacen se encienden con su color. */
.alm-bloque-cabeza { border-bottom: 2px solid transparent; border-image: var(--marca-franja) 1; padding-bottom: 6px; }

/* La señal dentro de un boton encendido de su misma marca: un filo oscuro la
   separa del fondo, que es de su mismo color. */
.btn-primary .marca-signo { outline: 1.5px solid rgba(20, 23, 26, 0.55); outline-offset: 0; }

/* El boton que lleva al otro sistema (Finanzas / Inventario): en una linea,
   que con la flecha partida en dos renglones no se lee como un enlace. */
.btn-sistema { white-space: nowrap; }

/* ---------- el recorrido de bienvenida (tour.js, Fase 2 de SHOP) ----------
   Vive fuera de #app. El foco recorta el fondo oscuro con una sombra enorme
   alrededor del objetivo; el globo va al lado, con su flecha. El mismo que en
   ADMOS CAJA. */
.tour-capa { position: fixed; inset: 0; z-index: 1000; }
.tour-capa.sin-objetivo { background: rgba(0, 0, 0, 0.62); }
.tour-foco {
  position: fixed; border-radius: 12px; pointer-events: none;
  /* 200vmax cubre la pantalla desde donde este el foco; con 9999px, en un
     telefono con densidad 2 Chrome no pintaba la sombra (paso en ONE). */
  box-shadow: 0 0 0 200vmax rgba(0, 0, 0, 0.62), 0 0 0 2px var(--acento);
  transition: left 240ms ease-out, top 240ms ease-out, width 240ms ease-out, height 240ms ease-out, opacity 160ms ease;
}
.tour-globo {
  position: fixed; width: min(340px, calc(100vw - 24px)); padding: 16px 18px 14px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border2);
  border-radius: 14px; box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  transition: left 240ms ease-out, top 240ms ease-out;
}
.tour-flecha {
  position: absolute; left: var(--tour-flecha-x, 50%); width: 14px; height: 14px; margin-left: -7px;
  background: var(--surface); border: 1px solid var(--border2); transform: rotate(45deg); display: none;
}
.tour-globo.abajo .tour-flecha { display: block; top: -8px; border-right: 0; border-bottom: 0; }
.tour-globo.arriba .tour-flecha { display: block; bottom: -8px; border-left: 0; border-top: 0; }
.tour-paso { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--acento); }
.tour-titulo { margin: 6px 0 0; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.25; }
.tour-texto { margin: 8px 0 0; font-size: 14px; line-height: 1.55; color: var(--text-dim); }
.tour-texto b { color: var(--text); font-weight: 600; }
.tour-acciones { margin-top: 16px; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tour-acciones-der { display: flex; gap: 8px; }
.tour-acciones .btn { padding: 9px 16px; }
.tour-saltar { font-size: 13px; }
.config-tour { margin-top: 18px; text-align: center; }
@media (prefers-reduced-motion: reduce) { .tour-foco, .tour-globo { transition: none; } }
