/* Seller HQ — THE GLASS COUNTER, desktop.
   The same world the app locked in (DESIGN.md): a dark cabinet, shelves a
   shade lighter, hairlines instead of borders, cream card-stock tickets for
   the figures that matter, and one red voice for whatever is chosen or about
   to move money. Barlow Condensed speaks the titles, JetBrains Mono counts
   the money, the system face does the talking. */
:root{
  --bg:#0B0D10; --panel:#12151A; --raise:#1B2027; --raise-2:#232A33; --line:#232A33;
  --ink:#EDEFF2; --ink-2:#A9B1BC;
  --ink-3:#8B93A0;
  --good:#4CAF6E; --warn:#E8C15A;
  /* brass asks for attention, leaf is money in, the cool blue stays for
     information; every one a role, never decoration */
  --gold:#E8C15A; --gold-soft:rgba(232,193,90,.13);
  --cool:#6BA8E8; --cool-soft:rgba(107,168,232,.12);
  --good-soft:rgba(76,175,110,.13);
  /* cream ticket stock and the ink that sits on it */
  --ticket:#F5EDD8; --tick-ink:#17140E; --tick-mut:rgba(23,20,14,.62);
  /* set by theme.js from the client's brand colour */
  --brand:#C62F1D; --accent:#D8442F; --accent-fill:#C62F1D; --on-accent:#fff;
  --accent-soft:rgba(198,47,29,.16); --accent-line:rgba(198,47,29,.38);
  --r:14px; --r-sm:10px;
  --f:system-ui,-apple-system,'Segoe UI',sans-serif;
  --ftick:'Barlow Condensed',system-ui,sans-serif;
  --fmono:'JetBrains Mono',ui-monospace,monospace;
}
*{box-sizing:border-box}
html,body{height:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--f);font-size:14px;
  -webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums}
img{display:block;max-width:100%}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
h1,h2,h3{margin:0;letter-spacing:-.02em}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:var(--raise-2);border-radius:9px}
::-webkit-scrollbar-track{background:transparent}
[hidden]{display:none !important}

/* The rail collapses to icons to buy width for the goods, but an unlabelled
   icon is a thing you have to learn, so the labels are one click away and the
   choice is remembered. */
/* grid-template-rows matters here: height:100vh sizes the container, but the
   implicit row defaults to auto and grows to fit its contents, so a long bill
   pushed the totals and the pay button past the bottom of the screen instead of
   scrolling inside their own column. minmax(0,1fr) pins the row to the viewport
   and lets the panes scroll internally. */
.app{display:grid;grid-template-columns:var(--rail) 1fr;grid-template-rows:minmax(0,1fr);
  height:100vh;overflow:hidden;--rail:72px}
.app.has-rail{grid-template-columns:var(--rail) 1fr 384px}
.app.rail-open{--rail:216px}

/* ---------- nav rail ---------- */
.rail{background:var(--panel);display:flex;flex-direction:column;gap:4px;padding:14px 10px;z-index:5;
  align-items:stretch;min-width:0;overflow:hidden}
/* Just the logo. No tile, no name, no subtitle: the person looking at this
   knows whose shop it is and what screen they are on, and a red box around
   someone's artwork is a second logo competing with the first.
   Wide marks span the rail, square ones sit at mark size, and the proportions
   are read off the image rather than asked about in a setting. */
.brandrow{display:flex;align-items:center;justify-content:center;margin-bottom:16px;padding:2px 4px;min-width:0}
.mark{display:block;flex:none;max-width:100%;line-height:0;color:var(--accent)}
.mark svg{width:30px;height:30px;fill:currentColor}
.mark img{display:block;width:auto;height:auto;max-width:100%;max-height:44px;object-fit:contain}
.app.rail-open .brandrow{justify-content:flex-start}
.app.rail-open .mark.wide img{width:100%;max-height:40px}
/* No room for a wordmark at 72px, so it shrinks rather than being cut. */
.app:not(.rail-open) .mark img{max-width:52px;max-height:36px}

.rnav{height:44px;border-radius:12px;display:flex;align-items:center;gap:12px;padding:0 11px;
  color:var(--ink-3);flex:none;min-width:0;overflow:hidden}
.rnav svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.7;flex:none}
.rnav .t{font-size:13.5px;font-weight:700;white-space:nowrap}
.rnav:hover{background:var(--raise);color:var(--ink-2)}
.rnav.on{background:var(--accent-soft);color:var(--accent)}
.rail .sp{flex:1}

/* collapsed: centre everything and drop the words */
.app:not(.rail-open) .rnav{justify-content:center;padding:0}
.app:not(.rail-open) .rnav .t,
.app:not(.rail-open) .railtog .t,
.app:not(.rail-open) .me .mt{display:none}
.app:not(.rail-open) .brandrow{justify-content:center}
.app:not(.rail-open) .me{justify-content:center}

.railtog{height:38px;border-radius:10px;display:flex;align-items:center;gap:12px;padding:0 11px;
  color:var(--ink-3);flex:none;margin-top:2px}
.railtog:hover{background:var(--raise);color:var(--ink-2)}
.railtog svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;flex:none;
  transition:transform .18s ease}
.app.rail-open .railtog svg{transform:rotate(180deg)}
.railtog .t{font-size:12.5px;font-weight:700;white-space:nowrap}

.me{display:flex;align-items:center;gap:11px;padding:7px 8px;border-radius:11px;margin-top:6px;min-width:0}
.me:hover{background:var(--raise)}
.me .av{width:32px;height:32px;border-radius:50%;background:var(--raise-2);flex:none;overflow:hidden}
.me .av img{width:100%;height:100%;object-fit:cover}
.me .mt{min-width:0;overflow:hidden}
.me .mt b{display:block;font-size:12.5px;font-weight:700;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
.me .mt span{display:block;color:var(--ink-3);font-size:11px;font-weight:600;white-space:nowrap}

/* ---------- shared page furniture ---------- */
.view{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:hidden}
.phead{display:flex;align-items:center;gap:14px;padding:20px 24px 16px;flex-wrap:wrap}
.phead h1{font-size:21px;font-weight:800}
.phead .sub{color:var(--ink-3);font-size:13px;font-weight:600}
.phead .sp{flex:1}
.scroll{flex:1;overflow-y:auto;padding:0 24px 24px;min-height:0}

.card{background:var(--panel);border-radius:var(--r);padding:18px}
.card > h2{font-size:14px;font-weight:800;margin-bottom:14px}
.muted{color:var(--ink-3);font-size:12.5px;font-weight:600}

.btn{border-radius:var(--r-sm);padding:11px 16px;font-size:13.5px;font-weight:700;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--raise);color:var(--ink-2)}
.btn:hover{background:var(--raise-2);color:var(--ink)}
.btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.8}
.btn.primary{background:var(--accent-fill);color:var(--on-accent)}
.btn.primary:hover{filter:brightness(1.08)}
.btn.big{padding:15px 22px;font-size:15px;border-radius:var(--r)}

.chip{background:var(--panel);color:var(--ink-2);border-radius:999px;padding:8px 15px;font-size:13px;
  font-weight:700;white-space:nowrap;display:inline-flex;gap:7px;align-items:center}
.chip:hover{background:var(--raise)}
.chip.on{background:var(--accent-fill);color:var(--on-accent)}
.chip .n{color:var(--ink-3);font-weight:700;font-size:12px}
.chip.on .n{color:currentColor;opacity:.72}

.field{display:block}
.field > span{display:block;font-size:12px;font-weight:700;color:var(--ink-3);margin-bottom:6px;letter-spacing:.02em}
.field input,.field select,.field textarea{width:100%;background:var(--raise);border:1.5px solid transparent;
  border-radius:var(--r-sm);padding:11px 13px;font-size:14px;font-weight:600}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);outline:none}
.field input::placeholder{color:var(--ink-3);font-weight:500}

/* ---------- dashboard ---------- */
.dash-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:14px}
.dash-grid.c5{grid-template-columns:repeat(5,1fr)}
.dash-grid.c4{grid-template-columns:repeat(4,1fr)}
.dash-grid.c3{grid-template-columns:repeat(3,1fr)}
.stat{background:var(--panel);border-radius:var(--r);padding:16px 18px}
.stat .lbl{color:var(--ink-3);font-size:12px;font-weight:700;margin-bottom:8px}
.stat .val{font-size:26px;font-weight:800;line-height:1;letter-spacing:-.03em}
.stat .delta{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:700;margin-top:8px}
.stat .delta svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2.2}
.delta.up{color:var(--good)} .delta.down{color:var(--accent)} .delta.flat{color:var(--ink-3)}

/* The front door's job is to start a sale, so the till is a destination, not a
   nav item you hunt for. */
.till-cta{grid-column:span 2;background:var(--accent-fill);color:var(--on-accent);border-radius:var(--r);
  padding:20px;display:flex;align-items:center;gap:16px;text-align:left}
.till-cta:hover{filter:brightness(1.08)}
.till-cta .ic{width:46px;height:46px;border-radius:12px;background:rgba(0,0,0,.16);display:grid;place-items:center;flex:none}
.till-cta .ic svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.7}
.till-cta b{display:block;font-size:18px;font-weight:800;letter-spacing:-.02em}
.till-cta span{display:block;font-size:13px;font-weight:600;opacity:.82;margin-top:2px}
.till-cta .go{margin-left:auto;width:28px;height:28px}
.till-cta .go svg{width:28px;height:28px;stroke:currentColor;fill:none;stroke-width:1.8}

.split{display:grid;grid-template-columns:1.5fr 1fr;gap:14px;align-items:start}
.split.three{grid-template-columns:repeat(3,1fr)}
.rows{display:flex;flex-direction:column}
.row{display:grid;grid-template-columns:38px 1fr auto;gap:12px;align-items:center;padding:11px 0;border-top:1px solid var(--line)}
/* A row that carries an action button needs a column for it, or the button
   drops onto a line of its own under the card it belongs to. */
.row:has(> .tool){grid-template-columns:38px 1fr auto auto}
.row:first-child{border-top:0}
.row .th{border-radius:8px;overflow:hidden;background:var(--bg);aspect-ratio:63/88}
.row .th img{width:100%;height:100%;object-fit:cover}
/* These sit inside a plain span wrapper, so they need blockifying by hand;
   the flex children elsewhere get it for free and that inconsistency bit. */
.row .nm{display:block;font-size:13px;font-weight:700;line-height:1.25}
.row .sub{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.row .amt{font-size:14px;font-weight:800;text-align:right;white-space:nowrap}
.row .amt small{display:block;color:var(--ink-3);font-size:11px;font-weight:600}
.pill{border-radius:999px;padding:3px 9px;font-size:11px;font-weight:800;white-space:nowrap}
.pill.low{background:var(--accent-soft);color:var(--accent)}
.pill.ok{background:rgba(63,179,127,.14);color:var(--good)}

/* ---------- till ---------- */
.session{display:flex;align-items:center;gap:9px;background:var(--panel);border-radius:999px;
  padding:7px 8px 7px 14px;color:var(--ink-2);font-size:13px;font-weight:600}
.session b{color:var(--ink);font-weight:700}
.session .dot{width:7px;height:7px;border-radius:50%;background:var(--good)}
.session .end{background:var(--raise);color:var(--ink-2);border-radius:999px;padding:5px 11px;font-size:12px;font-weight:700}
.session .end:hover{background:var(--raise-2);color:var(--ink)}

.scan{position:relative;margin:0 24px 16px}
.scan input{width:100%;background:var(--panel);border:1.5px solid var(--line);border-radius:var(--r);
  padding:15px 16px 15px 50px;font-size:15px;font-weight:600}
.scan input::placeholder{color:var(--ink-3);font-weight:500}
.scan input:focus{border-color:var(--accent);outline:none}
.scan .ico{position:absolute;left:17px;top:50%;transform:translateY(-50%);width:20px;height:20px;
  stroke:var(--ink-3);fill:none;stroke-width:1.8}
.scan .hint{position:absolute;right:14px;top:50%;transform:translateY(-50%);display:flex;gap:6px;
  align-items:center;color:var(--ink-3);font-size:12px;font-weight:600}
.kbd{background:var(--raise);border-radius:6px;padding:3px 7px;font-size:11px;font-weight:700;color:var(--ink-2)}

.filters{display:flex;gap:8px;margin:0 24px 16px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none;flex:none}
.filters::-webkit-scrollbar{display:none}
.gridhead{display:flex;align-items:baseline;gap:10px;margin-bottom:12px}
.gridhead h2{font-size:15px;font-weight:800}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:13px}
.tile{background:var(--panel);border-radius:var(--r);padding:10px;text-align:left;display:flex;flex-direction:column;
  transition:background .14s,transform .14s}
.tile:hover{background:var(--raise);transform:translateY(-2px)}
.tile .ph{position:relative;border-radius:var(--r-sm);overflow:hidden;background:var(--bg);aspect-ratio:63/88;margin-bottom:9px}
.tile .ph img{width:100%;height:100%;object-fit:cover}
.tile .code{position:absolute;left:6px;top:6px;background:rgba(10,11,13,.82);color:var(--ink-2);
  border-radius:6px;padding:2px 6px;font-size:10.5px;font-weight:800;letter-spacing:.04em}
.tile .nm{font-size:13px;font-weight:700;line-height:1.25;margin-bottom:2px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.tile .set{color:var(--ink-3);font-size:11.5px;font-weight:600;margin-bottom:8px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tile .nm,.tile .set{display:block}
.tile .foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:auto}
.tile .pr{font-size:16px;font-weight:800}
.tile .stk{color:var(--ink-3);font-size:11.5px;font-weight:600}
.tile .stk.low{color:var(--accent)}

/* ---------- bill rail ---------- */
.bill{background:var(--panel);display:flex;flex-direction:column;min-width:0;min-height:0}
.bill-top{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:20px 20px 14px}
.bill-top h2{font-size:17px;font-weight:800}
.bill-top .clear{color:var(--ink-3);font-size:12.5px;font-weight:700}
.bill-top .clear:hover{color:var(--accent)}
.seg{display:flex;gap:6px;padding:0 20px 14px}
.seg button{flex:1;background:var(--raise);color:var(--ink-2);border-radius:var(--r-sm);padding:9px;font-size:13px;font-weight:700}
.seg button.on{background:var(--accent-fill);color:var(--on-accent)}
.lines{flex:1;overflow-y:auto;padding:0 20px;min-height:0}
.line{display:grid;grid-template-columns:38px 1fr auto;gap:10px;padding:9px 0;border-top:1px solid var(--line)}
.line:first-child{border-top:0}
.line .th{border-radius:8px;overflow:hidden;background:var(--bg);aspect-ratio:63/88}
.line .th img{width:100%;height:100%;object-fit:cover}
.line .nm{font-size:12.5px;font-weight:700;line-height:1.25}
.line .sub{color:var(--ink-3);font-size:11px;font-weight:600;margin-top:1px}
.line .pr{font-size:14px;font-weight:800;text-align:right;white-space:nowrap}
.line .was{display:block;color:var(--ink-3);font-size:11px;font-weight:600;text-decoration:line-through}
.linerow{display:flex;align-items:center;gap:6px;margin-top:6px;flex-wrap:wrap}
.qty{display:inline-flex;align-items:center;gap:2px;background:var(--raise);border-radius:8px}
.qty button{width:22px;height:22px;display:grid;place-items:center;color:var(--ink-2);border-radius:6px}
.qty button:hover{background:var(--raise-2);color:var(--ink)}
.qty svg{width:12px;height:12px;stroke:currentColor;stroke-width:2.2;fill:none}
.qty b{min-width:18px;text-align:center;font-size:12.5px;font-weight:800}
.line .tools{display:flex;gap:5px;flex-wrap:wrap}
.tool{background:var(--raise);color:var(--ink-3);border-radius:7px;padding:3px 8px;font-size:11.5px;font-weight:700}
.tool:hover{background:var(--raise-2);color:var(--ink)}
.tool.on{background:var(--accent-soft);color:var(--accent)}
.empty{flex:1;display:grid;place-items:center;text-align:center;color:var(--ink-3);padding:30px}
.empty svg{width:38px;height:38px;stroke:currentColor;fill:none;stroke-width:1.4;margin:0 auto 12px}
.empty p{margin:0;font-size:13.5px;font-weight:600;line-height:1.5;max-width:24ch}
/* Pinned below the scrolling list. At a table the total is the number you read
   out loud, so it never scrolls away. */
.sums{flex:none;padding:12px 20px 0;border-top:1px solid var(--line);background:var(--panel)}
.sum{display:flex;justify-content:space-between;align-items:baseline;padding:4px 0;color:var(--ink-2);font-size:13px;font-weight:600}
.sum.tot{color:var(--ink);font-size:20px;font-weight:800;padding-top:9px;margin-top:5px;border-top:1px solid var(--line)}
.sum .off{color:var(--accent);font-weight:700}
.pay{flex:none;display:flex;gap:8px;padding:12px 20px}
.pay button{flex:1;background:var(--raise);color:var(--ink-2);border-radius:var(--r-sm);padding:11px;
  font-size:13px;font-weight:700;display:flex;align-items:center;justify-content:center;gap:7px}
.pay button svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7}
.pay button.on{background:var(--raise-2);color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--accent)}
.take{flex:none;margin:0 20px 18px;background:var(--accent-fill);color:var(--on-accent);border-radius:var(--r);padding:16px;
  font-size:15px;font-weight:800;display:flex;align-items:center;justify-content:center;gap:9px}
.take:hover{filter:brightness(1.08)}
.take:disabled{background:var(--raise);color:var(--ink-3);cursor:default;filter:none}

/* ---------- settings ---------- */
/* ---------------- settings, as a settings page ----------------
   One grammar for the whole surface: every setting is a row with its name and
   its meaning on the left and its control on the right, rows divided by
   hairlines inside one card per group, the group named once above the card.
   Editors that need the whole width (the ladder, the logo drop, the discount
   composer) use the same row with the control beneath the words, so nothing
   is ever a paragraph with widgets dumped after it. */
.set-wrap{display:grid;grid-template-columns:216px minmax(0,780px);gap:28px;align-items:start}
.set-nav{display:flex;flex-direction:column;gap:2px;position:sticky;top:12px}
.set-nav button{text-align:left;border-radius:var(--r-sm);padding:10px 13px;font-size:13.5px;font-weight:700;color:var(--ink-3);
  display:flex;align-items:center;gap:10px}
.set-nav button svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8;flex:none}
.set-nav button:hover{background:var(--panel);color:var(--ink-2)}
.set-nav button.on{background:var(--accent-soft);color:var(--accent)}
.set-panel{display:flex;flex-direction:column;gap:30px;min-width:0}

.sec-head{padding:0 2px}
.sec-head h2{font-size:16px;font-weight:800;letter-spacing:.01em}
.sec-head p{color:var(--ink-3);font-size:12.5px;font-weight:600;line-height:1.55;margin-top:3px;max-width:68ch}
.sec-card{background:var(--panel);border-radius:var(--r);padding:2px 20px;margin-top:12px}
.sec-card + .sec-card{margin-top:14px}

.setrow{display:grid;grid-template-columns:minmax(190px,290px) minmax(0,1fr);gap:8px 28px;
  padding:16px 0;border-top:1px solid var(--line);align-items:center}
.sec-card > .setrow:first-child,.sec-card > :first-child .setrow:first-child{border-top:0}
.sr-info b{display:block;font-size:13.5px;font-weight:700}
.sr-info span{display:block;color:var(--ink-3);font-size:12px;font-weight:600;line-height:1.55;margin-top:2px;max-width:44ch}
.sr-ctl{display:flex;justify-content:flex-end;align-items:center;gap:10px;flex-wrap:wrap;min-width:0}
.sr-ctl .field{flex:1 1 220px;max-width:340px}
.sr-ctl > .btn{flex:none}
/* The control needs the room: it drops below the words and takes the width. */
.setrow.wide{grid-template-columns:minmax(0,1fr)}
.setrow.wide .sr-ctl{display:block}
.setrow.wide .sr-info{margin-bottom:12px}
.setrow .msg{flex-basis:100%;margin:0}
/* Field pairs and the discount composer share one responsive mini-grid. */
.two{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}
.composer{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;align-items:end}
.composer .btn{height:40px}

/* brand controls */
.swatches{display:flex;gap:9px;flex-wrap:wrap;margin-bottom:14px}
.sw{width:38px;height:38px;border-radius:11px;position:relative;box-shadow:inset 0 0 0 1px rgba(255,255,255,.08)}
.sw.on{box-shadow:inset 0 0 0 1px rgba(255,255,255,.08),0 0 0 2px var(--panel),0 0 0 4px var(--accent)}
.hexrow{display:flex;gap:10px;align-items:flex-end}
.hexrow .field{flex:1}
.colorbox{width:46px;height:44px;border-radius:var(--r-sm);overflow:hidden;flex:none;background:var(--raise);position:relative}
.colorbox input{position:absolute;inset:-6px;width:calc(100% + 12px);height:calc(100% + 12px);border:0;padding:0;background:none;cursor:pointer}

.drop{border:1.5px dashed var(--line);border-radius:var(--r);padding:20px;text-align:center;color:var(--ink-3);
  display:flex;flex-direction:column;align-items:center;gap:10px}
.drop.has{border-style:solid;border-color:var(--accent-line)}
.drop svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:1.6}
.drop b{color:var(--ink-2);font-size:13px;font-weight:700}
.drop .logo-prev{width:64px;height:64px;border-radius:14px;background:var(--raise);overflow:hidden;display:grid;place-items:center}
.drop .logo-prev img{width:100%;height:100%;object-fit:contain}

/* the preview proves the derived colours before they are committed */
.preview{background:var(--bg);border-radius:var(--r);padding:16px;display:flex;flex-direction:column;gap:12px}
.preview .pv-top{display:flex;align-items:center;gap:11px}
.preview .pv-mark{width:36px;height:36px;border-radius:10px;background:var(--accent-fill);color:var(--on-accent);
  display:grid;place-items:center;overflow:hidden;flex:none}
.preview .pv-mark svg{width:19px;height:19px;fill:currentColor}
.preview .pv-mark img{width:100%;height:100%;object-fit:contain}
.preview .pv-name{font-size:14px;font-weight:800}
.ratios{display:flex;gap:8px;flex-wrap:wrap}
.ratio{background:var(--raise);border-radius:8px;padding:7px 10px;font-size:11.5px;font-weight:700;color:var(--ink-2);
  display:flex;align-items:center;gap:6px}
.ratio b{color:var(--ink);font-weight:800}
.ratio .ok{color:var(--good)}
.ratio .no{color:var(--warn)}

/* modules: what a client sees at all */
.mods{display:flex;flex-direction:column}
.mod{display:flex;align-items:center;gap:13px;padding:15px 0;border-top:1px solid var(--line)}
.mod:first-child{border-top:0}
.mod .mi{width:34px;height:34px;border-radius:9px;background:var(--raise);display:grid;place-items:center;color:var(--ink-2);flex:none}
.mod .mi svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8}
.mod .mt{flex:1;min-width:0}
.mod .mt b{display:block;font-size:13.5px;font-weight:700}
.mod .mt span{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:1px}
.tog{width:42px;height:24px;border-radius:999px;background:var(--raise-2);position:relative;flex:none;transition:background .16s}
.tog::after{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:var(--ink-3);transition:transform .16s,background .16s}
.tog.on{background:var(--accent-fill)}
.tog.on::after{transform:translateX(18px);background:var(--on-accent)}
.mod.locked .tog{opacity:.4;cursor:not-allowed}

@media(max-width:1200px){ .dash-grid{grid-template-columns:repeat(2,1fr)} .till-cta{grid-column:span 2} .split{grid-template-columns:1fr} .split.three{grid-template-columns:1fr} }
@media(max-width:1080px){
  .set-wrap{grid-template-columns:minmax(0,1fr);gap:14px}
  .set-nav{position:static;flex-direction:row;overflow-x:auto;gap:4px;padding-bottom:6px;scrollbar-width:none}
  .set-nav::-webkit-scrollbar{display:none}
  .set-nav button{white-space:nowrap;flex:none}
}
@media(max-width:640px){
  .setrow{grid-template-columns:minmax(0,1fr);gap:10px}
  .sr-ctl{justify-content:flex-start}
  .sr-ctl .field{max-width:none}
  .sr-info span{max-width:none}
}
@media(prefers-reduced-motion:reduce){*{transition:none !important;animation:none !important}}

/* ---------- consignment ---------- */
/* Stock taken in to sell for someone else. It is marked everywhere it appears,
   because at a table you need to know whose card you are discounting before you
   discount it. */
.owned{display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:3px 8px;
  font-size:10.5px;font-weight:800;background:rgba(224,168,60,.15);color:var(--warn);white-space:nowrap}
.owned svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2}
.tile .ph .owned{position:absolute;right:6px;top:6px}
.line .owned{margin-top:6px}

/* a real checkbox, not the browser's */
/* It is a <button>, which centres its text by default. */
.check{display:flex;align-items:flex-start;gap:11px;cursor:pointer;padding:13px;border-radius:var(--r-sm);
  background:var(--raise);transition:background .14s;text-align:left;width:100%}
.check:hover{background:var(--raise-2)}
.check.on{background:var(--accent-soft)}
.check .box{width:20px;height:20px;border-radius:6px;background:var(--bg);box-shadow:inset 0 0 0 1.5px var(--line);
  display:grid;place-items:center;flex:none;margin-top:1px;transition:background .14s,box-shadow .14s}
.check.on .box{background:var(--accent-fill);box-shadow:none}
.check .box svg{width:12px;height:12px;stroke:var(--on-accent);fill:none;stroke-width:3;opacity:0;transition:opacity .12s}
.check.on .box svg{opacity:1}
.check .lbl b{display:block;font-size:13.5px;font-weight:700}
.check .lbl span{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:2px;line-height:1.45}
.check.on .lbl b{color:var(--accent)}

.reveal{display:grid;grid-template-columns:1fr 150px;gap:12px;margin-top:12px}
.split-note{grid-column:1/-1;background:var(--bg);border-radius:var(--r-sm);padding:11px 13px;
  font-size:12.5px;font-weight:600;color:var(--ink-2);line-height:1.5}
.split-note b{color:var(--ink);font-weight:800}

/* inventory */
.inv-wrap{display:grid;grid-template-columns:360px 1fr;gap:18px;align-items:start}
/* the reworked inventory: intake and pricing side by side, the stock grid
   full width beneath them where the eye can sweep whole shelves at once */
.inv-top{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;align-items:start;margin-bottom:18px}
.inv-q{background:var(--raise);border:1px solid var(--line);border-radius:8px;padding:8px 12px;
  font-size:13px;color:var(--ink);width:230px;margin-left:14px}
.inv-q::placeholder{color:var(--ink-3)}
.sel{background:var(--raise);border:0;border-radius:var(--r-sm);padding:8px 11px;font-size:13px;
  font-weight:700;color:var(--ink);margin-left:10px}
.inv-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(185px,1fr));gap:12px}
.inv-tile{position:relative;background:var(--raise);border-radius:var(--r);padding:10px;
  display:flex;flex-direction:column;gap:5px;border:1px solid transparent}
.inv-tile.picked{border-color:var(--accent)}
.inv-tile .pick{position:absolute;top:16px;left:16px;z-index:2}
.inv-tile .ith{aspect-ratio:63/88;background:var(--raise-2);border-radius:8px;overflow:hidden;
  display:flex;align-items:center;justify-content:center}
.inv-tile .ith img{width:100%;height:100%;object-fit:contain}
.inv-tile .nm{font-size:13px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden;min-height:2.6em}
.inv-tile .sub{font-size:11.5px;color:var(--ink-2)}
.inv-tile .owned{align-self:flex-start}
.inv-tile .ifoot{display:flex;align-items:flex-end;justify-content:space-between;gap:8px;margin-top:auto}
.inv-tile .amt{font-size:14px;font-weight:800;white-space:nowrap}
.inv-tile .pick{background:var(--card,#171a20);box-shadow:inset 0 0 0 1.5px var(--edge)}

.inv-row{display:grid;grid-template-columns:18px 38px 1fr auto auto auto;gap:12px;align-items:center;
  padding:11px 0;border-top:1px solid var(--line)}
.inv-row:first-child{border-top:0}
.inv-row .th{border-radius:8px;overflow:hidden;background:var(--bg);aspect-ratio:63/88}
.inv-row .th img{width:100%;height:100%;object-fit:cover}
.inv-row .nm{display:block;font-size:13px;font-weight:700;line-height:1.25}
.inv-row .sub{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.inv-row .amt{font-size:14px;font-weight:800;text-align:right;white-space:nowrap}

/* books */
.books-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.owed{background:rgba(224,168,60,.12);border-radius:var(--r);padding:14px 18px;display:flex;
  align-items:center;gap:14px;margin-bottom:14px}
.owed .ic{width:38px;height:38px;border-radius:10px;background:rgba(224,168,60,.18);color:var(--warn);
  display:grid;place-items:center;flex:none}
.owed .ic svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:1.8}
.owed b{display:block;font-size:19px;font-weight:800;color:var(--warn)}
.owed span{display:block;color:var(--ink-2);font-size:12.5px;font-weight:600;margin-top:1px}
.owed .who{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.owed .who span{background:var(--raise);border-radius:999px;padding:5px 11px;font-size:12px;font-weight:700;color:var(--ink-2);margin:0}

/* ---------- users ---------- */
.user-row{display:grid;grid-template-columns:38px 1fr auto auto;gap:13px;align-items:center;
  padding:13px 0;border-top:1px solid var(--line)}
.user-row:first-child{border-top:0}
.user-row .av{width:38px;height:38px;border-radius:50%;background:var(--raise-2);display:grid;place-items:center;
  font-size:14px;font-weight:800;color:var(--ink-2)}
.user-row .un{display:block;font-size:13.5px;font-weight:700}
.user-row .ue{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:1px}
.role{border-radius:999px;padding:4px 11px;font-size:11.5px;font-weight:800;background:var(--raise);color:var(--ink-2)}
.role.owner{background:var(--accent-soft);color:var(--accent)}
.role.off{opacity:.5;text-decoration:line-through}
.rowbtn{width:30px;height:30px;border-radius:8px;display:grid;place-items:center;color:var(--ink-3)}
.rowbtn:hover{background:var(--raise-2);color:var(--ink)}
.rowbtn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9}
.caplist{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:12px}
/* One row per person, ticked if they may read this mailbox. A checkbox is the
   honest control here: access is on or off, and there is no third state. */
.cap{display:flex;align-items:center;gap:10px;background:var(--raise);
  border-radius:var(--r-sm);padding:9px 12px;cursor:pointer}
.cap:hover{background:var(--raise-2)}
.cap input{accent-color:var(--accent);width:15px;height:15px;flex:none}
.cap > span{font-size:13px;font-weight:700;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cap small{display:block;font-size:11px;font-weight:600;color:var(--ink-3);margin-top:1px;text-transform:capitalize}
/* Trading shows both lists at once, so each needs saying which side it is.
   Two full-size empty states stacked reads as a broken screen, so while trading
   they shrink to a line of text under their own heading. */
.side{padding:12px 20px 2px;font-size:11px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.bill.trading .lines{min-height:0}
.bill.trading .empty{padding:6px 20px 10px;min-height:0}
.bill.trading .empty svg{display:none}
.bill.trading .empty p{font-size:12.5px;margin:0}

/* Bundling sits with the total because that is the number it changes. */
.bundle{display:flex;align-items:center;gap:9px;padding:10px 20px 0}
.bundle label{font-size:12.5px;font-weight:700;color:var(--ink-2);white-space:nowrap}
.bundle input{flex:1;min-width:0;background:var(--raise);border:1.5px solid transparent;
  border-radius:var(--r-sm);padding:9px 12px;font-size:14px;font-weight:700}
.bundle input:focus{border-color:var(--accent);outline:none}
.bundle input::placeholder{color:var(--ink-3);font-weight:500}
/* Want lists: one row per person, with whatever in stock answers them
   sitting underneath it rather than in a column of its own. */
.wantrow{padding:12px 0;border-top:1px solid var(--line)}
.wantrow:first-child{border-top:0}
.wantrow.done{opacity:.5}
.wanthead{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.wanthead .nm{font-size:14px;font-weight:800}
.wanthead .sub{color:var(--ink-3);font-size:12px;font-weight:600;margin-top:3px}
.wanthead .acts{display:flex;gap:6px;flex:none}
.wanthit{display:flex;align-items:center;gap:10px;background:var(--raise);
  border-radius:var(--r-sm);padding:8px 10px;margin-top:8px}
.wanthit img,.wanthit .ph{width:26px;border-radius:5px;aspect-ratio:63/88;object-fit:cover;
  background:var(--raise-2);flex:none}
.wanthit .wn{display:block;font-size:12.5px;font-weight:700}
.wanthit .ws{display:block;font-size:11.5px;font-weight:600;color:var(--ink-3)}
.wanthit > span:nth-child(2){flex:1;min-width:0}
.wanthit b{color:var(--good);font-size:13.5px;font-weight:800}
.capitem{display:flex;align-items:center;gap:8px;background:var(--bg);border-radius:8px;padding:8px 10px;
  font-size:12px;font-weight:600;color:var(--ink-2)}
.capitem svg{width:13px;height:13px;stroke:var(--good);fill:none;stroke-width:2.6;flex:none}
.capitem.no{color:var(--ink-3);opacity:.55}
.capitem.no svg{stroke:var(--ink-3)}
.msg{border-radius:var(--r-sm);padding:10px 13px;font-size:12.5px;font-weight:600;margin-top:10px}
.msg.err{background:rgba(232,85,47,.14);color:var(--accent)}
.msg.ok{background:rgba(63,179,127,.14);color:var(--good)}

/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:26px;transform:translate(-50%,14px);z-index:90;
  background:var(--raise-2);color:var(--ink);border-radius:var(--r-sm);padding:12px 20px;
  font-size:13.5px;font-weight:700;box-shadow:0 10px 30px rgba(0,0,0,.4);
  opacity:0;pointer-events:none;transition:opacity .18s,transform .18s}
.toast.show{opacity:1;transform:translate(-50%,0)}
.toast.bad{background:var(--accent-fill);color:var(--on-accent)}

/* stock that cannot be sold reads as unavailable rather than merely saying so */
.tile.out{opacity:.42}
.tile.out:hover{transform:none;background:var(--panel)}

/* ---------- first-run setup ---------- */
.setup-bar{display:flex;align-items:center;gap:14px;padding:12px 20px;background:var(--accent-soft);
  border-bottom:1px solid var(--accent-line)}
.setup-bar .sb-ic{width:34px;height:34px;border-radius:9px;background:var(--accent-fill);color:var(--on-accent);
  display:grid;place-items:center;flex:none}
.setup-bar .sb-ic svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8}
.setup-bar .sb-t{flex:1;min-width:0}
.setup-bar .sb-t b{display:block;font-size:13.5px;font-weight:800;color:var(--ink)}
.setup-bar .sb-t span{display:block;font-size:12.5px;font-weight:600;color:var(--ink-2);margin-top:1px}
body:has(.setup-bar:not([hidden])) .app{height:calc(100vh - 60px)}

.setup-modal{position:fixed;inset:0;z-index:100;background:rgba(8,9,11,.72);display:grid;place-items:center;padding:24px}
.setup-box{width:min(420px,100%);background:var(--panel);border-radius:18px;padding:26px}
.setup-box h2{font-size:20px;font-weight:800;margin-bottom:4px}
.setup-box .hint{color:var(--ink-3);font-size:12.5px;font-weight:600;line-height:1.5;margin-bottom:18px}
.setup-box .field{margin-bottom:12px}
.setup-acts{display:flex;gap:9px;margin-top:16px}
.setup-acts .btn{flex:1}

/* ---------- account menu ---------- */
.me-wrap{position:relative;margin-top:6px}
.me .av{display:grid;place-items:center;font-size:12px;font-weight:800;color:var(--ink-2)}
.me-menu{position:absolute;bottom:calc(100% + 8px);left:0;right:0;min-width:190px;z-index:30;
  background:var(--raise);border-radius:12px;padding:6px;box-shadow:0 14px 34px rgba(0,0,0,.5)}
.app:not(.rail-open) .me-menu{left:0;right:auto;width:196px}
.me-who{padding:9px 10px 10px;border-bottom:1px solid var(--line);margin-bottom:5px}
.me-who b{display:block;font-size:13px;font-weight:800}
.me-who span{display:block;font-size:11.5px;font-weight:600;color:var(--ink-3);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis}
.me-item{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border-radius:8px;
  padding:9px 10px;font-size:13px;font-weight:700;color:var(--ink-2)}
.me-item:hover{background:var(--raise-2);color:var(--ink)}
.me-item svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.8;flex:none}

/* ---------- buy desk ---------- */
.buy-wrap{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:18px;align-items:start}
@media(max-width:1100px){ .buy-wrap{grid-template-columns:1fr} .offer{position:static} }
.bres{display:flex;flex-direction:column;gap:8px;margin-bottom:14px}
.bres:empty{display:none}
.bcand{display:grid;grid-template-columns:34px 1fr auto;gap:11px;align-items:center;background:var(--panel);
  border-radius:var(--r-sm);padding:9px 11px;text-align:left;width:100%}
.bcand:hover{background:var(--raise)}
.bcand img{width:34px;border-radius:5px;background:var(--bg)}
.bcand .cn{display:block;font-size:13px;font-weight:700;line-height:1.2}
.bcand .cs{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:1px}
.bcand .cnum{font-size:11.5px;font-weight:800;color:var(--ink-3);white-space:nowrap}

/* the offer panel: the two numbers you say out loud */
.offer{background:var(--panel);border-radius:var(--r);padding:18px;position:sticky;top:0}
.offer h2{font-size:14px;font-weight:800;margin-bottom:12px}
.offer-row{display:flex;justify-content:space-between;align-items:baseline;padding:6px 0;
  color:var(--ink-2);font-size:13.5px;font-weight:600}
.offer-row b{color:var(--ink);font-size:16px;font-weight:800}
.rates{display:grid;grid-template-columns:1fr 1fr;gap:9px;margin:12px 0}
.rate{display:block;background:var(--raise);border-radius:var(--r-sm);padding:9px 11px}
/* One short word, never broken across lines however tight the column gets. */
.rate > span:first-child{display:block;font-size:11.5px;font-weight:700;color:var(--ink-3);
  margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rate-in{display:flex;align-items:baseline;gap:2px;font-size:17px;font-weight:800}
.rate-in input{width:2.6em;background:transparent;border:0;padding:0;font:inherit;color:var(--ink)}
.rate-in input:focus{outline:none;color:var(--accent)}
.offer-big{display:flex;flex-direction:column;gap:9px;margin-top:6px}
.ob{background:var(--raise);border-radius:var(--r-sm);padding:12px 13px}
.ob span{display:block;font-size:12px;font-weight:700;color:var(--ink-3)}
.ob b{display:block;font-size:26px;font-weight:800;letter-spacing:-.02em;margin-top:2px}
.ob.credit{background:var(--accent-soft)}
.ob.credit b{color:var(--accent)}
.offer-acts{display:flex;gap:9px;margin-top:14px}
.offer-acts .btn{flex:1}

/* ---------- credit ---------- */
.crsearch{background:var(--raise);border:0;border-radius:var(--r-sm);padding:9px 12px;font-size:13px;
  font-weight:600;width:190px}
.crsearch:focus{outline:1.5px solid var(--accent)}
.crow{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;padding:11px 0;
  border-top:1px solid var(--line)}
.crow:first-child{border-top:0}
.crcode{display:block;font-size:13.5px;font-weight:800;letter-spacing:.06em}
.crmeta{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.crbal{font-size:16px;font-weight:800;white-space:nowrap}
.crbal.spent{color:var(--ink-3)}
.crkind{border-radius:999px;padding:3px 9px;font-size:10.5px;font-weight:800;background:var(--raise);color:var(--ink-2)}
.crkind.buyin{background:var(--accent-soft);color:var(--accent)}
.crcheck{background:var(--raise);border-radius:var(--r-sm);padding:14px;margin-top:12px;text-align:center}
.crcheck .b{font-size:30px;font-weight:800;letter-spacing:-.02em}
.crcheck .c{font-size:12.5px;font-weight:700;color:var(--ink-3);letter-spacing:.06em;margin-top:2px}
.crcheck.bad{color:var(--accent)}
.qrwrap{display:flex;gap:14px;align-items:center;margin-top:12px}
.qrwrap canvas,.qrwrap img{background:#fff;border-radius:8px;padding:7px;width:110px;height:110px}
.qrwrap .qt{flex:1;min-width:0}
.qrwrap .qt b{display:block;font-size:15px;font-weight:800;letter-spacing:.06em}
.qrwrap .qt span{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:3px;line-height:1.4}

/* credit on the till */
.credit-apply{padding:0 20px 4px}
.credit-apply .gc-row{margin-top:8px}
.credit-line{color:var(--accent) !important}
.bcand .cnum{font-size:13px;font-weight:800;color:var(--ink)}
.bcand.noprice{opacity:.55}
.bcand.noprice .cnum{font-size:11px;font-weight:700;color:var(--ink-3)}

/* ---------- books ---------- */
.seg.tabs{padding:0}
/* A shop makes one address per service, so this strip grows without limit.
   It scrolls sideways rather than wrapping into a block that pushes the
   mail itself off the screen. Order stays put: tabs that reshuffle
   themselves as mail arrives are tabs you cannot learn. */
#mail-boxes{flex-wrap:nowrap;overflow-x:auto;max-width:min(52vw,620px);
  scrollbar-width:thin;padding-bottom:2px}
#mail-boxes button{white-space:nowrap;flex:none}
.seg.tabs button{padding:8px 15px;font-size:13px;white-space:nowrap}
.tinbox{background:var(--raise);border-radius:var(--r-sm);padding:16px;text-align:center;margin-bottom:12px}
.tinbig{font-size:38px;font-weight:800;letter-spacing:-.03em;line-height:1}
.tinrows{display:flex;flex-direction:column}
.tinrow{display:flex;justify-content:space-between;align-items:baseline;padding:9px 0;
  border-top:1px solid var(--line);font-size:13.5px;font-weight:600;color:var(--ink-2)}
.tinrow:first-child{border-top:0}
.tinrow b{color:var(--ink);font-weight:800;font-size:14.5px}
.tinrow.neg b{color:var(--accent)}
.exprow{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;
  padding:11px 0;border-top:1px solid var(--line)}
.exprow:first-child{border-top:0}
.exprow .ed{display:block;font-size:13.5px;font-weight:700}
.exprow .em{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.exprow .ea{font-size:15px;font-weight:800;white-space:nowrap}
.rcpt{display:inline-flex;align-items:center;gap:5px;border-radius:999px;padding:3px 9px;
  font-size:10.5px;font-weight:800;background:var(--raise);color:var(--ink-2);text-decoration:none}
.rcpt:hover{background:var(--raise-2);color:var(--ink)}
.rcpt svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2}
.rcpt.none{opacity:.45}

/* ---------- sumup handoff ---------- */
.smp{position:fixed;inset:0;z-index:110;background:rgba(8,9,11,.82);display:grid;place-items:center;padding:24px}
.smp-box{width:min(400px,100%);background:var(--panel);border-radius:18px;padding:26px;text-align:center}
.smp-box .amt{font-size:40px;font-weight:800;letter-spacing:-.03em;margin:6px 0 2px}
.smp-box .sub{color:var(--ink-3);font-size:13px;font-weight:600;line-height:1.5;margin-bottom:18px}
.smp-acts{display:flex;flex-direction:column;gap:9px}
.gc-apply.scanbtn{padding:9px 11px;display:grid;place-items:center}
.gc-apply.scanbtn svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.9}
.cashout{background:var(--raise);border-radius:var(--r-sm);padding:13px;margin-top:12px}
.cashout .co-line{display:flex;justify-content:space-between;align-items:baseline;padding:4px 0;
  font-size:13px;font-weight:600;color:var(--ink-2)}
.cashout .co-line b{color:var(--ink);font-weight:800}
.cashout .co-pay{font-size:24px;font-weight:800;color:var(--accent)}

/* labels live inside Inventory rather than on a page of their own */
.inv-bar{display:flex;align-items:center;gap:10px;background:var(--accent-soft);border-radius:var(--r-sm);
  padding:10px 13px;margin-bottom:12px}
.inv-bar b{font-size:13.5px;font-weight:800;color:var(--accent)}
.inv-bar .sp{flex:1}
.inv-row .pick,.inv-tile .pick{width:22px;height:22px;border-radius:5px;background:var(--bg);box-shadow:inset 0 0 0 1.5px var(--line);
  display:grid;place-items:center;cursor:pointer;flex:none}
.inv-row .pick.on,.inv-tile .pick.on{background:var(--accent-fill);box-shadow:none}
.inv-row .pick svg,.inv-tile .pick svg{width:12px;height:12px;stroke:var(--on-accent);fill:none;stroke-width:3;opacity:0}
.inv-row .pick.on svg,.inv-tile .pick.on svg{opacity:1}
.lab-sheet{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;max-height:52vh;overflow:auto;margin:14px 0}
.lab-sheet img{width:100%;background:#fff;border-radius:6px;padding:5px}

/* ---------- inline code entry ---------- */
/* These class names came over from the old dashboard's markup but never had
   rules here, so the field and its buttons were stacking as loose inline blocks.
   Three controls share one line: the field takes whatever the buttons leave. */
.gc-row{display:flex;gap:8px;margin-bottom:9px;flex-wrap:nowrap;align-items:stretch}
.gc-row input{flex:1 1 auto;min-width:0;background:var(--raise);border:1.5px solid transparent;
  border-radius:var(--r-sm);padding:10px 12px;font-size:14px;font-weight:600}
.gc-row input:focus{border-color:var(--accent);outline:none}
.gc-row input::placeholder{color:var(--ink-3);font-weight:500}
.gc-apply{flex:0 0 auto;white-space:nowrap;background:var(--raise);color:var(--ink-2);
  border-radius:var(--r-sm);padding:10px 14px;font-size:13px;font-weight:700}
.gc-apply:hover{background:var(--raise-2);color:var(--ink)}
.picked-card{display:flex;align-items:center;gap:11px;background:var(--raise);border-radius:var(--r-sm);padding:9px 11px}
.picked-card img{width:36px;border-radius:5px;background:var(--bg)}
.picked-card .pc-t{flex:1;min-width:0}
.picked-card .pc-t b{display:block;font-size:13px;font-weight:700;line-height:1.2}
.picked-card .pc-t span{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:1px}
.costrow{display:grid;grid-template-columns:1fr 110px 32px;gap:8px;margin-bottom:8px}
.costrow input{background:var(--raise);border:1.5px solid transparent;border-radius:var(--r-sm);
  padding:10px 12px;font-size:13.5px;font-weight:600;min-width:0}
.costrow input:focus{border-color:var(--accent);outline:none}
.costrow button{color:var(--ink-3);border-radius:8px}
.costrow button:hover{background:var(--raise-2);color:var(--ink)}
.session .end{background:var(--raise);color:var(--ink-2);border-radius:999px;padding:5px 11px;font-size:12px;font-weight:700}
.session.none{color:var(--ink-2)}
.session .startbtn{background:var(--accent-fill);color:var(--on-accent);border-radius:999px;
  padding:6px 14px;font-size:12.5px;font-weight:800}
.se-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px}
.se-cell{background:var(--raise);border-radius:var(--r-sm);padding:11px 13px}
.se-cell span{display:block;font-size:11.5px;font-weight:700;color:var(--ink-3)}
.se-cell b{display:block;font-size:19px;font-weight:800;margin-top:2px}
.se-cell.wide{grid-column:1/-1}
.planrow{display:grid;grid-template-columns:1fr auto auto;gap:10px;align-items:center;padding:11px 0;border-top:1px solid var(--line)}
.planrow:first-child{border-top:0}
.planrow .pn{display:block;font-size:13.5px;font-weight:700}
.planrow .pd{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.planpick{display:block;width:100%;text-align:left;background:var(--raise);border-radius:var(--r-sm);padding:12px 14px;margin-bottom:8px}
.planpick:hover{background:var(--raise-2)}
.planpick b{display:block;font-size:14px;font-weight:800}
.planpick span{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:2px}

/* ---------- orders ---------- */
.tabn{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;margin-left:6px;
  border-radius:999px;background:var(--accent-fill);color:var(--on-accent);font-size:11px;font-weight:800}
.tabn:empty{display:none}
.seg.tabs button.on .tabn{background:rgba(0,0,0,.22)}
.orow{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:start;padding:13px 0;border-top:1px solid var(--line)}
.orow:first-child{border-top:0}
.orow .ot{display:block;font-size:13.5px;font-weight:700}
.orow .os{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px;line-height:1.5}
.orow .oa{font-size:15px;font-weight:800;white-space:nowrap;text-align:right}
.orow .acts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.ostat{border-radius:999px;padding:3px 9px;font-size:10.5px;font-weight:800;white-space:nowrap}
.ostat.new{background:var(--accent-soft);color:var(--accent)}
.ostat.done{background:rgba(63,179,127,.14);color:var(--good)}
.ostat.off{background:var(--raise);color:var(--ink-3)}
.oitems{margin-top:6px;padding-left:12px;border-left:2px solid var(--line)}
.oitems div{color:var(--ink-2);font-size:12px;font-weight:600;padding:1px 0}

/* ---------------- mail ----------------
   Two panes, the same shape as the till: what is waiting on the left, the thing
   you are dealing with on the right. Nothing here scrolls the page; each pane
   scrolls inside itself, so the mailbox switch never leaves the screen. */
.mailwrap{flex:1;display:grid;grid-template-columns:200px 330px minmax(0,1fr);gap:0;
  min-height:0;border-top:1px solid var(--line)}
/* The address column wears the chrome, like the rail it is. */
.mailboxes{background:var(--chrome);border-right:1px solid var(--edge);
  overflow-y:auto;min-height:0;padding:14px 10px;display:flex;flex-direction:column;gap:2px}
.mwrite{width:100%;justify-content:center;margin-bottom:12px}
.mbx{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  padding:8px 10px;border-radius:var(--r-sm);background:transparent;color:var(--ink-2);
  font-size:13px;font-weight:700}
.mbx:hover{background:var(--raise);color:var(--ink)}
.mbx.on{background:var(--accent-soft);color:var(--accent)}
.mbx .mbx-n{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mbx .tabn{margin-left:0}
.mbx-closed{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.mnewbox{margin-top:auto}
.maillist{overflow-y:auto;padding:14px 16px;border-right:1px solid var(--line);min-height:0}
.mailread{overflow-y:auto;padding:0 0 18px;min-height:0;display:flex;flex-direction:column}

.mthread{display:grid;grid-template-columns:34px minmax(0,1fr);gap:10px;align-items:start;
  width:100%;text-align:left;padding:11px 12px;border-radius:var(--r-sm);
  margin-bottom:4px;background:transparent}
.mav{width:34px;height:34px;border-radius:50%;background:var(--raise-2);color:var(--ink-2);
  display:inline-flex;align-items:center;justify-content:center;
  font-size:14px;font-weight:800;flex:none}
.mthread .trest{min-width:0;display:block}
.mthread .clip{width:12px;height:12px;stroke:var(--ink-3);fill:none;stroke-width:2;
  margin-left:6px;vertical-align:-1px}
.mthread:hover{background:var(--panel)}
.mthread.on{background:var(--panel)}
.mthread .top{display:flex;justify-content:space-between;gap:8px;align-items:baseline}
.mthread .who{font-size:13px;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mthread .when{font-size:11px;font-weight:700;color:var(--ink-3);flex:none}
.mthread .subj{display:block;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mthread .prev{display:block;font-size:12px;font-weight:500;color:var(--ink-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Which address a search hit arrived at. Only shown while searching across
   mailboxes, where a list of results with no idea where anything lives is
   worse than no search at all. */
.mthread .inbox{display:inline-block;margin-top:4px;background:var(--raise);color:var(--ink-2);
  border-radius:999px;padding:2px 8px;font-size:10.5px;font-weight:800}
.mthread.unread .who,.mthread.unread .subj{color:var(--ink)}
.mthread.unread .who::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--accent);margin-right:7px;vertical-align:middle}
.mthread .n{font-size:11px;font-weight:800;color:var(--ink-3);margin-left:6px}

.msg-head{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
  padding:16px 22px 14px;border-bottom:1px solid var(--line);margin-bottom:16px;
  position:sticky;top:0;background:var(--bg);z-index:2}
.msg-head h2{font-size:18px;font-weight:800;line-height:1.3}
.msg-head .to{color:var(--ink-3);font-size:12.5px;font-weight:600;margin-top:4px}
.mmsg{margin:0 22px 10px;background:var(--panel);border:1px solid var(--edge);
  border-top-color:var(--edge-top);border-radius:var(--r);padding:14px 16px;box-shadow:var(--shadow-1)}
.mmsg .from{display:flex;gap:12px;align-items:center;margin-bottom:8px}
.mmsg .from .fwrap{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.mmsg .from .mav{width:30px;height:30px;font-size:13px}
/* Folded history: one line, a hand cursor, and everything back on a click. */
.mmsg.folded{cursor:pointer;padding:10px 16px}
.mmsg.folded .mopen{display:none}
.mmsg.folded .from{margin-bottom:0}
.mmsg.folded:hover{background:var(--raise)}
.fold-prev{font-size:12px;font-weight:500;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:52ch}
.mmsg .from b{font-size:13.5px;font-weight:800}
.mmsg .from .addr{color:var(--ink-3);font-size:12px;font-weight:600}
.mmsg .from .when{color:var(--ink-3);font-size:11.5px;font-weight:700;flex:none}
.mmsg.out{background:var(--raise);}
.mmsg.out .mav{background:var(--accent-soft);color:var(--accent)}
.mbody{font-size:14px;line-height:1.62;white-space:pre-wrap;color:var(--ink-2);word-break:break-word}
/* A link in somebody else's message. Underlined because in a wall of plain
   text a colour change alone is easy to miss. */
.mbody a{color:var(--accent);text-decoration:underline;text-underline-offset:2px}
.mbody a:hover{color:var(--ink)}
/* Somebody else's HTML is never rendered into this page. It goes in a frame with
   no scripts and no access to the shop's origin, and only when asked for. */
.mframe{width:100%;border:0;border-radius:var(--r-sm);background:#fff;margin-top:10px;
  resize:vertical;overflow:auto}
.matt i{font-style:normal;font-weight:600;color:var(--ink-3);font-size:11.5px}
.matt{display:inline-flex;align-items:center;gap:7px;background:var(--raise);
  border-radius:var(--r-sm);padding:7px 11px;margin:8px 8px 0 0;font-size:12.5px;font-weight:700;
  color:var(--ink-2);text-decoration:none}
.matt:hover{background:var(--raise-2);color:var(--ink)}
.mauth{font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  border-radius:999px;padding:3px 9px;margin-left:8px}
.mauth.pass{background:rgba(63,179,127,.14);color:var(--good)}
.mauth.fail{background:var(--accent-soft);color:var(--accent)}
.mreply{margin:8px 22px 0;background:var(--panel);border:1px solid var(--edge);
  border-top-color:var(--edge-top);border-radius:var(--r);padding:14px 16px;box-shadow:var(--shadow-1)}
.mreply textarea{width:100%;min-height:120px;resize:vertical;background:var(--raise);
  border:1.5px solid transparent;border-radius:var(--r-sm);padding:12px 14px;
  font-size:14px;line-height:1.6;font-family:inherit}
.mreply textarea:focus{border-color:var(--accent);outline:none}
.mreply .row{display:flex;gap:9px;align-items:center;margin-top:10px;border:0;padding:0}
.railn{background:var(--accent-fill);color:var(--on-accent);border-radius:999px;
  min-width:18px;height:18px;padding:0 5px;font-size:10.5px;font-weight:800;
  display:inline-flex;align-items:center;justify-content:center;margin-left:auto}
/* Narrow screens: the list and the reading pane become two states of one
   column, with a way back, instead of the reading pane simply not existing. */
@media(max-width:1000px){
  .mailwrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  .mailboxes{flex-direction:row;align-items:center;overflow-x:auto;overflow-y:hidden;
    border-right:0;border-bottom:1px solid var(--edge);padding:10px 12px;gap:6px}
  .mailboxes #mail-boxes{display:contents}
  .mwrite{width:auto;margin-bottom:0;flex:none}
  .mbx{width:auto;flex:none}
  .mnewbox{margin-top:0;flex:none}
  .mailread{display:none}
  .mailwrap.reading .mailread{display:flex}
  .mailwrap.reading .maillist{display:none}
  .mailwrap.reading .mailboxes{display:none}
}

/* ---------------- mailbox rows ----------------
   One row per mailbox, closed by default. Drawing every mailbox open repeated
   the whole staff list down the page and buried the addresses in among it. */
.mbrow{position:relative;border-top:1px solid var(--line)}
.mbrow:first-child{border-top:0}
.mbhead{display:flex;align-items:center;gap:11px;width:100%;text-align:left;
  padding:13px 92px 13px 0;background:transparent}
.mbhead:hover .addr{color:var(--accent)}
.mbhead:disabled{cursor:default;opacity:.65}
.mbhead .chev{width:14px;height:14px;flex:none;stroke:var(--ink-3);fill:none;stroke-width:2.4;
  transition:transform .15s ease}
.mbrow.open .mbhead .chev{transform:rotate(90deg);stroke:var(--accent)}
.mbrow.closed .mbhead .chev{visibility:hidden}
.mbwho{flex:1;min-width:0}
.mbwho .addr{display:block;font-size:14px;font-weight:800}
.mbwho .sub{display:block;font-size:12px;font-weight:600;color:var(--ink-3);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mbhead .n{flex:none;background:var(--raise);color:var(--ink-2);border-radius:999px;
  min-width:22px;padding:2px 8px;font-size:11.5px;font-weight:800;text-align:center}
/* Sits over the row rather than inside the button, so closing a mailbox is not
   also a click on the thing that expands it. */
.mbtog{position:absolute;right:0;top:11px}
.mbdel{position:absolute;right:72px;top:11px;color:var(--accent)}
/* A closed row carries two buttons, so its label keeps clear of both. */
.mbrow:has(.mbdel) .mbhead{padding-right:150px}
.mbdel:hover{background:rgba(224,90,60,.14)}
.mbrow .caplist{margin:0 0 14px;padding-left:25px}

/* ---------------- mail settings ----------------
   One panel. The page is a list of addresses and who reads each, so the list is
   the page and everything else is a header. */
.mailadmin{padding:18px 20px 8px}
.ma-head{display:flex;align-items:flex-start;gap:14px;margin-bottom:16px}
.ma-head h2{margin-bottom:2px}
.ma-head .hint{margin:0;font-size:12.5px}
.ma-head .sp{flex:1}

/* Whether mail can arrive at all, as a light rather than a paragraph. */
.intake{display:inline-flex;align-items:center;gap:8px;background:var(--raise);
  border-radius:999px;padding:7px 13px;font-size:12px;font-weight:700;color:var(--ink-2);flex:none}
.intake .dot{width:7px;height:7px;border-radius:50%;background:var(--ink-3);flex:none}
.intake.on .dot{background:var(--good);box-shadow:0 0 0 3px rgba(63,179,127,.16)}
.intake.off .dot{background:var(--warn);box-shadow:0 0 0 3px rgba(224,168,60,.16)}
.intake:hover{background:var(--raise-2);color:var(--ink)}

/* Typing the part before the @ while the whole address forms in front of you.
   The domain lives here because this is the only place it means anything. */
.ma-new{display:flex;gap:9px;align-items:stretch;margin-bottom:4px}
.addrfield{display:flex;align-items:stretch;background:var(--raise);border:1.5px solid transparent;
  border-radius:var(--r-sm);overflow:hidden;flex:1;max-width:420px}
.addrfield:focus-within{border-color:var(--accent)}
.addrfield input{flex:1;width:auto;min-width:0;background:transparent;border:0;outline:none;
  padding:11px 0 11px 13px;font-size:14px;font-weight:700;text-align:right}
.addrfield input::placeholder{color:var(--ink-3);font-weight:500}
.addrfield input#mail-domain{text-align:left;padding:11px 13px 11px 2px;color:var(--ink-2)}
.addrfield .suffix{padding:11px 13px 11px 0;font-size:14px;font-weight:700;color:var(--ink-3);
  white-space:nowrap;background:transparent}
.addrfield .suffix:hover{color:var(--accent)}

/* One row per mailbox; see .mbrow above for why they are closed by default. */
.mbrow .facts{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:3px}
.mbrow .facts .f{font-size:11.5px;font-weight:600;color:var(--ink-3)}
.mbrow .facts .f b{color:var(--ink-2);font-weight:800}
/* Initials rather than a comma list once a mailbox is shared widely: at three
   or more, names wrap the row and stop being scannable. */
.who-chips{display:inline-flex;gap:-4px;align-items:center}
.who-chip{width:20px;height:20px;border-radius:50%;background:var(--raise-2);color:var(--ink-2);
  font-size:9.5px;font-weight:800;display:inline-flex;align-items:center;justify-content:center;
  margin-right:-6px;border:2px solid var(--panel)}
.who-chip:last-child{margin-right:4px}

/* The list's own controls: what to show, and in which order. */
.mailbar{display:flex;align-items:center;gap:8px;margin:10px 0 12px}
.mailbar .seg.tabs{flex:1;min-width:0;overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
.mailbar .seg.tabs::-webkit-scrollbar{display:none}
.mailbar .seg.tabs button{padding:6px 11px;font-size:12px;white-space:nowrap;flex:none}
.mailbar #mail-sort{flex:none}
/* Actions on the conversation you are reading, kept beside its subject rather
   than hovering over the list: you act on a thing after opening it. */
.msg-head .acts{display:flex;gap:7px;flex:none}
.mmsg.filed{opacity:.55}

/* ---------------- pricing ----------------
   Four numbers set every price in the shop, so the panel shows its working. */
.pricegrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,240px));gap:14px;margin-bottom:16px}
/* A number with its unit attached, so nobody has to guess whether to type the
   percent sign. The old panel was a plain text box holding "60% of market". */
/* `.field > span` in the shared form styles is display:block and outranks a
   bare class, so this is scoped to beat it rather than losing to it silently. */
.numfield,.field > .numfield{display:flex;align-items:stretch;background:var(--raise);
  border:1.5px solid transparent;border-radius:var(--r-sm);overflow:hidden;
  font-size:inherit;font-weight:inherit;color:inherit;letter-spacing:normal;margin:0}
.numfield:focus-within{border-color:var(--accent)}
.numfield input{flex:1;width:auto;min-width:0;background:transparent;border:0;outline:none;
  padding:11px 4px 11px 13px;font-size:14px;font-weight:700}
.numfield i{display:flex;align-items:center;padding:0 13px 0 0;font-style:normal;
  font-size:13px;font-weight:700;color:var(--ink-3);white-space:nowrap}
.numfield i.pre{padding:0 0 0 13px}

/* The same sum the labels and the till do, run on a real number as you type. */
.worked{background:var(--bg);border-radius:var(--r-sm);padding:13px 15px;margin-bottom:6px}
.worked .line{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font-size:13px;
  font-weight:600;color:var(--ink-3)}
.worked .line b{color:var(--ink);font-weight:800}
.worked .line .eq{color:var(--accent);font-weight:800;font-size:15px}
.worked .note{margin-top:6px;font-size:12px;font-weight:600;color:var(--ink-3)}

.subhead{font-size:13px;font-weight:800;margin:18px 0 3px;color:var(--ink)}
.set-sec .subhead + .hint{margin-bottom:12px}

/* The rounding ladder as the ladder it is, rather than one step pretending to
   cover both a £4 card and a £40 one. */
.ladder{display:flex;flex-direction:column;gap:7px}
.lrow{display:grid;grid-template-columns:1fr 92px;gap:10px;align-items:center;
  background:var(--raise);border-radius:var(--r-sm);padding:9px 12px}
.lrow span{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.lrow .numfield{background:var(--bg)}
.lrow .numfield input{padding:7px 4px 7px 10px;font-size:13px}
.lrow .numfield i{padding-right:10px;font-size:12px}

.conds{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:9px}
.cond{background:var(--raise);border-radius:var(--r-sm);padding:10px 12px}
.cond .nm{display:block;font-size:12.5px;font-weight:800;margin-bottom:6px}
.cond .numfield{background:var(--bg)}
.cond .numfield input{padding:7px 4px 7px 10px;font-size:13px}
.cond .numfield i{padding-right:10px;font-size:12px}

/* ---------------- dashboard uplift ----------------
   The takings tile is the one number a shop looks at first, so it earns a
   trend and a week of shape rather than sitting as a bare figure. Hierarchy
   comes from weight and a sparkline, not from a border. */
.stat.hero{grid-row:span 1}
.stat .statrow{display:flex;align-items:center;justify-content:space-between;gap:8px}
.stat .statrow .lbl{white-space:nowrap}
.stat .spark{width:100%;height:40px;margin:8px 0 2px;overflow:visible}
.stat .spark path.line{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.stat .spark path.area{fill:var(--accent-soft);stroke:none}
.stat .spark circle{fill:var(--accent)}
/* The day-on-day move, as a coloured pill. Up is good for takings, so up is the
   accent-positive colour and down is muted rather than alarming: a quiet day is
   not an error. */
.trend{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-weight:800;
  padding:2px 7px;border-radius:999px;white-space:nowrap}
.trend.up{background:rgba(63,179,127,.15);color:var(--good)}
.trend.down{background:var(--raise);color:var(--ink-3)}
.trend svg{width:10px;height:10px;stroke:currentColor;fill:none;stroke-width:2.6}
/* An actionable stat looks pressable and, when it has something waiting, pulls
   the eye with the accent rather than sitting the same as a reference number. */
.stat.action{cursor:pointer;text-align:left;border:1.5px solid transparent;transition:border-color .12s,background .12s}
.stat.action:hover{background:var(--raise)}
.stat.action.live{border-color:var(--gold-soft)}
.stat.action.live .val{color:var(--gold)}
.stat.action.live:hover{border-color:var(--gold)}

/* Chips for files about to be sent with a message. */
.filechips{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
.filechip{display:inline-flex;align-items:center;gap:6px;background:var(--raise);
  border-radius:999px;padding:5px 11px;font-size:12px;font-weight:700;color:var(--ink-2)}
.filechip .x{cursor:pointer;color:var(--ink-3);font-size:14px;line-height:1}
.filechip .x:hover{color:var(--accent)}

/* Who is writing to you: one dense line under the subject, facts separated by
   the shop's own record, shown only when the sender is actually known. */
.person{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  background:var(--raise);border-radius:var(--r-sm);padding:9px 13px;margin:0 22px 14px}
.person .pwho{font-size:12.5px;font-weight:800;color:var(--ink)}
.person .pf{font-size:12px;font-weight:600;color:var(--ink-3)}
.person .pf b{color:var(--ink-2);font-weight:800}
.person .have{background:rgba(63,179,127,.14);color:var(--good);border-radius:999px;
  padding:1px 8px;font-size:10.5px;font-weight:800;margin-left:4px}

/* ---------------- label console ----------------
   Printing stock is part of handling stock, so it happens over the Inventory
   list rather than on a page of its own. The dialog is wider than the others
   because a label sheet is the content, not a confirmation. */
.labbox{width:min(860px,100%);text-align:left;max-height:88vh;display:flex;flex-direction:column}
.lab-bar{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin:12px 0 4px}
.labf{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:700;color:var(--ink-3)}
.labf .numfield{background:var(--raise)}
.labf .numfield input{width:56px;padding:8px 2px 8px 10px;font-size:13px;text-align:right}
.labf .numfield i{padding-right:9px;font-size:11.5px}
.labf .x{color:var(--ink-3);font-size:12px}
.labf select{background:var(--raise);border:1.5px solid transparent;border-radius:var(--r-sm);
  padding:8px 10px;font-size:13px;font-weight:700;color:inherit}
.labf select:focus{border-color:var(--accent);outline:none}
.warn{background:rgba(224,168,60,.14);color:var(--warn);border-radius:var(--r-sm);
  padding:11px 13px;font-size:12.5px;font-weight:600;line-height:1.5;margin-top:12px}

/* Each label is pickable, because reprinting three cards should not mean
   reprinting forty. State sits on the tile so a failure is visible where the
   thing that failed is. */
.lab-sheet{flex:1;min-height:0}
.labcard{position:relative;background:var(--raise);border-radius:8px;padding:6px;
  border:2px solid transparent;cursor:pointer}
.labcard.on{border-color:var(--accent)}
.labcard img{width:100%;background:#fff;border-radius:4px;display:block}
.labcard .nm{display:block;font-size:11px;font-weight:700;color:var(--ink-2);margin-top:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.labcard .st{position:absolute;top:9px;right:9px;border-radius:999px;padding:2px 8px;
  font-size:10px;font-weight:800;background:var(--raise-2);color:var(--ink-2)}
.labcard .st.printing{background:var(--accent-soft);color:var(--accent)}
.labcard .st.printed{background:rgba(63,179,127,.16);color:var(--good)}
.labcard .st.failed{background:var(--accent-soft);color:var(--accent)}
.labcard.off{opacity:.4}
.lab-log{font:11.5px/1.6 ui-monospace,Menlo,monospace;color:var(--ink-3);background:var(--bg);
  border-radius:var(--r-sm);padding:10px 12px;max-height:110px;overflow:auto;white-space:pre-wrap;margin-top:10px}

/* ---------------- the palette ----------------
   cmd-K. Fixed near the top rather than centred, because it is aimed at, not
   read: the eye goes to where the last one was. */
.cmdk{position:fixed;inset:0;z-index:160;background:rgba(8,9,11,.7);
  display:flex;justify-content:center;align-items:flex-start;padding:12vh 20px 20px}
.cmdk-box{width:min(560px,100%);background:var(--panel);border:1px solid var(--raise-2);
  border-radius:var(--r);overflow:hidden;box-shadow:0 18px 60px -18px rgba(0,0,0,.65)}
.cmdk-box input{width:100%;background:transparent;border:0;outline:none;
  padding:16px 18px;font-size:15px;font-weight:600;border-bottom:1px solid var(--line)}
.cmdk-box input::placeholder{color:var(--ink-3);font-weight:500}
.cmdk-list{max-height:min(46vh,380px);overflow-y:auto;padding:7px}
.cmdk-item{display:flex;align-items:baseline;gap:11px;padding:10px 12px;
  border-radius:var(--r-sm);cursor:pointer}
.cmdk-item.on{background:var(--raise)}
.cmdk-item .k{flex:none;width:36px;font-size:10px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3)}
.cmdk-item.on .k{color:var(--accent)}
.cmdk-item .l{font-size:13.5px;font-weight:700;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.cmdk-item .s{margin-left:auto;font-size:12px;font-weight:600;color:var(--ink-3);flex:none}
.cmdk-empty{padding:18px 12px;font-size:13px;font-weight:600;color:var(--ink-3)}
.cmdk-foot{display:flex;gap:16px;padding:9px 16px;border-top:1px solid var(--line);
  font-size:11px;font-weight:700;color:var(--ink-3)}

/* ---------------- the chart ----------------
   uPlot draws on canvas; only its chrome needs telling about the theme. */
.chartcard .legend{display:inline-flex;align-items:center;gap:6px;
  font-size:11.5px;font-weight:700;color:var(--ink-3);margin-right:10px}
.chartcard .sw{width:14px;height:3px;border-radius:2px;display:inline-block}
.chartcard .sw.cashline{background:var(--good)}
.chartcard .sw.cardline{background:var(--accent);margin-left:10px}
.u-tooltip,.uplot .u-legend{font-family:var(--f)}
.uplot .u-cursor-pt{border-radius:50%}

/* ---------------- motion ----------------
   One authored moment: a view arrives with a 4px rise over 160ms, which says
   "you moved" and nothing else. Buttons press down 1px so a tap answers the
   finger. Everything else stays still, per the design notes: this is a tool in
   use at a table, not a launch film. */
.view:not([hidden])>.scroll,.view:not([hidden])>.phead{animation:viewin .16s cubic-bezier(.2,.8,.3,1)}
@keyframes viewin{from{opacity:.4;transform:translateY(4px)}to{opacity:1;transform:none}}
.btn:active,.tool:active,.seg button:active,.rnav:active,.chip:active{transform:translateY(1px)}
.btn,.tool,.seg button,.chip{transition:background .12s,color .12s,transform .06s}

/* Skeletons for lists that arrive over the network, so a slow answer reads as
   loading rather than empty. */
.skel-rows{display:flex;flex-direction:column;gap:9px;padding:4px 0}
.skel-row{height:38px;border-radius:var(--r-sm);background:
  linear-gradient(100deg,var(--raise) 40%,var(--raise-2) 50%,var(--raise) 60%);
  background-size:200% 100%;animation:skel 1.1s linear infinite}
@keyframes skel{to{background-position:-200% 0}}
@media(prefers-reduced-motion:reduce){.skel-row{animation:none}}

/* ---------------- elevation ----------------
   The palette felt finished and the rest of the app did not, and the reason
   was one line: the palette had an edge and a shadow, everything else was a
   flat fill told apart only by lightness. This block is the missing third
   dimension, defined once and worn by every surface, so "sleek" is a property
   of the system rather than of whichever panel got attention last.

   Three levels, nothing else:
     resting  — cards, stats, panels: hairline edge, lit top, ambient shadow
     chrome   — the rail: darker than the stage, so content sits in the light
     floating — dialogs and the palette: same edge, deep soft shadow */
:root{
  --edge:rgba(255,255,255,.055);
  --edge-top:rgba(255,255,255,.09);
  --chrome:#101215;
  --shadow-1:0 1px 2px rgba(0,0,0,.28), 0 6px 18px -12px rgba(0,0,0,.5);
  --shadow-2:0 2px 6px rgba(0,0,0,.35), 0 24px 70px -24px rgba(0,0,0,.7);
}
.card,.stat,.set-sec{
  border:1px solid var(--edge);
  border-top-color:var(--edge-top);
  box-shadow:var(--shadow-1);
}
/* Dialogs float. The palette already did this; now it is the rule, not the
   exception. */
.smp-box,.cmdk-box{
  border:1px solid var(--edge);
  border-top-color:var(--edge-top);
  box-shadow:var(--shadow-2);
}
/* The rail is chrome, not content: darker than the stage with a hairline
   seam, so the working area reads as the lit surface. */
.rail{background:var(--chrome);border-right:1px solid var(--edge)}
.bill{border-left:1px solid var(--edge)}
/* A breath of the brand at the top of the stage. Derived from the accent, so
   a whitelabelled shop is tinted its own colour, at a strength you feel
   rather than see. */
.app{position:relative}
.app::before{content:"";position:absolute;inset:0 0 auto 0;height:340px;pointer-events:none;
  background:radial-gradient(600px 340px at 50% -80px, var(--accent-soft), transparent 70%);
  opacity:.5;z-index:0}
.rail,.view,.bill{position:relative;z-index:1}

/* Segmented switches become one machined control: an inset track with the
   active option raised out of it, instead of loose buttons in a row. */
.seg{background:var(--chrome);padding:3px;border-radius:12px;gap:2px;
  border:1px solid var(--edge)}
.seg button{border-radius:9px}
.seg button.on{box-shadow:0 1px 2px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.08)}
.seg.tabs{padding:3px}

/* The primary action carries a lit top edge, the way a physical key does. */
.btn.primary{box-shadow:inset 0 1px 0 rgba(255,255,255,.14), var(--shadow-1)}
.btn:not(.primary){border:1px solid var(--edge)}
.take{box-shadow:inset 0 1px 0 rgba(255,255,255,.14), var(--shadow-1)}

/* One hover for every list row in the app, so moving the pointer down a list
   feels like one surface answering, not five components disagreeing. */
.row:hover,.orow:hover,.line:hover,.tinrow:hover,.wantrow:hover,.mbrow .mbhead:hover,
.planrow:hover{background:rgba(255,255,255,.025)}
.row,.orow,.line,.tinrow,.wantrow,.planrow{border-radius:8px;margin:0 -8px;padding-left:8px;padding-right:8px;
  transition:background .1s}

/* ---------------- the front door, at conviction ----------------
   Every number on the dashboard was 26px, so the one the business runs on had
   the same voice as "lines in stock". Bolder here is not more effects, it is
   hierarchy the system already owns turned up in exactly two places and
   nowhere else: the greeting is the landing moment, and Taken today is the
   peak. Everything around them stays quiet on purpose, because if every
   element gets louder the page gets flatter. */
#v-dash .phead h1{font-size:32px;letter-spacing:-.03em}
#v-dash .phead .sub{font-size:14px;margin-top:2px}
#v-dash .stat.hero .val{font-size:44px;letter-spacing:-.04em;font-variant-numeric:tabular-nums}
#v-dash .stat.hero .spark{height:54px;margin-top:12px}
#v-dash .stat.hero{padding:20px 20px 16px}


/* ---------------- colour as meaning, on the front door ----------------
   Five tiles carried five different kinds of number in the same white: an
   asset, a liability, a job to do, and two counts, distinguishable only by
   reading their labels. The number now wears its meaning. Every coloured
   value still sits under its text label, so colour is never the only code. */
#v-dash .stat.hero .val{color:var(--good)}
#v-dash .stat.hero .spark .line{stroke:var(--good)}
#v-dash .stat.hero .spark .area{fill:var(--good-soft)}
#v-dash .stat.hero .spark circle{fill:var(--good)}
#v-dash .stat[data-role="asset"] .val{color:var(--cool)}
#v-dash .stat[data-role="liability"] .val{color:var(--gold)}
/* "Needs a price" is a job, not a danger: it was borrowing the action red,
   which belongs to the till. Gold is the brand's own attention colour, and it
   keys off .live so a cleared queue goes back to quiet — those rules sit with
   the tile itself, further up. */
/* Money arriving in the recent list reads as money. */
#v-dash #recent .amt{color:var(--good)}
#v-dash #recent .amt small{color:var(--ink-3)}
/* A quiet day stays quiet: a zero is a fact, not a highlight, so tiles drop
   their role colour while the number is nothing. renderDash sets .nil. */
#v-dash .stat.nil .val{color:var(--ink)}


/* ---------------- void and refund ---------------- */
/* A refund row reads as what it is: money going the other way. The amount
   already carries the minus; the tag says why. */
.row.refund .amt,.orow.refund .amt{color:var(--ink-2)}
.rf-tag{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  color:var(--gold);background:var(--gold-soft);border-radius:5px;padding:1px 6px;margin-left:6px;vertical-align:1px}
.rf-done{font-size:11.5px;color:var(--ink-3);font-weight:600;white-space:nowrap}

/* The dialog borrows the SumUp handoff's shell: same overlay, same card,
   because taking money back should feel like taking money, reversed. */
.rf-box{text-align:left}
.rf-box h2{font-size:17px;font-weight:800;margin-bottom:2px}
.rf-box .rf-what{color:var(--ink-2);font-size:13px;font-weight:600;margin-bottom:14px}
.rf-box .rf-amt{font-size:34px;font-weight:800;letter-spacing:-.03em;margin:2px 0 12px}
.rf-qty{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.rf-qty .qty{display:inline-flex}
.rf-note{background:var(--raise);border-radius:10px;padding:10px 12px;font-size:12.5px;line-height:1.55;
  color:var(--ink-2);font-weight:600;margin-bottom:16px}
.rf-note b{color:var(--ink)}
.rf-row{display:flex;gap:10px;justify-content:flex-end}

/* Undo lives inside the toast for a few seconds after a sale. */
.toast .undo{margin-left:12px;background:rgba(255,255,255,.14);border-radius:7px;padding:3px 10px;
  font-size:12px;font-weight:800;color:inherit}
.toast .undo:hover{background:rgba(255,255,255,.22)}

/* Text for screen readers only: the unread dot's meaning, said out loud. */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* Inline price and note editing on a bill line, replacing browser prompts:
   a numeric keypad on the phone, the app's own field on the desk. */
.line .editrow{margin-top:6px}
.line .editrow .numfield input{width:86px}
.line .editrow input[type="text"]{width:100%;background:var(--raise);border:1px solid var(--line);
  border-radius:8px;padding:5px 9px;font-size:12.5px;color:var(--ink)}


/* The bill's quantity is a button that types. The steppers stay for one-tap
   nudges; tapping the number itself takes a typed amount. */
.qty .qtynum{background:none;font-weight:800;font-size:13px;color:var(--ink);
  padding:2px 6px;border-radius:6px;min-width:24px}
.qty .qtynum:hover{background:var(--raise-2)}
.qty .qtyin{width:44px;background:var(--raise);border:1px solid var(--line);border-radius:6px;
  padding:3px 6px;font-size:13px;font-weight:800;color:var(--ink);text-align:center}


/* ---------------- bulk reprice + the to-do plate ---------------- */
.drift-pick{width:18px;height:18px;border-radius:5px;background:var(--bg);
  box-shadow:inset 0 0 0 1.5px var(--line);display:grid;place-items:center;flex:none;cursor:pointer}
.drift-pick.on{background:var(--accent-fill);box-shadow:none}
.drift-pick svg{width:11px;height:11px;stroke:var(--on-accent);fill:none;stroke-width:3;opacity:0}
.drift-pick.on svg{opacity:1}
/* Five things live in a drift row: the tick, the picture, the card, the price
   and the way to say no. The grid only ever declared four columns, so the last
   one wrapped onto a line of its own and read as an empty box. */
.row:has(> .drift-pick){grid-template-columns:auto 38px minmax(0,1fr) auto auto}
.drift-off{white-space:nowrap}
.rows .sub.sum{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:10.5px;opacity:.7}
.rows .row .drift-off{align-self:center;justify-self:end;width:auto;flex:none}
/* A new price under the cost floor is a loss somebody must choose, never a
   side effect of "accept all". */
.drift-tag{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.04em;
  text-transform:uppercase;color:var(--warn);background:rgba(224,168,60,.13);
  border-radius:5px;padding:1px 6px;margin-top:2px}
.todo-row{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;
  padding:10px 0;border-top:1px solid var(--line)}
.todo-row:first-child{border-top:0}
.todo-row .tt{font-weight:700;font-size:13.5px}
.todo-row .ts{display:block;font-size:11.5px;color:var(--ink-3);font-weight:600;margin-top:1px}
.todo-row .tx{background:none;color:var(--ink-3);font-size:16px;line-height:1;padding:4px 8px;border-radius:6px}
.todo-row .tx:hover{background:var(--raise-2);color:var(--ink)}
/* A primary with nothing to act on says so. */
.btn.primary:disabled{opacity:.45;cursor:default;box-shadow:none}


/* ---------------- how this works ---------------- */
/* Read mode inside the Operate chrome: a slide-over the width of the bill
   rail, so help never costs you your place mid-task. */
.help{position:fixed;top:0;right:0;bottom:0;height:100dvh;width:min(440px,100vw);z-index:120;
  background:var(--chrome);border-left:1px solid var(--edge);box-shadow:var(--shadow-2);
  display:grid;grid-template-rows:auto auto 1fr;
  animation:hpin .18s cubic-bezier(.2,.8,.3,1)}
@keyframes hpin{from{transform:translateX(30px);opacity:0}}
.hp-head{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 10px}
.hp-head h2{font-size:17px;font-weight:800}
.hp-rail{display:flex;gap:6px;overflow-x:auto;padding:0 20px 12px;border-bottom:1px solid var(--line);
  scrollbar-width:none}
.hp-rail::-webkit-scrollbar{display:none}
.hp-rail button{flex:none;background:var(--raise);color:var(--ink-2);border-radius:7px;
  padding:5px 10px;font-size:12px;font-weight:700;white-space:nowrap}
.hp-rail button.on{background:var(--accent-soft);color:var(--accent)}
.hp-body{overflow-y:auto;padding:6px 22px 40px;scroll-behavior:smooth}
.hp-body section{padding:18px 0;border-bottom:1px solid var(--line)}
.hp-body section:last-child{border-bottom:0}
.hp-body h3{font-size:15px;font-weight:800;margin-bottom:8px}
.hp-body p{font-size:13.5px;line-height:1.65;color:var(--ink-2);font-weight:500;margin:0 0 10px;max-width:62ch}
.hp-body p:last-child{margin-bottom:0}
.hp-body b{color:var(--ink);font-weight:700}
.hp-body kbd{background:var(--raise);border:1px solid var(--line);border-radius:5px;
  padding:1px 6px;font-size:11.5px;font-weight:700;font-family:inherit;color:var(--ink)}
/* Who may do a thing, said inline rather than hidden. */
.hp-who{color:var(--gold);font-weight:700}
/* The owner's own sentence pinned under the manual. */
.hp-note{background:var(--raise);border-radius:10px;padding:10px 14px;margin-top:12px}
.hp-note .hn-k{display:block;font-size:10.5px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--gold);margin-bottom:3px}
.hp-note .hn-t{font-size:13px;line-height:1.6;color:var(--ink-2);font-weight:600;white-space:pre-wrap}
.hp-note-edit{margin-top:10px}
.hp-note-edit textarea{width:100%;min-height:64px;background:var(--raise);border:1px solid var(--line);
  border-radius:8px;padding:8px 10px;font-size:13px;color:var(--ink);font-family:inherit;resize:vertical}
.hp-note-edit .row2{display:flex;gap:8px;justify-content:flex-end;margin-top:6px}
.hp-addnote{margin-top:10px}
@media(max-width:700px){.help{width:100vw}}

.mback{display:none;margin-bottom:10px}
@media(max-width:1000px){ .mback{display:inline-block} }

/* A removed credit note: present, legible, unmistakably not live. */
.crow.removed{opacity:.6}
.crow.removed .crcode{text-decoration:line-through;text-decoration-thickness:1.5px}


/* ---------------- the phone till ----------------
   HQ was drawn for a desk; at a fair the till is a phone held in one hand.
   Below 740px the rail becomes a bottom tab bar, every view goes single
   column, and on the till the bill lives as a bottom sheet: a one-line bar
   carrying the running total, the whole bill on a tap. */
@media(max-width:740px){
  .inv-top{grid-template-columns:1fr}
  .inv-q{width:100%;margin:10px 0 0;order:9}
  .inv-toolbar{flex-wrap:wrap}
  .inv-list{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:9px}
  .inv-tile{padding:8px}

  .app,.app.has-rail,.app.rail-open{grid-template-columns:1fr;--rail:0px}
  .rail{position:fixed;left:0;right:0;bottom:0;top:auto;height:calc(58px + env(safe-area-inset-bottom));
    flex-direction:row;align-items:center;justify-content:flex-start;gap:2px;
    overflow-x:auto;overflow-y:hidden;padding:4px 8px calc(4px + env(safe-area-inset-bottom));
    border-right:0;border-top:1px solid var(--edge);z-index:70;scrollbar-width:none}
  .rail::-webkit-scrollbar{display:none}
  /* The mark belongs at the top of a rail, not in a tab bar: on a phone it was
     eating a sixth of the row and squeezing every label into an ellipsis. */
  .rail .logo,.rail .brandrow,.railtog,.me-wrap{display:none}
  .rail .rnav{flex:none;flex-direction:column;gap:2px;width:56px;padding:6px 2px;border-radius:10px}
  .rail .rnav .t{display:block;font-size:9.5px}
  .rail .rnav svg{width:19px;height:19px}
  .view{padding-bottom:70px}
  .phead{padding:14px 14px 10px}
  .phead h1{font-size:22px}
  .scroll{padding:0 14px 90px}
  .grid{grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:9px}
  .split{grid-template-columns:1fr}
  .dash-grid{grid-template-columns:1fr}
  .till-cta{grid-column:auto}

  /* The till is one page: viewfinder, then the bill, one natural scroll.
     has-rail only exists on the till, so no other view is touched. */
  .app.has-rail{display:block;height:auto;min-height:100dvh;overflow:visible}
  .app.has-rail .view{height:auto;overflow:visible;padding-bottom:0}
  .app.has-rail .view>.scroll{overflow:visible;height:auto;padding-bottom:0}
  .app.has-rail #bill{position:static;border-top:1px solid var(--edge);
    /* Clearance for the tab bar AND a browser's own bottom chrome: the one
       button that takes the money must never sit under either. */
    padding-bottom:calc(110px + env(safe-area-inset-bottom))}
  .app.has-rail .sums{padding-top:10px}
  .app.has-rail .sum{padding:4px 0}
  .app.has-rail .take{padding:16px;font-size:16px}
  .app.has-rail #bill .lines{min-height:0}
  .app.has-rail .empty{padding:14px}
  .app.has-rail .empty svg{width:26px;height:26px;margin-bottom:6px}
  /* Bigger fingers than pointers. */
  .line .qty button{width:40px;height:40px}
  .tool{padding:6px 11px}
  /* The enter-key hint has no key to hint at on a phone. */
  .scan .hint{display:none}

  /* Stat rows: two honest columns, never a horizontal bleed. The desktop's
     inline five-across never survives a phone. */
  .dash-grid,.dash-grid.c5,.dash-grid.c4,.dash-grid.c3{grid-template-columns:repeat(2,1fr);gap:10px}
  .till-cta{grid-column:span 2}
  .stat.hero{grid-column:span 2}
  .stat{padding:14px;min-height:0}
  .stat .val{font-size:22px}
  #v-dash .stat.hero .val{font-size:36px}
  .card{padding:16px}
  .phead{gap:10px}
  .phead .btn{padding:8px 12px}
  .seg button{white-space:nowrap}

  /* Settings: the two columns become one, the section nav a chip row. */
  .set-wrap{display:block}
  .set-nav{flex-direction:row;overflow-x:auto;position:static;margin:0 0 14px;
    scrollbar-width:none;gap:6px;padding-bottom:4px}
  .set-nav::-webkit-scrollbar{display:none}
  .set-nav button{flex:none;white-space:nowrap}

  /* Filter chip rows ride sideways instead of stacking forever. */
  #books-filters{display:flex;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-bottom:4px}
  #books-filters::-webkit-scrollbar{display:none}
  #books-filters .chip{flex:none}

  /* Dialogs take the room a phone has. */
  .smp{padding:10px}
  .labbox{width:100%;max-height:96dvh}
  .cmdk-box{width:100%}

  /* The toast clears the tab bar. */
  .toast{bottom:calc(74px + env(safe-area-inset-bottom))}
}
/* Buying searches the catalogue; the viewfinder scans YOUR labels, which is
   the selling and trading gesture. It steps aside in buy mode. */
#v-till.buymode .pcam{display:none}
/* A buylist status wears its own colour: settled green, declined quiet. */
.ostat.no{background:var(--raise);color:var(--ink-3)}

/* The inventory side column: add stock, then prices, one scroll. */
.inv-side{display:flex;flex-direction:column;gap:18px;min-width:0}
.inv-side .rows{max-height:340px;overflow-y:auto}
#inv-sel:empty{display:none}


/* ---------------- the phone till is a scanner ----------------
   A big screen browses shelves; a hand at a fair scans stickers. Below 740px
   the grid only exists while a search is being typed, and the viewfinder
   button is the till's centre. */
.pcam{display:none}
@media(max-width:740px){
  #v-till .filters,#v-till .gridhead{display:none}
  #v-till.searching .gridhead{display:flex}
  #v-till .grid{display:none}
  #v-till.searching .grid{display:flex;flex-direction:column;gap:8px}
  #v-till.searching .pcam{display:none}
  /* search results as tappable rows, not shelf tiles */
  #v-till.searching .tile{display:grid;grid-template-columns:44px minmax(0,1fr) auto;gap:4px 10px;
    align-items:center;text-align:left;padding:8px 10px}
  #v-till.searching .tile .ph{width:44px;grid-row:1/4}
  #v-till.searching .tile .ph .code{display:none}
  #v-till.searching .tile .nm{grid-column:2}
  #v-till.searching .tile .set{grid-column:2;margin:0}
  #v-till.searching .tile .foot{grid-column:3;grid-row:1/4;flex-direction:column;align-items:flex-end}
  .pcam{display:block;position:relative;width:100%;height:150px;margin:6px 0 12px;
    border-radius:var(--r);overflow:hidden;background:#000;border:1px solid var(--edge)}
  .pcam video{width:100%;height:100%;object-fit:cover;display:block}
  .pcam-hint{position:absolute;left:0;right:0;bottom:8px;text-align:center;color:#fff;
    font-weight:700;font-size:12.5px;text-shadow:0 1px 6px rgba(0,0,0,.85);pointer-events:none}
}

/* ---------------- collector ---------------- */
.col-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start}
.col-grid .card:first-child{grid-column:1/-1}
.col-worth{font-size:34px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;margin:6px 0 8px}
.col-spark{width:100%;height:60px;display:block}
.col-spark polyline{fill:none;stroke:var(--leaf,#3fb37f);stroke-width:2}
.col-spark .fill{fill:var(--leaf,#3fb37f);opacity:.12;stroke:none}
.col-rows{max-height:320px;overflow-y:auto}
.col-pct{font-weight:800;color:var(--leaf,#3fb37f);white-space:nowrap}
.col-bar{height:5px;border-radius:3px;background:var(--raise-2);overflow:hidden;margin-top:5px}
.col-bar i{display:block;height:100%;background:var(--gold,#e0a83c)}
.col-missing{padding:8px 0 4px 46px}
.col-missing .mrow{display:flex;justify-content:space-between;font-size:12px;padding:3px 0;color:var(--ink-2)}
@media(max-width:900px){.col-grid{grid-template-columns:1fr}}

/* discount code rows breathe like list rows, not grid cells */
#pr-list .row{display:flex;gap:12px;align-items:center}
#pr-list .row > span:first-child{flex:1;min-width:0}

/* collapsible intake modules: as small as their job allows */
.fold-head{display:flex;align-items:center;gap:10px;width:100%;background:none;padding:0;
  cursor:pointer;text-align:left;color:var(--ink)}
.fold-head h2{margin:0}
.fold-head .chev{width:18px;height:18px;stroke:var(--ink-3);fill:none;stroke-width:2.4;flex:none;
  transition:transform .18s ease-out}
.fold.closed .fold-head .chev{transform:rotate(-90deg)}
.fold .fold-body{margin-top:12px}
.fold.closed .fold-body{display:none}
.fold.closed{padding-top:14px;padding-bottom:14px}
/* money fields hold "0.00": they earn a third of the row, not half */
#fold-add:not(.closed) .fold-body{display:flex;flex-direction:column;gap:9px}
#fold-add .field input{padding:8px 11px}
.add-row{display:flex;gap:10px;align-items:flex-end;min-width:0}
.add-row .btn{white-space:nowrap;flex:none}
.add-row .field.money{width:110px;flex:none}
.add-row .field.grow{flex:1;min-width:0}
.check.compact{padding:7px 10px;align-items:center}
.warnword{color:var(--warn,#e0a33a);font-weight:800}
/* A compact check standing in a row of buttons is one control among several,
   not a block of its own, so it takes only the width of what it says. */
.add-row .check.compact,.lab-bar .check.compact{width:auto;flex:none}
.feed-dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--ink-3)}
.feed-dot.ok{background:var(--leaf,#3fb37f)}
.feed-dot.bad{background:var(--accent)}
.feed-dot.back{background:var(--gold,#e0a83c)}
.feed-failed{color:var(--accent)}
#till-feed .row{grid-template-columns:8px minmax(0,1fr) auto;display:grid;gap:12px;align-items:center}
.custom-row{display:flex;gap:8px;align-items:center;margin:10px 0;flex-wrap:wrap}
.custom-row input{background:var(--raise);border:1px solid var(--line);border-radius:8px;
  padding:8px 11px;font-size:13px;color:var(--ink)}
.custom-row #custom-name{flex:1;min-width:140px}
.phone-pay{width:100%;margin:8px 0 0}
.phone-pay.on{background:var(--accent-soft, rgba(224,90,60,.1))}
.phone-pay.on .box{background:var(--accent-fill);box-shadow:none}
.phone-pay.on .box svg{opacity:1}
.check.compact .lbl b{font-size:12.5px}
@media(max-width:740px){.add-row{flex-wrap:wrap}.add-row .field.grow{flex-basis:100%}}

/* paying a consignor: the bill and its button, beside the filter that raised it */
.settle-bar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:10px;
  background:var(--raise);border-radius:var(--r-sm);padding:10px 14px;font-size:13px}
.settle-bar b{font-variant-numeric:tabular-nums}

/* the trophy shelf: one quiet row, medals then the road to the next */
.mile-strip{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.mile-lab{font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);margin-right:2px}
.mile-lab:not(:first-child){margin-left:14px}
.mile{background:var(--gold-soft);color:var(--gold);border-radius:999px;padding:4px 11px;
  font-size:12px;font-weight:800;font-variant-numeric:tabular-nums}
.mile.next{position:relative;overflow:hidden;background:var(--raise);color:var(--ink-3);
  border:1px dashed var(--line);padding:4px 11px}
.mile.next i{position:absolute;inset:0;width:0;background:var(--gold-soft)}
.mile.next b{position:relative;font-weight:800}

/* the network's state: loud enough to change what you reach for */
.offline-bar{position:fixed;left:50%;top:12px;transform:translateX(-50%);z-index:420;
  border-radius:10px;padding:9px 14px;font-size:13px;font-weight:700;
  box-shadow:0 8px 30px rgba(0,0,0,.45);max-width:calc(100% - 24px)}
.offline-bar.out{background:var(--accent);color:#fff}
.offline-bar.back{background:var(--leaf,#3fb37f);color:#08130d}
.offline-bar .held{opacity:.85;font-weight:600}
@media(max-width:740px){.offline-bar{top:8px;font-size:12.5px;padding:8px 12px}}

/* the stale-tab bar: quiet, fixed, impossible to misread */
.newbuild{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);z-index:400;
  display:flex;align-items:center;gap:14px;background:var(--card,#171a20);color:var(--ink);
  border:1px solid var(--edge);border-radius:12px;padding:10px 12px 10px 16px;
  font-size:13px;font-weight:700;box-shadow:0 8px 30px rgba(0,0,0,.45)}
@media(max-width:740px){.newbuild{bottom:74px;width:calc(100% - 24px);justify-content:space-between}}

/* ---------------- the scan station: the stack ---------------- */
.stk-wrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:18px;align-items:start;
  max-width:1060px;margin:0 auto}
.stk-stage{padding:22px;position:relative;overflow:hidden}
.stk-imgwrap{position:relative;width:min(340px,80%);margin:0 auto 14px}
.stk-imgwrap img{width:100%;border-radius:12px;display:block;box-shadow:var(--shadow-2)}
.stk-flip{position:absolute;right:8px;bottom:8px}
.stk-rot{position:absolute;left:8px;bottom:8px}
.stk-swap{position:absolute;left:8px;bottom:44px}
.stk-cropbtn{position:absolute;left:8px;bottom:80px}
.stk-cropstage{position:relative;max-width:420px;margin:0 auto;user-select:none;touch-action:none;
  overflow:hidden;border-radius:10px}
.stk-cropstage img{width:100%;display:block;border-radius:10px}
.stk-cropbox{position:absolute;border:2px solid var(--gold,#e0a83c);border-radius:6px;
  box-shadow:0 0 0 2000px rgba(10,12,16,.55);cursor:move}
.stk-cropbox i{position:absolute;width:26px;height:26px;border-radius:50%;
  background:var(--gold,#e0a83c);opacity:.92;border:2px solid #0d0f13}
.stk-cropbox i[data-ch="nw"]{left:-13px;top:-13px;cursor:nwse-resize}
.stk-cropbox i[data-ch="ne"]{right:-13px;top:-13px;cursor:nesw-resize}
.stk-cropbox i[data-ch="sw"]{left:-13px;bottom:-13px;cursor:nesw-resize}
.stk-cropbox i[data-ch="se"]{right:-13px;bottom:-13px;cursor:nwse-resize}
.stk-corners{display:flex;align-items:center;gap:10px;margin-top:12px;justify-content:space-between}
.stk-conf{position:absolute;left:8px;top:8px;font-size:10.5px;font-weight:800;letter-spacing:.05em;
  text-transform:uppercase;border-radius:999px;padding:3px 9px;background:rgba(0,0,0,.55);color:#fff}
.stk-conf.sure{background:rgba(63,179,127,.85)}
.stk-id{text-align:center;margin-bottom:4px}
.stk-id b{display:block;font-size:19px;font-weight:800}
.stk-id .muted{font-size:13px}
.stk-price{text-align:center;font-size:34px;font-weight:800;letter-spacing:-.02em;margin:6px 0 14px;
  font-variant-numeric:tabular-nums}
.stk-price.nil{font-size:14px;font-weight:700;color:var(--ink-3)}
.stk-fields{display:flex;gap:14px;align-items:flex-end;justify-content:center;flex-wrap:wrap;margin-bottom:14px}
.stk-problem{margin:0 auto 12px;max-width:420px}
.stk-acts{display:flex;gap:10px;justify-content:center;align-items:center}
.stk-fix{margin-top:16px;border-top:1px solid var(--line);padding-top:14px}
.stk-modebar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px;
  background:var(--panel);border-radius:var(--r);padding:10px 14px}
.stk-thr{flex-direction:row;align-items:center;gap:8px}
.stk-thr span{margin:0}
.stk-thr input{width:70px;background:var(--raise);border:1px solid var(--line);border-radius:7px;
  padding:6px 9px;font-size:13px;color:var(--ink)}
.stk-conf.bulk{background:rgba(122,132,148,.85)}
.stk-conf.pull{background:var(--gold,#e0a83c);color:#1a1406}
/* dealing off: the card leaves the way a dealt card leaves */
@keyframes dealoff{to{transform:translateX(120%) rotate(9deg);opacity:0}}
.stk-stage.dealing #stk-card{animation:dealoff .28s cubic-bezier(.4,0,.9,.4) forwards}
@media(prefers-reduced-motion:reduce){.stk-stage.dealing #stk-card{animation:none;opacity:0}}

.stk-side{display:flex;flex-direction:column;gap:14px}
.stk-pile{text-align:center;padding:18px}
.stk-pilewrap{height:64px;position:relative;margin-bottom:8px}
.stk-pilewrap i{position:absolute;left:50%;width:84px;height:6px;border-radius:3px;
  background:var(--raise-2);border-top:1px solid var(--edge-top);transform:translateX(-50%)}
.stk-count{font-size:13px;color:var(--ink-2);font-weight:700}
.stk-count b{font-size:20px;color:var(--ink)}
.stk-watcher{font-size:11px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-3);margin-top:6px}
.stk-watcher.live{color:var(--leaf,#3fb37f)}
.stk-filters{display:flex;flex-direction:column;gap:6px}
.stk-filters button{display:flex;justify-content:space-between;align-items:center;width:100%;
  text-align:left;background:var(--raise);border-radius:8px;padding:8px 12px;
  font-size:13px;font-weight:700;color:var(--ink-2)}
.stk-filters button:hover{background:var(--raise-2)}
.stk-filters button.on{background:var(--accent-soft);color:var(--accent)}
.stk-filters button .tabn{margin-left:8px}
.stk-drawer-row{display:grid;grid-template-columns:52px 1fr 66px 66px 28px;gap:8px;margin-bottom:8px;align-items:center}
.stk-drawer-row input{background:var(--raise);border:1px solid var(--line);border-radius:7px;
  padding:6px 8px;font-size:13px;color:var(--ink);width:100%}
.stk-drawer-row .tx{background:none;color:var(--ink-3);font-size:15px}
@media(max-width:900px){
  .stk-wrap{grid-template-columns:1fr}
  .stk-side{flex-direction:row;flex-wrap:wrap}
  .stk-side .card{flex:1;min-width:140px}
}
/* ---------------- the station's ledger and bench ---------------- */
.stk-strip{display:flex;align-items:center;gap:16px;padding:10px 16px;margin-bottom:14px;
  font-size:13px;font-weight:700;color:var(--ink-2);flex-wrap:wrap}
.stk-strip b{color:var(--ink);font-size:16px}
.rl-allwrap{display:flex;align-items:center;gap:10px;cursor:pointer}
.rl-allwrap input,.rl-ck{width:18px;height:18px;accent-color:var(--accent);cursor:pointer;flex:none}
.rl-row{display:grid;grid-template-columns:18px 44px minmax(0,1fr) auto auto auto auto;
  gap:12px;align-items:center;padding:8px 0;border-top:1px solid var(--line)}
.rl-row:first-child{border-top:0}
.rl-row.sel{background:var(--accent-soft, rgba(224,90,60,.06))}
.rl-row .th{width:44px;aspect-ratio:63/88;border-radius:6px;overflow:hidden;background:var(--bg);cursor:pointer}
.rl-row .th img{width:100%;height:100%;object-fit:cover}
.rl-main{min-width:0}
.rl-main .nm{display:block;font-size:13px;font-weight:700;line-height:1.25;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.rl-main .sub{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.rl-pill{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;
  border-radius:999px;padding:1px 7px;background:var(--raise);color:var(--ink-2);vertical-align:1px}
.rl-pill.sure{background:rgba(63,179,127,.16);color:var(--leaf,#3fb37f)}
.rl-pill.bulk{background:rgba(122,132,148,.2)}
.rl-pill.pull{background:var(--gold,#e0a83c);color:#1a1406}
.rl-pill.dupe{background:rgba(224,90,60,.15);color:var(--accent)}
.rl-pill.owner{background:rgba(90,130,224,.16);color:#7fa4e8}
.rl-drawer,.rl-cond{background:var(--raise);border:0;border-radius:7px;padding:7px 8px;
  font-size:12.5px;font-weight:700;color:var(--ink);max-width:120px}
.rl-acts{display:flex;gap:6px}
.rl-btn{width:34px;height:34px;border-radius:8px;background:var(--raise);display:grid;place-items:center;cursor:pointer}
.rl-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.2}
.rl-btn.ok{color:var(--leaf,#3fb37f)}
.rl-btn.ok:hover{background:rgba(63,179,127,.16)}
.rl-btn.no{color:var(--ink-3)}
.rl-btn.no:hover{color:var(--accent);background:rgba(224,90,60,.12)}
.rl-btn:hover{background:var(--raise-2)}

.ck-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.ck-tile{background:var(--raise);border-radius:var(--r);padding:10px;display:flex;flex-direction:column;gap:8px}
.ck-img{position:relative;border-radius:8px;overflow:hidden;background:var(--bg)}
.ck-img img{width:100%;display:block}
.ck-img .stk-conf{position:absolute;left:8px;top:8px}
.ck-tools{position:absolute;right:6px;bottom:6px;display:flex;gap:4px}
.ck-tools .tool{padding:4px 8px;font-size:11px;background:rgba(10,12,16,.72);color:#fff}
.ck-problem{font-size:12px;color:var(--warn,#e0a83c);font-weight:600}
.ck-cands{display:flex;flex-direction:column;gap:5px}
.ck-cand{text-align:left;background:var(--raise-2);border-radius:7px;padding:6px 9px;font-size:12px;
  color:var(--ink-2);cursor:pointer;line-height:1.35}
.ck-cand b{color:var(--ink)}
.ck-cand:hover{background:var(--panel)}
.ck-inputs{display:grid;grid-template-columns:1fr 90px;gap:7px}
.ck-inputs input{background:var(--bg);border:1px solid var(--line);border-radius:7px;
  padding:7px 9px;font-size:13px;color:var(--ink);min-width:0}
.ck-custom{display:flex;align-items:center;gap:8px;padding-top:8px;border-top:1px solid var(--line)}
.ck-custom input{width:64px;background:var(--bg);border:1px solid var(--line);border-radius:7px;
  padding:6px 8px;font-size:13px;color:var(--ink)}
.ck-acts{display:flex;align-items:center;gap:8px;margin-top:auto}
@media(max-width:1100px){.ck-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:740px){
  .ck-grid{grid-template-columns:1fr}
  .rl-row{grid-template-columns:18px 44px minmax(0,1fr) auto;grid-auto-rows:auto;row-gap:6px}
  .rl-drawer{grid-column:3}
  .rl-cond{grid-column:3}
  .rl-row .amt{grid-column:4;grid-row:1}
  .rl-acts{grid-column:3/5;justify-content:flex-end}
}

/* the drawer chip a card wears wherever inventory is listed */
.drawer-chip{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.04em;
  background:var(--raise);color:var(--ink-2);border-radius:5px;padding:1px 6px;margin-left:6px}

/* ================= dashboard redesign (handoff 1a) =================
   The dashboard wears the handoff's own palette and faces: Archivo for the
   words, JetBrains Mono for every figure. Scoped here so the rest of HQ keeps
   its incumbent skin until each view earns the same treatment. */
#v-dash{--d-bg:#0f1013;--d-card:#15171c;--d-bord:#22252c;--d-div:#1e2026;--d-btn:#2a2d34;
  --d-ink:#f2f0ec;--d-ink2:#e8e6e2;--d-mut:#8b8f99;--d-mut2:#7b7f89;--d-faint:#5f636d;
  --d-red:#d63b2f;--d-redh:#c1332a;--d-link:#e8756a;--d-green:#4fae6e;
  --d-gold:#eecb74;--d-goldm:#c9a755;--d-golddim:#8a7847;
  background:var(--d-bg);font-family:'Archivo',var(--f)}
#v-dash .dashwrap{display:flex;flex-direction:column;gap:20px;padding:28px 32px}
#v-dash .dash-head{display:flex;align-items:flex-end;gap:10px}
#v-dash .dash-head .sp{flex:1}
#v-dash .dash-date{font-size:12.5px;color:var(--d-mut2);margin-bottom:4px}
#v-dash .dash-head h1{font-size:26px;font-weight:600;letter-spacing:-.3px;color:var(--d-ink);margin:0}
#v-dash .dbtn{border-radius:8px;padding:10px 16px;font:600 13px 'Archivo',var(--f);cursor:pointer;border:0}
#v-dash .dbtn.ghost{background:none;border:1px solid var(--d-btn);color:#c9ccd3}
#v-dash .dbtn.ghost:hover{border-color:#3a3e47}
#v-dash .dbtn.primary{background:var(--d-red);color:#fff;display:flex;align-items:center;gap:8px}
#v-dash .dbtn.primary:hover{background:var(--d-redh)}
#v-dash .ctasub{font-weight:400;opacity:.75}

#v-dash .dash-band{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:14px}
#v-dash .dcard{background:var(--d-card);border:1px solid var(--d-bord);border-radius:12px;padding:18px 20px;text-align:left}
#v-dash .dcard .lbl{font:500 12px 'Archivo',var(--f);color:var(--d-mut2);letter-spacing:0;text-transform:none;margin:0}
#v-dash .dcard .val{font:600 24px 'JetBrains Mono',monospace;color:var(--d-ink);margin:8px 0 2px;letter-spacing:0}
#v-dash .dcard.hero .val{font-size:34px;letter-spacing:-1px;margin:6px 0 2px}
#v-dash .sub2{font:400 12px 'Archivo',var(--f);color:var(--d-faint)}
#v-dash .dcard.alert{background:#191612;border-color:#43351c;cursor:pointer}
#v-dash .dcard.alert:hover{border-color:#5d4a24}
#v-dash .dcard.alert .lbl{color:var(--d-goldm)}
#v-dash .dcard.alert .val{color:var(--d-gold)}
#v-dash .dcard.alert .sub2{color:var(--d-golddim)}
#v-dash .stat.nil .val{color:var(--d-mut)}
/* the handoff's band keeps its figures off-white; the old dash coloured them */
#v-dash .stat.hero .val{color:var(--d-ink);font-size:34px;letter-spacing:-1px}
#v-dash .stat[data-role] .val{color:var(--d-ink)}

#v-dash .todo-strip{background:var(--d-card);border:1px solid var(--d-bord);border-radius:10px;padding:2px 16px}
#v-dash .todo-row{display:flex;align-items:center;gap:12px;padding:10px 0;border:0}
#v-dash .todo-row + .todo-row{border-top:1px solid var(--d-div)}
#v-dash .todo-row::before{content:"TO DO";font:600 10.5px 'JetBrains Mono',monospace;color:var(--d-mut2);letter-spacing:1px}
#v-dash .todo-row > span:first-of-type{display:flex;align-items:baseline;gap:12px;flex:1;min-width:0}
#v-dash .todo-row .tt{font:500 13px 'Archivo',var(--f);color:#d5d8de}
#v-dash .todo-row .ts{font:400 12px 'Archivo',var(--f);color:var(--d-faint)}
#v-dash .todo-row .tool{background:none;border:0;padding:0;font:600 12.5px 'Archivo',var(--f);color:var(--d-link)}
#v-dash .todo-row .tool:hover{color:#f0968d;background:none}
#v-dash .todo-row .tx{background:none;border:0;color:var(--d-faint);cursor:pointer;font-size:15px}

#v-dash .dash-two{display:grid;grid-template-columns:1.5fr 1fr;gap:14px;align-items:start}
#v-dash .dash-rcol{display:flex;flex-direction:column;gap:14px}
#v-dash .dcard.pad{padding:20px}
#v-dash .dc-head{display:flex;align-items:baseline;gap:8px;margin-bottom:6px}
#v-dash .dc-head h2{font:600 15px 'Archivo',var(--f);color:var(--d-ink);margin:0}
#v-dash .live-ind{font:400 11.5px 'Archivo',var(--f);color:var(--d-green);display:flex;align-items:center;gap:6px}
#v-dash .live-ind:not(:empty)::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--d-green)}
#v-dash .rows .row{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--d-div);border-bottom:0;background:none}
#v-dash .rows .row:first-child{border-top:1px solid var(--d-div)}
#v-dash .rows .row > span:has(.nm){flex:1;min-width:0}
#v-dash .rows .nm{font:600 13.5px 'Archivo',var(--f);color:var(--d-ink2)}
#v-dash .rows .sub{font:400 12px 'Archivo',var(--f);color:var(--d-faint)}
#v-dash .rows .amt{font:600 14px 'JetBrains Mono',monospace;color:var(--d-ink);text-align:right}
#v-dash .rows .amt small{font:400 11px 'Archivo',var(--f);color:var(--d-green);display:block}
#v-dash .rows .amt small.feed-failed{color:var(--d-red)}
#v-dash #recent .amt{color:var(--d-green);font-size:13.5px}
#v-dash #recent .amt small{color:var(--d-faint)}
#v-dash .rows .th{width:34px;height:46px;border-radius:4px;overflow:hidden;flex:none;background:#1a1c22}
#v-dash .rows .th img{width:100%;height:100%;object-fit:cover}
#v-dash .rows .tool{font:500 11.5px 'Archivo',var(--f);color:var(--d-mut);border:1px solid var(--d-btn);border-radius:6px;padding:4px 9px;background:none}
#v-dash .rows .tool:hover{color:#d5d8de;background:none}
#v-dash .feed-dot{width:6px;height:6px;border-radius:50%;flex:none}
#v-dash .feed-dot.ok{background:var(--d-green)}
#v-dash .feed-dot.bad{background:var(--d-red)}
#v-dash .feed-dot.back{background:var(--d-gold)}
#v-dash .muted{color:var(--d-faint)}

/* the rail earns the handoff's nav treatment everywhere: red-tint active with
   its dot, quiet hover, and the milestones module living above Settings */
.rnav{border-radius:8px}
.rnav:hover{background:#191b20}
.rnav.on{background:var(--accent-soft);color:var(--accent)}
.rnav.on svg{stroke:var(--accent)}
.rnav.on .t::after{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--accent-fill);margin-left:8px;vertical-align:1px}
/* the bottom of the rail: Help with its little menu, then one row holding the
   cog against the rail's edge and the person it belongs to */
.help-wrap{position:relative}
.help-menu{bottom:calc(100% + 6px);top:auto}
.help-menu .railn{position:static;margin-left:auto}
.me-row{display:flex;align-items:center;gap:2px;border-top:1px solid var(--edge);margin-top:6px;padding-top:6px}
.me-row .me{margin-top:0;flex:1;min-width:0}
.me-cog{width:34px;height:34px;border-radius:9px;border:0;background:none;color:var(--ink-3);
  display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;position:relative}
.me-cog svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.7}
.me-cog:hover{background:#191b20;color:#d5d8de}
.app:not(.rail-open) .me-row{flex-direction:column;gap:4px}
/* On a phone the Help tab is the one door to Settings, Support and the manual;
   the desktop menu hides its Settings entry because the cog already lives on
   the user row there. */
#help-set{display:none}
#help-set[hidden]{display:none !important}
@media(max-width:740px){
  .me-row{display:none}
  .help-wrap{flex:none}
  #help-set{display:flex}
  .help-menu{position:fixed;left:10px;right:10px;bottom:calc(66px + env(safe-area-inset-bottom));width:auto}
}

.mile-mod{margin:0 6px 8px;background:#15171c;border:1px solid #22252c;border-radius:10px;padding:11px 13px 10px}
.mile-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:8px}
.mile-head span{font:600 10.5px 'JetBrains Mono',monospace;color:#9aa0ac;letter-spacing:1.2px;text-transform:uppercase}
.mile-head b{font:600 12px 'JetBrains Mono',monospace;color:#eecb74}
.mile-row{display:flex;align-items:center;gap:8px;padding:3px 0}
.mile-row + .mile-row{margin-top:6px}
.mile-rlab{font:500 10.5px 'Archivo',var(--f);color:#8b8f99;width:38px;flex:none}
.mile-rbar{flex:1;height:5px;border-radius:3px;background:#22252c;overflow:hidden}
.mile-rbar i{display:block;height:100%;border-radius:3px;background:#eecb74;transition:width .3s ease-out}
.mile-rnext{font:600 10.5px 'JetBrains Mono',monospace;color:#9aa0ac;flex:none;min-width:30px;text-align:right}
.app:not(.rail-open) .mile-mod{display:none}

@media(max-width:1100px){ #v-dash .dash-band{grid-template-columns:1fr 1fr} #v-dash .dash-two{grid-template-columns:1fr} }
@media(max-width:740px){
  #v-dash .dashwrap{padding:16px 14px 80px;gap:14px}
  #v-dash .dash-band{grid-template-columns:1fr}
  #v-dash .dash-head{flex-wrap:wrap;align-items:center}
  .mile-mod{display:none}
}

/* ================= till redesign (handoff) =================
   The till joins the dashboard in the handoff's world: same palette, Archivo
   for words, JetBrains Mono for figures, and Saira Condensed as the page's
   display voice. Scoped to the till and its bill; behaviour untouched. */
#v-till{background:#0f1013;font-family:'Archivo',var(--f)}
#v-till .phead h1{font:700 26px 'Saira Condensed',var(--f);font-style:italic;color:#f2f0ec;
  letter-spacing:.5px;text-transform:uppercase}
#v-till .session{font:400 12.5px 'Archivo',var(--f);color:#7b7f89;background:none;border:0;padding:0}
#v-till .scan{background:#15171c;border:1px solid #2a2d34;border-radius:10px;min-height:52px;
  padding:0 10px 0 16px;display:flex;align-items:center;gap:12px}
#v-till .scan .ico{position:static;transform:none;width:18px;height:18px;flex:none}
#v-till .scan .hint{position:static;transform:none;margin-left:auto;flex:none}
#v-till .scan .tool{position:static;flex:none}
#v-till .scan:focus-within{border-color:var(--accent-fill)}
#v-till .scan .ico{stroke:#8b8f99}
#v-till .scan input{background:transparent;border:0;color:#f2f0ec;font:400 14.5px 'Archivo',var(--f);
  padding:14px 0;min-width:0;flex:1}
#v-till .scan input:focus{border:0;outline:none}
#v-till .scan .hint{font:500 11px 'JetBrains Mono',monospace;color:#5f636d;border:1px solid #2a2d34;
  border-radius:5px;padding:3px 8px;white-space:nowrap}
#v-till .scan .hint .kbd{background:none;border:0;padding:0;font:inherit;color:inherit}
#v-till .scan .tool{border:1px solid #2a2d34;border-radius:8px;background:none;color:#c9ccd3;
  font:600 12px 'Archivo',var(--f);padding:7px 12px}
#v-till .scan .tool:hover{border-color:#3a3e47;background:none}

#v-till .filters{display:flex;gap:8px;flex-wrap:wrap}
#v-till .chip{display:flex;align-items:center;gap:7px;padding:8px 14px;border-radius:999px;
  font:600 12.5px 'Archivo',var(--f);background:#15171c;color:#8b8f99;border:1px solid #2a2d34}
#v-till .chip .n{font:500 11.5px 'JetBrains Mono',monospace;opacity:.65;background:none;padding:0}
#v-till .chip.on{background:var(--accent-fill);color:var(--on-accent);border-color:var(--accent-fill)}
#v-till .chip.on .n{opacity:.8}

#v-till .gridhead h2{font:600 15px 'Archivo',var(--f);color:#f2f0ec}
#v-till .gridhead .muted{font:400 12px 'Archivo',var(--f);color:#5f636d}
#v-till .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:12px}
#v-till .tile{background:#15171c;border:1px solid #22252c;border-radius:12px;padding:10px;
  display:flex;flex-direction:column;gap:7px;text-align:left;cursor:pointer}
#v-till .tile:hover{border-color:#3a3e47;background:#15171c}
#v-till .tile.out{opacity:.45}
#v-till .tile .ph{position:relative;aspect-ratio:3/4;border-radius:8px;overflow:hidden;
  background:#1b1e24;border:1px solid #22252c;width:auto;height:auto}
#v-till .tile .ph img{width:100%;height:100%;object-fit:cover}
#v-till .tile .code{position:absolute;top:7px;left:7px;font:500 9.5px 'JetBrains Mono',monospace;
  color:#8b8f99;background:rgba(0,0,0,.55);border-radius:4px;padding:2px 6px;letter-spacing:0}
#v-till .tile .owned{position:absolute;top:7px;right:7px;font:600 9.5px 'JetBrains Mono',monospace;
  color:#eecb74;background:rgba(67,53,28,.7);border:1px solid #43351c;border-radius:4px;padding:2px 6px}
#v-till .tile .owned svg{display:none}
#v-till .tile .nm{font:600 13px 'Archivo',var(--f);color:#e8e6e2;line-height:1.3}
#v-till .tile .set{font:400 11.5px 'Archivo',var(--f);color:#5f636d}
#v-till .tile .foot{display:flex;justify-content:space-between;align-items:baseline;margin-top:auto}
#v-till .tile .pr{font:600 14px 'JetBrains Mono',monospace;color:#f2f0ec}
#v-till .tile .stk{font:500 11px 'Archivo',var(--f);color:#e8756a;background:none;padding:0}
#v-till .tile.out .stk{color:#5f636d}

/* the bill wears the same room */
.app.has-rail #bill{background:#0f1013;border-left:1px solid #1e2026}
#bill .bill-top h2{font:600 17px 'Archivo',var(--f);color:#f2f0ec}
#bill .clear{font:500 12.5px 'Archivo',var(--f);color:#8b8f99;background:none;border:0}
#bill .clear:hover{color:#d5d8de}
#bill .seg{background:#15171c;border:1px solid #22252c;border-radius:10px;padding:4px;gap:6px}
#bill .seg button{border-radius:7px;font:600 12.5px 'Archivo',var(--f);color:#8b8f99;background:transparent}
#bill .seg button.on{background:var(--accent-fill);color:var(--on-accent)}
#bill .line{border-top:1px solid #1e2026}
#bill .line .nm{font:600 13px 'Archivo',var(--f);color:#e8e6e2}
#bill .line .sub{font:400 11.5px 'Archivo',var(--f);color:#5f636d}
#bill .line .pr{font:600 13.5px 'JetBrains Mono',monospace;color:#f2f0ec}
#bill .qty button{width:26px;height:26px;border-radius:7px;border:1px solid #2a2d34;background:none;color:#c9ccd3}
#bill .qty button:hover{border-color:#3a3e47;background:none}
#bill .tools .tool{border:1px solid #2a2d34;border-radius:7px;background:none;color:#8b8f99;
  font:500 11.5px 'Archivo',var(--f);padding:4px 9px}
#bill .tools .tool:hover{color:#d5d8de;background:none}
#bill .tools .tool.on{color:var(--accent);border-color:var(--accent-line);background:var(--accent-soft)}
#bill .qty .qtynum{font:600 12.5px 'JetBrains Mono',monospace;color:#f2f0ec;border:0;background:none}
#bill .sums .sum{font:400 13px 'Archivo',var(--f);color:#8b8f99}
#bill .sums .sum > span:last-child{font:500 13px 'JetBrains Mono',monospace;color:#d5d8de}
#bill .sums .sum .off{color:#e8756a}
#bill .sum.tot > span:first-child{font:600 17px 'Archivo',var(--f);color:#f2f0ec}
#bill .sum.tot > span:last-child{font:600 24px 'JetBrains Mono',monospace;color:#f2f0ec;letter-spacing:-.5px}
#bill #use-credit{align-self:flex-start;padding:8px 13px;border-radius:999px;border:1px solid #2a2d34;
  color:#8b8f99;font:500 12px 'Archivo',var(--f);background:none}
#bill #use-credit:hover{color:#d5d8de;background:none}
#bill [data-pay]{border-radius:9px;font:600 13px 'Archivo',var(--f);background:transparent;
  color:#8b8f99;border:1px solid #2a2d34;padding:11px 0}
#bill [data-pay] svg{stroke:currentColor}
#bill [data-pay].on{background:var(--accent-soft);color:var(--accent);border-color:var(--accent-line)}
#bill .take{background:var(--accent-fill);color:var(--on-accent);border-radius:10px;font:600 14px 'Archivo',var(--f);padding:14px 0}
#bill .take:hover:not(:disabled){filter:brightness(1.08)}
#bill .take:disabled{background:#1b1e24;color:#5f636d}
#bill .empty p{font:400 13px 'Archivo',var(--f);color:#8b8f99}
#bill .empty .btn{border:1px solid #2a2d34;background:none;color:#c9ccd3;font:600 13px 'Archivo',var(--f);border-radius:8px}
#bill .empty .btn:hover{border-color:#3a3e47}

/* the sale's QR: a quiet card by the bill, never over the scan box */
#haul-pop{position:fixed;right:352px;bottom:16px;z-index:60;display:flex;gap:12px;align-items:center;
  background:#15171c;border:1px solid #2a2d34;border-radius:14px;padding:12px;
  box-shadow:0 12px 34px rgba(0,0,0,.55);max-width:330px}
#haul-pop img{width:104px;height:104px;border-radius:8px;background:#fff;padding:6px;box-sizing:border-box}
#haul-pop b{display:block;font:600 13.5px 'Archivo',var(--f);color:#f2f0ec}
#haul-pop span{display:block;font:400 12px 'Archivo',var(--f);color:#8b8f99;margin-top:2px}
#haul-pop .tx{background:none;border:0;color:#5f636d;font-size:16px;cursor:pointer;align-self:flex-start}
@media(max-width:740px){#haul-pop{right:12px;left:12px;bottom:calc(140px + env(safe-area-inset-bottom));max-width:none}}

/* the phone's viewfinder, dressed as the handoff's scan tile */
@media(max-width:740px){
  .pcam{background:repeating-linear-gradient(45deg,#14161b,#14161b 6px,#101216 6px,#101216 12px);
    border:1px solid #22252c;border-radius:12px}
  .pcam-hint{font:500 10.5px 'JetBrains Mono',monospace;letter-spacing:.5px;text-transform:uppercase;
    color:#8b8f99;text-shadow:none}
  /* the phone till stays camera-first: shelves and filters only appear while
     a search is being typed, as before this skin arrived */
  #v-till .filters,#v-till .gridhead{display:none}
  #v-till.searching .gridhead{display:flex}
  #v-till .grid{display:none}
  #v-till.searching .grid{display:flex;flex-direction:column;gap:8px}
  #v-till .scan .hint{display:none}
  /* money within thumb's reach: the take button rides above the tab bar */
  /* The till on a phone is one natural scroll, so the button that takes the
     money sits at the end of the bill where the total is, rather than floating
     over the figures it is meant to follow. A button pinned above content it
     obscures is worse than one you scroll to. */
  .app.has-rail .take{position:static;width:100%;margin-top:12px;
    background:var(--accent-fill);color:#fff;box-shadow:none}
  .app.has-rail .take:disabled{background:var(--raise-2);color:var(--ink-3)}
  .app.has-rail #bill{padding-bottom:calc(var(--sab) + 24px)}
  .app.has-rail #bill{padding-bottom:130px}
}

/* ================= the whole of HQ joins the world =================
   The handoff's tokens, promoted from two scoped islands to the shell itself.
   Every view is built from the same parts - cards, buttons, chips, segments -
   so restating those parts once brings Inventory, Buy, Books and the rest
   across without touching their bones. Later in the file than everything
   above, deliberately: these are the world's final word. */
:root{
  --bg:#0f1013; --panel:#15171c; --raise:#1b1e24; --raise-2:#22252c; --line:#22252c;
  --ink:#f2f0ec; --ink-2:#8b8f99; --ink-3:#7b7f89;
  --good:#4fae6e; --warn:#eecb74; --gold:#eecb74; --gold-soft:rgba(238,203,116,.13);
  --cool:#6BA8E8; --cool-soft:rgba(107,168,232,.12); --good-soft:rgba(79,174,110,.13);
  /* Defaults only, for the instant before theme.js applies the shop's own
     brand as inline properties (which win over any stylesheet). Nothing below
     may use these hues as literals: the whole app recolours from one setting. */
  --brand:#d63b2f; --accent:#e8756a; --accent-fill:#d63b2f; --on-accent:#fff;
  --accent-soft:rgba(214,59,47,.14); --accent-line:rgba(214,59,47,.5);
  --edge:#1e2026; --r:12px; --r-sm:8px;
  --f:'Archivo',system-ui,-apple-system,sans-serif;
}
body{font-family:var(--f)}
.view .phead h1{font:700 26px 'Saira Condensed',var(--f);font-style:italic;color:var(--ink);
  letter-spacing:.5px;text-transform:uppercase}
.card{background:var(--panel);border:1px solid var(--line);border-radius:12px}
.card h2{font:600 15px var(--f);color:var(--ink)}
.btn{border-radius:8px;font:600 13px var(--f);background:none;border:1px solid #2a2d34;color:#c9ccd3}
.btn:hover{border-color:#3a3e47;background:none}
.btn.primary{background:var(--accent-fill);border-color:var(--accent-fill);color:#fff}
.btn.primary:hover{background:#c1332a;border-color:#c1332a}
.tool{border:1px solid #2a2d34;border-radius:7px;background:none;color:var(--ink-2);font-weight:500}
.tool:hover{color:#d5d8de;background:none}
.tool.on{color:var(--accent);border-color:var(--accent-line);background:var(--accent-soft)}
.chip{display:inline-flex;align-items:center;gap:7px;border-radius:999px;background:var(--panel);
  color:var(--ink-2);border:1px solid #2a2d34;font-weight:600}
.chip .n{background:none;padding:0;font-family:'JetBrains Mono',monospace;font-weight:500;opacity:.65}
.chip.on{background:var(--accent-fill);color:#fff;border-color:var(--accent-fill)}
.chip.on .n{opacity:.8;background:none;color:#fff}
.seg{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:4px;gap:6px}
.seg button{border-radius:7px;font:600 12.5px var(--f);color:var(--ink-2);background:transparent}
.seg button.on{background:var(--accent-fill);color:#fff}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:12px}
.stat .lbl{font:500 12px var(--f);color:var(--ink-3);letter-spacing:0;text-transform:none}
.stat .val{font-family:'JetBrains Mono',monospace;font-weight:600;letter-spacing:0}
input,select,textarea{font-family:var(--f)}
.sum > span:last-child,.amt,.pr,.railn,.tabn,.col-worth{font-family:'JetBrains Mono',monospace}
/* a remove control is a chip, not a bar: never let one stretch the row's width */
.rows .tool,.rows .btn{width:auto;align-self:flex-start;flex:none;justify-self:start}
/* four things live on a note's row: code block, kind, balance, and its action */
.crow{grid-template-columns:1fr auto auto auto}


/* ---------------- the provider ----------------
   The support line and the plan, inside Settings. Borrows the app's own panel
   language rather than inventing a chat skin: this is one more thing the back
   office does, not a separate product bolted to the side. */
.prov-tier { font-weight: 800; font-size: 15px; margin-bottom: 12px; }
.prov-meter { margin-bottom: 10px; max-width: 420px; }
.prov-meter-row { display: flex; justify-content: space-between; font-size: 12px; font-weight: 700; margin-bottom: 4px; opacity: .8; }
.prov-track { height: 5px; border-radius: 3px; background: rgba(128,128,128,.22); overflow: hidden; }
.prov-track i { display: block; height: 100%; background: var(--brand, #C62F1D); border-radius: 3px; }
.prov-track i.low { background: #E0A83C; }
.prov-track i.dry { background: #E45746; }

.prov-feats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.prov-feat { font-size: 11px; font-weight: 700; opacity: .75; background: rgba(128,128,128,.14); border-radius: 6px; padding: 3px 8px; }

.prov-msgs { display: flex; flex-direction: column; gap: 10px; max-height: 360px; overflow-y: auto; padding: 6px 2px; margin-bottom: 4px; }
.prov-msg { max-width: 80%; display: flex; flex-direction: column; gap: 3px; }
.prov-msg.me { align-self: flex-end; align-items: flex-end; }
.prov-msg.them { align-self: flex-start; }
.prov-bubble { border-radius: 12px; padding: 9px 13px; line-height: 1.45; background: rgba(128,128,128,.14); white-space: pre-wrap; word-break: break-word; }
.prov-msg.me .prov-bubble { background: rgba(128,128,128,.24); }
.prov-meta { font-size: 11px; font-weight: 700; opacity: .55; }

.prov-send { display: flex; gap: 8px; align-items: flex-end; margin-top: 10px; max-width: 620px; }
.prov-send textarea { flex: 1; resize: vertical; min-height: 44px; }


/* Support as its own view: the plan on the left, the conversation on the right
   and given the room, because reading a thread is the job here. */
.prov-wrap {
  display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 18px; align-items: start; padding: 4px 0 24px;
}
.prov-plan-card, .prov-chat-card {
  background: rgba(128,128,128,.06); border-radius: 14px; padding: 18px 20px;
  box-shadow: inset 0 0 0 1px rgba(128,128,128,.16);
}
.prov-plan-card h2 { font-size: 15px; font-weight: 800; margin-bottom: 4px; }
.prov-chat-card .prov-msgs { max-height: min(52vh, 520px); }
@media (max-width: 900px) {
  .prov-wrap { grid-template-columns: 1fr; }
  .prov-chat-card .prov-msgs { max-height: 46vh; }
}

/* the import's preview: rows that read like the stock they will become */
#imp-report{margin-top:12px}
#imp-report .row{display:flex;align-items:center;gap:12px;padding:10px 0;border-top:1px solid var(--edge)}
#imp-report .row > span:first-child{flex:1;min-width:0}
#imp-report .nm{display:block;font-weight:600;font-size:13.5px}
#imp-report .sub{display:block;font-size:12px;color:var(--ink-3)}
#imp-report .amt{font-family:'JetBrains Mono',monospace;font-weight:600;text-align:right;white-space:nowrap}
#imp-report .amt small{display:block;font-family:var(--f);font-weight:500;font-size:11px;color:var(--ink-3)}
#imp-file{max-width:100%}

/* a portfolio reads like a statement: what it is worth, and which way it moved.
   The dashboard's band styles are scoped to the dashboard, so this borrows the
   shape rather than inheriting it. */
#v-portfolio{background:var(--bg);font-family:'Archivo',var(--f)}
#v-portfolio .pf-band{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:14px;margin-bottom:16px}
#v-portfolio .dcard{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:18px 20px}
#v-portfolio .dcard .lbl{font:500 12px 'Archivo',var(--f);color:var(--ink-3);text-transform:none;letter-spacing:0;margin:0}
#v-portfolio .dcard .val{font:600 24px 'JetBrains Mono',monospace;color:var(--ink);margin:8px 0 2px;letter-spacing:0}
#v-portfolio .dcard.hero .val{font-size:34px;letter-spacing:-1px}
#v-portfolio .sub2{font:400 12px 'Archivo',var(--f);color:var(--ink-3)}
#v-portfolio .rows .row{display:flex;align-items:center;gap:12px;padding:12px 0;
  border-top:1px solid var(--edge);min-width:0}
/* A flex child will not shrink below its content unless told, which is how a
   long card name pushes a whole row past the edge of its card. */
#v-portfolio .rows .row > *{min-width:0}
#v-portfolio .rows .row > span:nth-child(2){flex:1;min-width:0}
#v-portfolio .rows .th{width:38px;height:52px;border-radius:5px;overflow:hidden;flex:none;background:var(--raise)}
#v-portfolio .rows .th img{width:100%;height:100%;object-fit:cover}
#v-portfolio .rows .nm{font-weight:600;font-size:13.5px}
#v-portfolio .rows .sub{font-size:12px;color:var(--ink-3)}
#v-portfolio .rows .amt{font-family:'JetBrains Mono',monospace;font-weight:600;text-align:right;flex:none}
.pf-up{color:var(--good)}
.pf-down{color:var(--accent)}
.pf-row .amt small{display:block;font-weight:600;font-size:11px}
.pf-tag{display:inline-block;margin-left:8px;padding:2px 7px;border-radius:999px;font-size:10.5px;
  font-weight:700;background:var(--cool-soft);color:var(--cool);vertical-align:1px}
.pf-tag.keep{background:var(--gold-soft);color:var(--gold)}
.pf-stale{color:var(--warn)}
.pf-acts{display:flex;gap:6px;align-items:center;flex:none}
@media(max-width:740px){
  #v-portfolio .pf-band{grid-template-columns:1fr 1fr}
  .pf-acts{flex-wrap:wrap;justify-content:flex-end}
}
.pf-tag.stock{background:var(--good-soft);color:var(--good)}

/* the portfolio, read the way a holder reads one: the line first, then what
   moved, then what they hold */
#v-portfolio .pf-hero{padding:20px 22px 16px;margin-bottom:14px}
#v-portfolio .pf-top{display:flex;align-items:flex-start;gap:14px;margin-bottom:14px;flex-wrap:wrap}
#v-portfolio .pf-top .lbl{font:500 12px 'Archivo',var(--f);color:var(--ink-3)}
.pf-worth{font:600 40px 'JetBrains Mono',monospace;letter-spacing:-1.5px;line-height:1.05;margin:4px 0 2px}
.pf-move{font:500 13px 'Archivo',var(--f);color:var(--ink-3)}
.pf-range{padding:3px;gap:3px;flex:none;max-width:100%;overflow:hidden}
.pf-range button{padding:6px 12px;font-size:12px;border-radius:6px}
.pf-chart{width:100%;height:130px;display:block;margin:0 -2px}
.pf-chart polyline{fill:none;stroke-width:2;vector-effect:non-scaling-stroke}
.pf-chart polyline.up{stroke:var(--good)} .pf-chart polyline.down{stroke:var(--accent)}
.pf-chart .fill{stroke:none;opacity:.13}
.pf-chart .fill.up{fill:var(--good)} .pf-chart .fill.down{fill:var(--accent)}
.pf-legend{font:400 11.5px 'Archivo',var(--f);color:var(--ink-3);margin-top:8px}

/* the secondary figures, folded into the chart card: a line of facts under the
   headline rather than four boxes competing with it */
.pf-facts{display:flex;flex-wrap:wrap;gap:26px;padding:12px 0 14px;margin-bottom:2px;
  border-top:1px solid var(--edge)}
.pf-facts span{display:flex;flex-direction:column;gap:1px;min-width:0}
.pf-facts i{font:500 10.5px 'Archivo',var(--f);color:var(--ink-3);font-style:normal;letter-spacing:.02em}
.pf-facts b{font:600 15px 'JetBrains Mono',monospace;color:var(--ink)}
.pf-facts em{font:400 10.5px 'Archivo',var(--f);color:var(--ink-3);font-style:normal}
#v-portfolio .pf-movers{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}
#v-portfolio .pf-movers .amt small{display:block;font-family:'Archivo',var(--f);font-weight:500;font-size:11px;color:var(--ink-3)}

.pf-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(172px,1fr));gap:12px}
.pf-card{background:var(--raise);border:1px solid var(--line);border-radius:12px;padding:10px;
  display:flex;flex-direction:column;gap:5px}
.pf-pic{position:relative;aspect-ratio:3/4;border-radius:8px;overflow:hidden;background:var(--raise-2)}
.pf-pic img{width:100%;height:100%;object-fit:cover}
.pf-chip{position:absolute;top:6px;left:6px;font:700 9.5px 'JetBrains Mono',monospace;
  background:var(--cool-soft);color:var(--cool);border-radius:4px;padding:2px 6px}
.pf-chip.stock{background:var(--good-soft);color:var(--good)}
.pf-chip.keep{background:var(--gold-soft);color:var(--gold);left:auto;right:6px}
.pf-qty{position:absolute;bottom:6px;right:6px;font:700 10px 'JetBrains Mono',monospace;
  background:rgba(0,0,0,.6);color:#fff;border-radius:4px;padding:2px 6px}
.pf-nm{font:600 13px 'Archivo',var(--f);line-height:1.25}
.pf-set{font:400 11.5px 'Archivo',var(--f);color:var(--ink-3)}
.pf-foot{display:flex;justify-content:space-between;align-items:baseline;margin-top:auto;
  font:600 12.5px 'JetBrains Mono',monospace}
.pf-val{font-size:14px}
.pf-sub-q{font:400 11px 'Archivo',var(--f);color:var(--ink-3)}
.pf-card .pf-acts{display:flex;gap:5px;flex-wrap:wrap;margin-top:4px}
.pf-card .pf-acts .tool{font-size:11px;padding:4px 8px}
@media(max-width:900px){
  #v-portfolio .pf-stats{grid-template-columns:1fr 1fr}
  #v-portfolio .pf-movers{grid-template-columns:1fr}
}
@media(max-width:740px){
  .pf-worth{font-size:32px}
  .pf-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
}

/* whose card is it: a button that names a person, and the sheet behind it */
.ownbox{width:min(440px,100%);text-align:left}
.ownbox h2{margin:0 0 14px;font:600 17px 'Archivo',var(--f)}
.ownbox .field span{font-size:11.5px}
.ownpick{background:var(--raise);border:1px solid var(--line);border-radius:8px;padding:9px 12px;
  color:var(--ink-3);font:600 13px 'Archivo',var(--f);cursor:pointer;text-align:left;width:100%}
.ownpick:hover{border-color:#3a3e47;color:var(--ink)}
.ownpick.on{color:var(--gold);border-color:rgba(238,203,116,.4);background:var(--gold-soft)}
.ownlist{display:flex;flex-direction:column;gap:6px;max-height:46vh;overflow:auto}
.ownrow{display:flex;align-items:center;gap:11px;width:100%;text-align:left;cursor:pointer;
  background:var(--raise);border:1px solid var(--line);border-radius:10px;padding:11px 13px;color:var(--ink)}
.ownrow:hover{border-color:#3a3e47}
.ownrow.on{border-color:rgba(238,203,116,.5);background:var(--gold-soft)}
.ownrow b{display:block;font:600 13.5px 'Archivo',var(--f)}
.ownrow span span{display:block;font:400 11.5px 'Archivo',var(--f);color:var(--ink-3)}
.ownmark{width:16px;height:16px;border-radius:50%;border:2px solid var(--line);flex:none}
.ownrow.on .ownmark{border-color:var(--gold);background:var(--gold);box-shadow:inset 0 0 0 3px var(--panel)}

/* the phone's five tabs: everything else waits behind More */
.phone-more{display:none}
.phone-sheet .morebox{width:min(420px,100%);text-align:left}
.morebox h2{margin:0 0 14px;font:600 17px 'Archivo',var(--f)}
.morelist{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.morerow{display:flex;align-items:center;gap:11px;padding:13px 14px;border-radius:11px;cursor:pointer;
  background:var(--raise);border:1px solid var(--line);color:var(--ink);font:600 13.5px 'Archivo',var(--f)}
.morerow:hover{border-color:#3a3e47}
.morerow svg{width:19px;height:19px;stroke:var(--ink-3);fill:none;stroke-width:1.8;flex:none}
.morerow .railn{margin-left:auto;position:static}
@media(max-width:740px){
  /* only the five a hand at a table reaches for, plus the door to the rest */
  .rail .rnav{display:none}
  .rail .rnav[data-go="dash"],.rail .rnav[data-go="till"],.rail .rnav[data-go="inv"],
  .rail .rnav[data-go="diary"],.rail .rnav[data-go="portfolio"],.rail .rnav[data-go="mail"],
  .rail .phone-more{display:flex}
  .rail .rnav[hidden]{display:none !important}
  .rail{overflow-x:hidden;justify-content:space-around;gap:0}
  .rail .rnav{width:auto;flex:1 1 0;min-width:0;padding:6px 2px}
  .rail .rnav .t{font-size:9.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;
    letter-spacing:-.01em}
  .rail .rnav .railn{top:2px;right:calc(50% - 20px)}
}

/* the calendar: a date block, what it is, and who it concerns */
.dy-row{display:flex;align-items:center;gap:14px;padding:12px 0;border-top:1px solid var(--edge)}
.dy-row:first-child{border-top:0}
.dy-row.past{opacity:.55}
.dy-date{width:46px;flex:none;text-align:center;background:var(--raise);border-radius:9px;padding:6px 0}
.dy-date b{display:block;font:600 17px 'JetBrains Mono',monospace;line-height:1}
.dy-date i{display:block;font:600 10px 'Archivo',var(--f);font-style:normal;color:var(--ink-3);
  text-transform:uppercase;letter-spacing:.06em;margin-top:2px}
.dy-what{flex:1;min-width:0}
.dy-title{display:block;font:600 13.5px 'Archivo',var(--f)}
.dy-note{display:block;font:400 12px 'Archivo',var(--f);color:var(--ink-3)}
.dy-auto{margin-left:8px;font:600 10px 'JetBrains Mono',monospace;color:var(--cool);
  background:var(--cool-soft);border-radius:4px;padding:2px 6px;vertical-align:1px}
.dy-acts{display:flex;align-items:center;gap:10px;flex:none}
.dy-share{font:500 11.5px 'Archivo',var(--f);color:var(--gold)}
.dy-share.all{color:var(--ink-3)}
.dy-who{margin-top:6px}
.dy-who .lbl{display:block;font:500 11.5px 'Archivo',var(--f);color:var(--ink-3);margin-bottom:6px}
.dy-people{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:6px}
.dy-person{background:var(--raise);border:1px solid var(--line);border-radius:999px;padding:6px 13px;
  font:600 12.5px 'Archivo',var(--f);color:var(--ink-2);cursor:pointer}
.dy-person.on{background:var(--gold-soft);border-color:rgba(238,203,116,.45);color:var(--gold)}
@media(max-width:740px){.dy-acts .dy-share{display:none}}

/* ---- the phone, gone over properly ----
   Everything below is one pass for the small screen: nothing overhangs its
   card, nothing wraps into a second line it did not ask for, and a form is a
   column rather than a squeezed row. */
@media(max-width:740px){
  /* forms stop pretending to be rows */
  .add-row{flex-direction:column;align-items:stretch;gap:10px}
  .add-row .field,.add-row .field.grow,.add-row .numfield{width:100%}
  /* an inline width set for a desktop row must not survive into a column */
  .add-row .field input,.add-row .field select,.add-row input[style*="width"]{width:100% !important}
  .add-row .btn,.add-row .tool{width:100%;justify-content:center}
  .add-row .seg{width:100%}
  .add-row .seg button{flex:1}
  /* the portfolio's headline and its range switch */
  #v-portfolio .pf-top{gap:10px}
  #v-portfolio .pf-range{width:100%;display:flex}
  #v-portfolio .pf-range button{flex:1;padding:8px 0}
  .pf-facts{gap:18px 22px}
  /* the calendar reads as a list, not a table */
  .dy-row{gap:11px}
  .dy-date{width:42px}
  .dy-acts{gap:6px}
  /* stock tiles: names get two lines and stay inside the box */
  .inv-tile .nm,.pf-nm{overflow-wrap:anywhere}
  .inv-tile *,.pf-card *{min-width:0}
  /* cards breathe on a phone rather than hugging the frame */
  .card{padding:14px}
  .scroll{padding:0 12px 96px}
}

/* ---- the notch, the home bar, and everything they cover ----
   The page asks iOS for the whole screen (viewport-fit=cover) and a
   see-through status bar, which means the app owns the job of keeping its own
   content out from under them. It never did: on a home-screen install the
   title ran beneath the clock and the buttons hid behind the signal bars.
   Held as variables so the same rules can be proved with a fake notch. */
:root{
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
}
@media(max-width:740px){
  /* every page begins below the clock, once, rather than each header
     remembering to */
  .view{padding-top:var(--sat)}
  .phead{padding-left:calc(14px + var(--sal));padding-right:calc(14px + var(--sar))}
  .scroll{padding-left:calc(12px + var(--sal));padding-right:calc(12px + var(--sar))}

  /* the bar reads as a bar: its own surface, carried down through the home
     indicator so the strip below the labels is part of it, not a gap */
  /* One authoritative rule for the bar, rather than another layer arguing with
     the last: it sits on the bottom edge, spans the full width, and its own
     surface runs down through the home indicator. Height comes from the
     content plus that inset, so nothing floats above a band of nothing. */
  .rail{background:var(--panel);left:0;right:0;width:100%;
    height:auto;min-height:calc(54px + var(--sab));
    padding:5px calc(4px + var(--sal)) calc(5px + var(--sab)) calc(4px + var(--sar));
    display:flex;align-items:center;justify-content:space-between;gap:0}
  .rail .rnav{flex:1 1 0;width:auto;min-width:0;padding:5px 1px;margin:0}
  /* The rail's spacer pushes Settings to the bottom on a desktop; left in a tab
     bar it was an invisible eighth tab eating fifty pixels of the row. */
  .rail .sp,.rail .mile-mod{display:none}

  /* anything pinned to the top of the screen clears the clock too */
  .offline-bar{top:calc(8px + var(--sat))}
  .newbuild{top:calc(10px + var(--sat))}
  #ownmodal .smp-box,#moresheet .smp-box{margin-top:var(--sat)}

  /* a phone header is a title and one action, not a wrapping row of buttons */
  .phead{gap:8px 10px;align-items:flex-start}
  .phead h1{font-size:20px;line-height:1.15}
  .phead .btn{padding:9px 13px;font-size:12.5px}
}

/* ---- stop the phone zooming itself ----
   iOS zooms into any field whose text is under 16px the moment it is tapped,
   and leaves the page scaled up afterwards, which is what made every form feel
   like it fell off the side of the screen. Sixteen pixels on a phone is not a
   style choice, it is the price of the keyboard behaving. */
@media(max-width:740px){
  input,select,textarea,
  .field input,.field select,.numfield input,.scan input,#q,
  .add-row input,.add-row select{font-size:16px !important}
  /* and nothing may be wider than the phone, whatever it thinks it needs */
  html,body{max-width:100%;overflow-x:hidden}
  .app,.view,.scroll,.card,.add-row,.seg{max-width:100%}
  input[type="date"],input[type="time"]{min-width:0;-webkit-appearance:none;appearance:none}
}

/* the till's scan row on a phone: the box gets the width, the button its own
   line, because a 16px field and a button cannot share 360 pixels */
@media(max-width:740px){
  #v-till .scan{flex-wrap:wrap;padding:10px 12px;gap:8px}
  #v-till .scan input{flex:1 1 100%;order:1;padding:6px 0}
  #v-till .scan .ico{order:0}
  #v-till .scan .tool{order:2;width:100%;justify-content:center;padding:10px}
  #v-till .scan .hint{display:none}
}

/* ---- the real height of a phone screen ----
   100vh on iOS means the tallest the viewport ever gets, not the height it is
   right now, so a bar pinned to the bottom of it can sit a browser-chrome's
   worth above the glass. dvh is the height as it actually stands. */
@supports (height: 100dvh){
  .app{height:100dvh}
  body:has(.setup-bar:not([hidden])) .app{height:calc(100dvh - 60px)}
}
@media(max-width:740px){
  /* And the bar itself answers to the visual viewport, not the layout one:
     anchored to the bottom, with its own surface filling the inset beneath. */
  .rail{position:fixed;bottom:0;left:0;right:0;top:auto}
  /* iOS gives a standalone app no bottom inset on some devices while still
     keeping a home indicator, so a floor under it keeps the labels clear. */
  @supports (padding: max(0px)){
    .rail{padding-bottom:max(8px, calc(5px + var(--sab)))}
  }
}

/* ---- the rail, grouped ----
   Eight destinations instead of twelve. A section's children appear when that
   section is where you are, so the rail stays short and still says where you
   stand. No chevron: opening a section is the same act as going to it. */
.rsub{display:none;padding:2px 0 4px}
.rsub.open{display:block}
.rail .rnav.sub{padding-left:34px;font-size:13px;opacity:.9}
.app:not(.rail-open) .rail .rnav.sub{padding-left:0}
.rail .rnav.sub svg{width:17px;height:17px}
.rail .rnav.sub .t{font-size:12.5px}
/* a parent whose child you are inside is lit, but not as the current page */
.rail .rnav.in{color:var(--ink);background:var(--raise)}
.rail .rnav.in svg{stroke:var(--ink)}

/* Finance: figures that are doors */
#v-finance .fin-band{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:14px}
#v-finance .fin-card{text-align:left;cursor:pointer;background:var(--panel);
  border:1px solid var(--line);border-radius:12px;padding:18px 20px}
#v-finance .fin-card:hover{border-color:#3a3e47}
#v-finance .lbl{font:500 12px 'Archivo',var(--f);color:var(--ink-3);margin:0}
#v-finance .val{font:600 26px 'JetBrains Mono',monospace;color:var(--ink);margin:8px 0 2px}
#v-finance .sub2{font:400 12px 'Archivo',var(--f);color:var(--ink-3)}
#v-finance .fin-two{display:grid;grid-template-columns:1fr 1fr;gap:14px}
#v-finance .rows .row{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--edge)}
#v-finance .rows .row > span:first-child{flex:1;min-width:0}
#v-finance .rows .amt{font-family:'JetBrains Mono',monospace;font-weight:600}
@media(max-width:1100px){#v-finance .fin-band{grid-template-columns:1fr 1fr}#v-finance .fin-two{grid-template-columns:1fr}}
@media(max-width:740px){
  #v-finance .fin-band{grid-template-columns:1fr 1fr;gap:10px}
  .rsub{display:none !important}
}

/* ============================================================
   THE GLASS COUNTER — the desktop layer.
   Appended last so it wins the cascade: the component bones above
   keep working, this block gives them the world the app locked in,
   and a little more theatre than a phone has room for.
   ============================================================ */

/* -- titles speak Barlow, uppercase, like the tickets on the shelf edge -- */
.phead h1{
  font:600 30px/1 var(--ftick);letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink)}
.phead{padding:26px 28px 18px}
.phead .sub{font-size:13px}

/* -- figures count in mono, everywhere -- */
.stat .val,.mono,td.num,.num{font-family:var(--fmono);font-weight:600}

/* -- the cream tickets: the app's signature, given room on a desk -- */
.stat{
  background:var(--ticket);color:var(--tick-ink);border-radius:var(--r-sm);
  box-shadow:0 12px 28px rgba(0,0,0,.38),inset 0 1px 0 rgba(255,255,255,.55);
  transition:transform .15s ease,box-shadow .15s ease}
.stat:hover{transform:translateY(-2px);box-shadow:0 18px 36px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,255,255,.55)}
.stat .lbl{
  font:600 12px/1 var(--ftick);letter-spacing:.14em;text-transform:uppercase;
  color:var(--tick-mut)}
.stat .val{font-size:28px;color:var(--tick-ink);letter-spacing:0}
.stat .delta{font-weight:700}
.stat .delta.up{color:#2E6B43}
.stat .delta.down{color:var(--brand)}
.stat .delta.flat{color:var(--tick-mut)}
.stat .muted,.stat small{color:var(--tick-mut)}

/* -- the rail is the cabinet's spine; the chosen room burns red -- */
.rail{background:var(--bg);border-right:1px solid var(--line)}
.rnav{border-radius:10px}
.rnav.on{background:var(--accent-fill);color:var(--on-accent);
  box-shadow:0 6px 18px rgba(198,47,29,.35)}
.rnav.on:hover{background:var(--accent-fill);color:var(--on-accent)}
.rsub .rnav.on{box-shadow:none}

/* -- shelves get the faint light of the glass -- */
.panel,.card{box-shadow:inset 0 1px 0 rgba(255,255,255,.03)}

/* -- money commits in red; the key throws a little heat -- */
.btn{border-radius:var(--r-sm)}
.btn.primary{
  box-shadow:0 8px 22px rgba(198,47,29,.30);
  font-weight:700;letter-spacing:.01em;
  transition:transform .12s ease,box-shadow .12s ease,filter .12s ease}
.btn.primary:hover{transform:translateY(-1px);box-shadow:0 12px 26px rgba(198,47,29,.38)}
.btn.primary:active{transform:translateY(0)}

/* -- chosen chips speak red like the app's segments -- */
.chip{border-radius:999px}
.chip.on{box-shadow:0 4px 14px rgba(198,47,29,.28)}

/* -- inputs sit in the shelf, hairline when idle, red when spoken to -- */
input:focus,select:focus,textarea:focus{outline:none;box-shadow:0 0 0 2px var(--accent-line)}

/* -- the dashboard sheds the old handoff skin and joins the counter -- */
#v-dash{
  --d-bg:var(--bg);--d-card:var(--panel);--d-bord:var(--line);--d-div:var(--line);
  --d-btn:var(--raise);--d-ink:var(--ink);--d-ink2:var(--ink);--d-mut:var(--ink-2);
  --d-mut2:var(--ink-3);--d-faint:var(--ink-3);--d-red:var(--brand);
  --d-redh:#A5271A;--d-link:var(--accent);--d-green:var(--good);
  --d-gold:var(--gold);--d-goldm:#C9A755;--d-golddim:#8A7847;
  font-family:var(--f)}
#v-dash .dash-head h1{
  font:600 34px/1 var(--ftick);letter-spacing:.06em;text-transform:uppercase}
#v-dash .dcard .val{font-family:var(--fmono)}
#v-dash .dcard .lbl{font:600 12px/1 var(--ftick);letter-spacing:.14em;text-transform:uppercase}
/* Only the stat tickets take the cream: the content shelves (feed, recent
   sales) stay dark, and the brass attention card keeps its own voice. */
#v-dash .dcard.stat{
  background:var(--ticket);border:0;color:var(--tick-ink);
  box-shadow:0 12px 28px rgba(0,0,0,.38),inset 0 1px 0 rgba(255,255,255,.55)}
#v-dash .dcard.stat .val,#v-dash .stat.hero .val,#v-dash .stat.nil .val{color:var(--tick-ink)}
#v-dash .dcard.stat .lbl{
  font:600 12px/1 var(--ftick);letter-spacing:.14em;text-transform:uppercase;
  color:var(--tick-mut)}
#v-dash .dcard.stat .sub2,#v-dash .dcard.stat .muted,#v-dash .dcard.stat small{color:var(--tick-mut)}
#v-dash .dcard.stat .delta.up{color:#2E6B43}
#v-dash .dcard.stat .delta.down{color:var(--brand)}
#v-dash .dcard.stat a,#v-dash .dcard.stat .tool{color:#8E1C0E}
/* the hero's sparkline draws in leaf ink on the cream */
#v-dash .stat.hero .spark .line{stroke:#2E6B43}
#v-dash .stat.hero .spark .area{fill:rgba(46,107,67,.14)}
#v-dash .stat.hero .spark circle{fill:#2E6B43}

/* -- scrollbars in the world's colours -- */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-thumb{background:var(--raise-2);border-radius:5px}
::-webkit-scrollbar-thumb:hover{background:#2E3743}
::-webkit-scrollbar-track{background:transparent}

/* -- selection, in the shop's red -- */
::selection{background:rgba(198,47,29,.45);color:#fff}

/* -- the SHOW overlays: one line of extra truth on each stock tile -- */
.show-tag{
  display:inline-block;margin:4px 0 2px;padding:3px 8px;border-radius:6px;
  font:500 11px var(--fmono);letter-spacing:.02em;
  background:var(--raise);color:var(--ink-2)}
.show-tag.up{background:var(--good-soft);color:var(--good)}
.show-tag.down{background:var(--accent-soft);color:var(--accent)}
.show-tag.warn{background:var(--gold-soft);color:var(--gold)}

/* -- the calendar, opened up -- */
.dy-row.tap{cursor:pointer}
.dy-until{color:var(--brand);font-weight:700}
.dy-chev{width:18px;height:18px;stroke:var(--ink-3);fill:none;stroke-width:2;
  transition:transform .18s ease}
.dy-chev.open{transform:rotate(180deg)}
.dy-exp{padding:2px 0 16px 60px;animation:dyexp .18s ease}
@keyframes dyexp{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.dy-fullnote{margin:0 0 12px;font:400 13px var(--f);color:var(--ink-2);line-height:1.5}
.dy-checklist{display:flex;flex-direction:column;gap:2px;margin-bottom:12px}
.dy-check{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:8px;
  background:var(--raise);cursor:pointer}
.dy-check input{width:17px;height:17px;accent-color:var(--brand);flex:none}
.dy-check span{flex:1;font:500 13px var(--f);color:var(--ink)}
.dy-check.done span{text-decoration:line-through;color:var(--ink-3)}
.dy-x{background:none;border:0;color:var(--ink-3);font-size:17px;cursor:pointer;padding:0 4px;flex:none}
.dy-x:hover{color:var(--brand)}
.dy-addchk input{width:100%;background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:9px 11px;font:500 13px var(--f);color:var(--ink)}
.dy-addchk input::placeholder{color:var(--ink-3)}
.dy-addchk input:focus{outline:none;box-shadow:0 0 0 2px var(--accent-line)}
.dy-exp-acts{display:flex;gap:8px;margin-top:12px}
.tool.danger{color:var(--accent)}
@media(max-width:740px){.dy-exp{padding-left:14px}}

/* -- one card's own page -- */
.inv-tile .prlink{cursor:pointer;background:none;border:0;padding:0;text-align:inherit;font:inherit;color:inherit;display:block;width:100%}
b.nm.prlink:hover,.inv-tile .ith.prlink:hover{opacity:.85}
.pr-head{display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap}
.pr-img{width:150px;flex:none;border-radius:12px;overflow:hidden;background:var(--raise);
  box-shadow:0 12px 28px rgba(0,0,0,.4)}
.pr-img img{width:100%;display:block}
.pr-meta{flex:1;min-width:220px}
.pr-meta h1{font:600 26px var(--ftick);letter-spacing:.04em;text-transform:uppercase;margin:0 0 4px;color:var(--ink)}
.pr-price{font:600 34px var(--fmono);color:var(--ink);margin:10px 0 2px}
.pr-actions{display:flex;gap:8px;margin-top:14px}
.pr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin-top:18px}
.pr-fact{background:var(--panel);border-radius:10px;padding:12px 14px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.03)}
.pr-fact span{display:block;font:600 11px var(--ftick);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.pr-fact b{display:block;font:600 15px var(--f);color:var(--ink);margin-top:4px}
.pr-hist{display:flex;flex-direction:column;gap:2px;margin-top:8px}
.pr-move{display:flex;align-items:center;gap:12px;padding:8px 10px;border-radius:8px}
.pr-move:nth-child(odd){background:var(--raise)}
.pr-mw{font:600 13px var(--f);color:var(--ink);flex:none;min-width:110px}
.pr-move .muted{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pr-mt{font:500 12px var(--fmono);color:var(--ink-3);flex:none}

/* A full-shop reprice takes minutes, so it shows its working as it goes. */
.px-progress{margin:6px 0 12px}
.px-bar{height:6px;border-radius:99px;background:var(--raise,#1b2027);overflow:hidden}
.px-bar i{display:block;height:100%;width:0;background:var(--accent,#c62f1d);transition:width .6s ease}
.px-line{font-size:12px;color:var(--ink-3);margin-top:6px}
.px-sub{font-size:13.5px;margin:0}
.ed-printing{display:flex;align-items:center;gap:10px}
.ed-printing b{font-size:13.5px}
.pr-opt{cursor:pointer}
.pr-opt.on{background:var(--accent-soft)}

/* ---------------- the hunt ---------------- */
/* One pill for a grading play, wherever a card is being bought. Gold because
   gold already means "worth acting on" in HQ; the hitlist version is solid. */
.hpill{display:inline-block;margin-left:6px;padding:2px 7px;border-radius:999px;font-size:10.5px;
  font-weight:800;letter-spacing:.02em;white-space:nowrap;vertical-align:1px;
  background:var(--gold-soft);color:var(--gold)}
.hpill.on{background:var(--gold);color:#1a1406}

.hunt-assume{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin-bottom:14px;align-items:end}
.hunt-assume .hint{grid-column:1/-1;margin:0;color:var(--ink-3);font-size:12px;font-weight:600}

.hunt-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
.hunt-q{background:var(--raise);border:1.5px solid transparent;border-radius:var(--r-sm);
  padding:10px 13px;font-size:14px;font-weight:600;min-width:220px;flex:0 1 280px}
.hunt-q:focus{border-color:var(--accent);outline:none}
.hunt-presets{display:flex;gap:6px;flex-wrap:wrap;flex:1;min-width:0}
.hpre{cursor:pointer;padding:7px 8px 7px 13px;font-size:12.5px;background:var(--raise)}
.hpre .x{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:50%;
  font-size:13px;line-height:1;opacity:.55}
.hpre .x:hover{opacity:1;background:rgba(0,0,0,.18)}

.hunt-filters{display:flex;gap:8px 14px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.hf-g{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--ink-3)}
.hf-g b{font-weight:700}
.hf-g em{font-style:normal}
.hf-g input{width:62px;background:var(--raise);border:1.5px solid transparent;border-radius:7px;
  padding:6px 8px;font-size:13px;font-weight:700;color:var(--ink)}
.hf-g input:focus{border-color:var(--accent);outline:none}
.hunt-filters .chip{padding:6px 12px;font-size:12.5px;background:var(--raise)}
.hunt-filters .chip.on{background:var(--accent-fill);color:var(--on-accent)}
.hf-sort{background:var(--raise);border:0;border-radius:7px;padding:7px 9px;font-size:12.5px;font-weight:700;color:var(--ink-2)}

/* A table, but read as a decision. Every column has a fixed width so each
   figure sits under its header on every row (auto columns sized each row on
   its own, which is what made the old table ragged). Only the average profit
   is loud; everything else is quieter the less it matters to the choice. */
.hunt-table{padding:4px 8px 10px}
.hrow{display:grid;grid-template-columns:52px minmax(200px,1fr) 84px 84px 116px 150px 172px;
  column-gap:18px;align-items:center;padding:12px 12px;border-top:1px solid var(--line);border-radius:10px}
.hrow:not(.hhead):hover{background:var(--raise)}
.hrow:not(.hhead):hover + .hrow{border-top-color:transparent}
.hrow.hhead{border-top:0;padding:10px 12px 8px;font-size:10.5px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);position:sticky;top:0;z-index:2;background:var(--panel);border-radius:0}
.hrow.hhead span:nth-child(n+3){text-align:right}
.hrow.hhead span:last-child{text-align:right}
.hrow .th img{width:52px;border-radius:5px;display:block;background:var(--bg);box-shadow:0 2px 8px rgba(0,0,0,.28)}
.hrow .hmain{min-width:0}
.hrow .nm{display:block;font-size:14.5px;font-weight:800;line-height:1.2;letter-spacing:-.005em}
.hrow .nm em{font-style:normal;color:var(--ink-3);font-weight:700;margin-left:2px}
.hrow .sub{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:3px}
.hrow .sub.seen{color:var(--gold)}
.hrow .hn{text-align:right;font-size:14px;font-weight:700;white-space:nowrap;font-variant-numeric:tabular-nums}
.hrow .hn.dim{color:var(--ink-2)}
.hrow .hn.ten{font-weight:800;color:var(--ink)}
.hrow .hn small{display:block;font-size:10.5px;font-weight:700;color:var(--ink-3);margin-top:3px}
.hrow .hev{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.hrow .hev b{display:block;font-size:18px;font-weight:900;letter-spacing:-.01em;line-height:1.1}
.hrow .hev.pos b{color:var(--good)}
.hrow .hev.neg b{color:var(--ink-3)}
.hrow .hev small{display:block;font-size:11px;font-weight:700;color:var(--ink-3);margin-top:4px}
.hrow .hev small i{font-style:normal}
.hrow .hev small i.neg{color:var(--accent)}
.hbuy{display:flex;align-items:center;justify-content:flex-end;gap:12px}
.hbuy.col{flex-direction:column;align-items:flex-end;gap:4px}
.hbuy.col small,.hpay small{display:block;font-size:10px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.hpay{text-align:right;font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
.hadd{background:var(--raise-2,var(--raise));color:var(--ink);border-radius:8px;padding:8px 11px;
  font-size:12.5px;font-weight:800;white-space:nowrap;border:1px solid var(--line)}
.hadd:hover{background:var(--accent-fill);color:var(--on-accent);border-color:transparent}
.hrow:hover .hadd{border-color:var(--ink-3)}
.hflags{display:flex;gap:5px;flex-wrap:wrap;margin-top:6px}
.hflag{font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;background:var(--raise);color:var(--ink-3)}
.hflag.bad{background:rgba(224,90,60,.14);color:var(--accent)}
.hrow.hl{grid-template-columns:52px minmax(200px,1fr) 84px 96px 116px 130px minmax(120px,200px) 36px}
.hrow .hmax{width:118px}
.hrow .hmax input{padding:8px 6px 8px 4px;font-size:14px;text-align:right}
.hrow .hmax i.pre{padding-left:10px}
.hnote{background:var(--raise);border:1.5px solid transparent;border-radius:var(--r-sm);padding:9px 10px;
  font-size:13px;font-weight:600;min-width:0;width:100%}
.hnote:focus{border-color:var(--accent);outline:none}
.hdel{width:30px;height:30px;border-radius:8px;font-size:18px;line-height:1;color:var(--ink-3);background:transparent}
.hdel:hover{background:rgba(224,90,60,.14);color:var(--accent)}
.hrow .hact{text-align:right}
@media (max-width:1180px){
  .hrow{grid-template-columns:48px minmax(160px,1fr) 76px 96px 128px 150px}
  .hrow > :nth-child(4){display:none}
  .hrow.hl{grid-template-columns:48px minmax(160px,1fr) 90px 110px 124px 36px}
  .hrow.hl > :nth-child(3),.hrow.hl > :nth-child(7){display:none}
  .hrow.hl > :nth-child(4){display:block}
}
/* Phone: the row becomes a card. Name on top, the ladder in a line, and the
   verdict and the button side by side at the bottom. */
@media (max-width:720px){
  .hrow.hhead{display:none}
  .hrow,.hrow.hl{grid-template-columns:48px 1fr auto;grid-template-areas:"th main main" "th raw ten" "ev ev buy";
    row-gap:10px;column-gap:12px;padding:14px 10px}
  .hrow > .th{grid-area:th;align-self:start}
  .hrow > .hmain{grid-area:main}
  .hrow > :nth-child(3){grid-area:raw;text-align:left}
  .hrow > :nth-child(3)::before{content:"Raw ";color:var(--ink-3);font-size:11px;font-weight:700}
  .hrow > .ten{grid-area:ten}
  .hrow > .hev{grid-area:ev;text-align:left}
  .hrow > .hbuy{grid-area:buy}
  .hrow.hl > .hbuy{grid-area:buy}
  .hrow.hl > .hnote{display:none}
  .hrow.hl > .hact{position:absolute;right:8px;top:8px}
  .hrow.hl{position:relative}
}
.hunt-foot{padding:10px 0 2px}
.hunt-add{display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding:12px 0}
.hunt-add .hunt-q{flex:1 1 320px;max-width:520px}
.hunt-results{max-width:620px}

/* ---------------- buylist detail ---------------- */
.orow.open{grid-template-columns:1fr auto auto}
.bl-detail{grid-column:1/-1;background:var(--bg);border-radius:var(--r-sm);padding:6px 14px 12px;margin-top:4px}
.bl-note{font-size:13px;font-weight:600;color:var(--ink-2);margin:10px 0 4px;font-style:italic}
.bl-item{display:grid;grid-template-columns:auto 1fr 110px 130px;gap:14px;align-items:center;padding:10px 0;border-top:1px solid var(--line)}
.bl-item:first-of-type{border-top:0}
.bl-phs{display:flex;gap:6px}
.bl-ph{width:46px;height:64px;object-fit:cover;border-radius:4px;cursor:zoom-in;background:var(--raise)}
.bl-ph.none{display:grid;place-items:center;font-size:10px;font-weight:700;color:var(--ink-3);cursor:default;text-align:center}
.bl-main{min-width:0}
.bl-main .nm{display:block;font-size:13.5px;font-weight:700}
.bl-main .sub{display:block;color:var(--ink-3);font-size:11.5px;font-weight:600;margin-top:2px}
.bl-mk,.bl-of{text-align:right;font-size:13.5px;font-weight:800;white-space:nowrap}
.bl-mk small,.bl-of small{display:block;font-size:10.5px;font-weight:700;color:var(--ink-3);letter-spacing:.03em;margin-bottom:3px}
.bl-of .numfield input{padding:7px 4px 7px 6px;font-size:13.5px;text-align:right}
.bl-of .numfield i.pre{padding-left:9px}
.bl-foot{display:flex;gap:10px;align-items:center;flex-wrap:wrap;padding-top:12px}
.bl-method{flex:0 0 auto}
.bl-total{font-size:17px;font-weight:800;font-variant-numeric:tabular-nums}
.bl-rev{margin:8px 0 0}
.bl-zoom{position:fixed;inset:0;z-index:999;background:rgba(0,0,0,.82);display:grid;place-items:center;cursor:zoom-out;padding:24px}
.bl-zoom img{max-width:min(92vw,560px);max-height:90vh;border-radius:10px}
@media (max-width:700px){ .bl-item{grid-template-columns:auto 1fr;} .bl-mk{display:none} .bl-of{grid-column:2} }
.orow.unpaid .ot{color:var(--ink-3)}
.orow.unpaid .oa{color:var(--ink-3)}

/* ---------------- orders to pick ---------------- */
.pickbar{display:flex;align-items:center;gap:16px;width:100%;text-align:left;margin:4px 0 18px;
  padding:18px 22px;border-radius:var(--r);background:var(--accent-fill);color:var(--on-accent);
  box-shadow:0 10px 30px rgba(198,47,29,.28);cursor:pointer}
.pickbar:hover{filter:brightness(1.06)}
.pickbar[hidden]{display:none}
.pk-dot{width:12px;height:12px;border-radius:50%;background:currentColor;flex:0 0 auto;
  box-shadow:0 0 0 0 rgba(255,255,255,.6);animation:pkpulse 1.8s ease-out infinite}
@keyframes pkpulse{0%{box-shadow:0 0 0 0 rgba(255,255,255,.55)}100%{box-shadow:0 0 0 14px rgba(255,255,255,0)}}
@media (prefers-reduced-motion:reduce){.pk-dot{animation:none}}
.pk-main{flex:1;min-width:0}
.pk-main b{display:block;font-size:clamp(18px,2.2vw,24px);font-weight:900;line-height:1.1;letter-spacing:-.01em}
.pk-main span{display:block;font-size:13px;font-weight:700;opacity:.85;margin-top:4px}
.pk-cta{display:inline-flex;align-items:center;gap:6px;font-size:14px;font-weight:800;white-space:nowrap;
  background:rgba(0,0,0,.18);padding:10px 14px;border-radius:var(--r-sm)}
.pk-cta svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.2}
/* Two days unpicked: the wait itself is the headline. */
.pickbar.late .pk-main span{opacity:1;font-weight:900}
@media (max-width:600px){.pickbar{padding:15px 16px;gap:12px}.pk-cta{display:none}}
/* buylist: market check, one percentage, remarks, counter */
.bl-mk{width:auto}
.bl-now{display:block;font-size:11.5px;font-weight:800;color:var(--good);margin-top:3px}
.bl-now.none{color:var(--ink-3)}
.bl-main .nm em{font-style:normal;color:var(--ink-3)}
.bl-tools{display:flex;gap:12px;align-items:center;flex-wrap:wrap;padding-top:12px;border-top:1px solid var(--line)}
.bl-pct{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;font-weight:700;color:var(--ink-3)}
.bl-pct .numfield{width:190px}
.bl-pct .numfield input{padding:9px 4px 9px 12px;font-size:14px}
.bl-tools .bl-total{margin-left:auto}
.bl-remark{display:block;width:100%;margin-top:10px;background:var(--raise);border:1.5px solid transparent;
  border-radius:var(--r-sm);padding:10px 12px;font:600 13.5px/1.45 inherit;color:var(--ink);resize:vertical}
.bl-remark:focus{border-color:var(--accent);outline:none}
.bl-foot .sp{flex:1}
.ctr-pill{display:inline-block;margin-left:6px;padding:2px 7px;border-radius:999px;font-size:10.5px;font-weight:800;
  vertical-align:1px;background:var(--raise);color:var(--ink-3)}
.ctr-pill.sent{background:rgba(90,130,224,.16);color:#7fa4e8}
.ctr-pill.accepted{background:rgba(63,179,127,.16);color:var(--good)}
.ctr-pill.declined{background:rgba(224,90,60,.14);color:var(--accent)}
/* Phone: saved searches in one swipeable line rather than pushing the page wide. */
@media (max-width:720px){
  .hunt-bar{flex-direction:column;align-items:stretch}
  .hunt-q{min-width:0;flex:1 1 auto;width:100%}
  .hunt-presets{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;width:100%}
  .hunt-presets::-webkit-scrollbar{display:none}
}

/* ---------------- hunt views ---------------- */
/* The views are the page's main control, so they are big enough to be one:
   a name and a live count each, the current one lit. */
.hunt-lenses{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;margin:0 0 12px;padding-bottom:2px}
.hunt-lenses::-webkit-scrollbar{display:none}
.hlens{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:2px;flex:0 0 auto;
  min-width:128px;padding:10px 14px;border-radius:12px;background:var(--panel);border:1px solid var(--line);
  color:var(--ink-2);text-align:left}
.hlens b{font-size:13.5px;font-weight:800;white-space:nowrap}
.hlens span{font-size:20px;font-weight:900;font-variant-numeric:tabular-nums;color:var(--ink);line-height:1.1}
.hlens:hover{background:var(--raise)}
.hlens.on{background:var(--accent-fill);border-color:transparent;color:var(--on-accent)}
.hlens.on span{color:var(--on-accent)}
.hlens.mine{border-style:dashed}
.hlens .x{position:absolute;top:4px;right:6px;font-style:normal;font-size:14px;opacity:.5;padding:0 3px;border-radius:4px}
.hlens .x:hover{opacity:1;background:rgba(0,0,0,.2)}
.hunt-bar .hunt-hint{font-size:12.5px;font-weight:600;color:var(--ink-3)}
.hf-more{padding:9px 14px}
.hunt-filters.card{padding:14px 16px;margin-bottom:14px}
.hunt-empty{padding:34px 12px;text-align:center}
.hunt-empty b{display:block;font-size:16px;font-weight:800;margin-bottom:6px}
.hunt-empty p{color:var(--ink-3);font-size:13.5px;font-weight:600;max-width:52ch;margin:0 auto 14px}
.hunt-empty-acts{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
.hunt-empty-acts .chip{background:var(--raise)}
@media (max-width:720px){
  .hlens{min-width:108px;padding:9px 12px}
  .hlens span{font-size:17px}
  .hunt-bar .hunt-hint{display:none}
}

/* ---------------- web order detail ---------------- */
.orow .noaddr{color:var(--accent);font-weight:800}
.od{grid-column:1/-1;background:var(--bg);border-radius:var(--r-sm);padding:14px;margin-top:6px}
.od-cols{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:12px}
.od-card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.od-h{display:block;font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px}
.od-addr{font-size:14px;font-weight:600;line-height:1.5;color:var(--ink-2)}
.od-addr b{color:var(--ink);font-weight:800}
.od-ship .od-addr{font-size:15px}
.od-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.od-warn{font-size:12.5px;font-weight:700;color:var(--accent);margin:4px 0 10px}
.od-sum{display:flex;justify-content:space-between;font-size:13px;font-weight:600;color:var(--ink-2);padding:2px 0}
.od-sum b{font-variant-numeric:tabular-nums;color:var(--ink)}
.od-sum.tot{border-top:1px solid var(--line);margin-top:4px;padding-top:6px;font-size:14.5px;font-weight:800}
.od-meta{font-size:11.5px;font-weight:600;color:var(--ink-3);margin:8px 0 0}
.od-meta a{color:var(--ink-2)}
.od-item{display:grid;grid-template-columns:40px 1fr 90px 90px;gap:12px;align-items:center;padding:8px 0;border-top:1px solid var(--line)}
.od-item img{width:40px;border-radius:4px;cursor:zoom-in}
.od-noimg{width:40px;height:56px;border-radius:4px;background:var(--raise)}
.od-nm b{display:block;font-size:13.5px}
.od-nm small{display:block;font-size:11.5px;color:var(--ink-3);font-weight:600;margin-top:2px}
.od-loc{text-align:right;font-weight:800;font-size:14px}
.od-loc small,.od-pr small{display:block;font-size:10px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.od-pr{text-align:right;font-weight:800;font-variant-numeric:tabular-nums}
@media (max-width:900px){ .od-cols{grid-template-columns:1fr} }
@media (max-width:600px){ .od-item{grid-template-columns:40px 1fr auto} .od-loc{display:none} }
/* posting and refunding */
.od-send,.od-refund{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.od-sendrow{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:6px 0}
.od-in{flex:1;min-width:180px;background:var(--raise);border:1.5px solid transparent;border-radius:var(--r-sm);padding:9px 11px;font-size:13.5px;font-weight:600;color:var(--ink)}
.od-in:focus{border-color:var(--accent);outline:none}
.od-refund .od-in{width:100%;margin:6px 0}
.od-chk{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:700;color:var(--ink-2);white-space:nowrap}
.od-rl{display:grid;grid-template-columns:20px 1fr auto auto;gap:10px;align-items:center;padding:7px 0;border-top:1px solid var(--line);font-size:13.5px;font-weight:600}
.od-rl b{font-variant-numeric:tabular-nums}
.od-qty{width:56px;background:var(--raise);border:0;border-radius:6px;padding:5px 6px;font-weight:700;color:var(--ink)}
.od-amt{width:140px}
.od-amt input{padding:8px 6px 8px 4px}

/* Which printing a search row is, and the question when there is a choice. */
.cprint{display:inline-block;margin-top:3px;font-size:10.5px;font-weight:800;letter-spacing:.03em;
  text-transform:uppercase;color:var(--ink-3)}
.cprint.special{color:var(--warn,#e0a33a)}
.printings{margin:10px 0 4px;border-radius:var(--r-sm);background:var(--raise);padding:10px}
.printings .pq{font-size:12.5px;font-weight:700;color:var(--ink-2);margin:0 2px 8px}
.pr-row{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border-radius:8px;text-align:left}
.pr-row:hover{background:var(--raise-2)}
.pr-row.on{background:var(--accent-soft)}
.pr-dot{width:14px;height:14px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--line);flex:none}
.pr-row.on .pr-dot{background:var(--accent-fill);box-shadow:none}
.pr-name{flex:1;font-size:13px;font-weight:700}
.pr-name small{font-weight:600;color:var(--ink-3);margin-left:4px}
.pr-gbp{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12.5px}

/* Prices sits beside Add stock at the same height and scrolls its own list,
   so a long reprice never stretches the page. The buttons stay in view. */
#fold-prices:not(.closed){display:flex;flex-direction:column;max-height:75vh}
#fold-prices:not(.closed) .fold-body{flex:1;min-height:0;display:flex;flex-direction:column}
.px-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;margin-right:-8px;padding-right:8px}
@media(min-width:741px){
  .inv-top:has(#fold-add:not(.closed)):has(#fold-prices:not(.closed)){align-items:stretch}
  .inv-top:has(#fold-add:not(.closed)) #fold-prices:not(.closed){contain:size;max-height:none;min-height:420px}
}

/* The Prices bar: one quiet line. Select all, refresh with its age, your own
   prices on or off, and the one red button that does the work. */
.px-bar-row{display:flex;align-items:center;gap:6px;flex-wrap:nowrap;margin-bottom:8px;min-width:0}
.px-bar-row .sp{flex:1}
.pxb{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 10px;border-radius:8px;
  background:var(--raise);color:var(--ink-2);font-size:12.5px;font-weight:700;white-space:nowrap;flex:none}
.pxb:hover{background:var(--raise-2);color:var(--ink)}
.pxb:disabled{opacity:.45;pointer-events:none}
.pxb svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
#px-refresh{flex:0 1 auto;min-width:0}
#px-fresh{overflow:hidden;text-overflow:ellipsis}
#px-refresh:disabled svg{animation:pxspin 1s linear infinite}
@keyframes pxspin{to{transform:rotate(360deg)}}
.pxb-all .drift-pick{pointer-events:none}
.pxsw{position:relative;width:24px;height:14px;border-radius:7px;background:var(--line);flex:none;transition:background .15s}
.pxsw::after{content:"";position:absolute;top:2px;left:2px;width:10px;height:10px;border-radius:50%;background:var(--ink-3);transition:transform .15s,background .15s}
.pxb-mine.on{color:var(--ink)}
.pxb-mine.on .pxsw{background:var(--accent-fill)}
.pxb-mine.on .pxsw::after{transform:translateX(10px);background:var(--on-accent)}
.pxb-go{height:32px;padding:0 14px;font-size:12.5px;flex:none;white-space:nowrap}
@media(max-width:740px){.px-bar-row{flex-wrap:wrap}}

/* Delete in the selection bar: quiet until hovered, then plainly a delete. */
.inv-bar .inv-del{color:var(--d-red,#d63b2f)}
.inv-bar .inv-del:hover{background:var(--d-red,#d63b2f);color:#fff}

/* Stocktake: one card per line, the three answers on the right. */
.st-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.st-head .sp{flex:1}
.st-head .inv-q{width:220px;margin:0}
.st-bar{width:120px;height:6px;border-radius:3px;background:var(--raise);overflow:hidden}
.st-bar i{display:block;height:100%;width:0;background:var(--good);transition:width .3s}
.st-item{border-top:1px solid var(--line)}
.st-item:first-child{border-top:0}
.st-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;gap:14px;align-items:center;padding:10px 0}
.st-th{display:block;width:44px;aspect-ratio:63/88;border-radius:5px;overflow:hidden;background:var(--bg)}
.st-th img{width:100%;height:100%;object-fit:cover}
/* Ours, then the market's: the pair is the first thing the eye compares. */
.st-pair{display:flex;gap:4px;padding:0;background:none;border:0;border-radius:6px;cursor:zoom-in}
.st-pair:hover .st-th{box-shadow:0 0 0 1px var(--ink-3)}
.st-q{display:grid;place-items:center;width:100%;height:100%;color:var(--ink-3);font-size:13px;font-weight:700}
.st-alts{display:flex;gap:4px;flex-wrap:wrap;margin-top:6px}
.st-alt{display:inline-flex;align-items:baseline;gap:6px;font-size:11px;font-weight:700;padding:3px 8px;border-radius:999px;
  background:none;color:var(--ink-3);border:1px solid var(--line)}
.st-alt i{font-style:normal;font-family:var(--fmono);font-weight:500}
.st-alt:hover{background:var(--raise);color:var(--ink)}
.st-alt.on{background:var(--raise-2);color:var(--ink);border-color:var(--ink-3);cursor:default}
.st-px{display:flex;flex-direction:column;gap:3px;min-width:150px}
.st-pr{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.st-pr i{font-style:normal;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.st-pr b{font-family:var(--fmono);font-size:13px;font-weight:600}
.st-pr b.nil{font-family:var(--f);font-size:11.5px;color:var(--ink-3)}
.st-pr b.warn{color:var(--warn)}
.st-gap{font-style:normal;font-family:var(--fmono);font-size:10.5px;font-weight:700;letter-spacing:0;color:var(--warn);
  background:var(--gold-soft);border-radius:4px;padding:1px 5px;margin-left:4px}
.st-ask{background:none;padding:0;font-size:11.5px;font-weight:700;color:var(--cool)}
.st-what b{display:block;font-size:13.5px;line-height:1.25}
.st-what .sub{display:block;color:var(--ink-3);font-size:12px;font-weight:600;margin-top:2px}
.st-warn{color:var(--warn)}
.st-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:5px}
.st-tag{font-size:10.5px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;color:var(--ink-3);
  background:var(--raise);border-radius:5px;padding:2px 6px}
.st-tag.special{color:var(--warn)}
.st-tag.jp{color:#fff;background:var(--d-red,#d63b2f)}
.st-acts{display:flex;gap:6px;align-items:center}
.st-yes{padding:7px 14px;font-size:12.5px;background:var(--raise-2);color:var(--ink);border:1px solid var(--ink-3)}
.st-yes:hover:not(:disabled){background:var(--good-soft);border-color:var(--good);color:var(--ink)}
.st-yes:disabled{opacity:.45}
.st-ok{font-size:12px;font-weight:800;color:var(--good);padding:0 6px}
.st-rm{color:var(--d-red,#d63b2f)}
.st-item.done .st-what b{color:var(--ink-2)}
.st-fix{display:grid;grid-template-columns:auto minmax(0,1fr);gap:16px;background:var(--raise);border-radius:var(--r-sm);
  padding:12px;margin:0 0 12px}
.st-cmp{display:flex;gap:8px;align-items:flex-start}
.st-cmp figure{margin:0;width:156px}
.st-big{display:block;width:100%;aspect-ratio:63/88;border-radius:8px;overflow:hidden;background:var(--bg)}
.st-big img{width:100%;height:100%;object-fit:contain}
.st-cmp figcaption{font-size:11px;font-weight:700;color:var(--ink-3);margin-top:6px;text-align:center;line-height:1.35}
.st-fixr{min-width:0}
.st-fixbar{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.st-fixbar .inv-q{flex:1;min-width:0;margin:0}
.st-opts{display:flex;flex-direction:column;gap:2px;max-height:300px;overflow-y:auto}
.st-opt{display:grid;grid-template-columns:34px minmax(0,1fr) auto;gap:10px;align-items:center;padding:6px 8px;border-radius:8px;text-align:left;width:100%}
.st-opt:hover{background:var(--raise-2)}
.st-opt.on{background:var(--raise-2);box-shadow:inset 2px 0 0 var(--ink-3)}
.st-oth{display:block;width:34px;aspect-ratio:63/88;border-radius:4px;overflow:hidden;background:var(--bg)}
.st-oth img{width:100%;height:100%;object-fit:cover}
.st-ow b{display:block;font-size:13px}
.st-ow b small{font-weight:600;color:var(--ink-3);margin-left:4px}
.st-ow span{display:block;font-size:11.5px;color:var(--ink-3);font-weight:600}
.st-og{font-family:'JetBrains Mono',ui-monospace,monospace;font-size:12.5px}
@media(max-width:740px){
  .st-row{grid-template-columns:auto minmax(0,1fr)}
  .st-px{grid-column:1/-1;flex-direction:row;gap:16px;min-width:0}
  .st-acts{grid-column:1/-1;justify-content:flex-end}
  .st-fix{grid-template-columns:1fr}
  .st-cmp figure{flex:1;width:auto}
  .st-head .inv-q{width:100%}
  .st-head .seg{max-width:100%;overflow-x:auto;scrollbar-width:none}
  .st-pair .st-th{width:36px}
}

/* Bulk: one dense line per card, tick, thumb, name, price, edit */
.blk-rows .blk-row{grid-template-columns:22px 34px 1fr auto auto;gap:11px;padding:8px 0}
.blk-row .th{width:34px}
#blk-import{cursor:pointer}
@media (max-width:640px){ .blk-rows .blk-row{gap:8px} }

/* the scan drop zone */
.scan-drop{border:1.5px dashed var(--line);border-radius:var(--r-sm);padding:14px 16px;margin-bottom:14px;
  color:var(--ink-3);font-size:12.5px;font-weight:600;line-height:1.5;text-align:center}
.scan-drop b{color:var(--ink-2)}
.scan-drop.over{border-color:var(--accent);background:var(--accent-soft);color:var(--ink)}
