/* ── Design tokens — matched to theluxuryzone.online ───────── */
:root{
  /* brand */
  --copper:#b45a20;          /* top bar / primary */
  --copper-dark:#94481a;
  --copper-lite:#d2691e;     /* active link orange */
  --ink:#131417;             /* nav black */
  --ink-2:#1c1e23;
  --cream:#fff7f1;           /* page background */
  --cream-2:#fdefe5;

  /* semantic */
  --bg:var(--cream);
  --bg-grid:rgba(180,90,32,.045);
  --panel:#ffffff;
  --panel-2:#fffaf6;
  --line:#ecdfd4;
  --line-soft:#f3e9e0;
  --txt:#221c17;
  --txt-dim:#7b6b5e;
  --txt-mute:#a3948a;
  --accent:var(--copper);
  --accent-soft:rgba(180,90,32,.1);
  --ok:#2f8f5b;
  --danger:#c0392b;
  --radius:12px;
  --shadow:0 10px 26px rgba(90,50,20,.08);
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:"Segoe UI",Inter,system-ui,-apple-system,sans-serif;
  background:var(--bg);
  color:var(--txt);
  font-size:14px;
  background-image:
    linear-gradient(var(--bg-grid) 1px,transparent 1px),
    linear-gradient(90deg,var(--bg-grid) 1px,transparent 1px);
  background-size:48px 48px;
}

/* ── Layout ────────────────────────────────────────────────── */
.app{display:flex;min-height:100vh}

.sidebar{
  width:248px;flex:0 0 248px;
  background:var(--ink);
  border-right:1px solid #000;
  padding:22px 16px;
  display:flex;flex-direction:column;gap:26px;
  position:sticky;top:0;height:100vh;
}
.brand{display:flex;align-items:center;gap:11px;padding:0 6px}
.brand .mark{
  width:34px;height:34px;border-radius:7px;
  background:var(--copper);
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:14px;
  letter-spacing:.5px;
}
.brand h1{font-size:15px;font-weight:800;letter-spacing:.4px;color:#fff;text-transform:uppercase}
.brand small{display:block;color:#8b8177;font-size:10.5px;font-weight:600;letter-spacing:1.1px;text-transform:uppercase}

.nav{display:flex;flex-direction:column;gap:4px}
.nav-label{font-size:10.5px;letter-spacing:1.4px;color:#7c7168;text-transform:uppercase;padding:0 10px 8px}
.nav-item{
  display:flex;align-items:center;gap:11px;
  padding:10px 12px;border-radius:8px;
  color:#c9c0b8;font-size:13.5px;font-weight:500;
  background:none;border:0;width:100%;text-align:left;cursor:pointer;
  transition:background .15s,color .15s;
}
.nav-item svg{width:17px;height:17px;flex:0 0 17px;stroke:currentColor;fill:none;stroke-width:1.7}
.nav-item:hover{background:var(--ink-2);color:#fff}
.nav-item.active{background:var(--copper);color:#fff;font-weight:650}
.sidebar-foot{margin-top:auto;font-size:11px;color:#7c7168;padding:0 10px;line-height:1.6}
.sidebar-foot a{color:#9b9089}
.side-who{
  color:#c9c0b8;font-size:12px;font-weight:600;line-height:1.4;
  padding-bottom:8px;margin-bottom:8px;border-bottom:1px solid #2a2320;
}
.side-who:empty{display:none}
/* Above the drawer breakpoint the topbar already shows this — no need twice. */
@media (min-width:981px){.side-who{display:none}}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  height:60px;
  background:var(--copper);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 28px;position:sticky;top:0;z-index:20;
  box-shadow:0 2px 10px rgba(90,50,20,.14);
}
.topbar .crumb{font-size:12.5px;color:rgba(255,255,255,.78);letter-spacing:.4px}
.topbar .crumb b{color:#fff;font-weight:700}
.topbar .meta{display:flex;align-items:center;gap:18px;font-size:12px;color:rgba(255,255,255,.85)}
.chip{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.5px;
  border:1px solid rgba(255,255,255,.35);background:rgba(255,255,255,.14);
  padding:5px 10px;border-radius:6px;color:#fff;
}
.content{padding:26px 28px 60px;flex:1}

/* ── Page head ─────────────────────────────────────────────── */
.page{display:none;animation:fade .22s ease}
.page.active{display:block}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:22px;flex-wrap:wrap}
.page-head h2{font-size:22px;font-weight:800;letter-spacing:-.3px;color:var(--ink)}
.page-head p{color:var(--txt-dim);font-size:13px;margin-top:5px;max-width:620px;line-height:1.55}
.head-actions{display:flex;gap:10px;align-items:center}

/* ── Cards ─────────────────────────────────────────────────── */
.card{
  background:var(--panel);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:var(--shadow);
}
.card-head{
  padding:16px 20px;border-bottom:1px solid var(--line-soft);
  display:flex;align-items:center;justify-content:space-between;gap:14px;
}
.card-head h3{font-size:14.5px;font-weight:700;color:var(--ink)}
/* Actions in a card head belong with whatever else sits on the right, not
   stranded in the middle by space-between. */
.card-head .head-actions{margin-left:auto}
.card-body{padding:20px}
.grid-2{display:grid;grid-template-columns:1fr 460px;gap:20px;align-items:start}
@media (max-width:1180px){.grid-2{grid-template-columns:1fr}}

/* ── Forms ─────────────────────────────────────────────────── */
.field{margin-bottom:16px}
.field label,.lbl{
  display:block;font-size:10.5px;letter-spacing:1.3px;text-transform:uppercase;
  color:var(--txt-dim);margin-bottom:7px;font-weight:700;
}
.input,select.input,textarea.input{
  width:100%;background:var(--panel-2);border:1px solid var(--line);
  color:var(--txt);padding:11px 13px;border-radius:8px;font-size:13.5px;
  font-family:inherit;outline:none;transition:border-color .15s,box-shadow .15s;
}
.input::placeholder{color:var(--txt-mute)}
.input:focus{border-color:var(--copper);box-shadow:0 0 0 3px var(--accent-soft);background:#fff}
textarea.input{resize:vertical;min-height:92px}
select.input{appearance:none;cursor:pointer;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237b6b5e' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat:no-repeat;background-position:right 11px center;background-size:16px;padding-right:34px}
/* Date fields open their picker from anywhere in the box, not just from the
   little icon. The browser's own indicator is hidden and replaced with a
   drawn one, so the click handler in app.js is the only thing that opens the
   picker — nothing left to fire twice. */
input[type="date"].input{
  cursor:pointer;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237b6b5e' stroke-width='2'><rect x='3' y='5' width='18' height='16' rx='2'/><path d='M16 3v4M8 3v4M3 11h18'/></svg>");
  background-repeat:no-repeat;background-position:right 11px center;background-size:16px;
  padding-right:34px;
}
input[type="date"].input::-webkit-calendar-picker-indicator{display:none}
.row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.row-3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
@media (max-width:640px){.row,.row-3{grid-template-columns:1fr}}
.hint{font-size:11.5px;color:var(--txt-mute);margin-top:6px}

/* ── Combobox (searchable dropdown) ────────────────────────── */
.combo{position:relative}
.combo-hidden{
  position:absolute!important;opacity:0;pointer-events:none;
  width:1px;height:1px;padding:0;border:0;margin:0;left:14px;bottom:6px;
}
.combo-input{padding-right:36px!important}
.combo-arrow{
  position:absolute;right:1px;top:1px;bottom:1px;width:34px;
  background:none;border:0;cursor:pointer;color:var(--txt-dim);
  display:grid;place-items:center;border-radius:0 8px 8px 0;
}
.combo-arrow svg{width:16px;height:16px;transition:transform .18s}
.combo.open .combo-arrow{color:var(--copper)}
.combo.open .combo-arrow svg{transform:rotate(180deg)}
.combo.open .combo-input{border-color:var(--copper);box-shadow:0 0 0 3px var(--accent-soft);background:#fff}

.combo-panel{
  display:none;position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:60;
  background:#fff;border:1px solid var(--line);border-radius:10px;
  box-shadow:0 14px 34px rgba(60,32,12,.16);
  padding:5px;overflow-y:auto;overscroll-behavior:contain;
  max-height:266px;   /* 7 × 38px rows */
}
.combo.open .combo-panel{display:block}
/* Set by combo.js when there is not enough room below — otherwise the list
   covers whatever sits under the field, such as a modal's Save button. */
.combo.drop-up .combo-panel{top:auto;bottom:calc(100% + 6px)}
.combo-opt{
  display:flex;align-items:center;gap:9px;
  height:38px;padding:0 11px;border-radius:7px;cursor:pointer;
  font-size:13.5px;color:var(--txt);line-height:1;
}
.combo-opt span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-opt b{color:var(--copper);font-weight:700}
.combo-opt em{font-style:normal;font-size:11.5px;color:var(--txt-mute);font-family:var(--mono)}
.combo-opt:hover,.combo-opt.on{background:var(--cream-2)}
.combo-opt.sel{color:var(--copper);font-weight:650}
.combo-opt.sel::after{content:"✓";font-size:12px;color:var(--copper)}
.combo-dot{width:11px;height:11px;border-radius:3px;border:1px solid rgba(0,0,0,.18);flex:0 0 11px}
.combo-none{padding:14px 12px;font-size:12.5px;color:var(--txt-mute);text-align:center}
.combo-panel::-webkit-scrollbar{width:8px}
.combo-panel::-webkit-scrollbar-thumb{background:#e0cfc0;border-radius:8px;border:2px solid #fff}
.combo-panel::-webkit-scrollbar-thumb:hover{background:var(--copper)}

/* ── Combobox: multi-select chips ──────────────────────────── */
/* The wrap itself is painted like an input, and the real text box sits
   inside it with no border of its own, so chips and typing share one field. */
.combo-multi{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:8px;
  padding:6px 34px 6px 7px;min-height:44px;cursor:text;
  transition:border-color .15s,box-shadow .15s;
}
.combo-multi:focus-within{
  border-color:var(--copper);box-shadow:0 0 0 3px var(--accent-soft);background:#fff;
}
.combo-multi .combo-chips{display:contents}
.combo-multi .combo-input{
  flex:1 1 80px;min-width:80px;width:auto;
  background:none!important;border:0!important;box-shadow:none!important;
  padding:3px 2px!important;border-radius:0;
}
.combo-multi .combo-arrow{top:50%;transform:translateY(-50%)}
.combo-multi.open .combo-arrow{transform:translateY(-50%) rotate(180deg)}
.combo-chip{
  display:inline-flex;align-items:center;gap:5px;
  background:var(--accent-soft);border:1px solid rgba(180,101,42,.32);
  color:var(--copper);font-weight:650;font-size:12.5px;font-family:var(--mono);
  padding:3px 5px 3px 9px;border-radius:6px;line-height:1.5;white-space:nowrap;
}
.combo-chip-x{
  background:none;border:0;cursor:pointer;color:var(--copper);
  font-size:15px;line-height:1;padding:0 2px;opacity:.65;
}
.combo-chip-x:hover{opacity:1}

/* ── Variable list: sizes grouped onto one row ─────────────── */
.size-chips{display:flex;flex-wrap:wrap;gap:6px}
.size-chip{
  display:inline-flex;align-items:center;gap:2px;
  background:var(--cream-2);border:1px solid var(--line);
  border-radius:6px;padding:2px 3px 2px 9px;
  font-family:var(--mono);font-size:12px;font-weight:700;color:var(--ink);
  line-height:1.6;
}
/* The × only earns its contrast on hover — a row of eight sizes should read
   as data first, and eight delete buttons second. */
.size-x{
  background:none;border:0;cursor:pointer;color:var(--txt-mute);
  font-size:15px;line-height:1;padding:0 3px;border-radius:4px;
}
.size-chip:hover .size-x{color:var(--danger)}
.size-x:hover{background:rgba(192,57,43,.12)}

/* ── Buttons ───────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;gap:8px;justify-content:center;
  border:1px solid transparent;border-radius:8px;padding:10px 18px;
  font-size:13px;font-weight:650;cursor:pointer;font-family:inherit;
  transition:filter .15s,background .15s,border-color .15s,color .15s;white-space:nowrap;
}
.btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9}
.btn-primary{background:var(--copper);color:#fff}
.btn-primary:hover{background:var(--copper-dark)}
.btn-ghost{background:#fff;color:var(--txt-dim);border-color:var(--line)}
.btn-ghost:hover{color:var(--copper);border-color:var(--copper)}
.btn-quiet{background:transparent;color:var(--txt-dim);border:0}
.btn-quiet:hover{color:var(--copper)}
.btn-danger{background:transparent;color:var(--danger);border-color:rgba(192,57,43,.28)}
.btn-danger:hover{background:rgba(192,57,43,.08)}
.btn-block{width:100%}
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
.btn-sm{padding:7px 12px;font-size:12px}

/* ── Table ─────────────────────────────────────────────────── */
.table-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:13.2px}
thead th{
  text-align:left;padding:12px 16px;font-size:10.5px;letter-spacing:1.2px;
  text-transform:uppercase;color:var(--txt-dim);font-weight:700;
  border-bottom:1px solid var(--line);background:var(--cream-2);white-space:nowrap;
}
tbody td{padding:13px 16px;border-bottom:1px solid var(--line-soft);color:var(--txt);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
/* Inline editable price in the stock-out cart */
/* Wide enough for a five-figure price plus the number spinners, which eat
   about 20px of the box on their own. */
.price-cell{width:100%;max-width:150px;padding:7px 10px;text-align:right;
  font-family:var(--mono);font-size:13.5px;margin-left:auto;display:block}
/* A pair still sitting at 0.00 — the one thing stopping the sale. */
.price-cell.bad{border-color:var(--danger);background:rgba(192,57,43,.05)}
.price-cell.bad:focus{box-shadow:0 0 0 3px rgba(192,57,43,.14)}
.cart-warn{margin-top:14px;font-size:12.5px;color:var(--danger);line-height:1.5}
.cart-warn:empty{display:none}
tbody tr:hover{background:var(--panel-2)}
td.mono,.mono{font-family:var(--mono);font-size:12.5px;letter-spacing:.4px}
td.num{text-align:right;font-family:var(--mono)}
.empty{padding:44px 20px;text-align:center;color:var(--txt-mute);font-size:13px}
.empty svg{width:34px;height:34px;stroke:var(--line);fill:none;stroke-width:1.4;margin-bottom:10px;display:block;margin-inline:auto}

.swatch{display:inline-flex;align-items:center;gap:8px}
.swatch i{width:11px;height:11px;border-radius:3px;border:1px solid rgba(0,0,0,.18)}
.badge{
  display:inline-block;padding:3.5px 9px;border-radius:20px;font-size:11px;font-weight:650;
  background:var(--cream-2);color:var(--txt-dim);border:1px solid var(--line);
}
.badge.ok{background:rgba(47,143,91,.1);color:var(--ok);border-color:rgba(47,143,91,.25)}
.badge.out{background:rgba(192,57,43,.09);color:var(--danger);border-color:rgba(192,57,43,.22)}
.badge.dmg{background:#3a3a3a;color:#fff;border-color:#3a3a3a}

/* ── Stats ─────────────────────────────────────────────────── */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:14px;margin-bottom:20px}
.stat{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);
  padding:16px 18px;border-top:3px solid var(--copper);box-shadow:var(--shadow);
}
.stat .k{font-size:10.5px;letter-spacing:1.2px;text-transform:uppercase;color:var(--txt-dim);font-weight:700}
.stat .v{font-size:24px;font-weight:800;margin-top:6px;font-family:var(--mono);letter-spacing:-.5px;color:var(--ink)}
.stat .v.accent{color:var(--copper)}

/* ── Modal ─────────────────────────────────────────────────── */
.modal-back{
  position:fixed;inset:0;background:rgba(30,18,8,.5);backdrop-filter:blur(3px);
  display:none;align-items:flex-start;justify-content:center;padding:60px 20px;z-index:100;overflow-y:auto;
}
.modal-back.open{display:flex}
.modal{
  width:100%;max-width:560px;background:var(--panel);
  border:1px solid var(--line);border-radius:14px;
  box-shadow:0 24px 60px rgba(50,26,10,.3);
  animation:pop .18s ease;
}
@keyframes pop{from{opacity:0;transform:translateY(-10px) scale(.98)}to{opacity:1;transform:none}}
.modal-head{
  padding:16px 22px;background:var(--ink);border-radius:13px 13px 0 0;
  display:flex;justify-content:space-between;align-items:center;
}
.modal-head h3{font-size:15px;font-weight:700;color:#fff}
.modal-head .x{background:none;border:0;color:#9b9089;font-size:22px;cursor:pointer;line-height:1;padding:0 4px}
.modal-head .x:hover{color:#fff}
.modal-body{padding:22px}
.modal-foot{padding:16px 22px;border-top:1px solid var(--line-soft);background:var(--panel-2);display:flex;justify-content:flex-end;gap:10px}

/* ── Barcode label ─────────────────────────────────────────── */
/* A label is physically 1.5in × 1in — every size below is in inches so
   the on-screen preview and the printed sticker are identical. */
.label-preview{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:16px 0;background:var(--cream-2);border:1px solid var(--line);
  border-radius:10px;margin-bottom:14px;
}
.label-size{font-size:11px;color:var(--txt-mute)}
/* A batch can be 50 stickers — cap the preview height on screen, never in print */
/* The preview sits in a narrow column-flex card, so auto-fill collapses to a
   single track — pin it to two labels per row instead. */
.label-preview .label-grid{
  grid-template-columns:repeat(2,1.5in);justify-content:center;
  max-height:3.9in;overflow-y:auto;padding:0 10px;
}
.kv{display:flex;justify-content:space-between;gap:16px;padding:9px 0;border-bottom:1px solid var(--line-soft);font-size:13px}
.kv:last-of-type{border-bottom:0}
.kv span{color:var(--txt-dim)}
.kv b{font-weight:700;text-align:right;color:var(--ink)}

/* Sheet of printable labels */
.label-grid{
  display:grid;grid-template-columns:repeat(auto-fill,1.5in);
  gap:10px;justify-content:start;
}
.lbl-card{
  width:1.5in;height:1in;background:#fff;color:#000;box-sizing:border-box;
  padding:.05in .06in;display:flex;flex-direction:column;justify-content:space-between;
  border:1px solid #e3d5c8;border-radius:3px;overflow:hidden;
}
/* Article No · Colour · Size, the three fields that ride above the bars */
.lbl-info{display:flex;align-items:baseline;gap:.05in;line-height:1.1}
.lbl-info .t{font-weight:800;font-size:7.5pt;flex:1;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lbl-info .s{font-size:6.5pt;color:#000;white-space:nowrap}
.lbl-info .s + .s{border-left:1px solid #999;padding-left:.05in}
.lbl-card svg{width:100%;height:.42in;display:block}
.lbl-card .c{font-family:var(--mono);font-size:6.5pt;letter-spacing:1.1px;text-align:center;font-weight:700;line-height:1}
/* ── Scanner ───────────────────────────────────────────────── */
.scan-box{
  display:flex;gap:10px;align-items:center;
  background:var(--cream-2);border:1px dashed var(--copper);border-radius:10px;padding:14px;
}
.scan-box .input{border-style:solid;font-family:var(--mono);letter-spacing:2px;background:#fff}
.toast{
  position:fixed;right:24px;bottom:24px;z-index:200;
  background:var(--ink);color:#fff;border-left:3px solid var(--copper);
  padding:13px 18px;border-radius:9px;box-shadow:0 14px 34px rgba(30,18,8,.35);font-size:13px;
  transform:translateY(20px);opacity:0;pointer-events:none;transition:.22s;
}
.toast.show{transform:none;opacity:1}
.toast.ok{border-left-color:#2ecc71}
.toast.err{border-left-color:#ff6b5e}



/* ── Stock Summary: the size-wise pop-up table ─────────────── */
/* Everything centred, headers and values alike, so the columns read as one
   grid. The treatments below are the ones .rep gave it; the right-aligned
   numbers are the one part deliberately left behind. */
.ss-size-table th,.ss-size-table td{text-align:center}
.ss-size-table thead th{vertical-align:bottom;line-height:1.35}
.ss-size-table tbody td.num{font-weight:600}
.ss-size-table tbody td.z{color:var(--txt-mute);font-weight:400}
/* ── Stock Summary: the colour opens a size-wise breakdown ─── */
/* A plain swatch gives no hint that it does anything, so it gets the
   underline and the cursor of a link while staying a real button. */
.ss-color{
  background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer;
  text-align:left;border-bottom:1px dashed var(--copper);
}
.ss-color:hover .swatch{color:var(--copper)}
.ss-color:focus-visible{outline:2px solid var(--copper);outline-offset:2px}
/* ── Print ─────────────────────────────────────────────────── */
@media print{
  body{background:#fff;background-image:none}
  .sidebar,.topbar,.no-print,.toast,.head-actions{display:none!important}
  /* A modal left open would otherwise land on the paper on top of the report. */
  .modal-back{display:none!important}
  #page-barcode .page-head,#page-barcode .card-head{display:none!important}
  /* On paper the colour is just a colour — nothing to click. */
  .ss-color{border-bottom:0}
  .content{padding:0;margin:0}
  .card{border:0;box-shadow:none;background:#fff;margin:0}
  #page-barcode .card-body{padding:0}
  .label-grid{gap:0}
  .lbl-card{border:1px dotted #bbb;page-break-inside:avoid;border-radius:0;
            width:1.5in;height:1in}
  /* Add Product: "Print Label" emits the sticker only, nothing else.
     Hide by position, not :last-child — the label card is the last child
     of .grid-2 and would disappear with it. */
  #page-product .page-head,
  #page-product > .card,                      /* Recently Generated table */
  #page-product .grid-2 > .card:first-child,  /* the entry form */
  #page-product .card-head,
  #page-product .kv,#page-product .hint,#page-product .btn{display:none!important}
  #page-product .grid-2{display:block;gap:0}
  #page-product .card-body{padding:0}
  .label-preview{border:0;padding:0;margin:0;background:#fff;display:block}
  /* on paper, fill the sheet width instead of the two-up preview layout */
  .label-preview .label-grid{grid-template-columns:repeat(auto-fill,1.5in);
                             max-height:none;overflow:visible;
                             justify-content:start;padding:0;gap:0}
  .label-size{display:none!important}
  /* reports keep their heading and print full-width */
  .page-head{margin-bottom:12px}
  .page-head p{display:none}
  table.rep{font-size:11px}
  table.rep thead th{background:#f2f2f2!important;color:#000}
  table.rep tfoot td{background:#f2f2f2!important}
  table.rep tbody tr{page-break-inside:avoid}
}

/* ── Collapsible nav group ─────────────────────────────────── */
.nav-group{display:flex;flex-direction:column}
.nav-parent{position:relative;padding-right:32px!important}
.nav-parent .caret{
  position:absolute;right:11px;top:50%;margin-top:-8px;
  width:16px;height:16px;transition:transform .25s ease;
}
.nav-group.open .nav-parent{color:#fff;background:var(--ink-2)}
.nav-group.open .nav-parent .caret{transform:rotate(180deg)}

.nav-sub{
  display:flex;flex-direction:column;gap:2px;
  max-height:0;opacity:0;overflow:hidden;
  transition:max-height .28s cubic-bezier(.4,0,.2,1),opacity .2s ease,margin .28s ease;
}
.nav-group.open .nav-sub{max-height:120px;opacity:1;margin-top:3px}

.nav-sub .nav-child{
  padding:9px 12px 9px 40px;font-size:13px;position:relative;border-radius:8px;
  transform:translateY(-6px);transition:transform .28s ease,background .15s,color .15s;
}
.nav-group.open .nav-sub .nav-child{transform:none}
.nav-group.open .nav-sub .nav-child:nth-child(2){transition-delay:.05s}
.nav-sub .nav-child::before{
  content:"";position:absolute;left:23px;top:50%;width:5px;height:5px;
  margin-top:-2.5px;border-radius:50%;background:#6d6259;transition:background .15s;
}
.nav-sub .nav-child:hover::before{background:#c9c0b8}
.nav-sub .nav-child.active::before{background:#fff}
/* ── Report tables ─────────────────────────────────────────── */
table.rep thead th{vertical-align:bottom;line-height:1.35}
table.rep thead th.num{text-align:right}
table.rep tbody td.num{font-weight:600}
table.rep tbody td.z{color:var(--txt-mute);font-weight:400}
table.rep tfoot td{
  padding:13px 16px;background:var(--cream-2);
  border-top:2px solid var(--copper);font-weight:800;color:var(--ink);
  font-family:var(--mono);font-size:13px;
}
table.rep tfoot td.lbl-cell{
  font-family:inherit;letter-spacing:1.2px;text-transform:uppercase;
  font-size:11px;color:var(--txt-dim);font-weight:700;
}
table.rep tfoot td.num{text-align:right}
.grp-strong{color:var(--copper);font-weight:700}

/* Product-type pill (By Date Stock) */
.ptype{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600}
.ptype i{width:13px;height:13px;border-radius:3px;flex:0 0 13px;display:inline-block}
.ptype.stockin i{background:#b4652a}
.ptype.sold   i{background:#1f9d55}
.ptype.damage i{background:#d64541}
.ptype.return i{background:#0578ad}
.ptype-legend{display:flex;gap:18px;flex-wrap:wrap}
/* Colour key in the report card head — sits between the title and the range */
.ptype-key{
  display:flex;gap:16px;flex-wrap:wrap;margin-left:auto;margin-right:auto;
  font-size:11.5px;color:var(--txt-dim);
}
.ptype-key .ptype{gap:5px;font-size:11.5px;font-weight:600;color:var(--txt-dim)}
.ptype-key .ptype i{width:10px;height:10px;flex:0 0 10px;border-radius:2px}

/* ── Customer purchase history ─────────────────────────────── */
.modal-wide{max-width:1500px}
.modal-back:has(.modal-wide){padding:34px 20px}
.modal-wide .modal-body{max-height:72vh;overflow-y:auto}
.row-actions{display:flex;gap:8px;justify-content:flex-end}

.hist-stats{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));margin-bottom:6px}
.hist-stats .stat{padding:12px 14px}
.hist-stats .v{font-size:18px}

.hist-sub{font-size:13px;font-weight:700;color:var(--txt-dim);
  text-transform:uppercase;letter-spacing:.8px;margin:22px 0 10px}

.hist-table{border:1px solid var(--line);border-radius:10px;overflow:hidden}
.hist-table thead th{white-space:nowrap}
.hist-table tfoot td{
  padding:13px 16px;background:var(--cream-2);
  border-top:2px solid var(--copper);font-weight:800;color:var(--ink);
  font-family:var(--mono);font-size:13px;
}
.hist-table tfoot td.lbl-cell{
  font-family:inherit;letter-spacing:1.2px;text-transform:uppercase;
  font-size:11px;color:var(--txt-dim);font-weight:700;
}
.hist-table tfoot td.num{text-align:right}
.hist-table tfoot td.accent{color:var(--copper)}
/* The table scrolls sideways in its own container, so nothing needs to wrap
   — a wrapped date turns one row into four lines of text. */
.hist-table td,.hist-table tfoot td{white-space:nowrap}

/* History table reads as a statement — every column centred */
.hist-table th,.hist-table td,
.hist-table td.num,.hist-table tfoot td,
.hist-table tfoot td.num,.hist-table tfoot td.lbl-cell{text-align:center}
.hist-table .swatch{justify-content:center}

/* ── Login ─────────────────────────────────────────────────── */
/* Hidden by default so a signed-in reload never flashes the form. */
.login-screen{
  position:fixed;inset:0;z-index:300;display:none;
  align-items:center;justify-content:center;padding:24px;
  background:var(--ink);
  background-image:radial-gradient(circle at 20% 20%,rgba(180,90,32,.28),transparent 55%),
                   radial-gradient(circle at 80% 80%,rgba(180,90,32,.16),transparent 55%);
}
.login-screen.show{display:flex}
body.locked .app{display:none}

.login-card{
  width:100%;max-width:400px;background:var(--panel);
  border:1px solid var(--line);border-radius:16px;padding:32px;
  box-shadow:0 30px 70px rgba(0,0,0,.45);
}
.login-brand{display:flex;align-items:center;gap:12px;margin-bottom:26px}
.login-brand .mark{
  width:42px;height:42px;border-radius:11px;background:var(--copper);color:#fff;
  display:grid;place-items:center;font-weight:800;font-size:15px;letter-spacing:.5px;
}
.login-brand h1{font-size:17px;font-weight:800;color:var(--ink);line-height:1.1}
.login-brand small{font-size:10.5px;letter-spacing:1.6px;text-transform:uppercase;color:var(--txt-mute)}
.login-card h2{font-size:21px;font-weight:800;color:var(--ink)}
.login-sub{font-size:13px;color:var(--txt-dim);margin:4px 0 20px}
.login-err{
  min-height:18px;font-size:12.5px;color:#c0392b;font-weight:600;margin-top:4px;
}

/* topbar identity */
.who{font-size:12.5px;color:rgba(255,255,255,.9);font-weight:600;white-space:nowrap}
/* btn-quiet is tuned for the cream page background; on the copper bar its
   muted brown all but disappears, so the logout control gets its own. */
.topbar .btn-quiet{
  color:#fff;background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.3);
}
.topbar .btn-quiet:hover{background:rgba(255,255,255,.26);color:#fff}

/* ── Permission checkbox grid ──────────────────────────────── */
.perm-grid{
  border:1px solid var(--line);border-radius:10px;padding:6px 4px;
  max-height:340px;overflow-y:auto;background:var(--cream-2);
}
.perm-group{
  font-size:10.5px;letter-spacing:1.2px;text-transform:uppercase;font-weight:700;
  color:var(--txt-mute);padding:12px 12px 5px;
}
.perm-row{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  padding:9px 12px;border-radius:8px;font-size:13.5px;color:var(--txt);
}
.perm-row:hover{background:var(--panel-2)}
.perm-row.sub{padding-left:26px}
.perm-row input{width:16px;height:16px;accent-color:var(--copper);cursor:pointer;flex:0 0 16px}
.perm-row input:checked + span{color:var(--ink);font-weight:600}

.access-bar{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:12px;
}
.access-bar .hint{margin:0}

.modal-sm{max-width:420px}

/* Master size list inside the Add Size modal — the same chips the multi-select
   combobox uses, so the list you manage looks like the list you pick from. */
.size-pool{
  display:flex;flex-wrap:wrap;gap:6px;
  padding:10px;border:1px solid var(--line);border-radius:8px;
  background:var(--panel-2);min-height:44px;align-items:center;
}
/* a disabled account should read as switched off at a glance */
.row-off td{opacity:.55}

/* ── Article image ─────────────────────────────────────────── */
/* The picker in the Add Articles modal. A native file input cannot be
   styled, so it is hidden and this stands in for it. */
.image-drop{
  position:relative;display:flex;align-items:center;justify-content:center;
  min-height:118px;padding:10px;cursor:pointer;
  background:var(--panel-2);border:1px dashed var(--line);border-radius:10px;
  transition:border-color .15s,background .15s;
}
.image-drop:hover,.image-drop:focus-visible{
  border-color:var(--copper);background:var(--cream-2);outline:none;
}
.image-drop.dragover{border-color:var(--copper);background:var(--accent-soft)}
.image-drop img{max-height:150px;max-width:100%;border-radius:7px;display:block}
.image-drop-empty{
  display:flex;flex-direction:column;align-items:center;gap:7px;
  color:var(--txt-mute);font-size:12.5px;text-align:center;
}
/* An explicit display beats the hidden attribute, which would otherwise
   leave the placeholder sitting next to the preview it was replaced by. */
.image-drop [hidden]{display:none!important}
.image-drop-empty svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:1.6}
.image-drop-x{
  position:absolute;top:6px;right:6px;width:24px;height:24px;
  display:grid;place-items:center;cursor:pointer;
  background:var(--ink);color:#fff;border:0;border-radius:50%;
  font-size:16px;line-height:1;opacity:.82;
}
.image-drop-x:hover{opacity:1}


/* The article photo that rides at the head of the Add Product field. It is a
   preview, not a control — pointer-events off so clicking it still opens the
   dropdown the way clicking anywhere else in the field does. */
.combo.has-thumb .combo-input{padding-left:46px!important}
.field-thumb{
  position:absolute;left:6px;top:50%;transform:translateY(-50%);z-index:2;
  width:32px;height:32px;border-radius:6px;overflow:hidden;pointer-events:none;
  display:grid;place-items:center;
  background:var(--cream-2);border:1px solid var(--line);color:var(--txt-mute);
}
.field-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.field-thumb svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7}
/* Nothing to show yet — keep it quiet rather than drawing the eye to a gap.
   Not ".empty": that is the app-wide placeholder class and it carries
   44px of padding, which inflated this box to 90px and pushed it over the
   field label. */
.field-thumb.is-empty{opacity:.5}
/* The thumbnail in the Article List. */
.thumb{
  width:46px;height:46px;overflow:hidden;display:grid;place-items:center;
  background:var(--panel-2);border:1px solid var(--line);border-radius:8px;
  color:var(--txt-mute);
}
.thumb img{width:100%;height:100%;object-fit:cover;display:block}
.thumb svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.7}
/* Table rows are tighter than the Article List — same thumb, smaller. */
.thumb-sm{width:34px;height:34px;border-radius:6px}
.thumb-sm svg{width:14px;height:14px}

/* ══ Responsive ════════════════════════════════════════════════
   The desktop layout is a fixed 248px sidebar next to the content. Below
   980px that sidebar becomes an off-canvas drawer instead of eating half a
   phone screen, and the header rearranges to match. Everything above that
   width is left exactly as it was.
   ─────────────────────────────────────────────────────────────── */

/* Hidden on desktop; the drawer handle on smaller screens. */
.hamburger{
  display:none;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.3);
  border-radius:8px;color:#fff;cursor:pointer;
  padding:7px;margin-right:12px;flex:0 0 auto;line-height:0;
}
.hamburger svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2}
.hamburger:hover{background:rgba(255,255,255,.24)}

.nav-scrim{
  position:fixed;inset:0;z-index:40;
  background:rgba(30,18,8,.5);backdrop-filter:blur(2px);
  opacity:0;pointer-events:none;transition:opacity .2s;
}

@media (max-width:980px){
  .hamburger{display:inline-flex}

  /* Out of the flex flow entirely, so .main gets the full width. */
  .sidebar{
    position:fixed;top:0;left:0;bottom:0;
    height:100vh;height:100dvh;   /* dvh keeps the drawer clear of mobile browser chrome */
    z-index:50;width:264px;flex-basis:264px;
    transform:translateX(-100%);
    transition:transform .22s ease;
    overflow-y:auto;
    box-shadow:0 0 40px rgba(0,0,0,.4);
  }
  .app.nav-open .sidebar{transform:none}
  .app.nav-open .nav-scrim{opacity:1;pointer-events:auto}

  .topbar{padding:0 16px;height:56px}
  .topbar .meta{gap:12px}
  .content{padding:20px 16px 48px}

  .page-head h2{font-size:19px}
  /* A search box and an Add button side by side stop fitting here. */
  .head-actions{width:100%;flex-wrap:wrap}
  .head-actions .input{flex:1 1 200px;width:auto!important}

  .modal-back{padding:24px 14px}
  .modal-back:has(.modal-wide){padding:24px 14px}
  .modal-wide .modal-body{max-height:none}
}

/* Phones. The header keeps only navigation, the page name, and the way out. */
@media (max-width:640px){
  .topbar{padding:0 12px;gap:8px}
  /* One line, truncated — two lines would push the bar out of alignment. */
  .topbar .crumb{
    font-size:12px;min-width:0;flex:1 1 auto;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  /* The date and the next-barcode chip are reference, not controls — the
     chip is repeated on the Add Product card, so nothing is lost. The
     signed-in name moves into the drawer, which has room for it. */
  .topbar #todayLbl,.topbar .chip,.topbar .who{display:none}
  .topbar .meta{flex:0 0 auto}

  .content{padding:16px 12px 40px}
  .card-body{padding:16px}
  .card-head{padding:14px 16px;flex-wrap:wrap;gap:8px}

  .stats{grid-template-columns:repeat(2,1fr);gap:10px}
  .stat{padding:13px 14px}
  .stat .v{font-size:19px}

  .page-head{gap:14px;margin-bottom:18px}
  .page-head h2{font-size:18px}
  .page-head p{font-size:12.5px}

  /* Scanner: the Add button drops under the input rather than squashing it. */
  .scan-box{flex-wrap:wrap;padding:12px}
  .scan-box .input{flex:1 1 100%}
  .scan-box .btn{width:100%}

  .modal-back{padding:0}
  .modal,.modal-sm,.modal-wide{
    max-width:none;border-radius:0;border-width:0;
    min-height:100vh;min-height:100dvh;
    /* Column layout pins the footer to the bottom of the screen instead of
       leaving it floating wherever the content happens to end. */
    display:flex;flex-direction:column;
  }
  .modal form{display:flex;flex-direction:column;flex:1}
  .modal-body{flex:1}
  .modal-head{position:sticky;top:0;z-index:2;border-radius:0}
  .modal-foot{flex-wrap:wrap}
  .modal-foot .btn{flex:1 1 auto}

  /* Two 1.5in labels do not fit across a phone; show them one up. */
  .label-preview .label-grid{grid-template-columns:1.5in}

  .ptype-key{display:none}
  .access-bar{gap:10px}
  .row-actions{flex-wrap:wrap}
}

/* Very narrow phones — one stat per row reads better than two cramped ones. */
@media (max-width:380px){
  .stats{grid-template-columns:1fr}
}

/* The drawer is a small-screen affordance; printing must never show it. */
@media print{
  .hamburger,.nav-scrim{display:none!important}
}

/* ── Information Change: the live preview ──────────────────── */
/* A mock browser tab, so the name and icon can be judged at the size they
   will actually be seen rather than as form fields. */
.tab-preview{
  display:flex;align-items:center;gap:9px;max-width:290px;
  background:var(--panel-2);border:1px solid var(--line);
  border-radius:9px 9px 0 0;border-bottom:0;padding:9px 12px;
  box-shadow:0 -1px 0 var(--line) inset;
}
.tab-icon{
  width:17px;height:17px;flex:0 0 17px;display:grid;place-items:center;
  color:var(--txt-mute);overflow:hidden;border-radius:3px;
}
.tab-icon img{width:100%;height:100%;object-fit:contain;display:block}
.tab-icon svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.7}
.tab-title{
  flex:1;min-width:0;font-size:12.5px;color:var(--txt);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.tab-x{color:var(--txt-mute);font-size:15px;line-height:1}

/* The sidebar's own brand block, on the light panel instead of the dark rail. */
.brand-preview{
  display:flex;align-items:center;gap:11px;
  background:var(--ink);border-radius:10px;padding:14px 16px;
}
.brand-preview .mark{
  width:34px;height:34px;border-radius:7px;background:var(--copper);
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:14px;
  letter-spacing:.5px;flex:0 0 34px;
}
.brand-preview h1{font-size:15px;font-weight:800;letter-spacing:.4px;color:#fff;text-transform:uppercase}
.brand-preview small{display:block;color:#8b8177;font-size:10.5px;font-weight:600;letter-spacing:1.1px;text-transform:uppercase}
.brand-preview small:empty{display:none}

/* An icon is small by nature — the article-sized drop zone dwarfs it, and the
   preview is capped so a 512px upload does not fill the card. */
#favImageDrop{min-height:96px}
#favImagePreview{max-height:72px;width:auto;object-fit:contain}

/* ── Confirm dialog ────────────────────────────────────────── */
/* The app's other modals sit near the top of the window because they are
   tall forms. A question is short, so this one is centred — where the eye
   already is when a native confirm would have appeared. */
.modal-centre{align-items:center;padding:20px}
.modal-ask{max-width:420px;text-align:center;animation:ask .16s ease}
@keyframes ask{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}

.ask-body{padding:30px 28px 22px}
.ask-icon{
  width:54px;height:54px;margin:0 auto 16px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--accent-soft);color:var(--copper);
}
.ask-icon.danger{background:rgba(192,57,43,.1);color:var(--danger)}
.ask-icon svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}

.ask-body h3{font-size:17px;font-weight:750;color:var(--ink);line-height:1.35}
.ask-body p{margin-top:9px;font-size:13.2px;color:var(--txt-dim);line-height:1.55}
.ask-body p[hidden]{display:none}

.ask-foot{
  display:flex;gap:10px;padding:0 28px 26px;
}
.ask-foot .btn{flex:1;padding:11px 18px}

/* A solid red confirm, for the asks that destroy something. */
.btn-danger-solid{background:var(--danger);color:#fff;border-color:var(--danger)}
.btn-danger-solid:hover{filter:brightness(1.07)}

/* ── Password reveal ───────────────────────────────────────── */
.pw-field{position:relative}
/* Room for the button, so long passwords never run under it. */
.pw-field .input{padding-right:42px}
.pw-eye{
  position:absolute;right:1px;top:1px;bottom:1px;width:40px;
  display:grid;place-items:center;
  background:none;border:0;cursor:pointer;color:var(--txt-mute);
  border-radius:0 8px 8px 0;transition:color .15s;
}
.pw-eye:hover{color:var(--copper)}
.pw-eye:focus-visible{outline:2px solid var(--copper);outline-offset:-2px;color:var(--copper)}
.pw-eye svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
