/* ============================================================================
   MyPanel de Ume Beauty — sistema de diseño (el de Mycostpanel con la marca de Ume).

   Cristal suave, profundidad por capas y mucho aire. Con dos reglas propias que
   pesan más que el efecto:

   1. EL CRISTAL NUNCA VA DETRÁS DE UNA CIFRA. Las tarjetas, la barra lateral y la
      cabecera llevan blur; las columnas de números van sobre fondo sólido. Esta
      herramienta se consulta con las manos llenas y en una cocina mal iluminada:
      ahí la legibilidad gana siempre al efecto.
   2. `backdrop-filter` se paga en batería. Se usa en pocas superficies grandes y
      nunca en elementos que se repiten en una lista.

   Escala de espaciado en múltiplos de 8. Tipografía de la marca, servida desde el propio
   origen (la CSP sigue estricta): Cormorant Garamond 500 en títulos y Jost en todo lo demás.
   Colores: los tokens de Ume (ciruela, marfil, flor, salvia, dorado) en claro y oscuro.
   ============================================================================ */

@font-face { font-family: 'Cormorant Garamond'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/cormorant-garamond-500.woff2') format('woff2'); }
@font-face { font-family: 'Cormorant Garamond'; font-style: italic; font-weight: 500; font-display: swap; src: url('../fonts/cormorant-garamond-500-italic.woff2') format('woff2'); }
@font-face { font-family: 'Jost'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/jost-400.woff2') format('woff2'); }
@font-face { font-family: 'Jost'; font-style: normal; font-weight: 500; font-display: swap; src: url('../fonts/jost-500.woff2') format('woff2'); }

:root {
  color-scheme: light dark;

  /* --- espaciado (múltiplos de 8) --- */
  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 32px; --s5: 40px; --s6: 48px;

  /* --- radios generosos --- */
  --r-sm: 12px; --r: 16px; --r-lg: 20px; --r-xl: 24px;

  /* --- color: claro (tokens de Ume) --- */
  --bg-a:      #F8F4EF;         /* marfil */
  --bg-b:      #EFE8DF;         /* superficie 2 */
  --bg-c:      #F7E6EA;         /* flor muy suave: el foco del fondo */
  --glass:     255 253 251;     /* base RGB del cristal, se compone con alfa */
  --glass-a:   0.66;
  --glass-brd: 255 255 255;
  --glass-brd-a: 0.8;
  --solid:     #FFFDFB;         /* superficies SIN blur: tablas, campos */
  --solid-2:   #F8F4EF;
  --border:    #D9CFC3;         /* línea fina */
  --border-soft: #E8DFD5;

  --text:      #2A1F24;         /* tinta */
  --text-dim:  #6B5B62;         /* tinta suave */
  --text-mute: #75656B;         /* AA sobre marfil (4,6:1) */

  --accent:      #4A2433;       /* ciruela de la marca */
  --accent-2:    #6E3A4F;
  --accent-deep: #3A1B28;
  --accent-soft: #F3E3E8;
  --accent-glow: 74 36 51;
  --on-accent:   #F8F4EF;

  --bar:       #7F5B27;         /* dorado profundo: el único dorado que puede ser texto */
  --bar-soft:  #F4ECDD;
  --flor:      #E4B8C2;
  --salvia:    #BFCDBE;

  --good: #2F6B4F; --good-soft: #E7EFE8;
  --warn: #7F5B27; --warn-soft: #F6EEDF;
  --bad:  #A3343F; --bad-soft:  #F8E5E7;

  /* --- sombras en capas: nunca una sola sombra dura --- */
  --sh-1: 0 1px 2px rgba(16,24,40,.04), 0 2px 6px rgba(16,24,40,.04);
  --sh-2: 0 1px 2px rgba(16,24,40,.05), 0 4px 12px rgba(16,24,40,.06), 0 12px 28px rgba(16,24,40,.05);
  --sh-3: 0 2px 4px rgba(16,24,40,.06), 0 8px 24px rgba(16,24,40,.08), 0 24px 56px rgba(16,24,40,.09);
  --sh-glow: 0 2px 8px rgba(var(--accent-glow)/.28), 0 8px 24px rgba(var(--accent-glow)/.22);

  --blur: 14px;
  --sans: Jost, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
  --ease: cubic-bezier(.32,.72,.36,1);
  --t: .2s var(--ease);
}

/* ---------- oscuro ---------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"], :root[data-theme="auto"][data-dark="1"] {
  color-scheme: dark;
  --bg-a: #1C1418; --bg-b: #271D22; --bg-c: #33202A;
  --glass: 39 29 34; --glass-a: 0.6;
  --glass-brd: 255 255 255; --glass-brd-a: 0.08;
  --solid: #231920; --solid-2: #2A1F25;
  --border: #3A2E34; --border-soft: #31262C;
  --text: #F3ECE4; --text-dim: #BFB0B5; --text-mute: #A3939A;
  --accent: #E8C3CC; --accent-2: #F0D3DA; --accent-deep: #D9A7B4;
  --accent-soft: #3A2430; --accent-glow: 232 195 204; --on-accent: #2A1F24;
  --bar: #D8B074; --bar-soft: #33281A;
  --flor: #5A3443; --salvia: #3B4B42;
  --good: #9FC2A8; --good-soft: #1E2A23;
  --warn: #D8B074; --warn-soft: #33281A;
  --bad:  #F0A0A6; --bad-soft:  #3A1F24;
  --sh-1: 0 1px 2px rgba(0,0,0,.30), 0 2px 6px rgba(0,0,0,.24);
  --sh-2: 0 1px 2px rgba(0,0,0,.34), 0 4px 12px rgba(0,0,0,.30), 0 12px 28px rgba(0,0,0,.28);
  --sh-3: 0 2px 4px rgba(0,0,0,.38), 0 8px 24px rgba(0,0,0,.34), 0 24px 56px rgba(0,0,0,.34);
}

/* ---------- ADAPTATIVO NOCTURNO ----------
   Tres intensidades que aplica el reloj, no el gusto. De noche la pantalla es la
   única fuente de luz del local: se baja el azul, se calienta el blanco y se
   atenúan los acentos. `atardecer` para el servicio de noche; `madrugada` para
   cuando se cierra la barra a las dos y lo único que queda encendido es esto. */
:root[data-dark="1"][data-night="dusk"] {
  --bg-a: #12131a; --bg-b: #191720; --bg-c: #0e0f15;
  --glass: 38 34 44;
  --solid: #1c1a23; --solid-2: #23212c;
  --border: #322e3b;
  --text: #ece6e2; --text-dim: #ada6a4; --text-mute: #776f73;
  --accent: #D9A7B4; --accent-2: #E4BCC6; --accent-deep: #C8909F;
  --accent-soft: #33222B; --accent-glow: 217 167 180; --on-accent: #2A1F24;
}
:root[data-dark="1"][data-night="deep"] {
  --bg-a: #0c0a0b; --bg-b: #120e0d; --bg-c: #080607;
  --glass: 29 24 23;
  --glass-a: 0.72;
  --solid: #151111; --solid-2: #1b1516;
  --border: #282020;
  --text: #cbbfb6; --text-dim: #8f837b; --text-mute: #625754;
  --accent: #B98A97; --accent-2: #C79CA8; --accent-deep: #A87A87;
  --accent-soft: #2A1C22; --accent-glow: 185 138 151; --on-accent: #1C1418;
  --good: #75a07b; --warn: #b78e55; --bad: #bc7165;
  /* En madrugada se baja el brillo general: a las 3:00 un panel a tope deslumbra. */
  --blur: 10px;
}
/* Aquí había un `filter: brightness(.92)` sobre body para atenuar la madrugada, y era
   un error de los caros: un `filter` en un ancestro crea bloque contenedor y ANULA
   `position: fixed` en todo lo que hay dentro. La barra inferior se iba con el scroll,
   la capa de los paneles dejaba de cubrir y los avisos se descolocaban — y solo en
   madrugada, que es justo cuando se usa tras el servicio.
   El atenuado vive ahora en los propios colores de la franja, que consigue lo mismo
   sin tocar el modelo de cajas. NUNCA un filter sobre html, body ni .shell. */

/* El cambio de modo se ve, pero no distrae. */
:root, body { transition: background-color .6s var(--ease); }

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  color: var(--text);
  font: 15px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior-y: none;
  /* Gradiente suave con dos focos: da profundidad sin dibujar nada. */
  background:
    radial-gradient(1100px 680px at 8% -10%, var(--bg-c), transparent 60%),
    radial-gradient(900px 620px at 96% 2%, var(--accent-soft), transparent 58%),
    radial-gradient(800px 600px at 70% 110%, rgb(var(--accent-glow) / .08), transparent 60%),
    linear-gradient(160deg, var(--bg-a) 0%, var(--bg-b) 100%);
  background-attachment: fixed;
}
button, input, select, textarea { font: inherit; color: inherit; }

/* ============================================================ cristal */

/* Una sola clase para todo lo que lleva blur, para poder auditar dónde se usa. */
.glass {
  background: rgb(var(--glass) / var(--glass-a));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.6);
  backdrop-filter: blur(var(--blur)) saturate(1.6);
  border: 1px solid rgb(var(--glass-brd) / var(--glass-brd-a));
}
/* Si el navegador no soporta blur, se cae a sólido en vez de a un panel lavado. */
@supports not (backdrop-filter: blur(2px)) {
  .glass { background: var(--solid); }
}

/* ============================================================ estructura */

#app { min-height: 100%; }
/* dvh y no vh: en iOS el 100vh incluye la barra del navegador, así que el último tramo
   del contenido queda debajo y no se alcanza nunca. vh se deja antes como respaldo para
   navegadores que aún no entienden dvh. */
.shell { display: grid; grid-template-columns: 252px 1fr; min-height: 100vh; min-height: 100dvh; }

.side {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s3) var(--s2) var(--s2);
  position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto;
  background: rgb(var(--glass) / calc(var(--glass-a) - .12));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.4);
  backdrop-filter: blur(var(--blur)) saturate(1.4);
  border-right: 1px solid rgb(var(--glass-brd) / calc(var(--glass-brd-a) - .35));
}

.brand { display: flex; align-items: center; gap: 10px; padding: 0 10px var(--s3); }
.brand b { font: 500 22px/1 var(--serif); letter-spacing: 0; }
.brand-t { display: flex; flex-direction: column; gap: 3px; }
.brand-t span { font-size: 11px; letter-spacing: .16em; font-variant: small-caps; color: var(--text-dim); }
.sub-brand { margin-left: auto; font-size: 12px; letter-spacing: .16em; font-variant: small-caps; color: var(--text-dim); }
/* Suelta, no acoplada a .brand: también se usa en la pantalla de entrada, donde
   estaba saliendo como una "M" pelada sin su cuadro. */
.mark {
  width: 30px; height: 30px; border-radius: 10px; flex: none;
  background: linear-gradient(145deg, var(--accent-2), var(--accent-deep));
  box-shadow: var(--sh-glow);
  display: grid; place-items: center; color: var(--on-accent); font-size: 15px; font-weight: 700;
}

.nav-group {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); padding: var(--s2) 10px 6px; font-weight: 600;
}
.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border: 1px solid transparent; border-radius: var(--r-sm);
  background: none; color: var(--text-dim); cursor: pointer;
  text-align: left; font-size: 14px; transition: background var(--t), color var(--t), border-color var(--t);
}
.nav-item:hover { background: rgb(var(--glass) / .5); color: var(--text); }
.nav-item[aria-current="page"] {
  color: var(--accent-deep); font-weight: 600;
  background: linear-gradient(100deg, var(--accent-soft), transparent 92%);
  border-color: rgb(var(--accent-glow) / .22);
  box-shadow: inset 0 1px 0 rgb(var(--glass-brd) / .5);
}
.nav-item .ic { width: 18px; height: 18px; display: grid; place-items: center; flex: none; }
.nav-item .ic svg { display: block; }
.nav-item .count {
  margin-left: auto; font-size: 12px; color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

/* Tarjeta del pie de la barra lateral. No es "Upgrade to Pro": esto es una
   herramienta de un solo dueño y no hay nada que vender. Ocupa ese sitio el
   estado de los respaldos, que es lo que de verdad conviene tener a la vista. */
.side-foot { margin-top: auto; padding-top: var(--s2); }
.side-card {
  border-radius: var(--r); padding: var(--s2);
  background: linear-gradient(150deg, var(--accent-soft), rgb(var(--glass) / .35));
  border: 1px solid rgb(var(--accent-glow) / .18);
  box-shadow: var(--sh-1);
}
.side-card h4 { margin: 0 0 4px; font-size: 13px; letter-spacing: -.01em; }
.side-card p { margin: 0 0 10px; font-size: 12px; color: var(--text-dim); line-height: 1.45; }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s4);
  /* viewport-fit=cover mete la app bajo la isla y las esquinas: sin esto, el saludo y
     los botones se meten debajo del reloj del iPhone. */
  padding-top: max(var(--s2), env(safe-area-inset-top));
  padding-left: max(var(--s4), env(safe-area-inset-left));
  padding-right: max(var(--s4), env(safe-area-inset-right));
  position: sticky; top: 0; z-index: 20;
  background: rgb(var(--glass) / calc(var(--glass-a) - .16));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.5);
  backdrop-filter: blur(var(--blur)) saturate(1.5);
  border-bottom: 1px solid rgb(var(--glass-brd) / calc(var(--glass-brd-a) - .45));
}
.topbar .hello { min-width: 0; }
.topbar h1 { font: 500 28px/1.1 var(--serif); margin: 0; letter-spacing: 0; }
.topbar .sub { font-size: 12.5px; color: var(--text-dim); margin-top: 1px; }
.topbar .spacer { flex: 1; }

.search {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 999px; min-width: 220px;
  background: rgb(var(--glass) / .55);
  border: 1px solid rgb(var(--glass-brd) / .5);
  transition: box-shadow var(--t), border-color var(--t);
}
.search:focus-within { border-color: rgb(var(--accent-glow) / .5); box-shadow: 0 0 0 4px rgb(var(--accent-glow) / .12); }
.search input { border: 0; background: none; padding: 0; width: 100%; }
.search input:focus { outline: none; }
.search .ic { color: var(--text-mute); flex: none; }

.content { padding: var(--s4); max-width: 1280px; width: 100%; }

/* Nada de la cabecera puede partirse en dos líneas: una etiqueta rota se lee como
   un error de maquetación y hace dudar del resto. Cuando falta sitio, lo primero
   que se encoge es el buscador, y después la píldora de red se queda en su punto. */
.topbar .btn, .netpill { white-space: nowrap; flex: none; }
.search { flex: 1 1 200px; min-width: 120px; max-width: 320px; }
@media (max-width: 1180px) {
  .netpill span:last-child { display: none; }
  .netpill { padding: 8px; }
  /* Dos excepciones: sin conexión y con datos de caché, el punto de color solo no dice
     nada. Son justo los estados en los que la pantalla puede estar mintiendo, así que
     ahí el texto se queda aunque no sobre sitio. */
  .netpill[data-state="offline"] span:last-child,
  .netpill[data-state="stale"] span:last-child { display: inline; }
  .netpill[data-state="offline"], .netpill[data-state="stale"] { padding: 6px 10px; font-size: 11.5px; }
}

/* ============================================================ tarjetas */

.card {
  border-radius: var(--r-lg);
  background: rgb(var(--glass) / var(--glass-a));
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.6);
  backdrop-filter: blur(var(--blur)) saturate(1.6);
  border: 1px solid rgb(var(--glass-brd) / var(--glass-brd-a));
  box-shadow: var(--sh-2);
  /* Brillo superior de un píxel: es lo que da la sensación de vidrio real. */
  position: relative; overflow: hidden;
}
.card::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 1px;
  background: linear-gradient(90deg, transparent, rgb(var(--glass-brd) / .8), transparent);
  pointer-events: none;
}
.card + .card { margin-top: var(--s2); }
.card-h {
  display: flex; align-items: center; gap: 10px;
  padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border-soft);
}
.card-h h2 { font: 500 21px/1.15 var(--serif); margin: 0; letter-spacing: 0; }
.card-h .sub { font-size: 12.5px; color: var(--text-dim); margin-top: 3px; }
.card-h .spacer { flex: 1; }
.card-b { padding: var(--s3); }

.grid { display: grid; gap: var(--s2); }
.grid.k4 { grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); }
.grid.k2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* ---------- métricas ---------- */

.kpi { padding: var(--s3); display: flex; flex-direction: column; gap: 6px; transition: transform var(--t), box-shadow var(--t); }
.kpi:hover { transform: translateY(-2px); box-shadow: var(--sh-3); }
.kpi .lbl {
  font-size: 12.5px; color: var(--text-dim); display: flex; align-items: center; gap: 8px;
  font-weight: 500;
}
.kpi .val {
  font-size: 30px; font-weight: 680; letter-spacing: -.035em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.kpi .val.bad { color: var(--bad); }
.kpi .val.good { color: var(--good); }
.kpi .sub { font-size: 12px; color: var(--text-mute); }
.kpi .spark { margin-top: 2px; height: 34px; }
.kpi .spark svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* ---------- tabla: SIN cristal, a propósito ---------- */

/* Una tabla ancha se desplaza DENTRO de su tarjeta, nunca empujando la página.
   La de Análisis mide 714 px con sus ocho columnas: en un teléfono de 440 se salía por
   el lado derecho sin forma de llegar a ella. Ahora la tarjeta la contiene y se arrastra
   con el dedo. Esconder columnas se descartó: son números de costo, no adorno. */
/* Solo el envoltorio, NUNCA la tabla directamente: poner `display: block` a un <table>
   cambia su modelo de caja y afecta a todas las tablas de la app, también en escritorio,
   donde no hay ningún problema que resolver. La tabla que se desborda se envuelve en el
   JavaScript y solo esa paga el coste. */
.card > .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.card > .scroll-x > table { min-width: max-content; }
table { width: 100%; border-collapse: collapse; font-size: 14px; background: var(--solid); }
th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-mute); font-weight: 600; padding: 11px var(--s2);
  border-bottom: 1px solid var(--border); background: var(--solid-2);
}
td { padding: 12px var(--s2); border-bottom: 1px solid var(--border-soft); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr { cursor: pointer; transition: background var(--t); }
tbody tr:hover { background: var(--solid-2); }
.num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); font-size: 13px; }

/* ---------- controles ---------- */

.btn {
  display: inline-flex; align-items: center; gap: 8px; padding: 9px 15px;
  border-radius: var(--r-sm); cursor: pointer; font-size: 14px; font-weight: 550;
  color: var(--text); background: rgb(var(--glass) / .6);
  border: 1px solid rgb(var(--glass-brd) / .6);
  box-shadow: var(--sh-1);
  transition: transform var(--t), box-shadow var(--t), background var(--t);
}
.btn:hover { background: rgb(var(--glass) / .85); transform: translateY(-1px); box-shadow: var(--sh-2); }
.btn:active { transform: translateY(0); }
.btn.pri {
  color: var(--on-accent); border-color: transparent; border-radius: 999px;
  background: linear-gradient(145deg, var(--accent-2), var(--accent-deep));
  box-shadow: var(--sh-glow);
}
.btn.pri:hover { filter: brightness(1.06); box-shadow: 0 4px 12px rgb(var(--accent-glow)/.34), 0 12px 32px rgb(var(--accent-glow)/.26); }
.btn.danger { color: var(--bad); background: var(--bad-soft); border-color: transparent; }
.btn.sm { padding: 6px 11px; font-size: 13px; border-radius: 10px; }
a.btn { text-decoration: none; }
.btn svg { flex: none; }

/* ---------- MyPanel: proveedores, contactos y pedidos ---------- */
.contact-links { display: flex; flex-wrap: wrap; gap: 6px; }
.btn.wa { color: var(--good); border-color: rgb(var(--glass-brd) / .6); }
.people { display: grid; gap: 10px; margin-top: 12px; }
.person { display: grid; gap: 6px; padding: 10px 12px; border-radius: var(--r-sm); background: var(--solid-2); border: 1px solid var(--border-soft); cursor: pointer; }
.person strong { font-weight: 500; }
.person .role { margin-left: 8px; font-size: 12.5px; color: var(--text-dim); }
.sup-block + .sup-block { border-top: 1px solid var(--border-soft); }
.sup-card .card-h { align-items: flex-start; }
details.sect > summary { cursor: pointer; font-weight: 500; color: var(--text-dim); padding: 4px 0; }
details.sect[open] > summary { margin-bottom: 10px; }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.btn.icon { padding: 8px; border-radius: 50%; }

/* Fila de vínculo POS ↔ receta. En ancho completo es una línea; en el teléfono, un bloque. */
.maprow { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.7fr) 120px 110px; gap: 10px 14px;
  align-items: center; padding: 12px var(--s3); border-top: 1px solid var(--border-soft); }
.maprow .mr-qty { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--text-mute); }
.maprow .mr-cost { font-family: var(--mono); font-size: 13px; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
@media (max-width: 760px) {
  .maprow { grid-template-columns: 1fr 1fr; }
  .maprow .mr-name, .maprow .mr-sel { grid-column: 1 / -1; }
  .maprow .mr-cost { align-items: flex-start; text-align: left; }
}

/* Pestañas de la pantalla del POS. En el teléfono se desplazan de lado en vez de apilarse. */
.subtabs { display: flex; gap: 6px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  padding: 2px 2px 8px; margin-bottom: 12px; }
.subtabs::-webkit-scrollbar { display: none; }
.subtabs .btn { flex: none; white-space: nowrap; }
.subtabs .btn[aria-current="page"] { background: var(--accent-soft); color: var(--accent-deep); border-color: rgb(var(--accent-glow) / .4); font-weight: 620; }

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--s2); }
.field > label { font-size: 12.5px; color: var(--text-dim); font-weight: 550; }
.field .hint { font-size: 11.5px; color: var(--text-mute); line-height: 1.45; }
input, select, textarea {
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--solid); width: 100%;
  transition: border-color var(--t), box-shadow var(--t);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: rgb(var(--accent-glow) / .55);
  box-shadow: 0 0 0 4px rgb(var(--accent-glow) / .13);
}
input[type="number"] { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.row { display: flex; gap: var(--s2); }
.row > * { flex: 1; }

/* ---------- insignias ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px;
  border-radius: 999px; font-size: 12px; font-weight: 620;
  font-variant-numeric: tabular-nums; border: 1px solid transparent;
}
.badge.good { background: var(--good-soft); color: var(--good); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.bad  { background: var(--bad-soft);  color: var(--bad); }
.badge.neutral { background: var(--solid-2); color: var(--text-dim); border-color: var(--border-soft); }
.badge.bar { background: var(--bar-soft); color: var(--bar); }

/* ---------- barras de progreso ---------- */

.meter { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--solid-2); }
.meter i { display: block; height: 100%; transition: width .4s var(--ease); }
.meter .cost { background: linear-gradient(90deg, var(--accent-2), var(--accent-deep)); }
.meter .over { background: linear-gradient(90deg, var(--bad), #e8695f); }

.bar-row { display: grid; grid-template-columns: 1fr 90px; gap: var(--s2); align-items: center; padding: 10px 0; }
.bar-row + .bar-row { border-top: 1px solid var(--border-soft); }
.bar-row .name { font-size: 13.5px; }
.bar-row .meter { margin-top: 6px; }

/* ---------- actividad ---------- */

.feed { display: flex; flex-direction: column; }
.feed-item { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border-soft); }
.feed-item:last-child { border-bottom: 0; }
.feed-item .dot {
  width: 32px; height: 32px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-deep); font-size: 14px;
}
.feed-item .dot.up { background: var(--bad-soft); color: var(--bad); }
.feed-item .dot.down { background: var(--good-soft); color: var(--good); }
.feed-item .txt { min-width: 0; font-size: 13.5px; }
.feed-item .when { font-size: 12px; color: var(--text-mute); margin-top: 2px; }

/* ---------- panel lateral ---------- */

.sheet-bg {
  /* `overflow: hidden` no es cosmético: la animación de entrada desplaza el panel 26 px
     y durante esos 220 ms la página se volvía desplazable en horizontal. En un iPhone
     eso se ve como un salto lateral cada vez que se abre una ficha. */
  position: fixed; inset: 0; z-index: 60; display: flex; justify-content: flex-end;
  overflow: hidden;
  background: rgba(10,14,22,.34);
  -webkit-backdrop-filter: blur(6px) saturate(1.2); backdrop-filter: blur(6px) saturate(1.2);
  animation: fade .16s var(--ease);
}
@keyframes fade { from { opacity: 0; } }
/* El panel de edición va OPACO. Es donde se escriben precios y cantidades, y ver la
   tabla anterior moverse detrás de un campo numérico es justo el tipo de ruido que
   hace equivocarse de casilla. El cristal se queda en el fondo que lo rodea, que es
   donde aporta profundidad sin estorbar. */
.sheet {
  width: min(600px, 100%); height: 100%; display: flex; flex-direction: column;
  background: var(--solid);
  border-left: 1px solid rgb(var(--glass-brd) / var(--glass-brd-a));
  box-shadow: var(--sh-3);
  animation: slide .22s var(--ease);
}
@keyframes slide { from { transform: translateX(26px); opacity: .5; } }
.sheet-h { display: flex; align-items: center; gap: 10px; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border-soft); }
.sheet-h h2 { margin: 0; font-size: 17px; letter-spacing: -.02em; }
.sheet-b { padding: var(--s3); overflow-y: auto; flex: 1; }
.sheet-f { padding: var(--s2) var(--s3); border-top: 1px solid var(--border-soft); display: flex; gap: 10px; }
.sheet-f .spacer { flex: 1; }

.sect { margin-top: var(--s4); }
.sect:first-child { margin-top: 0; }
.sect > h3 {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-mute); margin: 0 0 10px; font-weight: 620;
}
.sect.bar > h3 { color: var(--bar); }

.line {
  display: grid; grid-template-columns: 1fr 78px 66px 34px; gap: 8px;
  align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border-soft);
}
.line:last-of-type { border-bottom: 0; }
.line .role { grid-column: 1 / -1; font-size: 11.5px; color: var(--text-mute); }

.result { background: var(--solid-2); border-radius: var(--r); padding: var(--s2); border: 1px solid var(--border-soft); }
.result dl { display: grid; grid-template-columns: 1fr auto; gap: 7px 16px; margin: 0; font-size: 13px; }
.result dt { color: var(--text-dim); }
.result dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-family: var(--mono); }

/* ---------- avisos ---------- */

.note { display: flex; gap: 10px; padding: 12px 14px; border-radius: var(--r-sm); font-size: 13.5px; line-height: 1.5; }
.note.info { background: var(--solid-2); color: var(--text-dim); border: 1px solid var(--border-soft); }
.note.warn { background: var(--warn-soft); color: var(--warn); }
.note.bad  { background: var(--bad-soft);  color: var(--bad); }
.note.good { background: var(--good-soft); color: var(--good); }

.netpill {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px;
  padding: 6px 12px; border-radius: 999px; color: var(--text-dim);
  background: rgb(var(--glass) / .55); border: 1px solid rgb(var(--glass-brd) / .5);
}
.netpill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); box-shadow: 0 0 0 3px rgb(15 157 88 / .16); }
.netpill[data-state="offline"] { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.netpill[data-state="offline"] .dot { background: var(--warn); box-shadow: 0 0 0 3px rgb(185 119 14 / .16); }
.netpill[data-state="syncing"] .dot { background: var(--accent); animation: pulse 1.1s infinite; }
.netpill[data-state="stale"] { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.netpill[data-state="stale"] .dot { background: var(--warn); box-shadow: 0 0 0 3px rgb(185 119 14 / .16); }
@keyframes pulse { 50% { opacity: .25; } }

.empty { text-align: center; padding: var(--s6) var(--s3); color: var(--text-mute); }
.empty .big { font-size: 40px; margin-bottom: 12px; opacity: .6; color: var(--accent); display: grid; place-items: center; }

.gate { display: grid; place-items: center; min-height: 100vh; min-height: 100dvh; padding: var(--s3); }
.gate .card { width: min(400px, 100%); }

.toast {
  position: fixed; bottom: var(--s3); left: 50%; transform: translateX(-50%);
  background: rgb(var(--glass) / .92);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border: 1px solid rgb(var(--glass-brd) / var(--glass-brd-a));
  color: var(--text); padding: 12px 20px; border-radius: 999px;
  font-size: 13.5px; z-index: 90; box-shadow: var(--sh-3);
}

/* ---------- gráfico grande ---------- */
.chart { width: 100%; height: 240px; }
.chart svg { display: block; width: 100%; height: 100%; overflow: visible; }
.chart .grid-line { stroke: var(--border-soft); stroke-width: 1; }
.chart .axis { fill: var(--text-mute); font-size: 10.5px; font-family: var(--sans); }

/* ---------- dedo, no ratón ----------
   En un puntero grueso (dedo) Apple pide 44×44 como mínimo. Con ratón se mantienen
   compactos: obligar 44 px en escritorio hincharía toda la interfaz sin motivo. */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
  .btn.sm { min-height: 38px; padding: 8px 12px; }
  .btn.icon { min-width: 44px; min-height: 44px; }
  input, select, textarea { min-height: 44px; }
  .line select, .line input { min-height: 40px; }
  tbody td { padding-top: 14px; padding-bottom: 14px; }
}

/* ---------- accesibilidad ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

/* ---------- móvil ---------- */
/* ---------- teléfono ---------- */
.lbl-corto { display: none; }

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; }

  /* La barra inferior es FIJA y el contenido pasa por detrás. Con el cristal al 62 %
     el texto de la página se transparentaba a través de las pestañas y parecía que la
     interfaz se corría. Aquí el fondo va casi opaco: en una superficie que tapa
     contenido en movimiento, la legibilidad manda sobre el efecto. */
  .side {
    position: fixed; bottom: 0; top: auto; height: auto; width: 100%;
    flex-direction: row; border-right: 0;
    border-top: 1px solid rgb(var(--glass-brd) / calc(var(--glass-brd-a) - .3));
    padding: 6px max(6px, env(safe-area-inset-left)) calc(6px + env(safe-area-inset-bottom)) max(6px, env(safe-area-inset-right));
    gap: 2px; z-index: 40;
    background: rgb(var(--glass) / .97);
    -webkit-backdrop-filter: blur(20px) saturate(1.5);
    backdrop-filter: blur(20px) saturate(1.5);
    /* Sin overflow-x: las ocho pestañas DEBEN caber. Un carril que se desplaza en
       horizontal esconde las últimas sin avisar, que es justo lo que pasaba. */
    overflow: visible;
  }
  .brand, .nav-group, .nav-item .count, .side-foot { display: none; }

  /* Reparto a partes iguales: 8 pestañas en el ancho que haya, sea cual sea. */
  .nav-item {
    flex: 1 1 0; min-width: 0;
    flex-direction: column; gap: 2px; font-size: 9.5px; padding: 6px 2px;
    border-radius: 10px;
  }
  .nav-item .ic { width: 20px; height: 20px; }
  .nav-item .ic svg { width: 20px; height: 20px; }
  /* La etiqueta nunca parte en dos líneas ni empuja a la vecina. */
  .nav-item .lbl-full, .nav-item .lbl-corto {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}

/* En teléfonos estrechos (iPhone de 375 pt y menores) cada pestaña baja a 44 px y a
   9,5 px se truncaban «Insumos» y «Compras». Se aprieta la letra en vez de recortar
   palabras: una etiqueta a medias se lee peor que una etiqueta pequeña. */
@media (max-width: 400px) {
  .nav-item { font-size: 8.5px; padding: 6px 1px; }
  .nav-item .ic svg { width: 18px; height: 18px; }
}

@media (max-width: 860px) {
  /* Donde hay versión corta, manda la corta: «Preparaciones» no cabe en 55 px.
     Se usa un atributo en lugar de :has() — soporte universal y una regla menos que
     razonar cuando alguien lea esto dentro de seis meses. */
  .nav-item[data-corto] .lbl-corto { display: block; }
  .nav-item[data-corto] .lbl-full { display: none; }
  .content { padding: var(--s2); padding-bottom: 96px; }
  .topbar { padding: var(--s2); }
  .topbar .search { display: none; }
  .sheet { width: 100%; }
  /* La columna de unidad medía 58 px y, entre el relleno de 12 px a cada lado y la
     flecha del desplegable, dejaba 18 px de texto: «ml» salía como «m» y «und» como
     «ur». Se reparte distinto y se aprieta el relleno solo dentro de la línea. */
  .line { grid-template-columns: 1fr 62px 68px 40px; gap: 6px; }
  .line select, .line input { padding-left: 8px; padding-right: 4px; }
  .line > .btn { padding-left: 0; padding-right: 0; justify-content: center; }

  /* En el teléfono se consulta de pie y con prisa: cuatro cifras tienen que caber
     casi de una pantalla. Se recorta el aire, no el tamaño del número. */
  .grid.k4 { grid-template-columns: 1fr 1fr; gap: var(--s1); }
  .kpi { padding: var(--s2); gap: 2px; }
  .kpi .val { font-size: 23px; }
  .kpi .lbl { font-size: 11.5px; }
  .kpi .sub { font-size: 11px; }
  .kpi .spark { height: 22px; }
  /* El saludo no puede comerse media pantalla partido en dos líneas. */
  .topbar h1 { font-size: 22px; }
  .topbar .hello { overflow: hidden; }
  .topbar h1, .topbar .sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .chart { height: 180px; }
}
/* ================================================= ficha técnica impresa
   Se imprime en blanco y negro a propósito: esto acaba fotocopiado y pegado con cinta
   en la puerta de una nevera, no en un porfolio. Lo que importa es que se lea. */

#print-root { display: none; }

@media screen {
  body.printing > *:not(#print-root) { display: none; }
  body.printing #print-root { display: block; }
}

@media print {
  @page { size: A4; margin: 14mm; }

  body > *:not(#print-root) { display: none !important; }

  #print-root {
    display: block;
    color: #000; background: #fff;
    font: 11pt/1.45 -apple-system, "Hiragino Sans", "Noto Sans JP", sans-serif;
  }
  #print-root header { border-bottom: 2px solid #000; padding-bottom: 6pt; margin-bottom: 10pt; }
  #print-root h1 { font-size: 20pt; margin: 0 0 3pt; }
  #print-root .meta { font-size: 9.5pt; color: #444; }

  #print-root h2 {
    font-size: 9pt; text-transform: uppercase; letter-spacing: .08em;
    margin: 13pt 0 4pt; padding-bottom: 2pt; border-bottom: 1px solid #999;
    /* Un encabezado nunca debe quedar solo al pie de una página. */
    break-after: avoid; page-break-after: avoid;
  }

  #print-root .shot {
    width: 58mm; height: 44mm; object-fit: cover; float: right;
    margin: 0 0 6pt 8pt; border: 1px solid #000;
  }

  #print-root table { width: 100%; border-collapse: collapse; font-size: 10pt; }
  #print-root th {
    text-align: left; font-size: 8pt; text-transform: uppercase; letter-spacing: .05em;
    border-bottom: 1px solid #000; padding: 3pt 4pt;
  }
  #print-root td { padding: 2.5pt 4pt; border-bottom: 1px solid #ddd; }
  #print-root .n { text-align: right; font-variant-numeric: tabular-nums; }
  #print-root table.kv td:first-child { color: #333; }
  /* Una fila partida entre dos páginas hace perder el renglón al leerlo de pie. */
  #print-root tr { break-inside: avoid; page-break-inside: avoid; }
  #print-root .role { color: #666; font-size: 8.5pt; }

  #print-root .steps { white-space: pre-wrap; font-size: 10.5pt; margin: 0; }
  #print-root .allerg { font-size: 10.5pt; margin: 0 0 3pt; }
  #print-root .warn { font-size: 10.5pt; font-weight: 700; margin: 0; }

  #print-root footer {
    margin-top: 14pt; padding-top: 4pt; border-top: 1px solid #999;
    font-size: 8pt; color: #666;
  }
}

/* La vista previa en pantalla debe verse COMO SE IMPRIME. Enseñarla en tema oscuro
   y que salga en blanco de la impresora es la forma más fácil de imprimir tres veces
   hasta acertar con el margen. */
@media screen {
  body.printing { background: #666; }
  body.printing #print-root {
    background: #fff; color: #000;
    max-width: 210mm; min-height: 297mm;
    margin: 16px auto; padding: 14mm;
    box-shadow: 0 6px 28px rgba(0,0,0,.4);
    font: 11pt/1.45 -apple-system, "Hiragino Sans", "Noto Sans JP", sans-serif;
  }
  body.printing #print-root header { border-bottom: 2px solid #000; padding-bottom: 6pt; margin-bottom: 10pt; }
  body.printing #print-root h1 { font-size: 20pt; margin: 0 0 3pt; }
  body.printing #print-root .meta { font-size: 9.5pt; color: #444; }
  body.printing #print-root h2 {
    font-size: 9pt; text-transform: uppercase; letter-spacing: .08em;
    margin: 13pt 0 4pt; padding-bottom: 2pt; border-bottom: 1px solid #999; color: #000;
  }
  body.printing #print-root .shot { width: 58mm; height: 44mm; object-fit: cover; float: right; margin: 0 0 6pt 8pt; border: 1px solid #000; }
  body.printing #print-root table { width: 100%; border-collapse: collapse; font-size: 10pt; }
  body.printing #print-root th { text-align: left; font-size: 8pt; text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid #000; padding: 3pt 4pt; color: #000; }
  body.printing #print-root td { padding: 2.5pt 4pt; border-bottom: 1px solid #ddd; }
  body.printing #print-root .n { text-align: right; font-variant-numeric: tabular-nums; }
  body.printing #print-root .role { color: #666; font-size: 8.5pt; }
  body.printing #print-root .steps { white-space: pre-wrap; margin: 0; }
  body.printing #print-root .warn { font-weight: 700; }
  body.printing #print-root footer { margin-top: 14pt; padding-top: 4pt; border-top: 1px solid #999; font-size: 8pt; color: #666; }
}

/* iPhone de 375 pt: en Insumos la cabecera lleva «Importar CSV» y «+ Añadir» y se salía 17 px.
   Se deja solo el punto de estado de la red (su texto sigue en el título) y se aprieta el botón. */
@media (max-width: 400px) {
  .netpill > span:not(.dot) { display: none; }
  .netpill { padding-left: 8px; padding-right: 8px; }
  .topbar .btn { padding-left: 11px; padding-right: 11px; }
}
