:root{color-scheme:light;--bg:#f4f4f2;--surface:#fcfcfb;--surface-2:#f7f7f5;--surface-3:#f0efec;
--line:#e3e2de;--line-soft:#eeeeeb;--ink:#0b0b0b;--ink-2:#52514e;--ink-3:#8a8880;
--navy:#1f3864;--navy-ink:#fff;--accent:#2a78d6;--good:#0ca30c;--warning:#fab219;
--serious:#ec835a;--critical:#d03b3b;--cream:#fff2cc;--cream-line:#e8d9a8;
--shadow:0 1px 2px rgba(0,0,0,.05),0 10px 30px rgba(0,0,0,.07)}
@media (prefers-color-scheme:dark){:root:where(:not([data-theme=light])){color-scheme:dark;
--bg:#131312;--surface:#1a1a19;--surface-2:#212120;--surface-3:#282826;--line:#333331;
--line-soft:#282826;--ink:#fff;--ink-2:#c3c2b7;--ink-3:#8d8c84;--navy:#9db4dd;--navy-ink:#131312;
--accent:#3987e5;--cream:#3a3320;--cream-line:#574d2c;
--shadow:0 1px 2px rgba(0,0,0,.4),0 10px 30px rgba(0,0,0,.4)}}
:root[data-theme=dark]{color-scheme:dark;
--bg:#131312;--surface:#1a1a19;--surface-2:#212120;--surface-3:#282826;--line:#333331;
--line-soft:#282826;--ink:#fff;--ink-2:#c3c2b7;--ink-3:#8d8c84;--navy:#9db4dd;--navy-ink:#131312;
--accent:#3987e5;--cream:#3a3320;--cream-line:#574d2c;
--shadow:0 1px 2px rgba(0,0,0,.4),0 10px 30px rgba(0,0,0,.4)}
*{box-sizing:border-box}
/* [hidden] is a UA rule of the lowest possible specificity, so ANY author `display:` on the
   same element beats it and the element stays on screen. That is why the Custom commission
   boxes sat there live under a 50/50 basis: the toggle set hidden, and `.grid2{display:grid}`
   overruled it. Assert it once, here, for every element on every page. */
[hidden]{display:none !important}
body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 ui-sans-serif,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}
.bar{display:flex;align-items:center;gap:14px;padding:11px 18px;border-bottom:1px solid var(--line);background:var(--surface);flex-wrap:wrap}
.logo{font-weight:680;letter-spacing:-.01em;font-size:14px;white-space:nowrap}
.nav{display:flex;gap:3px}.nav a{font-size:12.5px;color:var(--ink-3);padding:5px 10px;border-radius:7px}
.nav a.on{background:var(--surface-3);color:var(--ink);font-weight:560}
.spacer{margin-left:auto}
.who{font-size:12px;color:var(--ink-2);display:flex;align-items:center;gap:7px}
.av{width:24px;height:24px;border-radius:50%;background:var(--navy);color:var(--navy-ink);display:grid;place-items:center;font-size:10px;font-weight:700}
.btn{background:var(--navy);color:var(--navy-ink);border:0;border-radius:8px;padding:8px 14px;font-size:13px;font-weight:620;cursor:pointer;font-family:inherit}
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink-2);font-weight:500}
.imp{background:color-mix(in srgb,var(--serious) 18%,transparent);border-bottom:1px solid color-mix(in srgb,var(--serious) 40%,transparent);padding:6px 18px;font-size:12px;color:var(--ink-2);display:flex;justify-content:space-between;align-items:center;gap:10px}
.imp form{display:inline}.imp button{background:none;border:0;color:var(--accent);font:inherit;font-size:12px;cursor:pointer;padding:0}
.wrap{max-width:1320px;margin:0 auto;padding:16px 18px 60px}
.filters{display:flex;gap:7px;align-items:center;flex-wrap:wrap;padding:10px 0 12px}
.f{font-size:12px;border:1px solid var(--line);background:var(--surface);border-radius:7px;padding:4px 10px;color:var(--ink-2);white-space:nowrap}
.f.on{background:var(--navy);border-color:var(--navy);color:var(--navy-ink);font-weight:560}
.f .c{color:var(--ink-3);font-size:11px;margin-left:5px}.f.on .c{color:var(--navy-ink);opacity:.7}
select,input[type=text],input[type=password],input[type=email]{font:inherit;font-size:13px;padding:6px 9px;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--ink)}
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:0;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  overflow:hidden;margin-bottom:14px}
.tile{background:var(--surface);padding:12px 16px;
  box-shadow:1px 0 0 var(--line-soft), 0 1px 0 var(--line-soft)}
.tile .k{font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-3)}
.tile .v{font-size:22px;font-weight:640;letter-spacing:-.025em;font-variant-numeric:tabular-nums;margin-top:2px}
.tile .s{font-size:10.5px;color:var(--ink-3);margin-top:2px}.tile .s.w{color:var(--serious)}
.card{background:var(--surface);border:1px solid var(--line);border-radius:10px;margin-bottom:9px;overflow:hidden;display:block;color:inherit}
.card.act{border-color:var(--warning);box-shadow:inset 3px 0 0 var(--warning)}
.ch{display:flex;align-items:center;gap:10px;padding:11px 14px 9px;flex-wrap:wrap;min-width:0}
.ref{font-size:13.5px;font-weight:660;font-variant-numeric:tabular-nums;white-space:nowrap}
.dot{color:var(--ink-3);font-size:11px}
.who2{font-size:12px;color:var(--ink-2)}
/* The title takes the slack and gives it back: it is the only thing here allowed to shrink,
   and it truncates rather than pushing the pill or the reference on top of itself. */
.prod{font-size:12.5px;color:var(--ink-2);flex:1 1 auto;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ch .refs{font-size:11.5px;color:var(--ink-3);flex:0 0 auto;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.ch .st{flex:0 0 auto}
.ch .ref,.ch .who2{flex:0 0 auto}
@media(max-width:640px){
  .ch{row-gap:3px}
  .prod{flex:1 1 100%;order:5}
  .ch .refs{order:6}
}
.st{font-size:10.5px;border-radius:20px;padding:2.5px 9px;border:1px solid var(--line);color:var(--ink-2);background:var(--surface-2);white-space:nowrap}
.st.b{background:color-mix(in srgb,var(--accent) 13%,transparent);border-color:color-mix(in srgb,var(--accent) 34%,transparent);color:var(--accent)}
.st.g{background:color-mix(in srgb,var(--good) 13%,transparent);border-color:color-mix(in srgb,var(--good) 34%,transparent);color:var(--good)}
/* The separators are drawn by the cells, not by a coloured gap behind them. Nine fields in a
   four-column row leaves three cells empty, and a gap-coloured background paints those as a
   grey band across half the card — which is what the empty space looked like. */
.bands{display:grid;gap:0;background:transparent;border-top:1px solid var(--line-soft);
  grid-template-columns:repeat(var(--cols,6),minmax(0,1fr))}
@media(max-width:1100px){.bands{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:760px){.bands{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:460px){.bands{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* Nine fields over two columns leaves one cell empty. Tinting the money cells would make
     that gap visible; on a narrow card the tint earns nothing anyway. */
  .b.m{background:var(--surface)}}
.b{background:var(--surface);padding:7px 11px;min-width:0;
  box-shadow:1px 0 0 var(--line-soft), 0 1px 0 var(--line-soft)}
.b .k{font-size:9px;text-transform:uppercase;letter-spacing:.055em;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.b .v{font-size:12px;font-variant-numeric:tabular-nums;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.b.m{background:var(--surface-2)}.b.m .v{font-weight:620}
.foot{background:color-mix(in srgb,var(--warning) 13%,transparent);border-top:1px solid color-mix(in srgb,var(--warning) 30%,transparent);padding:6px 14px;font-size:11.5px;color:var(--ink-2)}
.miss{background:var(--cream);border:1px solid var(--cream-line);border-radius:4px;padding:0 5px;font-size:10px;color:var(--ink-2)}
table{width:100%;border-collapse:collapse;font-size:12px}
th{font-size:9px;text-transform:uppercase;letter-spacing:.055em;color:var(--ink-3);text-align:right;padding:8px 7px 5px;font-weight:500;border-bottom:1px solid var(--line)}
th.l,td.l{text-align:left}
td{padding:6px 7px;text-align:right;font-variant-numeric:tabular-nums;border-bottom:1px solid var(--line-soft)}
.sect{margin-top:20px}
.sl{font-size:9.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-3);margin-bottom:7px}
.kv{display:flex;justify-content:space-between;gap:12px;padding:6px 0;border-bottom:1px solid var(--line-soft);font-size:12.5px}
.kv .k{color:var(--ink-3)}.kv .v{font-variant-numeric:tabular-nums;text-align:right}
.task{display:flex;gap:9px;padding:8px 0;border-bottom:1px solid var(--line-soft);font-size:12.5px;align-items:flex-start}
.tick{width:15px;height:15px;border-radius:4px;border:1.5px solid var(--line);display:grid;place-items:center;font-size:9px;color:transparent;flex:0 0 auto;margin-top:2px}
.tick.reported{border-color:var(--good);color:var(--good);border-style:dashed}
.tick.confirmed{border-color:var(--good);background:var(--good);color:#fff}
.meta{font-size:10px;color:var(--ink-3)}
.centre{max-width:380px;margin:9vh auto;padding:0 18px}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:24px;box-shadow:var(--shadow)}
.panel h1{font-size:19px;margin:0 0 4px;letter-spacing:-.02em}
.panel p.sub{color:var(--ink-2);font-size:13px;margin:0 0 18px}
label{display:block;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-3);margin:0 0 4px}
.fld{margin-bottom:13px}.fld input{width:100%}
.flash{border-radius:8px;padding:9px 12px;font-size:12.5px;margin-bottom:14px}
.flash.err{background:color-mix(in srgb,var(--critical) 12%,transparent);border:1px solid color-mix(in srgb,var(--critical) 35%,transparent)}
.secretrow{display:flex;gap:7px;align-items:stretch}
/* One unbroken line. It is a key to be copied, not prose — wrapping it invites a typo. */
.secret{flex:1;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:13px;
  letter-spacing:.04em;background:var(--surface-2);border:1px solid var(--line);
  border-radius:8px;padding:11px;white-space:nowrap;overflow-x:auto;text-align:center;
  display:block;user-select:all;-webkit-user-select:all}
.secretrow .copy{flex:0 0 auto;white-space:nowrap}
.secretrow .copy.done{border-color:var(--good);color:var(--good)}
.codes{display:grid;grid-template-columns:1fr 1fr;gap:6px;font-family:ui-monospace,Menlo,monospace;font-size:13px;margin:12px 0}
.codes span{background:var(--surface-2);border:1px solid var(--line);border-radius:6px;padding:6px;text-align:center}
.empty{color:var(--ink-3);font-size:13px;padding:26px;text-align:center;border:1px dashed var(--line);border-radius:10px}
@media(max-width:560px){.wrap{padding:12px 12px 50px}.tile .v{font-size:19px}}

/* ---- charts and the per-order expander ---------------------------------- */
/* .layout is the new-order form's two columns. The dashboard no longer uses it: its panels
   sit in a full-width band above the list, so the cards get the whole page. */
.layout{display:grid;grid-template-columns:1fr 300px;gap:18px;align-items:start}
/* A grid item is min-width:auto, so the widest child would otherwise stretch the whole column
   past the viewport and put the page on a horizontal scrollbar. */
.layout>*{min-width:0}
@media(max-width:980px){.layout{grid-template-columns:1fr}.rail{order:-1}}
.rail{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:14px 15px}

/* The band: one card divided into panels, the same construction as .tiles above it. The chart
   takes rather more than a third, because five months in a 300px column is a sparkline. */
.band{display:grid;grid-template-columns:minmax(0,2.1fr) minmax(0,1.1fr) minmax(0,1fr);
  gap:0;background:var(--surface);border:1px solid var(--line);border-radius:10px;
  overflow:hidden;margin-bottom:14px}
.band>.w{background:var(--surface);padding:14px 16px;margin:0;min-width:0;
  box-shadow:1px 0 0 var(--line-soft)}
.band>.w:last-child{box-shadow:none}
/* Two across: the chart keeps a full row to itself rather than being squeezed into half. */
@media(max-width:1100px){
  .band{grid-template-columns:repeat(2,minmax(0,1fr))}
  .band>.chartw{grid-column:1/-1;box-shadow:0 1px 0 var(--line-soft)}
}
@media(max-width:620px){
  .band{grid-template-columns:minmax(0,1fr)}
  .band>.w{box-shadow:0 1px 0 var(--line-soft)}
  .band>.w:last-child{box-shadow:none}
}
.list{min-width:0}
.w{margin-bottom:20px}.w:last-child{margin-bottom:0}
.wt{font-size:12px;font-weight:640;letter-spacing:-.005em}
.ws{font-size:10.5px;color:var(--ink-3);margin:1px 0 11px}
/* The value label sits in a fixed strip ABOVE the bar, and the bar is measured against the
   track that is left over. Every bar therefore resolves its height against the same box, so
   the bars are to scale with each other — which they were not when the label shared the
   flex column and stole a different amount of room from each one. */
.chart{display:flex;align-items:flex-end;gap:6px;height:150px;padding-top:16px;
  border-bottom:1px solid var(--line)}
.chart .cbar{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%}
.chart .cbar span{font-size:9px;color:var(--ink-3);font-variant-numeric:tabular-nums;margin-bottom:3px;white-space:nowrap}
.chart .cbar span.hi{color:var(--ink);font-weight:640}
/* flex:0 0 auto is the whole of the scaling fix. The bar's height IS its percentage of the
   peak; without this it is a shrinkable flex item, so the label above it steals room and each
   bar gives up a different amount — which is why the heights were never to scale. The label
   now sits in the 16px the chart already reserves for it at the top. */
.chart .cbar i{display:block;width:100%;flex:0 0 auto;background:var(--series-1,#2a78d6);border-radius:4px 4px 0 0;min-height:2px}
@media (prefers-color-scheme:dark){:root:where(:not([data-theme=light])) .chart .cbar i{background:#3987e5}}
:root[data-theme=dark] .chart .cbar i{background:#3987e5}
.xl{display:flex;gap:6px;margin-top:5px}
.xl span{flex:1;text-align:center;font-size:9.5px;color:var(--ink-3)}
.hbar{margin-bottom:9px}
.hbar .r{display:flex;justify-content:space-between;gap:8px;font-size:11px;margin-bottom:3px}
.hbar .r .k{color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hbar .r .v{color:var(--ink-3);font-variant-numeric:tabular-nums;flex:0 0 auto}
.hbar .t{height:6px;background:var(--surface-3);border-radius:4px;overflow:hidden}
.hbar .t i{display:block;height:100%;background:var(--series-1,#2a78d6);border-radius:4px}
@media (prefers-color-scheme:dark){:root:where(:not([data-theme=light])) .hbar .t i{background:#3987e5}}
:root[data-theme=dark] .hbar .t i{background:#3987e5}
details.lines{border-top:1px solid var(--line-soft);background:var(--surface-2)}
details.lines>summary{cursor:pointer;list-style:none;padding:7px 14px;font-size:11.5px;color:var(--accent);
  display:flex;justify-content:space-between;align-items:center}
details.lines>summary::-webkit-details-marker{display:none}
details.lines>summary::after{content:"⌄";transition:transform .15s}
details.lines[open]>summary::after{transform:rotate(180deg)}
details.lines .inner{padding:0 14px 12px;overflow-x:auto}
.card-wrap{background:var(--surface);border:1px solid var(--line);border-radius:10px;margin-bottom:9px;overflow:hidden}
.card-wrap.act{border-color:var(--warning);box-shadow:inset 3px 0 0 var(--warning)}
.card-wrap .card{border:0;border-radius:0;margin:0;box-shadow:none}

/* ---- order entry, the status control, and the intake screens ------------- */
.h1{font-size:22px;margin:0;letter-spacing:-.02em}
.sub{color:var(--ink-2);font-size:12.5px;margin:3px 0 14px;max-width:70ch}
.hint{font-size:11px;color:var(--ink-3);margin:4px 0 0;line-height:1.45}
.hint code{font-family:ui-monospace,Menlo,monospace;font-size:10.5px}
.derived{font-size:8.5px;letter-spacing:.06em;color:var(--ink-3);border:1px solid var(--line);
  border-radius:20px;padding:1px 6px;margin-left:5px;text-transform:none}
.card.p{padding:15px 16px;margin-bottom:12px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
@media(max-width:640px){.grid2{grid-template-columns:1fr}}
.fld select,.fld input,textarea{width:100%}
textarea{font:inherit;font-size:13px;padding:7px 9px;border:1px solid var(--line);
  border-radius:7px;background:var(--surface);color:var(--ink);resize:vertical;margin-bottom:8px}
input[type=file]{font-size:12px;color:var(--ink-2)}
.btn.primary{background:var(--navy);color:var(--navy-ink)}
.actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:6px}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
.tight{margin:5px 0 0;padding-left:18px;font-size:12px}
.tight li{margin-bottom:2px}
.flash.ok{background:color-mix(in srgb,var(--good) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--good) 32%,transparent)}
.flash.warn{background:color-mix(in srgb,var(--warning) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--warning) 38%,transparent)}
.st.w{background:color-mix(in srgb,var(--warning) 15%,transparent);
  border-color:color-mix(in srgb,var(--warning) 38%,transparent);color:var(--ink-2)}

/* product lines: a wide grid on a desk, two columns in a hand */
.lrow{display:grid;gap:0 8px;align-items:end;padding:9px 0;border-bottom:1px solid var(--line-soft);
  grid-template-columns:1.1fr 2fr .7fr .8fr .9fr .7fr .8fr .8fr 22px}
.lrow .lf label{font-size:8.5px;margin-bottom:2px}
.lrow input{width:100%;font-size:12.5px;padding:5px 7px}
.lrow input.looked-up{background:color-mix(in srgb,var(--good) 8%,var(--surface));
  border-color:color-mix(in srgb,var(--good) 28%,var(--line))}
.lrow.unknown .ean input{background:var(--cream);border-color:var(--cream-line)}
.lrow .drop{background:none;border:0;color:var(--ink-3);cursor:pointer;font-size:13px;padding:4px}
.lrow .drop:hover{color:var(--critical)}
@media(max-width:900px){
  .lrow{grid-template-columns:1fr 1fr;gap:6px 8px;padding:12px 0}
  .lrow .desc,.lrow .ean{grid-column:1/-1}
  .lrow .drop{grid-column:1/-1;justify-self:end}
}

/* the live panel */
.rail .kv,.band .kv{font-size:12px}
.rail .over,.band .over{color:var(--critical);font-weight:660}
.rail .note,.band .note{font-size:10.5px;color:var(--ink-3);margin-top:9px;
  line-height:1.5;max-width:62ch}
.amber{background:color-mix(in srgb,var(--warning) 13%,transparent);
  border:1px solid color-mix(in srgb,var(--warning) 32%,transparent);border-radius:7px;
  padding:7px 9px;font-size:11.5px;color:var(--ink-2);margin-bottom:6px}
.amberbox{border-color:var(--warning);box-shadow:inset 3px 0 0 var(--warning)}
.check{display:flex;gap:7px;align-items:center;font-size:12.5px;text-transform:none;
  letter-spacing:0;color:var(--ink);margin-top:8px}
.check input{width:auto}
.over{color:var(--critical)}

/* dropping a file / pasting rows */
details.intake{background:var(--surface);border:1px solid var(--line);border-radius:10px;
  margin-bottom:14px}
details.intake>summary{cursor:pointer;list-style:none;padding:10px 15px;font-size:12.5px;
  color:var(--accent)}
details.intake>summary::-webkit-details-marker{display:none}
details.intake .inner{padding:0 15px 14px}

/* status control */
.gate{background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
  padding:11px 13px;margin:8px 0;font-size:12.5px}
.blockers{margin-top:10px}
#statusform .actions{margin-top:10px}
.path{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:7px;padding:9px 11px;overflow-x:auto;
  white-space:nowrap;color:var(--ink-2)}
/* A panel that has stopped updating must not go on looking authoritative. */
.rail.stale{opacity:.5;filter:grayscale(.6)}
.rail.stale::before{content:"out of date";display:block;font-size:9.5px;text-transform:uppercase;
  letter-spacing:.07em;color:var(--critical);margin-bottom:8px}
#stale .msg{display:block;margin:3px 0 5px}

/* ---- Papi Co's six actions, on the card ---------------------------------- */
.acts{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:1px;
  background:var(--line-soft);border-top:1px solid var(--line-soft);margin-top:-1px}
.apill{background:var(--surface);padding:5px 8px;font-size:9.5px;color:var(--ink-3);
  display:flex;align-items:center;gap:4px;min-width:0;overflow:hidden}
/* A grid item is min-width:auto by default, so without this the six pills refuse to shrink
   and push the whole card wider than the phone. */
.apill .t{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.apill i{width:11px;height:11px;border-radius:3px;border:1.5px solid var(--line);flex:0 0 auto;
  display:grid;place-items:center;font-size:7px;font-style:normal;line-height:1}
.apill.close{background:var(--surface-2)}
.apill.confirmed i{background:var(--good);border-color:var(--good);color:#fff}
.apill.confirmed{color:var(--ink-2)}
.apill.reported i{border-color:var(--good);border-style:dashed;color:var(--good)}
.apill.reported{color:var(--ink-2)}
.apill.waived i{border-style:dotted;color:var(--ink-3)}
.apill.open i{border-color:var(--line)}
/* Six across is unreadable on a phone; two rows of three is not. Stated after the base rule,
   because a media query carries no extra specificity and would otherwise lose to it. */
@media(max-width:620px){.acts{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:340px){.acts{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ---- the quick-update bar and the feed ----------------------------------- */
.quick{background:var(--surface-2);border:1px solid var(--line);border-radius:10px;padding:13px 15px}
.qgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px 16px;margin-bottom:10px}
@media(max-width:640px){.qgrid{grid-template-columns:1fr}}
.qrow{display:flex;align-items:center;gap:8px;font-size:12.5px;padding:4px 0}
.qrow select{margin-left:auto;flex:0 0 auto;font-size:11.5px;padding:3px 6px}
.qrow .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.qrow .tag{font-size:8.5px;border:1px solid var(--line);border-radius:20px;padding:1px 6px;
  color:var(--ink-3);flex:0 0 auto}
.feed{border-left:2px solid var(--line);padding-left:12px;margin-left:4px}
.fitem{padding:7px 0;font-size:12.5px;border-bottom:1px solid var(--line-soft)}
.fitem:last-child{border-bottom:0}
.fitem .when{font-size:10px;color:var(--ink-3)}
.fitem .ic{display:inline-block;width:15px;color:var(--ink-3)}
.doc{display:flex;align-items:center;gap:9px;padding:7px 0;border-bottom:1px solid var(--line-soft);font-size:12.5px}
.doc .k{color:var(--ink-3);flex:0 0 128px;font-size:11px}
.doc .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc .sz{font-size:10px;color:var(--ink-3);flex:0 0 auto}

/* A finished order stays on the list — the month-end pack reads from it — but it should not
   compete with live work for attention. */
.card-wrap.done{opacity:.66}
.card-wrap.done:hover{opacity:1}
.st.done{background:color-mix(in srgb,var(--good) 13%,transparent);
  border-color:color-mix(in srgb,var(--good) 34%,transparent);color:var(--good)}
.st.cancelled{background:var(--surface-3);border-color:var(--line);color:var(--ink-3);
  text-decoration:line-through}

/* ---- closed vs open, labelled as well as coloured ------------------------ */
.chart .cbar .stack{display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}
.chart .cbar .stack u{display:block;width:100%;text-decoration:none}
.chart .cbar .stack u.open{background:var(--series-1,#2a78d6)}
.chart .cbar .stack u.closed{background:var(--good)}
@media (prefers-color-scheme:dark){:root:where(:not([data-theme=light])) .chart .cbar .stack u.open{background:#3987e5}}
:root[data-theme=dark] .chart .cbar .stack u.open{background:#3987e5}
.legend2{display:flex;gap:14px;flex-wrap:wrap;margin-top:9px;font-size:10.5px;color:var(--ink-3)}
.legend2 span{display:flex;align-items:center;gap:5px}
.legend2 .sw{width:9px;height:9px;border-radius:2px;display:inline-block}
.legend2 .sw.closed{background:var(--good)}
.legend2 .sw.open{background:var(--series-1,#2a78d6)}
.hbar .t{display:flex}
.hbar .t i.closed{background:var(--good)}
.hbar .t i.open{background:var(--series-1,#2a78d6)}
.hbar .seg{font-size:9.5px;color:var(--ink-3);margin-top:2px;font-variant-numeric:tabular-nums}
.closebar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;
  background:color-mix(in srgb,var(--good) 10%,transparent);
  border-top:1px solid color-mix(in srgb,var(--good) 28%,transparent);
  padding:8px 14px;font-size:12px;color:var(--ink-2)}
.closebar .btn{padding:5px 12px;font-size:12px}
.closepanel{border:1px solid color-mix(in srgb,var(--good) 34%,transparent);
  background:color-mix(in srgb,var(--good) 8%,transparent);border-radius:10px;padding:14px 16px;
  margin-top:14px}

/* ---- the four references, labelled and in the same order everywhere ------ */
.ch .refs{display:flex;gap:16px;flex:0 1 auto;min-width:0;align-items:baseline;white-space:nowrap}
.rf{display:flex;gap:5px;align-items:baseline;min-width:0}
/* Spelled out, so the label reads as the thing it names rather than as a code to decode.
   Sentence case, not uppercase: "SUPPLIER REF" at this letter-spacing is half again as wide. */
.rl{font-size:9.5px;letter-spacing:.01em;color:var(--ink-3);font-weight:560;flex:0 0 auto}
.rv{font-size:12px;color:var(--ink-2);font-weight:560;font-variant-numeric:tabular-nums;
  overflow:hidden;text-overflow:ellipsis}
.rf.wait .rv{color:var(--ink-3)}
.rf.na .rv{color:var(--ink-3);font-weight:450;font-variant-numeric:normal}
.rf.fill .rv{background:var(--cream);border:1px solid var(--cream-line);border-radius:4px;
  padding:0 5px;font-size:10px;color:var(--ink-2);font-weight:500}
.refline{margin:6px 0 10px}
.refline .refs{display:flex;gap:18px;flex-wrap:wrap;align-items:baseline}
.ls{display:none}
@media(max-width:640px){
  .ch .refs{flex:1 1 100%;order:7;gap:12px;white-space:normal;flex-wrap:wrap}
}
/* On a phone the spelled-out labels wrap the row onto two lines, and two cards side by side
   then wrap differently — so the short form comes back here, and only here. */
@media(max-width:460px){
  .ch .refs .lf{display:none}
  .ch .refs .ls{display:inline}
  .ch .refs{gap:14px;flex-wrap:nowrap}
}

/* ---- acting from the card ------------------------------------------------ */
form.acts{border:0;padding:0;margin:0}
.acts .apill{border:0;font-family:inherit;cursor:pointer;text-align:left;text-decoration:none}
.acts button.apill:hover{background:var(--surface-3)}
.acts button.apill:hover i{border-color:var(--good)}
.acts .chan{grid-column:1/-1;border:0;border-top:1px solid var(--line-soft);border-radius:0;
  font-size:11px;padding:5px 9px;background:var(--surface);width:100%}
.acts .chan:focus{outline:2px solid var(--accent);outline-offset:-2px}
.stepbar{display:flex;gap:7px;align-items:center;flex-wrap:wrap;padding:8px 14px;
  background:var(--surface-2);border-top:1px solid var(--line-soft)}
.stepbar .btn{padding:5px 13px;font-size:12px}
.stepbar .stepfield{font-size:11.5px;padding:4px 8px;min-width:150px}
/* The closing checklist is a list of what is still coming, not a warning. */
.closelist{background:var(--surface-2);border:1px solid var(--line);border-radius:10px;
  padding:12px 15px}
.closelist .tight{color:var(--ink-2)}

/* Our own tooltip, opening DOWNWARD from the action strip. A native title box appears above
   the pointer near the foot of a card and lands on the warehouse and ship-to values, which is
   exactly the data someone is reading. This can only ever cover the controls below it. */
.acts{position:relative}
.apill[data-tip]{position:relative}
.apill[data-tip]::after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);left:0;
  z-index:5;background:var(--ink);color:var(--bg);font-size:11px;font-weight:500;
  padding:5px 9px;border-radius:6px;white-space:nowrap;pointer-events:none;
  opacity:0;transition:opacity .12s ease .35s;box-shadow:var(--shadow)}
.apill[data-tip]:hover::after,.apill[data-tip]:focus-visible::after{opacity:1}
/* The last two would run off the right edge, so they hang from the right instead. */
.acts .apill:nth-last-child(-n+3)[data-tip]::after{left:auto;right:0}

/* ---- the principal's overview: paired bars, one shared axis, two lists ----
   Two series, so a legend is always present and the hues are the categorical
   slots in their fixed order — purchases never repaint when a filter changes
   which months survive. Gridlines are dashed and recessive; only the peak pair
   carries a direct label, the axis carries the rest.

   The pair is VALIDATED, not chosen by eye. #2a78d6 / #eb6834 (light) and
   #3987e5 / #d95926 (dark) were put through the palette validator: all six
   checks pass in both modes, worst-case colour-vision-deficiency separation
   ΔE 24.7 light and 26.8 dark — comfortably above the 8 target. Settled; do
   not re-pick these. */
/* Twelve columns, so five panels can be laid out honestly rather than fitted to a grid
   that only takes four. Wide: the month chart takes half a row and the buying/selling pair
   share the other half, side by side, which is the comparison they exist for. Below 1100 the
   chart takes a whole row — that also roughly doubles its column width, which is what keeps
   fourteen bar labels from being clipped. Below 620 everything is one column. */
.band.pc{grid-template-columns:repeat(12,minmax(0,1fr))}
.band.pc>.p6{grid-column:span 6}
.band.pc>.p3{grid-column:span 3}
@media(max-width:1100px){
  .band.pc>.wide{grid-column:span 12}
  .band.pc>.p3{grid-column:span 6}
}
@media(max-width:620px){
  .band.pc>.p6,.band.pc>.p3{grid-column:span 12}
}
/* Rows need to read as rows once there are two of them. */
.band.pc>.w{box-shadow:1px 0 0 var(--line-soft),0 1px 0 var(--line-soft)}
.pchart{position:relative;height:150px;padding:16px 0 0 44px}
.pgrid{position:absolute;left:44px;right:0;top:16px;bottom:0;pointer-events:none}
.pgrid i{position:absolute;left:0;right:0;border-top:1px dashed var(--line-soft)}
.pgrid b{position:absolute;right:calc(100% + 6px);transform:translateY(-50%);font-weight:400;
  font-size:9px;color:var(--ink-3);font-variant-numeric:tabular-nums;white-space:nowrap}
.prow{position:relative;display:flex;align-items:flex-end;gap:6px;height:100%;
  border-bottom:1px solid var(--line)}
.pcol{position:relative;flex:1;min-width:0;display:flex;align-items:flex-end;
  justify-content:center;gap:2px;height:100%}
/* A label per bar, sitting on its bar's top edge. `bottom` is the bar's own percentage, so
   the two track together and nothing has to be recomputed; margin-bottom lifts it clear of
   the fill. Each label is boxed into its half of the column and clipped, which is what makes
   fourteen labels safe: one can never drift onto its pair or into the next month. */
.pcol .pv{position:absolute;font-size:9px;line-height:1;margin-bottom:4px;pointer-events:none;
  color:var(--ink-3);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden}
.pcol .pv.l{left:0;right:50%;text-align:right;padding-right:2px}
.pcol .pv.r{left:50%;right:0;text-align:left;padding-left:2px}
.pcol .pv.pk{color:var(--ink);font-weight:640}
.pcol .pv em{display:none;font-style:normal}
.pcol i{display:block;flex:0 0 auto;width:clamp(8px,13%,22px);min-height:2px;
  border-radius:4px 4px 0 0}
.pcol i.s1,.legend2 .sw.s1{background:var(--series-1,#2a78d6)}
.pcol i.s2,.legend2 .sw.s2{background:#eb6834}
@media (prefers-color-scheme:dark){:root:where(:not([data-theme=light])) .pcol i.s1,
  :root:where(:not([data-theme=light])) .legend2 .sw.s1{background:#3987e5}
  :root:where(:not([data-theme=light])) .pcol i.s2,
  :root:where(:not([data-theme=light])) .legend2 .sw.s2{background:#d95926}}
:root[data-theme=dark] .pcol i.s1,:root[data-theme=dark] .legend2 .sw.s1{background:#3987e5}
:root[data-theme=dark] .pcol i.s2,:root[data-theme=dark] .legend2 .sw.s2{background:#d95926}
.wkh{display:flex;justify-content:space-between;gap:10px;align-items:baseline;
  font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-3);
  border-bottom:1px solid var(--line-soft);padding-bottom:3px;margin:12px 0 2px}
.w>.wkh:first-of-type{margin-top:0}
.wkh span{text-transform:none;letter-spacing:0;font-variant-numeric:tabular-nums;flex:0 0 auto}
.slist{width:100%;border-collapse:collapse;font-size:11.5px}
.slist td{padding:5px 6px 5px 0;vertical-align:top;border-bottom:1px solid var(--line-soft);
  color:var(--ink-2)}
.slist tr:last-child td{border-bottom:0}
.slist a{color:var(--ink);font-weight:600;text-decoration:none}
.slist a:hover{text-decoration:underline}
.slist .sub{display:block;font-size:10px;color:var(--ink-3)}
.slist .d,.slist .n{font-variant-numeric:tabular-nums;white-space:nowrap}
.slist .d{width:1%;color:var(--ink-3)}
.slist .n{text-align:right;padding-right:0}
.slist .sup{color:var(--ink-2)}
.slist .age{width:1%;text-align:left;font-weight:640;color:var(--ink-2)}
.slist .age.old{color:var(--critical,#d03b3b)}
/* Narrow: the € goes, because the axis and the subtitle already carry the unit and the
   glyph is the difference between the pair fitting over its column and colliding. */
@media(max-width:520px){
  /* Every pixel of the half-column goes to the label: at 36px per month the padding was
     the difference between "919k" fitting and losing its k. The clip boundary at the
     halfway line is what keeps the pair apart, not the padding. */
  .pchart{padding-left:36px}
  .pgrid{left:36px}
  .pchart+.xl{padding-left:36px}
  .pcol .pv{font-size:7.5px;margin-bottom:3px;padding-left:0;padding-right:0}
  .pcol .pv b{display:none}
  .pcol .pv em{display:inline}
  /* The peak keeps its darker ink but loses the bold: at this size the extra stroke width
     is what pushed "919k" past its half-column and clipped the k. */
  .pcol .pv.pk{font-weight:400}
}
/* The month labels have to clear the axis gutter, or every one sits a tick to the left. */
.pchart+.xl{padding-left:44px;gap:6px}

/* ---- a title someone chose, and a line that could not be computed -------- */
.prod.named,.named{font-weight:600;color:var(--ink)}
.byhand{font-size:9px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-3);
  border:1px solid var(--line);border-radius:3px;padding:1px 4px;margin-left:2px}
.lrow .lmsg{grid-column:1/-1;margin:5px 0 0;font-size:10.5px;color:var(--ink-2);
  background:var(--cream);border:1px solid var(--cream-line);border-radius:4px;padding:4px 7px}
.lrow input:disabled,.fld input:disabled{background:var(--surface-3);color:var(--ink-2);
  cursor:not-allowed}

/* ---- the export menu: <details>, so it needs no script at all ------------- */
.menu{position:relative;display:inline-block}
.menu>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary::after{content:"⌄";font-size:11px;line-height:1}
.menu[open]>summary::after{transform:rotate(180deg);display:inline-block}
.mpop{position:absolute;right:0;top:calc(100% + 6px);z-index:40;width:268px;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  box-shadow:var(--shadow);padding:6px;text-align:left}
.mpop .mh{margin:4px 8px 6px;font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-3)}
.mpop a{display:block;padding:7px 9px;border-radius:6px;color:var(--ink);text-decoration:none}
.mpop a:hover{background:var(--surface-2)}
.mpop a b{display:block;font-size:12.5px;font-weight:600}
.mpop a span{display:block;font-size:10.5px;color:var(--ink-3)}
.mpop .mf{margin:6px 9px 4px;font-size:10px;color:var(--ink-3);line-height:1.4}

/* ---- the document chase ---------------------------------------------------- */
.ch .late{flex:0 0 auto;font-size:9.5px;font-weight:660;font-variant-numeric:tabular-nums;
  color:var(--critical);background:color-mix(in srgb,var(--critical) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--critical) 32%,transparent);
  border-radius:4px;padding:1px 5px;white-space:nowrap}
.tile.warn{box-shadow:inset 3px 0 0 var(--warning)}

/* ---- the theme toggle ------------------------------------------------------
   The app defaults to LIGHT whatever the machine is set to, and remembers the choice per
   browser. The media queries above still describe dark; what changed is that an explicit
   [data-theme=dark] now selects it too, so the toggle can turn dark ON and not only off. */
.themetoggle{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;border:1px solid var(--line);border-radius:7px;
  background:var(--surface);color:var(--ink-2);cursor:pointer;font-size:13px;line-height:1}
.themetoggle:hover{background:var(--surface-2);color:var(--ink)}
.themetoggle .sun{display:none}
.themetoggle .moon{display:inline}
:root[data-theme=dark] .themetoggle .sun{display:inline}
:root[data-theme=dark] .themetoggle .moon{display:none}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
