/* Caravan — the approved C1 design.
   Dark operator console: staff repeat the same action hundreds of times a
   shift, so this is tuned for reading a code fast, not for looking friendly.
   The accent is spent in exactly one place (the open container at the scan
   station, C4); everything else stays quiet so it can carry. */

:root {
  --ink:#0C1116; --panel:#141C25; --panel-2:#1A242F;
  --line:#22303D; --line-2:#2E3F4F;
  --paper:#E8EDF2; --dim:#8497A8; --faint:#5D7285;
  --amber:#F0A22E; --amber-ink:#3A2708;
  --go:#35B27C; --stop:#E05A4E; --info:#4E9FE0;
  --mono: ui-monospace,"Cascadia Mono","SF Mono",Menlo,Consolas,monospace;
  --sans: ui-sans-serif,system-ui,"Segoe UI",Roboto,sans-serif;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin:0; background:var(--ink); color:var(--paper);
  font:400 14px/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
}
.cv-boot { display:grid; place-items:center; height:100vh; color:var(--faint); font:500 18px/1 var(--sans); }

a { color:var(--info); }
:focus-visible { outline:2px solid var(--amber); outline-offset:2px; }

/* ---- primitives ---- */
.mono { font-family:var(--mono); font-variant-numeric:tabular-nums; }
.code { font:500 13.5px/1 var(--mono); font-variant-numeric:tabular-nums; }
.dim  { color:var(--dim); }
.faint{ color:var(--faint); }
.muted{ font-size:12.5px; color:var(--dim); }

label, .lbl { display:block; font-size:12px; color:var(--dim); margin:0 0 5px; }
input, select, textarea {
  width:100%; height:38px; padding:0 11px;
  background:var(--ink); border:1px solid var(--line-2); border-radius:5px;
  color:var(--paper); font:400 14px/1 var(--sans);
}
textarea { height:auto; padding:9px 11px; line-height:1.5; }
input::placeholder { color:var(--faint); }
input:focus, select:focus, textarea:focus { border-color:var(--line-2); }
select { appearance:none; padding-right:28px;
  background-image:linear-gradient(45deg,transparent 50%,var(--dim) 50%),linear-gradient(135deg,var(--dim) 50%,transparent 50%);
  background-position:calc(100% - 15px) 17px, calc(100% - 10px) 17px;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat; }

.btn {
  height:38px; padding:0 16px; border-radius:5px; border:1px solid transparent;
  background:var(--amber); color:var(--amber-ink);
  font:500 14px/1 var(--sans); display:inline-flex; align-items:center;
  justify-content:center; gap:7px; cursor:pointer;
}
.btn:hover { filter:brightness(1.06); }
.btn:disabled { opacity:.55; cursor:default; filter:none; }
.btn.ghost { background:transparent; border-color:var(--line-2); color:var(--paper); }
.btn.ghost:hover { background:var(--panel-2); filter:none; }
.btn.danger { background:transparent; border-color:#4A2320; color:var(--stop); }
.btn.sm { height:28px; padding:0 10px; font-size:12.5px; }
.btn.block { width:100%; }

.card { background:var(--panel); border:1px solid var(--line); border-radius:7px; padding:15px 16px; }
.card h4 { margin:0 0 12px; font-size:12.5px; font-weight:500; color:var(--dim); }
.stack { display:flex; flex-direction:column; gap:12px; }
.row   { display:flex; gap:10px; align-items:center; }
.row > .grow { flex:1; min-width:0; }

.chip { display:inline-flex; align-items:center; gap:5px; font:500 10.5px/1 var(--mono);
  letter-spacing:.05em; padding:4px 7px; border-radius:4px; text-transform:uppercase; }
.chip.go   { color:var(--go);    background:#0D2019; }
.chip.wait { color:var(--amber); background:#241A08; }
.chip.done { color:var(--dim);   background:var(--panel-2); }
.chip.off  { color:var(--stop);  background:#241110; }
/* La estación escribe "chip bad" en sus filas de error desde C4; nunca tuvo
   estilo y salía sin color. El rojo del .off, que era la intención. */
.chip.bad  { color:var(--stop);  background:#241110; }

.pill { font:500 10.5px/1 var(--mono); letter-spacing:.06em; text-transform:uppercase;
  padding:4px 8px; border-radius:999px; border:1px solid var(--line-2); color:var(--dim); }
.pill.role { color:var(--info); border-color:#24445F; background:#0E1D28; }

.note-info { display:flex; gap:9px; padding:11px 12px; background:#0E1D28;
  border:1px solid #24445F; border-radius:6px; font-size:12.5px; color:#A8C4DA; line-height:1.5; }
.note-warn { display:flex; gap:9px; padding:11px 12px; background:#241A08;
  border:1px solid #4A3410; border-radius:6px; font-size:12.5px; color:#E4C07A; line-height:1.5; }
/* Verde y neutro. Faltaban los dos: "te cobramos y salió bien" no es una
   advertencia, y "no se completó el pago" tampoco — teñir de ámbar un checkout
   que el propio cliente canceló es alarmar por nada. Los verdes son los mismos
   de .stalebar y .pill.go, para no inventar una tercera familia. */
.note-ok   { display:flex; gap:9px; padding:11px 12px; background:#0D2019;
  border:1px solid #17402F; border-radius:6px; font-size:12.5px; color:#8FDCBB; line-height:1.5; }
.note-flat { display:flex; gap:9px; padding:11px 12px; background:var(--panel);
  border:1px solid var(--line); border-radius:6px; font-size:12.5px; color:var(--dim); line-height:1.5; }

/* El aviso de vuelta del pago: titular arriba, detalle abajo, botón a la
   derecha. Va en su propia clase para que las notas que ya existían no cambien
   de forma. */
.retnote b { display:block; font-weight:500; color:var(--paper); margin-bottom:2px; }
.retnote .btn { margin-left:auto; align-self:center; flex:none; }

/* ---- tables ---- */
.tbl { width:100%; border-collapse:collapse; font-size:13px; }
.tbl th { text-align:left; font:500 10.5px/1 var(--mono); letter-spacing:.11em;
  text-transform:uppercase; color:var(--faint); padding:0 10px 8px; border-bottom:1px solid var(--line); }
.tbl td { padding:0 10px; height:36px; border-bottom:1px solid var(--line); vertical-align:middle; }
.tbl tr:hover td { background:var(--panel); }
.scroller { overflow-x:auto; }

/* ---- brand ---- */
.brand { display:flex; align-items:center; gap:9px; font-weight:500; letter-spacing:-.01em; }
.brand svg { width:22px; height:22px; flex:none; }

/* ---- auth screens ---- */
.auth-wrap { min-height:100vh; display:grid; grid-template-columns:1.05fr .95fr; }
.auth-art { background:var(--panel); border-right:1px solid var(--line); padding:34px 36px;
  display:flex; flex-direction:column; justify-content:space-between; }
.auth-form { padding:34px 36px; display:flex; flex-direction:column; justify-content:center; }
.auth-form .inner { width:100%; max-width:340px; margin:0 auto; display:flex; flex-direction:column; gap:14px; }
.pitch { font-size:22px; font-weight:500; line-height:1.28; letter-spacing:-.02em; margin:22px 0 0; max-width:20ch; }
.pitch em { font-style:normal; color:var(--amber); }
.tag { font:500 11px/1 var(--mono); letter-spacing:.13em; text-transform:uppercase; color:var(--faint); }
.linkrow { display:flex; justify-content:space-between; align-items:center; gap:12px; font-size:12.5px; color:var(--dim); }
.linkbtn { background:none; border:0; padding:0; color:var(--dim); font:inherit; cursor:pointer; text-decoration:underline; }
.linkbtn:hover { color:var(--paper); }
.lang { display:flex; gap:5px; flex-wrap:wrap; }
.lang button { padding:3px 7px; border-radius:4px; font:500 11px/1 var(--mono);
  color:var(--faint); border:1px solid transparent; background:none; cursor:pointer; }
.lang button.on { color:var(--paper); border-color:var(--line-2); background:var(--panel-2); }
.company-known { display:flex; align-items:center; justify-content:space-between; gap:10px;
  height:38px; padding:0 11px; background:var(--ink); border:1px solid var(--line-2); border-radius:5px; }

.center-wrap { min-height:100vh; display:grid; place-items:center; padding:44px 20px; }
.center-stack { width:100%; max-width:392px; display:flex; flex-direction:column; gap:9px; }
.pick { display:flex; align-items:center; gap:12px; padding:13px; background:var(--panel);
  border:1px solid var(--line); border-radius:7px; cursor:pointer; text-align:left; width:100%; color:inherit; font:inherit; }
.pick:hover { border-color:var(--line-2); background:var(--panel-2); }
.pick .sq { width:34px; height:34px; border-radius:6px; background:var(--panel-2);
  border:1px solid var(--line-2); display:grid; place-items:center; font:500 12px/1 var(--mono); color:var(--amber); flex:none; }
.pick:disabled { opacity:.55; cursor:default; }

/* El "o" entre entrar a la empresa que te invitó y fundar la tuya. Separa dos
   caminos que siguen ambos disponibles; no es un divisor decorativo. */
.orline { display:flex; align-items:center; gap:10px; }
.orline i { flex:1; height:1px; background:var(--line); }
.orline span { font:500 10.5px/1 var(--mono); letter-spacing:.06em;
  text-transform:uppercase; color:var(--faint); }

/* ---- app layout ---- */
.app { display:grid; grid-template-columns:200px 1fr; min-height:100vh; }
.rail { background:var(--panel); border-right:1px solid var(--line); padding:14px 0;
  display:flex; flex-direction:column; position:sticky; top:0; height:100vh; }
.railhead { padding:0 14px 14px; border-bottom:1px solid var(--line); margin-bottom:10px; }
.nav { display:flex; flex-direction:column; gap:1px; padding:0 7px; flex:1; overflow-y:auto; }
.nav a { display:flex; align-items:center; gap:9px; height:32px; padding:0 8px; border-radius:5px;
  color:var(--dim); text-decoration:none; font-size:13.5px; }
.nav a:hover { background:var(--panel-2); color:var(--paper); }
.nav a.on { background:var(--panel-2); color:var(--paper); }
.nav a.on .ic { color:var(--amber); }
.ic { width:15px; text-align:center; color:var(--faint); font-size:13px; flex:none; }
.nav .grp { font:500 10px/1 var(--mono); letter-spacing:.13em; color:var(--faint);
  padding:14px 8px 6px; text-transform:uppercase; }
.who { padding:10px 14px 0; border-top:1px solid var(--line); margin-top:8px;
  display:flex; align-items:center; gap:9px; }
.av { width:26px; height:26px; border-radius:50%; background:var(--panel-2); border:1px solid var(--line-2);
  display:grid; place-items:center; font:500 10.5px/1 var(--mono); color:var(--dim); flex:none; }
.main { display:flex; flex-direction:column; min-width:0; }
.top { display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:11px 18px; border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--ink); z-index:5; }
.crumb { display:flex; align-items:baseline; gap:9px; }
.crumb b { font-weight:500; font-size:15px; }
.body { padding:18px; flex:1; min-width:0; }

.empty { text-align:center; max-width:392px; margin:44px auto; }
.empty .glyph { font:500 34px/1 var(--mono); color:var(--line-2); letter-spacing:.1em; }
.empty h3 { font-size:16px; font-weight:500; margin:14px 0 6px; }
.empty p { color:var(--dim); font-size:13.5px; margin:0 0 16px; }

/* ---- dashboard and reports (C6) ---- */
.tilegrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:10px; }
.tile { display:block; }
.tilenum { font:500 27px/1.15 var(--mono); letter-spacing:-.02em; margin-top:5px;
  font-variant-numeric:tabular-nums; }

.filterbar { display:flex; flex-wrap:wrap; gap:6px; align-items:center;
  margin:-18px -18px 14px; padding:10px 18px; background:#0A0F14; border-bottom:1px solid var(--line); }
.filterbar .filt { width:auto; height:30px; font-size:12.5px; padding:0 26px 0 9px; }
.filterbar .filt.dt { width:auto; padding:0 9px; font-family:var(--mono); font-size:12.5px; }
.filterbar select.filt { background-position:calc(100% - 13px) 13px, calc(100% - 9px) 13px; }
/* An applied filter is worth seeing from across the room — the difference
   between "nothing happened" and "nothing matched" is the whole report. */
.filterbar .filt.set { border-color:#4A3410; color:var(--amber); }
.filtsep { width:1px; height:20px; background:var(--line-2); margin:0 3px; }
.chipbtn { padding:5px 9px; border-radius:5px; font:500 11.5px/1 var(--mono);
  color:var(--dim); border:1px solid transparent; background:none; cursor:pointer; }
.chipbtn:hover { color:var(--paper); }
.chipbtn.on { color:var(--paper); border-color:var(--line-2); background:var(--panel-2); }
.chipbtn.clear { color:var(--stop); }

.agegrid { display:grid; grid-template-columns:repeat(auto-fit,minmax(96px,1fr)); gap:8px; text-align:center; }
.agecell { background:var(--panel-2); border:1px solid var(--line); border-radius:6px; padding:10px 4px; }
.agecell .v { font:500 21px/1.15 var(--mono); font-variant-numeric:tabular-nums; }

.tbl td.n, .tbl th.n { text-align:right; }
.tbl tfoot td { border-bottom:0; border-top:1px solid var(--line-2); font-weight:500; }
.bars { display:flex; align-items:flex-end; gap:3px; height:78px; }
.bars > div { flex:1; min-width:2px; background:#2A3B49; border-radius:2px 2px 0 0; }
.bars > div.hi { background:var(--amber); }
.barfoot { display:flex; justify-content:space-between; gap:10px; margin-top:7px; font-size:12px; }
.vipdot { width:5px; height:5px; border-radius:50%; background:var(--amber);
  display:inline-block; margin-right:6px; vertical-align:1px; }
.card h4 .csvbtn { float:right; margin:-4px 0 0; }

/* The row action sits right and never widens the row it lives in. */
.tbl td.rowact { text-align:right; white-space:nowrap; width:1%; }

/* Una pestaña abierta sigue corriendo el JavaScript viejo hasta que alguien
   recarga. Esto lo dice, en vez de dejar que alguien busque una pantalla que ya
   está desplegada y no aparece. */
.stalebar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:9px 18px; background:#0D2019; border-bottom:1px solid #17402F;
  color:#8FDCBB; font-size:12.5px; }

/* ---- el mostrador (S5.2) ---- */
.attbar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin:-18px -18px 0; padding:11px 18px; background:#0E1D28; border-bottom:1px solid #24445F; color:#A8C4DA; }
.attbar b { color:var(--paper); }

.scanout { border-color:var(--go) !important; }
.flash-ok  { animation:flashok .22s ease-out; }
.flash-warn{ animation:flashwarn .22s ease-out; }
.flash-err { animation:flasherr .22s ease-out; }
@keyframes flashwarn { from { background:#2B2008; } to { background:transparent; } }

/* Agrupado por estante, en el orden en que se camina la bodega. */
.area { margin-top:12px; }
.areahead { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
  padding:8px 13px; background:var(--panel-2); border:1px solid var(--line);
  border-bottom:0; border-radius:7px 7px 0 0; }
.areahead b { font:500 16px/1 var(--mono); color:var(--amber); }
.arearows { border:1px solid var(--line); border-radius:0 0 7px 7px; overflow:hidden; }
.prow { display:flex; align-items:center; gap:11px; padding:9px 13px;
  border-bottom:1px solid var(--line); background:var(--panel); font-size:13.5px; }
.prow:last-child { border-bottom:0; }
.prow.got { background:#0D1A16; }
/* Con cobro pendiente: no puede salir por la puerta hasta que se cobre. El
   tinte es apenas perceptible a propósito — quien tiene que verlo es quien está
   mirando esa fila, no toda la pantalla. Al imprimir desaparece con el resto
   del color: la hoja de recolección va en blanco y negro. */
.prow.due { background:#17110F; }
.prow.due .tick { border-color:#4A2320; }
.prow.pickable.due:hover { background:#211613; }
/* Toda la fila es el blanco, no la casilla de 19px: en un mostrador se toca a
   la carrera. Sin cursor de mano cuando el dueño exige escanear. */
.prow.pickable { cursor:pointer; }
.prow.pickable:hover { background:var(--panel-2); }
.prow.pickable.got:hover { background:#112620; }
.prow.pickable:focus-visible { outline:2px solid var(--amber); outline-offset:-2px; }
.prow .c { font:500 14.5px/1 var(--mono); min-width:124px; }
.tick { width:19px; height:19px; border-radius:4px; border:1px solid var(--line-2);
  flex:none; display:grid; place-items:center; font-size:12px; color:var(--faint); }
.tick.on { border-color:var(--go); color:var(--go); background:#0D2019; }

.pick .sq { flex:none; }
.pick:disabled { opacity:.6; cursor:default; }

/* La hoja de recolección. Quien camina la bodega lleva papel: blanco, grande,
   sin cromo, y sin el resto de la aplicación detrás. */
.printhead { display:none; }
@media print {
  body { background:#fff; }
  .rail, .top, .attbar, .noprint, .toasts, form { display:none !important; }

  /* 100vh en pantalla es "toda la ventana"; al imprimir es TODA LA HOJA, así
     que el encabezado se quedaba solo en la página 1 y la lista empezaba en la
     2. Hay que soltar todas las alturas del armazón, no sólo la del grid. */
  html, body, .app, .main, .body { height:auto !important; min-height:0 !important; }
  .app { display:block; }
  .main, .body { padding:0; overflow:visible !important; }
  .scroller { overflow:visible !important; }
  .printhead { display:block; font-size:15pt; margin:0 0 10pt; color:#000; }
  .printarea, .printarea * { color:#000 !important; background:#fff !important; }
  /* NUNCA break-inside:avoid en el área: un estante con 46 cajas es más alto
     que la hoja, el navegador lo empuja a una página nueva intentando no
     partirlo, no cabe igual, y lo parte — dejando la primera hoja con sólo el
     encabezado. Lo que de verdad no debe partirse es cada FILA, y lo que no
     debe quedarse solo al pie es el encabezado del estante. */
  .area { margin-top:8pt; }
  .areahead { border:0; border-bottom:1.5pt solid #000; border-radius:0; padding:3pt 0;
    break-after:avoid; page-break-after:avoid; }
  .areahead b { font-size:15pt; }
  .arearows { border:0; }
  .prow { border-bottom:.5pt solid #999; padding:4pt 0; font-size:11pt;
    break-inside:avoid; page-break-inside:avoid; }
  /* El título tampoco puede quedarse solo: la lista arranca pegada a él. */
  .printhead { break-after:avoid; page-break-after:avoid; }
  .tick { border:1pt solid #000; }
  .tick.on { background:#fff !important; }
  .chip { border:.5pt solid #666; }
}

/* Epson térmica y compañía. Rollo continuo, así que la ALTURA es `auto`: fijar
   una haría que cada lista corte donde no debe. Sin color, sin bordes finos que
   la térmica no resuelve, y monoespaciada — el código es lo que se lee. */
@media print {
  .pf-ticket80 .printarea { width:72mm; }
  .pf-ticket58 .printarea { width:50mm; }
  .pf-ticket80 .printhead, .pf-ticket58 .printhead { font-size:10pt; }
  .pf-ticket80 .areahead b, .pf-ticket58 .areahead b { font-size:12pt; }
  .pf-ticket80 .prow, .pf-ticket58 .prow { font-size:9pt; padding:2pt 0; flex-wrap:wrap; }
  .pf-ticket80 .prow .c, .pf-ticket58 .prow .c { min-width:0; font-size:10pt; }
  /* En 50 mm no cabe la columna del locker al lado: se va abajo, entera. */
  .pf-ticket58 .prow .muted { flex-basis:100%; font-size:8pt; }
  .pf-ticket80 .chip, .pf-ticket58 .chip { border:0; font-size:7.5pt; padding:0; }
}
@page { margin:12mm; }

/* ---- Entrega de bodega (13 ago 2026) ---- */
/* En pantalla un lote es un .area como los del picklist, así que hereda las
   reglas de impresión de arriba (filas que no se parten, térmicas, etc.). El
   encabezado del manifiesto y el bloque de firma sólo existen en papel. */
.wd-head { display:none; }
.wd-sign { display:none; }
.area.closed .wd-rows { display:none; }
@media print {
  .wd-head { display:block; color:#000; margin:0 0 6pt; break-after:avoid; page-break-after:avoid; }
  /* Imprimir UN manifiesto: sólo el lote marcado sobrevive a la impresión. */
  .wdroot.print-one .wd-lot { display:none; }
  .wdroot.print-one .wd-lot.printing { display:block; }
  .wdroot .wd-lot.printing .wd-rows { display:block; }
  /* La firma no se parte de su manifiesto ni se queda sola en otra hoja. */
  .wd-sign { display:flex; gap:18pt; margin-top:30pt; break-inside:avoid; page-break-inside:avoid; }
  .wd-sign > div { flex:1; border-top:1pt solid #000; padding-top:3pt; font-size:9pt; }
  .pf-ticket80 .wd-sign, .pf-ticket58 .wd-sign { display:block; }
  .pf-ticket80 .wd-sign > div, .pf-ticket58 .wd-sign > div { margin-top:16pt; }
}


/* ---- signup, trial and subscription (S7) ---- */
.hp { position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.bigglyph { font:500 30px/1 var(--mono); color:var(--line-2); letter-spacing:.1em; }
.steps { display:flex; gap:6px; align-items:center; flex-wrap:wrap;
  font:500 10.5px/1 var(--mono); letter-spacing:.1em; text-transform:uppercase; color:var(--faint); }
.steps b { color:var(--amber); font-weight:500; }

/* Full-width strips under the top bar: a property of the whole app, not of
   whichever screen happens to be open. */
.trialbar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:9px 18px; background:#241A08; border-bottom:1px solid #4A3410; font-size:12.5px; color:#E4C07A; }
.robar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 18px; background:#2A100E; border-bottom:1px solid #5A2A26; font-size:12.5px; color:#E4B5AF; }
.pill.go    { color:var(--go);    border-color:#17402F; background:#0D2019; }
.pill.amber { color:var(--amber); border-color:#4A3410; background:#241A08; }
.pill.stop  { color:var(--stop);  border-color:#5A2A26; background:#2A100E; }

.usage { display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:12px; }
.meter { height:6px; border-radius:3px; background:var(--panel-2); overflow:hidden; margin-top:6px; }
.meter i { display:block; height:100%; background:var(--go); }
.meter i.warn { background:var(--amber); }
.meter i.bad  { background:var(--stop); }

.plans { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:11px; }
.plan { background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:15px; }
.plan.on { border-color:var(--amber); background:#171B1B; }
.plan h5 { margin:0; font-size:14.5px; font-weight:500; }
.plan .price { font:500 26px/1.1 var(--mono); margin:8px 0 2px; letter-spacing:-.02em; }
.plan .price small { font-size:12px; color:var(--dim); font-weight:400; letter-spacing:0; }
/* El precio tachado del descuento fundador: pequeño y apagado, porque lo que
   se paga es el número grande — el tachado sólo explica por qué es ese. */
.plan .price .was { font-size:14px; color:var(--faint); text-decoration:line-through;
  margin-right:8px; letter-spacing:0; font-weight:400; }
.setupfee { margin-top:8px; font-size:12px; color:var(--dim); }
.setupfee .waived { color:var(--go); }
.plan ul { list-style:none; margin:11px 0 0; padding:0; font-size:12.5px; color:var(--dim); }
.plan li { padding:4px 0; border-bottom:1px solid var(--line); }
.plan li:last-child { border-bottom:0; }

/* Lo que Caravan le movió a este cliente, arriba en el mismo modal. El número
   grande va en VERDE y no en ámbar: el acento se gasta en el contenedor abierto
   de la estación y en ningún otro lado, y el verde ya significa "esto lo ganás"
   en .setupfee .waived y en .losses li.keep. */
.worth { border:1px solid var(--line); border-radius:6px; padding:11px 12px; }
.worth dl { margin:8px 0 0; display:grid; grid-template-columns:1fr auto; gap:5px 12px;
  font-size:12.5px; }
.worth dt { margin:0; color:var(--dim); }
.worth dd { margin:0; text-align:right; font-family:var(--mono);
  font-variant-numeric:tabular-nums; }
.worth .saved { margin-top:10px; padding-top:10px; border-top:1px solid var(--line); }
.worth .amount { display:block; font:500 20px/1.2 var(--mono); color:var(--go);
  letter-spacing:-.01em; }
.worth .saved .muted { display:block; margin-top:3px; }

/* Lo que se detiene al cancelar, y lo que se queda. Va DENTRO del modal y antes
   del botón: una ayuda que hay que abrir para leerla no la lee nadie, y "no se
   borra nada" es justamente lo que nadie da por sentado al cancelar. */
.losses { list-style:none; margin:0; padding:0; font-size:12.5px; color:var(--dim); }
.losses li { position:relative; padding:6px 0 6px 17px; line-height:1.5;
  border-bottom:1px solid var(--line); }
.losses li:last-child { border-bottom:0; }
.losses li::before { content:"—"; position:absolute; left:0; color:var(--stop); }
.losses li.keep::before { content:"+"; color:var(--go); }

/* ---- modal ---- */
.modal-back { position:fixed; inset:0; background:rgba(4,7,10,.72); display:grid;
  place-items:center; padding:20px; z-index:50; }
.modal { width:100%; max-width:440px; background:var(--panel); border:1px solid var(--line-2);
  border-radius:9px; padding:18px 20px; }
.modal h3 { margin:0 0 4px; font-size:16px; font-weight:500; }
.modal .sub { color:var(--dim); font-size:13px; margin:0 0 14px; }
.modal-actions { display:flex; justify-content:flex-end; gap:9px; margin-top:16px; }

/* ---- toast ---- */
.toasts { position:fixed; right:18px; bottom:18px; display:flex; flex-direction:column;
  gap:8px; z-index:60; }
.toast { padding:10px 14px; border-radius:6px; font-size:13px; background:var(--panel-2);
  border:1px solid var(--line-2); max-width:360px; }
.toast.err { border-color:#4A2320; color:#F0A9A0; background:#1D100F; }
.toast.ok  { border-color:#17402F; color:#8FDCBB; background:#0D2019; }

/* ---- structure tree ---- */
.tnode { display:flex; align-items:center; gap:10px; min-height:38px; padding:4px 10px;
  border-bottom:1px solid var(--line); font-size:13.5px; flex-wrap:wrap; }
.tnode:last-child { border-bottom:0; }
.tnode:hover { background:var(--panel); }
.tnode .grow { flex:1; min-width:120px; }
.tnode .cnt { font:500 12px/1 var(--mono); color:var(--faint); }
.tnode.lvl2 { padding-left:34px; }
.tnode.lvl3 { padding-left:62px; }
.badge { font:500 11px/1 var(--mono); padding:4px 7px; border-radius:4px; background:var(--panel-2);
  border:1px solid var(--line-2); color:var(--amber); letter-spacing:.06em; }

/* ---- the scan station ----
   Full-bleed: it breaks out of the body padding because it is a dedicated
   screen on a shared warehouse PC, not a page among pages. */
.station { margin:-18px; }
.station.flash-ok  { animation:flashok .22s ease-out; }
.station.flash-err { animation:flasherr .22s ease-out; }
@keyframes flashok  { from { background:#12301F; } to { background:transparent; } }
@keyframes flasherr { from { background:#341412; } to { background:transparent; } }
@media (prefers-reduced-motion: reduce) {
  .station.flash-ok, .station.flash-err { animation:none; }
}

.stationbar { display:flex; align-items:center; gap:12px; padding:9px 16px;
  background:#080B0F; border-bottom:1px solid var(--line); }
.syncstate { display:inline-flex; align-items:center; gap:7px; font:500 11px/1 var(--mono);
  letter-spacing:.09em; text-transform:uppercase; }
.syncstate .syncdot { width:8px; height:8px; border-radius:50%; flex:none; }
.syncstate.ok   { color:var(--go); }    .syncstate.ok   .syncdot { background:var(--go); }
.syncstate.bad  { color:var(--stop); }  .syncstate.bad  .syncdot { background:var(--stop); }
.syncstate.busy { color:var(--amber); } .syncstate.busy .syncdot { background:var(--amber); }

/* The one place the accent is spent: readable from arm's length, between boxes. */
.band { background:var(--amber); color:var(--amber-ink); padding:14px 18px;
  display:flex; align-items:center; gap:20px; flex-wrap:wrap; }
.band .lbl { font:500 10.5px/1 var(--mono); letter-spacing:.15em; text-transform:uppercase; opacity:.72; }
.band .big { font:500 42px/1 var(--mono); letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
.band .sub { font-size:13px; opacity:.82; }
.band.none { background:var(--panel-2); color:var(--dim); }
.band.none .big { color:var(--faint); font-size:26px; }

.offlinebar { background:#2A100E; border-top:1px solid #5A2A26; border-bottom:1px solid #5A2A26;
  padding:12px 18px; display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.offlinebar .t { font:500 12px/1 var(--mono); letter-spacing:.12em; text-transform:uppercase; color:#F0A9A0; }
.offlinebar .d { font-size:13px; color:#E4B5AF; max-width:60ch; }

/* El dueño activo (13 ago 2026): franja azul bajo la banda ámbar. El azul del
   attbar del mostrador a propósito — en esta app "azul" significa "esto es
   una persona, no un lugar". */
.ownerbar { display:flex; align-items:center; gap:10px; background:#0E1D28;
  border-bottom:1px solid #24445F; padding:9px 18px; font-size:13.5px; flex-wrap:wrap; }
.ownerbar .lbl { font:500 11px/1 var(--mono); letter-spacing:.08em; text-transform:uppercase; color:#A8C4DA; }
.ownerbar b { font-weight:500; }
.ownerbar .ocode { font-size:11.5px; color:#A8C4DA; border:1px solid #24445F; border-radius:4px; padding:3px 6px; }
.ownerbar .hint { color:var(--faint); font-size:11.5px; }

.scanin { padding:16px 18px; border-bottom:1px solid var(--line); }
.bigin { width:100%; height:60px; padding:0 16px; background:var(--panel);
  border:2px solid var(--amber); border-radius:7px; color:var(--paper);
  font:500 22px/60px var(--mono); letter-spacing:.04em; }
.bigin::placeholder { color:var(--faint); font-weight:400; font-size:18px; letter-spacing:0; }

.slist { font-size:13.5px; }
.srow { display:flex; align-items:center; gap:12px; padding:9px 18px; border-bottom:1px solid var(--line); }
.srow .c { font:500 15px/1 var(--mono); min-width:150px; }
.srow .grow { flex:1; min-width:0; }
.srow.pend { opacity:.72; }
.srow.err  { background:#1A0F0E; }

.tog { width:34px; height:20px; border-radius:999px; background:var(--panel-2);
  border:1px solid var(--line-2); position:relative; flex:none; cursor:pointer; padding:0; }
.tog i { position:absolute; top:2px; left:2px; width:14px; height:14px; border-radius:50%;
  background:var(--faint); transition:left .12s; }
.tog.on { background:#3A2003; border-color:var(--amber); }
.tog.on i { left:16px; background:var(--amber); }

/* ---- the sales desk ---- */
.lookin { width:100%; height:64px; padding:0 18px; background:var(--panel);
  border:2px solid var(--amber); border-radius:8px; color:var(--paper);
  font:500 24px/64px var(--mono); letter-spacing:.04em; max-width:720px; }
.lookin::placeholder { color:var(--faint); font-weight:400; font-size:18px; letter-spacing:0; }
/* The single biggest thing on the screen: it is the only fact somebody needs
   in order to walk away and fetch the box. */
.lookpos { font:500 46px/1 var(--mono); color:var(--amber); letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; }
.lookpos.faint { color:var(--faint); }

.banner { display:flex; gap:10px; padding:11px 14px; border-radius:6px; font-size:13.5px; align-items:center; }
.banner.big2 { background:#241110; border:1px solid #5A2A26; color:#F0A9A0; font-weight:500; }
.banner.warn { background:#241A08; border:1px solid #4A3410; color:#E4C07A; }

/* Header search: routes into the lookup screen so there is one behaviour. */
.headsearch { height:31px; min-width:200px; padding:0 10px; background:var(--panel);
  border:1px solid var(--line-2); border-radius:5px; color:var(--paper);
  font:400 12.5px/31px var(--mono); }
.headsearch::placeholder { color:var(--faint); font-family:var(--sans); }

/* ---- dashboard tiles ---- */
.tilenum { font:500 25px/1.15 var(--mono); letter-spacing:-.02em; margin-top:5px;
  font-variant-numeric:tabular-nums; }
a.card:hover { border-color:var(--line-2); }

/* ---- package detail ---- */
.pkgcode { font:500 30px/1 var(--mono); letter-spacing:-.01em; margin-top:4px;
  font-variant-numeric:tabular-nums; }
.pkgpos  { font:500 22px/1.25 var(--mono); color:var(--amber); margin-top:4px;
  font-variant-numeric:tabular-nums; }
.dotc { width:8px; height:8px; border-radius:50%; display:inline-block; flex:none; }
.dl { display:grid; grid-template-columns:auto 1fr; gap:8px 14px; font-size:13px; align-items:baseline; }
.dl dt { color:var(--dim); font-size:12px; }
.dl dd { margin:0; }

/* ---- event timeline ----
   The rail is drawn with a pseudo-element rather than a border on each row, so
   it stops cleanly at the first and last event instead of trailing into
   nothing. */
.tl { position:relative; padding-left:18px; }
.tl::before { content:""; position:absolute; left:4px; top:6px; bottom:6px; width:1px; background:var(--line-2); }
.tlrow { position:relative; padding:0 0 14px; }
.tlrow:last-child { padding-bottom:0; }
.tlrow::before { content:""; position:absolute; left:-18px; top:5px; width:9px; height:9px;
  border-radius:50%; background:var(--panel-2); border:1px solid var(--line-2); }
/* Amber marks what happened with nobody touching it — the pre-aviso attaching
   an owner is the moment staff most often disbelieve. */
.tlrow.hi::before { background:var(--amber); border-color:var(--amber); }
.tlrow .what { font-size:13px; }
.tlrow .meta { font:400 11.5px/1.4 var(--mono); color:var(--faint); margin-top:2px; }

/* ---- label sheet ----
   White on plain paper: these get taped to warehouse shelving, not printed on
   stock. The colours below are literal rather than tokens because a label is
   the one surface that must look identical whatever theme the screen is in. */
.sheet { background:#fff; border-radius:6px; padding:16px;
  display:grid; grid-template-columns:repeat(3,1fr); gap:12px; }
.lbl-card { border:1px dashed #bbb; border-radius:4px; padding:10px 8px; text-align:center; color:#111;
  break-inside:avoid; page-break-inside:avoid; }
.lbl-card .nm { font:500 12px/1.25 var(--sans); color:#111; margin-bottom:4px; }
.lbl-card .cd { font:600 15px/1 var(--mono); letter-spacing:.06em; margin-top:6px; color:#000; }
.lbl-bar { display:block; width:100%; max-width:180px; height:40px; margin:0 auto; }
.lbl-qr { margin:6px auto 0; width:64px; }
.lbl-qr svg { width:64px; height:64px; display:block; }

/* P2.S2 — la etiqueta de una CAJA. Más densa que la de un estante: la ruta y el
   dueño son lo que una persona lee de lejos, el número es lo que lee la
   pistola, y el rastreo del courier va abajo y chico porque casi nunca se lee a
   ojo — está para cuando hay que reclamarle a UPS. */
.lbl-card.pkg { text-align:left; padding:9px 10px; }
.lbl-card.pkg .hd { display:flex; justify-content:space-between; align-items:center;
  font:500 10px/1 var(--mono); color:#5F5E5A; margin-bottom:6px; }
.lbl-card.pkg .hd .pc { border:1px solid #111; color:#111; border-radius:3px; padding:1px 5px; }
.lbl-card.pkg .own { font:500 15px/1.15 var(--sans); color:#111; margin-bottom:7px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lbl-card.pkg .lbl-bar { margin:0; max-width:100%; height:34px; }
.lbl-card.pkg .lbl-qr { margin:5px 0 0; }
.lbl-card.pkg .cd { text-align:left; font-size:13.5px; margin-top:5px; }
.lbl-card.pkg .trk { font:400 9.5px/1 var(--mono); color:#5F5E5A; margin-top:5px;
  border-top:1px solid #D9D7D0; padding-top:5px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* La hoja de la recepción existe SÓLO para imprimir: en pantalla la estación ya
   muestra cada caja en su fila, y una hoja blanca debajo del listado sería ruido
   en el único sitio donde alguien pasa un turno entero mirando. */
.print-only { display:none; }

/* P2.S5a — la báscula. Vive junto al campo de escaneo y se comporta igual: la
   báscula teclea el número y un Enter, así que es otro campo con foco. */
.scalebar { display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 16px; background:var(--panel-2); border-bottom:1px solid var(--line); }
.scalebar .lbl { font:500 10.5px/1 var(--mono); color:var(--faint); text-transform:uppercase;
  letter-spacing:.09em; }
.scalein { width:150px; height:38px; font:600 19px/1 var(--mono); text-align:right;
  padding:0 11px; color:var(--go); background:var(--ink);
  border:2px solid var(--line-2); border-radius:6px; }
.scalein:focus { outline:none; border-color:var(--go); }
.selbox { accent-color:var(--amber); width:15px; height:15px; flex:none; }

/* P2.S5b — la rejilla de tarifas. Una casilla vacía se dibuja punteada y NO es
   un cero: es "por este medio no hay tarifa", y una caja que viaje así se niega
   a cobrarse en vez de aproximar. Que se vea distinto ES el punto. */
.rategrid { width:86px; height:30px; text-align:right; padding:0 8px;
  font:400 13px/1 var(--mono); color:var(--paper); background:var(--ink);
  border:1px solid var(--line-2); border-radius:5px; }
.rategrid:focus { outline:none; border-color:var(--amber); }
.rategrid.empty { border-style:dashed; border-color:#4A3A18; }
.rategrid:disabled { opacity:.65; }

/* P2.S6 — la factura. Se ve igual en pantalla y en papel a propósito: lo que
   alguien revisa antes de imprimir tiene que ser lo que sale de la impresora. */
.invdoc { background:#fff; color:#111; padding:22px 24px; }
.invdoc .ihead { display:flex; justify-content:space-between; align-items:flex-start; gap:24px;
  border-bottom:1.5px solid #111; padding-bottom:11px; margin-bottom:15px; }
.invdoc .iname { font:500 15px/1.25 var(--sans); color:#111; }
.invdoc .imeta { font:400 11px/1.55 var(--sans); color:#5F5E5A; }
.invdoc .iright { text-align:right; }
.invdoc .ititle { font:500 13px/1.2 var(--sans); color:#111; }
.invdoc .inum { font:500 14px/1.4 var(--mono); color:#111; }
.invdoc .itbl { width:100%; border-collapse:collapse; font-size:11.5px; color:#111; }
.invdoc .itbl th { text-align:left; font-weight:500; border-bottom:.5px solid #D9D7D0;
  padding:5px 0; color:#111; }
.invdoc .itbl th.n, .invdoc .itbl td.n { text-align:right; }
.invdoc .itbl td { padding:5px 0; border-bottom:.5px solid #EFEEE9; }
.invdoc .itbl tr.void td { color:#9A9791; text-decoration:line-through; }
.invdoc .itotal { display:flex; justify-content:flex-end; gap:18px; align-items:baseline;
  border-top:1.5px solid #111; margin-top:12px; padding-top:10px; font-size:13px; color:#111; }
.invdoc .itotal .mono { font-size:17px; }
.invdoc .ifoot { margin-top:20px; padding-top:10px; border-top:.5px solid #D9D7D0;
  font:400 10px/1.6 var(--sans); color:#5F5E5A; white-space:pre-wrap; }

/* El manifiesto impreso: el papel que viaja con la carga y que alguien firma. */
.manifest { background:#fff; color:#111; padding:0; }
.manifest .mhead { display:flex; justify-content:space-between; align-items:flex-start;
  border-bottom:1.5px solid #111; padding-bottom:7px; margin-bottom:11px; }
.manifest .mt { font:500 15px/1.2 var(--sans); }
.manifest .ms { font-size:11px; color:#5F5E5A; margin-top:2px; }
.manifest .mr { text-align:right; font-size:10.5px; color:#5F5E5A; line-height:1.5; }
.manifest .mgrp { margin-bottom:11px; break-inside:avoid; page-break-inside:avoid; }
.manifest .mgh { display:flex; justify-content:space-between; font:500 12px/1.3 var(--sans);
  border-bottom:.5px solid #D9D7D0; padding-bottom:3px; margin-bottom:4px; }
.manifest .mrow { display:flex; gap:14px; font-size:9.5px; line-height:1.65; }
.manifest .mrow .mc { min-width:180px; }
.manifest .mrow .mx { color:#5F5E5A; }
.manifest .msign { display:flex; gap:34px; margin-top:26px; break-inside:avoid; }
.manifest .msign div { flex:1; border-top:1px solid #111; padding-top:4px;
  font-size:10px; color:#5F5E5A; }

@media print {
  /* Only the sheet survives: nobody wants the navigation on a label sheet. */
  body { background:#fff; }
  .rail, .top, .no-print, .toasts { display:none !important; }
  .app { display:block; }
  .body { padding:0; }
  .sheet { padding:0; gap:8px; grid-template-columns:repeat(3,1fr); }
  .lbl-card { border:1px dashed #999; }
  .print-only { display:grid !important; }
  /* La factura se imprime sola, sin la tarjeta ni el borde de la aplicación. */
  .invdoc { border:0; border-radius:0; padding:0; }
  /* El manifiesto NO es una rejilla de etiquetas: es un documento. */
  .print-only.manifest { display:block !important; }
  /* La estación de recepción se imprime como hoja: sin franjas, sin listado. */
  .station > .stationbar, .station > .band, .station > .offlinebar, .station > .scalebar,
  .station > .scanin, .station > .slist, .station > .note-warn { display:none !important; }
  .station { margin:0; }
  @page { margin:12mm; }
}

@media (max-width:820px) {
  .sheet { grid-template-columns:repeat(2,1fr); }
  .auth-wrap { grid-template-columns:1fr; }
  .auth-art { border-right:0; border-bottom:1px solid var(--line); }
  .app { grid-template-columns:1fr; }
  .rail { position:static; height:auto; border-right:0; border-bottom:1px solid var(--line); }
  .nav { flex-direction:row; flex-wrap:wrap; }
}

/* Phase 4 — el kiosco: la fila del mostrador y el badge del riel */
.navbadge { margin-left:auto; min-width:18px; height:18px; padding:0 6px; border-radius:9px;
  background:var(--amber); color:var(--amber-ink); font:500 11px/18px var(--mono); text-align:center; }
.kq-row { display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:9px 0; border-top:1px solid var(--line); }
.kq-label { color:var(--amber); font-weight:500; min-width:52px; }
