/* ══ AIX Store admin — dark control panel ══════════════════════════════════ */
:root{
  /* Matte neutral charcoal — no blue cast in the greys, no neon in the accent.
     The chrome is monochrome and colour is carried by content, which is what
     stops a dark panel reading as a game HUD.
     --accent-rgb / --red-rgb exist so every translucent tint derives from the
     same value as the solid one; 17 literals used to hardcode the old green, so
     a theme change left half the panel behind. */
  --bg:#0a0a0b; --bg-rgb:10,10,11; --surface:#101011; --surface-2:#151517; --surface-3:#1c1c1f;
  /* Lifted: at #1f1f22 the card edges barely separated from the page and
     the whole panel read as flat. Still matte — visible, not bright. */
  --line:#2b2b31; --line-2:#3a3a42; --line-3:#4b4b56;
  --text:#f2f2f3; --text-2:#9b9ba3; --text-3:#6a6a73;
  --accent:#10a37f; --accent-rgb:16,163,127; --accent-ink:#04120d;
  /* Fills want a deeper green than text does: #10a37f is tuned to stay
     legible *on* the dark background, which makes it too vivid used *as*
     a background behind white text. */
  --accent-solid:#0d8563; --accent-solid-2:#0f9871;
  --accent-soft:rgba(var(--accent-rgb),.12);
  /* Small tinted tiles, one hue per metric — the only colour the chrome gets.
     Muted on purpose: saturated versions are what made this look synthetic. */
  --indigo:#7c81e8; --indigo-rgb:124,129,232;
  --amber:#d99a4e;  --amber-rgb:217,154,78;
  --rose:#e06b7a;   --rose-rgb:224,107,122;
  --violet:#8f8fbe; --gold:#d3a35e; --gold-rgb:211,163,94; --red:#e0706e; --red-rgb:224,112,110;
  --blue:#6f9ccf;
  --r-sm:8px; --r:11px; --r-lg:14px;
  --sans:ui-sans-serif,system-ui,"Segoe UI Variable Display","Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,"Cascadia Mono","Segoe UI Mono",Consolas,"Roboto Mono",monospace;
  /* Flatter: a matte surface shows depth through contrast, not a visible drop. */
  --shadow:0 1px 2px rgba(0,0,0,.45),0 6px 18px -14px rgba(0,0,0,.75);
  --ring:0 0 0 3px rgba(var(--accent-rgb),.20);
}
*{box-sizing:border-box;margin:0;padding:0}
html{color-scheme:dark;-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--text);font:14px/1.55 var(--sans);min-height:100vh;
  -webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
::selection{background:rgba(var(--accent-rgb),.26)}
:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--r-sm)}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:99px;border:3px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:#3a4250}

/* ── shell ────────────────────────────────────────────────────────────── */
.shell{display:grid;grid-template-columns:252px 1fr;min-height:100vh}

.sidebar{background:var(--surface);border-right:1px solid var(--line);padding:18px 14px 14px;
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.brand{display:flex;align-items:center;gap:11px;padding:4px 6px 16px}
.brand .logo{width:40px;height:40px;border-radius:12px;flex:none;display:grid;place-items:center;
  font-size:18px;background:linear-gradient(150deg,var(--surface-3),var(--surface-2));
  border:1px solid var(--line-2);box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.brand h1{font:650 15px/1.2 var(--sans);letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px}
.brand small{display:block;color:var(--text-3);font:600 9px var(--sans);
  letter-spacing:.16em;text-transform:uppercase;margin-top:3px}

.nav{display:flex;flex-direction:column;gap:2px;overflow-y:auto;margin:0 -4px;padding:0 4px}
.nav .group{color:var(--text-3);font:600 9.5px var(--sans);letter-spacing:.16em;
  text-transform:uppercase;padding:16px 12px 7px}
.nav a{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:var(--r-sm);
  color:var(--text-2);font-weight:500;position:relative;transition:background .14s,color .14s}
.nav a svg{width:17px;height:17px;flex:none;stroke-width:1.75}
.nav a:hover{color:var(--text);background:var(--surface-2)}
.nav a.active{color:var(--text);background:var(--surface-3)}
.nav a.active::before{content:"";position:absolute;left:-4px;top:9px;bottom:9px;width:3px;
  border-radius:0 3px 3px 0;background:var(--accent)}
.nav a .count{margin-left:auto;font:600 10.5px var(--mono);color:var(--text-3)}

.sidebar .foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--line)}
.sidebar .foot a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);
  color:var(--text-2);font-weight:500;transition:.14s}
.sidebar .foot a:hover{color:var(--red);background:rgba(var(--red-rgb),.07)}
.sidebar .foot svg{width:16px;height:16px;stroke-width:1.8}

/* ── topbar ───────────────────────────────────────────────────────────── */
.main{width:100%;max-width:1420px;padding:0 30px 64px}
.topbar{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:14px;
  padding:14px 0 13px;margin-bottom:26px;background:rgba(var(--bg-rgb),.82);
  backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}

.search{position:relative;flex:1;max-width:480px}
.search svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;stroke-width:1.8;color:var(--text-3);pointer-events:none}
.search input{padding:9px 62px 9px 38px;background:var(--surface);border-radius:99px;
  border-color:var(--line)}
.search input::placeholder{color:var(--text-3)}
.search kbd{position:absolute;right:8px;top:50%;transform:translateY(-50%);
  font:600 10px var(--mono);color:var(--text-3);background:var(--surface-3);
  border:1px solid var(--line-2);border-radius:6px;padding:2px 6px;pointer-events:none}

.statuspill{display:inline-flex;align-items:center;gap:8px;padding:6px 13px;border-radius:99px;
  font:600 11.5px var(--sans);border:1px solid var(--line);background:var(--surface);
  color:var(--text-2);white-space:nowrap}
.statuspill.on{color:var(--accent);border-color:rgba(var(--accent-rgb),.32);background:var(--accent-soft)}
.statuspill.off{color:var(--red);border-color:rgba(var(--red-rgb),.3);background:rgba(var(--red-rgb),.08)}
.dot{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.statuspill.on .dot{box-shadow:0 0 0 3px rgba(var(--accent-rgb),.14)}
@keyframes pulse{50%{opacity:.45}}

.iconbtn{position:relative;width:36px;height:36px;border-radius:10px;display:grid;place-items:center;
  border:1px solid var(--line);background:var(--surface);color:var(--text-2);cursor:pointer;transition:.14s}
.iconbtn:hover{color:var(--text);border-color:var(--line-2);background:var(--surface-2)}
.iconbtn svg{width:17px;height:17px;stroke-width:1.8}
.iconbtn .pip{position:absolute;top:-4px;right:-4px;min-width:17px;height:17px;padding:0 4px;
  border-radius:99px;background:var(--red);color:#fff;font:700 10px/17px var(--sans);
  text-align:center;border:2px solid var(--bg)}

.userchip{display:flex;align-items:center;gap:10px;padding:5px 12px 5px 5px;border-radius:99px;
  border:1px solid var(--line);background:var(--surface)}
.avatar{width:28px;height:28px;border-radius:50%;flex:none;display:grid;place-items:center;
  font:700 10.5px var(--sans);letter-spacing:.04em;color:var(--accent-ink);
  background:linear-gradient(140deg,var(--accent),#2bb47f)}
.userchip .who{line-height:1.25}
.userchip .who b{font:600 12.5px var(--sans)}
.userchip .who span{display:block;color:var(--text-3);font:500 10.5px var(--mono)}

/* alerts popover */
.popwrap{position:relative}
.popwrap>input{display:none}
.popover{position:absolute;right:0;top:calc(100% + 10px);width:330px;z-index:40;
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r);
  box-shadow:var(--shadow);padding:6px;display:none}
.popwrap>input:checked~.popover{display:block}
.popover h4{font:600 10px var(--sans);letter-spacing:.15em;text-transform:uppercase;
  color:var(--text-3);padding:10px 12px 6px}
.popover .arow{display:flex;gap:10px;align-items:flex-start;padding:9px 12px;border-radius:var(--r-sm)}
.popover .arow:hover{background:var(--surface-2)}
.popover .arow .ic{width:26px;height:26px;border-radius:7px;flex:none;display:grid;place-items:center;font-size:12px}
.popover .arow b{display:block;font:600 12.5px var(--sans)}
.popover .arow span{color:var(--text-3);font-size:11.5px}

/* ── page head ────────────────────────────────────────────────────────── */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  flex-wrap:wrap;margin-bottom:26px}
h2.page{font:650 31px/1.15 var(--sans);letter-spacing:-.028em}
.sub{color:var(--text-2);margin-top:6px;font-size:13.5px;max-width:70ch}
.page-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}

/* ── inline Lucide header icons (see _icons.html) ─────────────────────────── */
.hic{display:inline-block;width:1.06em;height:1.06em;vertical-align:-.16em;margin-right:.5em;
  color:var(--text-2);flex:none}
h2.page .hic{width:1em;height:1em;vertical-align:-.1em;margin-right:.42em}
h3 .hic{width:1.02em;height:1.02em}

/* ── cards ────────────────────────────────────────────────────────────── */
.grid{display:grid;gap:16px}
.grid.cols4{grid-template-columns:repeat(4,minmax(0,1fr))}
.grid.cols3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid.cols6{grid-template-columns:repeat(6,minmax(0,1fr))}
.grid.cols2{grid-template-columns:minmax(0,1.85fr) minmax(0,1fr)}
.grid.even2{grid-template-columns:repeat(2,minmax(0,1fr))}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:22px;box-shadow:var(--shadow)}
.card>h3{font:650 16px var(--sans);letter-spacing:-.012em;margin-bottom:5px;
  display:flex;align-items:center;gap:9px}
.card .hint{color:var(--text-2);font-size:12.5px;margin-bottom:18px;line-height:1.6}
.card .hint a{color:var(--accent);border-bottom:1px solid rgba(var(--accent-rgb),.35)}
.section{margin-bottom:20px}
.spread{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}
.spread h3{margin-bottom:0}

/* stat tiles */
.stat{position:relative;overflow:hidden}
.stat::after{content:"";position:absolute;inset:0 0 auto;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent)}
.stat .label{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;
  color:var(--text-3);font:600 10px var(--sans);letter-spacing:.14em;text-transform:uppercase}
.stat .icon{width:34px;height:34px;border-radius:10px;flex:none;display:grid;place-items:center;
  background:var(--surface-3);border:1px solid var(--line-2)}
.stat .icon svg{width:16px;height:16px;stroke-width:1.9}
.stat .value{font:650 30px/1.05 var(--sans);letter-spacing:-.035em;margin:16px 0 10px}
.stat .delta{display:flex;align-items:center;gap:6px;font:500 12px var(--sans);color:var(--text-2)}
.stat .delta b{font-weight:600}
.trend{display:inline-flex;align-items:center;gap:3px;font:600 12px var(--sans)}
.trend svg{width:13px;height:13px;stroke-width:2.4}
.trend.up{color:var(--accent)} .trend.down{color:var(--red)} .trend.flat{color:var(--text-3)}

/* ── chart ────────────────────────────────────────────────────────────── */
.chart{position:relative}
.chart svg{display:block;width:100%;height:auto;overflow:visible}
.chart .gridline{stroke:var(--line);stroke-width:1}
.chart .axis{fill:var(--text-3);font:500 10px var(--mono);font-variant-numeric:tabular-nums}
.chart .line{fill:none;stroke:var(--accent);stroke-width:2;stroke-linecap:round;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.chart .hit{fill:transparent;cursor:crosshair}
.chart .cross{stroke:var(--line-2);stroke-width:1;opacity:0}
.chart .cursor{fill:var(--accent);stroke:var(--surface);stroke-width:2;opacity:0}
.chart g.on .cross,.chart g.on .cursor{opacity:1}
.chart .end{fill:var(--accent);stroke:var(--surface);stroke-width:2}
.tip{position:absolute;pointer-events:none;opacity:0;transform:translate(-50%,-124%);
  background:var(--surface-3);border:1px solid var(--line-2);border-radius:var(--r-sm);
  padding:7px 11px;box-shadow:var(--shadow);white-space:nowrap;transition:opacity .1s}
.tip b{display:block;font:650 13px var(--sans);font-variant-numeric:tabular-nums}
.tip span{color:var(--text-3);font:500 10.5px var(--mono)}
.chart .mark{fill:var(--accent)}
.chart .rowlabel{fill:var(--text-2);font:500 11.5px var(--sans)}
.chart .rowvalue{fill:var(--text);font:600 11.5px var(--mono);font-variant-numeric:tabular-nums}
.chart .donut-total{fill:var(--text);font:650 19px var(--sans)}
.chart .donut-cap{fill:var(--text-3);font:600 8.5px var(--sans);letter-spacing:.18em}

.axis-caption{color:var(--text-3);font:600 10px var(--sans);letter-spacing:.14em;
  text-transform:uppercase;margin-bottom:8px}
.donutwrap{display:flex;gap:26px;align-items:center;flex-wrap:wrap}
.legend{list-style:none;display:flex;flex-direction:column;gap:9px;flex:1;min-width:190px}
.legend li{display:flex;align-items:center;gap:10px;font-size:12.5px}
.legend .key{width:11px;height:11px;border-radius:3px;flex:none}
.legend .name{flex:1;color:var(--text-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.legend .val{font:600 12px var(--mono);font-variant-numeric:tabular-nums}
.legend .pct{color:var(--text-3);font:500 11px var(--mono);min-width:38px;text-align:right}

details.tableview{margin-top:16px;border-top:1px solid var(--line);padding-top:12px}
details.tableview summary{cursor:pointer;color:var(--text-2);font:600 11.5px var(--sans);
  list-style:none;display:flex;align-items:center;gap:7px}
details.tableview summary::-webkit-details-marker{display:none}
details.tableview summary::before{content:"▸";color:var(--text-3);transition:transform .15s}
details.tableview[open] summary::before{transform:rotate(90deg)}

/* ── activity feed ────────────────────────────────────────────────────── */
.feed{display:flex;flex-direction:column}
.feed .item{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--line)}
.feed .item:last-child{border-bottom:0}
.feed .item:first-child{padding-top:0}
.feed .ic{width:30px;height:30px;border-radius:9px;flex:none;display:grid;place-items:center;
  background:var(--surface-2);border:1px solid var(--line)}
.feed .ic svg{width:14px;height:14px;stroke-width:1.9}
.feed .body{min-width:0;flex:1}
.feed .body b{font:600 13px var(--sans)}
.feed .meta{color:var(--text-3);font-size:12px;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.feed .when{margin-left:auto;color:var(--text-3);font:500 10.5px var(--mono);white-space:nowrap;flex:none}

/* ── list panels (rankings, key/value, recent orders) ─────────────────── */
.ranklist,.kvlist,.orderlist{display:flex;flex-direction:column;list-style:none}
.ranklist li,.kvlist .kv,.orderlist .o{border-bottom:1px solid var(--line)}
.ranklist li:last-child,.kvlist .kv:last-child,.orderlist .o:last-child{border-bottom:0}

.ranklist li{display:flex;align-items:center;gap:12px;padding:11px 0}
.ranklist .rank{width:24px;height:24px;border-radius:7px;flex:none;display:grid;place-items:center;
  font:700 11px var(--mono);color:var(--text-3);background:var(--surface-2);border:1px solid var(--line)}
.ranklist li:first-child .rank{color:var(--accent);border-color:rgba(var(--accent-rgb),.32);background:var(--accent-soft)}
.ranklist .nm{flex:1;min-width:0;font:600 13px var(--sans);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ranklist .qty{flex:none;color:var(--text-3);font:500 11.5px var(--mono)}
.ranklist .val{flex:none;font:600 13px var(--mono);color:var(--accent);font-variant-numeric:tabular-nums}

.kvlist .kv{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 0}
.kvlist .k{color:var(--text-2);font-size:13px}
.kvlist .v{font:650 16px var(--sans)}

.orderlist .o{display:flex;align-items:center;gap:11px;padding:11px 0}
.orderlist .ic{width:32px;height:32px;border-radius:9px;flex:none;display:grid;place-items:center;
  font:700 12px var(--sans);color:var(--text-2);background:var(--surface-2);border:1px solid var(--line)}
.orderlist .body{flex:1;min-width:0}
.orderlist .body b{display:block;font:600 13px var(--sans);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.orderlist .body span{color:var(--text-3);font:500 11px var(--mono)}
.orderlist .right{flex:none;text-align:right}
.orderlist .right .amt{display:block;font:600 13px var(--mono);font-variant-numeric:tabular-nums}

/* ── broadcast composer ───────────────────────────────────────────────── */
.toolbar{display:flex;align-items:center;gap:5px;flex-wrap:wrap;padding:8px;margin-bottom:10px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-sm)}
.tool{min-width:32px;height:30px;padding:0 8px;border-radius:7px;cursor:pointer;
  background:transparent;border:1px solid transparent;color:var(--text-2);
  font:600 13px var(--sans);transition:.14s}
.tool:hover{background:var(--surface-3);border-color:var(--line-2);color:var(--text)}
.tool-sep{width:1px;height:18px;background:var(--line-2);margin:0 4px}
.toolbar .counter{margin-left:auto;font:500 11px var(--mono);color:var(--text-3);padding-right:4px}

.tg-preview{background:#17212b;border:1px solid var(--line);border-radius:var(--r);
  padding:18px;min-height:200px}
.tg-bubble{background:#182533;border-radius:12px;padding:12px 14px;color:#e9edf2;
  font:14px/1.5 var(--sans);word-wrap:break-word;max-width:100%}
.tg-bubble b,.tg-bubble strong{font-weight:700}
.tg-bubble a{color:#6ab3f3;text-decoration:none}
.tg-bubble code{background:rgba(0,0,0,.28);border-radius:4px;padding:1px 5px;font:12.5px var(--mono)}
.tg-bubble pre{background:rgba(0,0,0,.28);border-radius:7px;padding:10px;overflow-x:auto;
  font:12.5px var(--mono);margin:6px 0}
.tg-bubble blockquote{border-left:3px solid #6ab3f3;padding:2px 0 2px 11px;margin:6px 0;
  background:rgba(106,179,243,.06);border-radius:0 6px 6px 0}
.tg-bubble tg-spoiler{background:#3a4a5a;color:transparent;border-radius:3px;cursor:pointer}
.tg-bubble tg-spoiler:hover{color:inherit;background:transparent}
.tg-bubble tg-emoji{font-style:normal}
.tg-btn{margin-top:6px;background:#2b5278;color:#e9edf2;border-radius:10px;padding:11px;
  text-align:center;font:600 13.5px var(--sans)}
/* the inline preview under an edited field — smaller than the broadcast one */
.editor-preview{min-height:0;padding:12px;margin-top:10px}
.editor-preview .tg-bubble{font-size:13.5px}
textarea[data-editor]{font:13px/1.6 var(--mono)}
input[type=file]{padding:8px 10px;font:13px var(--sans);cursor:pointer}
input[type=file]::file-selector-button{background:var(--surface-3);color:var(--text);
  border:1px solid var(--line-2);border-radius:6px;padding:5px 11px;margin-right:10px;
  font:600 12px var(--sans);cursor:pointer}

/* ── tables ───────────────────────────────────────────────────────────── */
.table-wrap{overflow-x:auto;margin:0 -22px;padding:0 22px}
table{width:100%;border-collapse:collapse}
th{color:var(--text-3);font:600 10px var(--sans);letter-spacing:.13em;text-transform:uppercase;
  text-align:left;padding:0 12px 11px;border-bottom:1px solid var(--line);white-space:nowrap}
td{padding:12px;border-bottom:1px solid var(--line);vertical-align:middle}
tr:last-child td{border-bottom:0}
tbody tr:hover td,table tr:hover td{background:rgba(255,255,255,.018)}
tr:hover td:first-child{border-radius:var(--r-sm) 0 0 var(--r-sm)}
tr:hover td:last-child{border-radius:0 var(--r-sm) var(--r-sm) 0}
.mono{font:500 12.5px var(--mono);font-variant-numeric:tabular-nums}
.amount{font:600 13px var(--mono);color:var(--accent);font-variant-numeric:tabular-nums}
.num{font:600 13px var(--mono);font-variant-numeric:tabular-nums}
td a:hover b,td a:hover{color:var(--accent)}

/* sortable column headers — the active one shows a solid arrow, the rest a
   faint ↕ so a glance says the table can be reordered */
th .sorth{display:inline-flex;align-items:center;gap:5px;color:inherit;
  letter-spacing:inherit;text-transform:inherit;transition:color .12s}
th .sorth:hover{color:var(--text)}
th .sorth .dirn{font-size:8.5px;opacity:.4;transition:opacity .12s}
th .sorth:hover .dirn{opacity:.8}
th .sorth.on{color:var(--accent)}
th .sorth.on .dirn{opacity:1;font-size:9.5px}

/* Keep flex/grid children shrinkable and stray wide content (long refs, raw
   JSON, code) inside the viewport so a page never scrolls sideways on mobile. */
.main,.card,.stat,.feed .body{min-width:0}
pre{max-width:100%;overflow-x:auto}

/* ── badges ───────────────────────────────────────────────────────────── */
.badge{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:99px;
  font:600 11px var(--sans);border:1px solid var(--line-2);background:var(--surface-2);
  color:var(--text-2);white-space:nowrap}
.badge.green{color:var(--accent);border-color:rgba(var(--accent-rgb),.3);background:var(--accent-soft)}
.badge.red{color:var(--red);border-color:rgba(var(--red-rgb),.3);background:rgba(var(--red-rgb),.08)}
.badge.gold{color:var(--gold);border-color:rgba(242,181,68,.3);background:rgba(242,181,68,.08)}
.badge.violet{color:var(--violet);border-color:rgba(139,140,240,.3);background:rgba(139,140,240,.09)}

/* ── forms ────────────────────────────────────────────────────────────── */
label{display:block;color:var(--text-3);font:600 10px var(--sans);letter-spacing:.12em;
  text-transform:uppercase;margin:0 0 7px}
input,select,textarea{width:100%;background:var(--surface-2);border:1px solid var(--line);
  color:var(--text);border-radius:var(--r-sm);padding:10px 12px;font:14px var(--sans);
  outline:none;transition:border-color .14s,box-shadow .14s}
input::placeholder,textarea::placeholder{color:var(--text-3)}
textarea{font-family:var(--mono);font-size:12.5px;min-height:120px;resize:vertical;line-height:1.6}
input:focus,select:focus,textarea:focus{border-color:var(--accent);box-shadow:var(--ring)}
select{appearance:none;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239b9ba3' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;background-size:15px;padding-right:34px}
input[type=checkbox]{width:16px;height:16px;accent-color:var(--accent);padding:0;flex:none}
.field{margin-bottom:16px}
.row{display:grid;gap:14px}
.row.c2{grid-template-columns:repeat(2,minmax(0,1fr))}
.row.c3{grid-template-columns:repeat(3,minmax(0,1fr))}
.row.c4{grid-template-columns:repeat(4,minmax(0,1fr))}
.pill-input{max-width:120px}
.check{display:flex;align-items:center;gap:9px;margin:0;text-transform:none;letter-spacing:0;
  font:500 13px var(--sans);color:var(--text);cursor:pointer}

/* ── buttons ──────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  background:var(--surface-2);color:var(--text);border:1px solid var(--line-2);
  border-radius:var(--r-sm);padding:9px 16px;font:600 13px var(--sans);cursor:pointer;
  transition:.14s;white-space:nowrap}
.btn svg{width:15px;height:15px;stroke-width:2}
.btn:hover{background:var(--surface-3);border-color:var(--line-3)}
.btn.primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
/* Replaced further down: brightening a solid fill on hover made it more
   vivid, not less. Kept as a no-op marker of where the rule used to be. */
.btn.danger{color:var(--red);border-color:rgba(var(--red-rgb),.32);background:rgba(var(--red-rgb),.06)}
.btn.danger:hover{background:rgba(var(--red-rgb),.12);border-color:rgba(var(--red-rgb),.5)}
.btn.small{padding:5px 11px;font-size:12px;border-radius:7px}
.btn.ghost{background:transparent;border-color:var(--line)}
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;filter:none;box-shadow:none}
.btn:disabled:hover{background:var(--surface-2);border-color:var(--line-2)}
.inline-form{display:inline}
.actions{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
/* maintenance mode — a closed shop must be impossible to miss */
.maint-banner{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 18px;padding:12px 16px;border-radius:var(--r-sm);
  background:rgba(var(--red-rgb),.09);border:1px solid rgba(var(--red-rgb),.4);
  color:var(--text);font-size:13.5px}
.maint-banner a{margin-left:auto;color:var(--red);font-weight:600;
  border-bottom:1px solid rgba(var(--red-rgb),.45)}
.card.maint-on{border-color:rgba(var(--red-rgb),.42)}

/* a read-only value beside a Copy button (referral links, keys) */
.copyrow{display:flex;gap:8px;align-items:stretch}
.copyrow input{flex:1;min-width:0;font-size:12.5px}
.copyrow .btn{flex:none}
/* In a table an actions cell must stay a real table cell, or a *flex* cell drops
   out of the row's height model and — when it's empty (e.g. a sold instance with
   no buttons) — collapses to its padding, so its bottom border sits above the row
   baseline and the divider looks broken under that column. Keep it a table cell;
   the buttons still sit in a row (inline-forms flow inline, adjacent items gapped). */
td.actions{display:table-cell;vertical-align:middle}
td.actions>*{vertical-align:middle}
td.actions>*+*{margin-left:7px}

/* ── list controls: filter chips, inline search, pager ────────────────── */
.listbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-bottom:18px;padding-bottom:18px;border-bottom:1px solid var(--line)}
.chips{display:flex;gap:7px;flex-wrap:wrap}
.chip-link{display:inline-flex;align-items:center;gap:7px;padding:7px 14px;border-radius:99px;
  border:1px solid var(--line-2);background:var(--surface-2);color:var(--text-2);
  font:600 12.5px var(--sans);transition:.14s;white-space:nowrap}
.chip-link:hover{color:var(--text);border-color:var(--line-3)}
.chip-link.on{color:var(--accent-ink);background:var(--accent);border-color:var(--accent)}
.chip-link .n{font:600 11px var(--mono);opacity:.75}
.findbox{display:flex;gap:8px;margin-left:auto;align-items:center}
.findbox input{width:250px;border-radius:99px;padding-left:15px}

.pager{display:flex;align-items:center;gap:10px;justify-content:space-between;
  margin-top:18px;padding-top:16px;border-top:1px solid var(--line);
  color:var(--text-3);font:500 12.5px var(--sans)}
.pager .pages{display:flex;gap:7px;align-items:center}

/* ── read-only detail rows (order / user pages) ───────────────────────── */
.deets{display:grid;grid-template-columns:minmax(120px,190px) 1fr;gap:0}
.deets>dt{padding:11px 0;color:var(--text-2);font-size:12.5px;
  border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px}
.deets>dd{padding:11px 0;font:500 13.5px var(--sans);
  border-bottom:1px solid var(--line);word-break:break-word}
.deets>dt:last-of-type,.deets>dd:last-of-type{border-bottom:0}
.deets .mono{font:12.5px var(--mono)}
details.raw{margin-top:14px}
details.raw>summary{cursor:pointer;color:var(--text-2);font:600 12.5px var(--sans);
  padding:9px 0;list-style:none;display:flex;align-items:center;gap:8px}
details.raw>summary::before{content:"▸";color:var(--text-3)}
details.raw[open]>summary::before{content:"▾"}
details.raw>summary:hover{color:var(--text)}
details.raw pre{background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:14px;overflow-x:auto;
  font:11.5px/1.65 var(--mono);color:var(--text-2);max-height:420px}

.idhead{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.idhead .av{width:54px;height:54px;border-radius:16px;flex:none;display:grid;
  place-items:center;font:700 20px var(--sans);color:var(--accent-ink);
  background:linear-gradient(140deg,var(--accent),#2bb47f)}
.idhead .who h3{font:650 20px var(--sans);letter-spacing:-.02em;margin:0}
.idhead .who .sub{margin:3px 0 0;font:12.5px var(--mono);color:var(--text-3)}

/* ── flash / empty ────────────────────────────────────────────────────── */
.flash{display:flex;align-items:center;gap:10px;background:var(--accent-soft);
  border:1px solid rgba(var(--accent-rgb),.34);color:var(--accent);border-radius:var(--r);
  padding:12px 16px;margin-bottom:18px;font-weight:500;font-size:13px}
.flash::before{content:"✓";font-weight:700}
.empty{color:var(--text-2);text-align:center;padding:40px 16px}
.empty b{display:block;font:650 15px var(--sans);color:var(--text);margin-bottom:5px}
code.chip{background:var(--surface-3);border:1px solid var(--line-2);border-radius:6px;
  padding:2px 7px;font:500 12px var(--mono)}
.truncate{max-width:320px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── login ────────────────────────────────────────────────────────────── */
.login-wrap{min-height:100vh;display:grid;place-items:center;padding:24px;
  background:var(--bg)}
.login-card{width:100%;max-width:392px;background:var(--surface);border:1px solid var(--line);
  border-radius:20px;padding:38px 34px;box-shadow:0 30px 70px -30px rgba(0,0,0,.9)}
.login-card .logo{width:52px;height:52px;border-radius:15px;display:grid;place-items:center;
  font-size:24px;background:linear-gradient(150deg,var(--surface-3),var(--surface-2));
  border:1px solid var(--line-2);margin-bottom:20px}
.login-card h1{font:650 25px var(--sans);letter-spacing:-.025em;margin-bottom:5px}
.login-card p{color:var(--text-2);margin-bottom:26px;font-size:13.5px}
.login-card .btn{width:100%;padding:11px}
.login-foot{text-align:center;color:var(--text-3);font:500 11px var(--mono);margin-top:22px}

/* ── responsive ───────────────────────────────────────────────────────── */
.stat.mini{padding:18px}
.stat.mini .value{font-size:23px;margin:13px 0 7px}
.stat.mini .delta{font-size:11.5px}

/* ── mobile drawer state (burger) — hidden on desktop ───────────────────── */
.nav-toggle{position:fixed;top:-100px;left:-100px;width:1px;height:1px;opacity:0;pointer-events:none}
.burger{display:none}
.nav-backdrop{display:none}

@media (max-width:1400px){ .grid.cols6{grid-template-columns:repeat(4,minmax(0,1fr))} }
@media (max-width:1180px){
  .grid.cols4,.grid.cols3{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid.cols6{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:980px){
  .grid.even2{grid-template-columns:1fr}
  .grid.cols2{grid-template-columns:1fr}
  .shell{grid-template-columns:1fr}

  /* the sidebar becomes an off-canvas drawer toggled by the burger */
  .sidebar{position:fixed;top:0;left:0;bottom:0;height:100vh;width:272px;z-index:60;
    transform:translateX(-100%);transition:transform .24s cubic-bezier(.4,0,.2,1);
    box-shadow:0 0 44px rgba(0,0,0,.55)}
  .nav{flex-direction:column;flex-wrap:nowrap;overflow-y:auto}
  #nav-toggle:checked ~ .shell .sidebar{transform:translateX(0)}

  .nav-backdrop{display:block;position:fixed;inset:0;background:rgba(4,6,10,.6);
    z-index:55;opacity:0;pointer-events:none;transition:opacity .22s}
  #nav-toggle:checked ~ .shell .nav-backdrop{opacity:1;pointer-events:auto}

  .burger{display:inline-grid;place-items:center;width:40px;height:40px;flex:none;
    border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);
    color:var(--text);cursor:pointer;transition:background .12s}
  .burger:hover{background:var(--surface-2)}
  .burger svg{width:20px;height:20px}

  .main{padding:0 16px 48px}
  .search{max-width:none;min-width:0}
  .userchip .who,.search kbd{display:none}
}
/* tablets & small laptops: dense multi-column form rows drop to two */
@media (max-width:900px){
  .row.c3,.row.c4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:620px){
  .grid.cols4,.grid.cols3{grid-template-columns:1fr}
  .grid.cols6{grid-template-columns:repeat(2,minmax(0,1fr))}
  .row.c2,.row.c3,.row.c4{grid-template-columns:1fr}
  h2.page{font-size:23px}
  /* The pill stays — it is how you find out the shop is shut, and tapping it
     is the only way to read the reasons on a phone. Shrunk to a dot + count
     instead of hidden, so the tight top bar still fits. */
  .statuspill{padding:6px 9px;gap:6px;font-size:0}
  .statuspill .dot{width:9px;height:9px}
  .statuspill .why{font-size:10px}
  .table-wrap{margin:0 -16px;padding:0 16px} /* match mobile main padding, no bleed */
  /* section headers stack so their action buttons sit below the title */
  .page-head{flex-direction:column;align-items:stretch;gap:12px}
  .page-actions{justify-content:flex-start}
  .spread{flex-wrap:wrap;gap:10px}
  /* tighter cards & tables so nothing feels cramped on a phone */
  .pad{padding:16px}
  td,th{padding:11px 10px}
  /* the list search takes the full width once the chips wrap under it */
  .findbox{width:100%}
  .findbox input{flex:1;min-width:0}
}
/* phones: a wide data table can't be read by scrolling sideways, so each row
   becomes a labelled card. A small script (base.html) stamps every cell with its
   column header as data-label; here we lift that label above the value and hide
   the header row. Everything degrades to a normal table if the script is off. */
@media (max-width:600px){
  .table-wrap{overflow-x:visible;margin:0;padding:0}
  .table-wrap table,.table-wrap tbody{display:block;width:100%}
  .table-wrap thead,.table-wrap tr.tr-head{display:none}
  .table-wrap tr{display:block;background:var(--surface);border:1px solid var(--line);
    border-radius:12px;margin:0 0 12px;padding:5px 15px}
  .table-wrap tr:hover td{background:transparent}
  .table-wrap td{display:block;text-align:left;padding:9px 0;border-radius:0;
    border-bottom:1px solid var(--line);white-space:normal;overflow-wrap:anywhere}
  .table-wrap tr td:last-child{border-bottom:0}
  .table-wrap td[data-label]::before{content:attr(data-label);display:block;margin-bottom:4px;
    color:var(--text-3);font:700 9.5px var(--sans);letter-spacing:.11em;text-transform:uppercase}
  .table-wrap td[colspan]{text-align:center;border-bottom:0}
  /* action buttons fill the width of the card instead of crowding one line */
  .table-wrap td.actions{display:flex;flex-wrap:wrap;gap:8px;padding-top:11px}
  .table-wrap td.actions>*{flex:1 1 auto;min-width:0}
  .table-wrap td.actions .btn{width:100%;justify-content:center}
  /* The first cell names the thing, so in card mode it IS the card's heading:
     no "CATEGORY" micro-label above it, a title-sized name, and the avatar
     beside it rather than stranded on its own line. */
  .table-wrap td:first-child[data-label]::before{display:none}
  .table-wrap tr td:first-child{padding:13px 0 11px}
  .table-wrap td:first-child .prow{gap:12px;align-items:center}
  .table-wrap td:first-child .pav{width:38px;height:38px;font-size:19px}
  .table-wrap td:first-child .pname{font-size:15px}
  .table-wrap td:first-child .pmeta{white-space:normal;max-width:none}
  /* reclaim the last of the top-bar width on a phone */
  .userchip{display:none}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ── Editor modal (replaces browser prompt/alert) ─────────────────────────── */
.te-modal-overlay{
  position:fixed;inset:0;z-index:9999;
  display:flex;align-items:center;justify-content:center;
  background:rgba(4,6,10,.72);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity .18s ease;
  padding:16px;
}
.te-modal-overlay.te-modal-visible{opacity:1}
.te-modal-overlay.te-modal-visible .te-modal{transform:translateY(0) scale(1);opacity:1}

.te-modal{
  background:var(--surface);border:1px solid var(--line-2);
  border-radius:var(--r-lg);
  box-shadow:0 4px 6px rgba(0,0,0,.3),0 24px 60px -8px rgba(0,0,0,.7);
  padding:24px;width:100%;max-width:420px;
  transform:translateY(14px) scale(.97);opacity:0;
  transition:transform .2s cubic-bezier(.16,1,.3,1),opacity .18s ease;
}

.te-modal-title{
  font:650 15px/1.3 var(--sans);color:var(--text);
  margin-bottom:6px;letter-spacing:-.01em;
}

.te-modal-hint{
  font:400 12.5px/1.5 var(--sans);color:var(--text-2);
  margin-bottom:16px;
}

.te-modal-label{
  display:flex;flex-direction:column;gap:5px;
  font:500 11.5px var(--sans);color:var(--text-2);
  letter-spacing:.02em;text-transform:uppercase;
  margin-bottom:12px;
}
.te-modal-label:last-of-type{margin-bottom:0}

.te-modal-input{
  width:100%;background:var(--surface-3);
  border:1px solid var(--line-2);border-radius:var(--r-sm);
  color:var(--text);font:400 13.5px var(--mono);
  padding:9px 12px;outline:none;
  transition:border-color .14s,box-shadow .14s;
}
.te-modal-input::placeholder{color:var(--text-3)}
.te-modal-input:focus{border-color:var(--accent);box-shadow:var(--ring)}

.te-modal-preview{
  margin-top:10px;padding:10px 12px;
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);font-size:22px;text-align:center;
  color:var(--text-2);font-style:italic;font-size:12px;
}

.te-modal-row{
  display:flex;gap:8px;justify-content:flex-end;
  margin-top:20px;
}

.te-modal-btn{
  padding:8px 18px;border-radius:var(--r-sm);
  font:600 13px var(--sans);cursor:pointer;
  border:1px solid transparent;
  transition:background .14s,color .14s,box-shadow .14s;
}
.te-modal-cancel{
  background:var(--surface-3);color:var(--text-2);
  border-color:var(--line-2);
}
.te-modal-cancel:hover{background:var(--line-2);color:var(--text)}
.te-modal-ok{
  background:var(--accent);color:var(--accent-ink);
  border-color:var(--accent);
}
.te-modal-ok:hover{filter:brightness(1.08)}


/* ══ reporting window: presets + calendar ═════════════════════════════════ */
.rangebar{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:14px 16px;margin-bottom:18px;box-shadow:var(--shadow)}
.rlabel{font:700 15px var(--sans);letter-spacing:-.01em}
.rsub{color:var(--text-3);font-size:12.5px;margin-top:3px}
.rpicks{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.rpick{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border-radius:99px;
  border:1px solid var(--line-2);background:var(--surface-2);color:var(--text-2);
  font:600 12.5px var(--sans);cursor:pointer;white-space:nowrap;
  transition:background .13s,color .13s,border-color .13s}
.rpick:hover{color:var(--text);border-color:var(--line-3);background:var(--surface-3)}
.rpick.on{color:var(--accent-ink);background:var(--accent);border-color:var(--accent)}
.rpick svg{width:14px;height:14px;flex:none}
.rpick .l-short{display:none}

.calwrap{position:relative}
.calpop{position:absolute;right:0;top:calc(100% + 8px);z-index:60;width:282px;
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:0 4px 6px rgba(0,0,0,.3),0 24px 60px -10px rgba(0,0,0,.75);padding:14px}
.calpop[hidden]{display:none}
.calhead{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.calmonth{font:660 13.5px var(--sans)}
.calnav{width:28px;height:28px;border-radius:8px;border:1px solid var(--line-2);
  background:var(--surface-2);color:var(--text-2);cursor:pointer;display:grid;place-items:center}
.calnav:hover{background:var(--surface-3);color:var(--text)}
.calnav svg{width:15px;height:15px}
.caldow{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}
.caldow span{text-align:center;font:700 9.5px var(--sans);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-3);padding:4px 0}
.calgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cd{height:33px;border:0;border-radius:8px;background:transparent;color:var(--text-2);
  font:600 12.5px var(--sans);cursor:pointer;display:grid;place-items:center;
  transition:background .1s,color .1s}
.cd.out{visibility:hidden}
.cd:hover:not(.dis):not(.out){background:var(--surface-3);color:var(--text)}
.cd.today{box-shadow:inset 0 0 0 1px var(--line-2);color:var(--text)}
.cd.between{background:var(--accent-soft);color:var(--text);border-radius:0}
.cd.pick{background:var(--accent);color:var(--accent-ink)}
.cd.dis{color:var(--text-3);opacity:.32;cursor:not-allowed}
.calfoot{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:12px;padding-top:11px;border-top:1px solid var(--line)}
.calhint{color:var(--text-3);font-size:11px;line-height:1.35}

@media (max-width:760px){
  .rangebar{padding:12px 13px}
  .rpicks{width:100%}
  .rpick{flex:1;justify-content:center;padding:7px 9px}
  .rpick .l-full{display:none}
  .rpick .l-short{display:inline}
  .calbtn .l-full{display:inline}
  .calpop{right:auto;left:0;width:min(88vw,282px)}
}

/* a value the platform sets for you — shown, copyable, not editable */
.readonly-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.readonly{flex:1;min-width:0;padding:11px 13px;border-radius:var(--r);
  border:1px dashed var(--line-2);background:var(--surface-2);color:var(--text-2);
  font:13px var(--mono);word-break:break-all}

/* an amber advisory inside a form — stronger than a hint, softer than an error */
.warnbox{display:block;padding:11px 13px;border-radius:var(--r);
  background:rgba(242,181,68,.08);border:1px solid rgba(242,181,68,.28);
  border-left:3px solid var(--gold);color:var(--text-2);font-size:12.5px;line-height:1.5}
.warnbox b{color:var(--text)}

/* the shop cannot take money — the one warning worth interrupting every page */
.alarm-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin:0 0 18px;padding:14px 16px;border-radius:var(--r-lg);
  background:rgba(var(--red-rgb),.09);border:1px solid rgba(var(--red-rgb),.32);
  border-left:3px solid var(--red);color:var(--text-2);font-size:13.5px;line-height:1.5}
.alarm-banner svg{width:19px;height:19px;flex:none;color:var(--red)}
.alarm-banner b{color:#ff8f8f}
.alarm-banner span{flex:1;min-width:200px}
.alarm-banner .btn{flex:none;border-color:rgba(var(--red-rgb),.4);color:#ff9b9b;
  background:rgba(var(--red-rgb),.08)}
.alarm-banner .btn:hover{background:rgba(var(--red-rgb),.16);border-color:rgba(var(--red-rgb),.6)}
@media (max-width:560px){
  .alarm-banner{align-items:flex-start}
  .alarm-banner .btn{width:100%;justify-content:center}
}

/* ── bot status pill + "why" popover ─────────────────────────────────────── */
.statuswrap{position:relative}
.statuswrap>input{position:absolute;opacity:0;pointer-events:none}
.statuswrap .statuspill{cursor:pointer;user-select:none}
.statuspill .why{display:inline-grid;place-items:center;min-width:16px;height:16px;
  padding:0 4px;border-radius:99px;background:rgba(var(--red-rgb),.22);color:#ff9b9b;
  font:700 10px var(--sans);margin-left:1px}
.statuspop{position:absolute;right:0;top:calc(100% + 9px);z-index:70;width:320px;
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-lg);
  box-shadow:0 4px 6px rgba(0,0,0,.3),0 24px 60px -10px rgba(0,0,0,.75);
  padding:12px;opacity:0;visibility:hidden;transform:translateY(-5px);
  transition:opacity .14s ease,transform .14s ease,visibility .14s}
.statuswrap:hover .statuspop,
.statuswrap>input:checked~.statuspop,
.statuswrap:focus-within .statuspop{opacity:1;visibility:visible;transform:none}
.statuspop h4{font:700 10px var(--sans);letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-3);padding:2px 6px 9px}
.srow{display:flex;gap:10px;align-items:flex-start;padding:9px 6px;
  border-top:1px solid var(--line)}
.statuspop h4+.srow,.statuspop .srow:first-child{border-top:0}
.srow .sic{width:20px;height:20px;flex:none;border-radius:6px;display:grid;place-items:center;
  font:700 11px var(--sans);background:rgba(var(--red-rgb),.14);color:#ff8f8f}
.srow.ok .sic{background:var(--accent-soft);color:var(--accent)}
.srow>span:last-child{display:flex;flex-direction:column;gap:3px;min-width:0}
.srow b{font:650 13px var(--sans);color:var(--text)}
.srow span span{font-size:12px;color:var(--text-3);line-height:1.45}
.srow a{font:600 12px var(--sans);color:var(--accent);margin-top:2px}
.srow a:hover{text-decoration:underline}
@media (max-width:900px){
  .statuspop{right:auto;left:50%;transform:translate(-50%,-5px);width:min(90vw,320px)}
  .statuswrap>input:checked~.statuspop{transform:translate(-50%,0)}
  .statuswrap:hover .statuspop{opacity:0;visibility:hidden}   /* tap, not hover */
  .statuswrap>input:checked~.statuspop{opacity:1;visibility:visible}
}

/* an id that takes you to the record it names */
.orderlink{display:inline-flex;align-items:center;gap:6px;color:var(--accent);
  font-weight:600;padding:3px 9px;border-radius:8px;background:var(--accent-soft);
  border:1px solid rgba(var(--accent-rgb),.24);transition:background .13s,border-color .13s}
.orderlink:hover{background:rgba(var(--accent-rgb),.18);border-color:rgba(var(--accent-rgb),.45)}
.orderlink svg{width:13px;height:13px;stroke-width:2.2}

/* ── background navigation ─────────────────────────────────────────────────
   A thin line at the very top is the only sign that a page is being fetched.
   It appears just late enough that a fast swap looks instant. */
.navbar-progress{position:fixed;top:0;left:0;height:2px;width:0;z-index:200;
  background:linear-gradient(90deg,var(--accent),#7ee7c0);
  opacity:0;transition:width .25s ease,opacity .2s ease;pointer-events:none}
.navbar-progress.on{width:92%;opacity:1;transition:width 8s cubic-bezier(.05,.7,.1,1),opacity .1s}
/* The swapped region fades in over a single frame — enough to feel like a
   change happened, too short to feel like waiting. */
#page{animation:pagein .16s ease}
@keyframes pagein{from{opacity:.55}to{opacity:1}}
@media (prefers-reduced-motion:reduce){#page{animation:none}}


/* ── collapsible panel ────────────────────────────────────────────────── */
/* A card that opens. Used where a page's real job is reading a list, and a long
   form above it would push that list below the fold — which is what made
   /products feel scattered: you landed on a 90-line form, not the catalog.
   <details> so it works with no JS and survives a background navigation. */
details.panel{padding:0}
details.panel>summary{list-style:none;cursor:pointer;display:flex;align-items:center;
  gap:12px;padding:17px 22px;border-radius:var(--r-lg);transition:background .13s}
details.panel>summary::-webkit-details-marker{display:none}
details.panel>summary:hover{background:var(--surface-2)}
details.panel[open]>summary{border-bottom:1px solid var(--line);
  border-radius:var(--r-lg) var(--r-lg) 0 0}
details.panel .s-title{font:650 15px var(--sans);color:var(--text);letter-spacing:-.01em;
  display:inline-flex;align-items:center;gap:9px;white-space:nowrap}
details.panel .s-hint{color:var(--text-3);font-size:12.5px;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
details.panel .chev{margin:0 0 0 auto;color:var(--text-3);transition:transform .18s;flex:none}
details.panel[open] .chev{transform:rotate(180deg)}
details.panel>*:not(summary){padding-left:22px;padding-right:22px}
details.panel>*:not(summary):last-child{padding-bottom:22px}
details.panel>.hint{padding-top:18px}
@media(max-width:700px){details.panel .s-hint{display:none}}


/* ── filter bar spacing, decided once ─────────────────────────────────── */
/* Seven templates carried style="margin-top:14px" on .listbar and five did not,
   so the filters sat at a different height depending on the page. The gap
   belongs to what the bar follows, not to each template's opinion. */
.listbar{margin-top:0}
.card>h3+.listbar,.card>.hint+.listbar,.spread+.listbar{margin-top:16px}
/* Two deliberate variants, named instead of inlined. */
.listbar.bare{margin:0;padding:0;border:0}
.listbar.tight{padding-bottom:14px}


/* ── buttons, refined ─────────────────────────────────── */
/* Tighter and quieter. The primary used a brightness() hover, so hovering made
   it *more* vivid — the opposite of what a solid button should do. It now
   deepens, and carries white text on a darker green rather than near-black on
   a bright one, which is what made it read as a highlighter. */
.btn{padding:8px 14px;font:600 12.5px var(--sans);border-radius:8px;gap:7px;
  letter-spacing:-.005em}
.btn svg{width:14px;height:14px;opacity:.72}
.btn:hover svg{opacity:1}
.btn.primary{background:var(--accent-solid);color:#fff;border-color:transparent}
.btn.primary:hover{background:var(--accent-solid-2);filter:none}
.btn.primary svg{opacity:.95}
.btn.small{padding:5px 10px;font-size:11.5px;border-radius:7px;gap:5px}
.btn.small svg{width:12px;height:12px}
.actions{gap:6px}
/* Aliases. Three templates used .btn-primary / .btn-sm, which never existed in
   this stylesheet, so those buttons silently rendered as plain grey. The markup
   is fixed — these stay so a stray one can never be invisible again. */
.btn.btn-primary{background:var(--accent-solid);color:#fff;border-color:transparent}
.btn.btn-sm{padding:5px 10px;font-size:11.5px;border-radius:7px}
.btn.btn-danger{color:var(--red);border-color:rgba(var(--red-rgb),.32);background:rgba(var(--red-rgb),.06)}


/* ── table row identity: avatar + name + meta ────────────────────── */
/* This was defined twice, both times inside a page-scoped <style> — bare in
   products.html and under `.cat-table` in categories.html. The search page uses
   the same markup and loads neither, so its rows rendered with no styling at
   all: the emoji sat stacked above the name. One definition, every page. */
.prow{display:flex;align-items:center;gap:11px;min-width:0}
.pav{width:34px;height:34px;border-radius:9px;flex:none;display:grid;place-items:center;
  font-size:17px;line-height:1;
  background:linear-gradient(150deg,var(--surface-3),var(--surface-2));
  border:1px solid var(--line-2)}
.pname{font:650 13.5px var(--sans);color:var(--text);display:block}
.pname:hover,.clickrow:hover .pname{color:var(--accent)}
.pmeta{font:500 11px var(--mono);color:var(--text-3);margin-top:2px;max-width:440px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
td .stock-out{color:var(--red)}
td .stock-low{color:var(--gold)}


/* ── formatting editor ─────────────────────────────────── */
/* The toolbar and its textarea are one control. They used to be a floating bar
   sitting above a separate box, which is what made the field look unfinished. */
.toolbar{gap:2px;padding:6px 7px;margin-bottom:0;border-bottom:0;
  border-radius:var(--r-sm) var(--r-sm) 0 0}
.toolbar+textarea{border-top-left-radius:0;border-top-right-radius:0}
.tool{min-width:29px;height:27px;padding:0 7px;border-radius:6px}
.tool svg{width:15px;height:15px;display:block}
.tool b,.tool i,.tool u,.tool s{font:700 13px var(--sans);line-height:1}
.tool i{font-weight:600}
.tool-sep{height:16px;margin:0 5px}
.toolbar .counter{font-size:10.5px}
.editor-preview{margin-top:10px}

/* ── checkboxes ───────────────────────────────────────── */
/* `accent-color` renders a solid, very bright green box the browser picks the
   shade of. This is the same affordance drawn at the panel's own weight. */
input[type=checkbox]{appearance:none;-webkit-appearance:none;width:17px;height:17px;
  border:1px solid var(--line-3);border-radius:5px;background:var(--surface-2);
  display:inline-grid;place-content:center;cursor:pointer;padding:0;flex:none;
  transition:background .12s,border-color .12s}
input[type=checkbox]:hover{border-color:var(--text-3)}
input[type=checkbox]::before{content:"";width:10px;height:10px;transform:scale(0);
  transition:transform .12s ease-out;background:#fff;
  clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%)}
input[type=checkbox]:checked{background:var(--accent-solid);
  border-color:var(--accent-solid)}
input[type=checkbox]:checked::before{transform:scale(1)}
input[type=checkbox]:focus-visible{box-shadow:var(--ring);border-color:var(--accent)}
input[type=checkbox]:disabled{opacity:.45;cursor:not-allowed}
.check{gap:10px}

/* ── selects ──────────────────────────────────────────── */
select{cursor:pointer}
select:hover{border-color:var(--line-3)}
/* A dropdown's list is drawn by the OS; without this it inherits the page's
   white default and flashes bright against a dark panel. */
select option{background:var(--surface-2);color:var(--text)}


/* ── stat tiles ───────────────────────────────────────── */
/* The tile takes its tint from whatever colour the card set on the icon, so one
   rule covers every metric and a new card needs no new CSS. This is the only
   colour the chrome carries — everything else stays grey. */
.stat .icon{background:color-mix(in srgb,currentColor 13%,transparent);
  border-color:color-mix(in srgb,currentColor 26%,transparent)}
/* Older engines without color-mix keep the previous flat tile rather than a
   transparent one — @supports is how that stays a graceful fallback. */
@supports not (background:color-mix(in srgb,red 10%,transparent)){
  .stat .icon{background:var(--surface-3);border-color:var(--line-2)}
}


/* ── checkboxes used purely as state holders ────────────────── */
/* The alerts popover is driven by a hidden checkbox. The generic checkbox
   styling above sets `display:inline-grid`, which has the same specificity as
   `.popwrap>input{display:none}` and comes later — so it won, and drew a box
   beside the bell. Named explicitly so it cannot drift back. */
.popwrap>input[type=checkbox]{display:none}

/* ── filter bar: chips, field and button share one height ───────── */
.chip-link{height:34px;padding:0 14px}
.chip-link .n{font:600 11px var(--mono);opacity:.7;background:var(--surface-3);
  border-radius:99px;padding:1px 7px;line-height:1.5}
/* The active chip was a solid fill of the brand green — a highlighter pen next
   to a row of quiet pills. Tinted instead: unmistakably on, without shouting. */
.chip-link.on{color:var(--accent);background:var(--accent-soft);
  border-color:rgba(var(--accent-rgb),.40)}
.chip-link.on .n{opacity:1;color:var(--accent);background:rgba(var(--accent-rgb),.16)}
.chip-link:hover{background:var(--surface-3)}
.findbox input{height:34px;padding:0 15px;font-size:13px;width:270px}
.findbox .btn{height:34px}

/* ── alerts ─────────────────────────────────────────── */
.iconbtn .pip{top:-5px;right:-5px;min-width:18px;height:18px;
  font:700 10px/18px var(--sans);border:2px solid var(--bg)}
/* It listed every low-stock product, so at 55 alerts the panel ran off the
   bottom of the screen with no way to reach the end. Scrolls now, with the
   heading pinned — no extra markup, just a sticky header. */
.popover{width:360px;padding:0 6px 6px;max-height:min(70vh,540px);overflow-y:auto}
.popover h4{position:sticky;top:0;z-index:1;background:var(--surface);
  margin:0 -6px 6px;padding:13px 14px 11px;border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:10px}
.popover .arow{gap:11px;align-items:center;padding:8px 10px}
.popover .arow .ic{width:30px;height:30px;border-radius:8px;font-size:14px;
  border:1px solid transparent}
.popover .arow b{font:600 13px var(--sans);margin-bottom:1px;max-width:252px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.popover .arow>span:last-child{min-width:0}


/* ── styled dropdown (static/select.js) ───────────────────── */
/* A native <select>'s popup is drawn by the OS — its white list and blue
   highlight are not reachable from CSS — so every dropdown opened bright on the
   dark panel. This wraps the real <select> (kept as the value holder) with a
   button and a listbox that match the panel. */
.xsel{position:relative}
/* The real control stays in place, invisible, on top of the button: a `required`
   field the browser cannot focus makes it refuse to submit with no visible
   reason, so it must remain focusable for the validation bubble to have a home. */
.xsel>select{position:absolute;inset:0;width:100%;height:100%;opacity:0;
  pointer-events:none;margin:0}
.xsel-btn{display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;background:var(--surface-2);border:1px solid var(--line);
  color:var(--text);border-radius:var(--r-sm);padding:10px 12px;font:14px var(--sans);
  cursor:pointer;text-align:left;transition:border-color .14s,box-shadow .14s}
.xsel-btn:hover{border-color:var(--line-3)}
.xsel.open .xsel-btn{border-color:var(--accent);box-shadow:var(--ring)}
.xsel-val{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.xsel-val.ph{color:var(--text-3)}
.xsel-chev{width:16px;height:16px;flex:none;color:var(--text-3);
  transition:transform .18s ease}
.xsel.open .xsel-chev{transform:rotate(180deg);color:var(--accent)}
.xsel-btn:disabled{opacity:.5;cursor:not-allowed}

.xsel-pop{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:60;
  background:var(--surface-2);border:1px solid var(--line-2);border-radius:var(--r-sm);
  box-shadow:0 10px 30px -8px rgba(0,0,0,.7);padding:5px;max-height:278px;
  overflow-y:auto;display:none;animation:xsel-in .13s ease}
.xsel.open .xsel-pop{display:block}
.xsel.up .xsel-pop{top:auto;bottom:calc(100% + 6px)}
@keyframes xsel-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.xsel-opt{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:6px;
  font:13.5px var(--sans);color:var(--text-2);cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.xsel-opt:hover,.xsel-opt.cur{background:var(--surface-3);color:var(--text)}
.xsel-opt.sel{color:var(--text);font-weight:600}
/* The tick marks the current value without a colour block behind the whole row. */
.xsel-opt.sel::after{content:"";width:14px;height:14px;margin-left:auto;flex:none;
  background:var(--accent);
  -webkit-mask:var(--tick) center/contain no-repeat;mask:var(--tick) center/contain no-repeat}
.xsel-opt.dis{color:var(--text-3);opacity:.6;cursor:not-allowed}
.xsel-opt.dis:hover{background:transparent}
:root{--tick:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")}


/* ── dropdown: corrections ──────────────────────────────── */
/* select.js emits `xs-chev`; the block above styled `.xsel-chev`. With no rule
   matching, the chevron <svg> had no width or height — and an SVG with a
   viewBox and no intrinsic size expands to fill its parent, which is why every
   dropdown blew up into a giant arrow. Same bug class as any CSS/JS name drift:
   nothing errors, it just silently renders wrong. */
.xs-chev{width:16px;height:16px;flex:none;color:var(--text-3);
  transition:transform .18s ease}
.xsel.open .xs-chev{transform:rotate(180deg);color:var(--accent)}
/* The label takes the room the arrow is not using, and truncates on its own. */
.xsel-val{flex:1 1 auto;min-width:0}
/* In a flex row (a duration value beside its unit) the wrapper has to stretch
   the way the bare <select> used to. */
.xsel{flex:1 1 auto;min-width:0}
.xsel-opt.dis{opacity:.45;cursor:not-allowed}
.xsel-opt.dis:hover{background:none;color:var(--text-2)}


/* ── page transition & scrolling ─────────────────────────── */
/* Smooth for in-page anchors and anything that asks the window to scroll.
   nav.js opts out explicitly when it jumps to the top after a swap, or the old
   scroll position would animate away while the new page is already showing. */
html{scroll-behavior:smooth}
/* Opacity only, deliberately: a transform on #page would make it the containing
   block for every fixed-position descendant for as long as the animation ran. */
#page{transition:opacity .22s ease}
#page.page-enter{opacity:0}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  #page{transition:none}
  #page.page-enter{opacity:1}
}


/* ── topbar ────────────────────────────────────────── */
/* Every control on one height. They were 36/38/40 and the row read as three
   things parked next to each other rather than one bar. */
.topbar{padding:12px 0;gap:12px}
.search input{height:36px;padding-top:0;padding-bottom:0}
.statuspill{height:36px;box-sizing:border-box}
.iconbtn{width:36px;height:36px;border-radius:10px}
.userchip{height:36px;box-sizing:border-box;padding:0 12px 0 4px}
.avatar{width:28px;height:28px}

/* ── brand mark ───────────────────────────────────── */
/* The same Lucide bot as the favicon, so the tab and the sidebar are one mark. */
.logo svg{width:21px;height:21px;color:var(--accent);stroke-width:2}
.login .logo svg,.card .logo svg{width:27px;height:27px}


/* ── alert pip & rows ────────────────────────────────── */
/* The pip sat half over the button's own border, so its 2px ring cut a notch
   out of the corner. Pushed clear, so the ring lands on the topbar behind it
   and the button's outline stays whole. */
.iconbtn .pip{top:-7px;right:-7px;min-width:18px;height:18px;padding:0 5px;
  font:700 10px/18px var(--sans);letter-spacing:0;border:2px solid var(--bg)}
/* One class per severity, instead of the same inline style on every row. */
.popover .arow .ic-red{background:rgba(var(--red-rgb),.13);
  border-color:rgba(var(--red-rgb),.26);color:var(--red)}
.popover .arow .ic-amber{background:rgba(var(--amber-rgb),.13);
  border-color:rgba(var(--amber-rgb),.26);color:var(--amber)}
.popover .arow .ic-indigo{background:rgba(var(--indigo-rgb),.14);
  border-color:rgba(var(--indigo-rgb),.26);color:var(--indigo)}
.popover .arow .ic-gold{background:rgba(var(--gold-rgb),.14);
  border-color:rgba(var(--gold-rgb),.28);color:var(--gold)}
.popover .arow .ic-green{background:var(--accent-soft);
  border-color:rgba(var(--accent-rgb),.26);color:var(--accent)}
.popover .arow .ic svg{width:15px;height:15px}


/* ── entity marks ───────────────────────────────────── */
/* Products, categories and freebies each get one Lucide mark, told apart by
   colour. The shop's own emoji still reaches buyers — this is only how the
   panel lists things. */
.emark{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:1.6em;height:1.6em;border-radius:6px;margin-right:.5em;
  vertical-align:-.38em;border:1px solid transparent}
.emark svg{width:.92em;height:.92em;stroke-width:2.1;margin:0}
.t-prod{background:rgba(var(--indigo-rgb),.14);
  border-color:rgba(var(--indigo-rgb),.30);color:var(--indigo)}
.t-cat{background:rgba(var(--amber-rgb),.14);
  border-color:rgba(var(--amber-rgb),.30);color:var(--amber)}
.t-free{background:rgba(var(--rose-rgb),.14);
  border-color:rgba(var(--rose-rgb),.30);color:var(--rose)}
/* The big avatars already carry a box; they take the tint, not the gradient. */
.pav.t-prod,.pav.t-cat,.pav.t-free,
.prod-emoji.t-prod,.prod-emoji.t-cat,.prod-emoji.t-free{background-image:none}
.pav svg{width:17px;height:17px;stroke-width:2;margin:0}
.prod-emoji svg{width:25px;height:25px;stroke-width:1.9;margin:0}

/* ── dropdown: don't let a unit select collapse ───────────────── */
/* `min-width:0` let the wrapper shrink to nothing beside a number input in a
   flex row — "months" rendered as "m…". The label truncates inside the button
   instead, so long option text still behaves in a narrow column. */
.xsel{min-width:108px}
.xsel-val{min-width:0}
@media(max-width:560px){.xsel{min-width:84px}}


/* ── entity tiles: a monogram, not an icon ──────────────────── */
/* The letter says which row you are on; the colour says what kind of thing it
   is. One Lucide glyph repeated down a column did neither. */
.emark{font:700 .74em/1 var(--sans);letter-spacing:.01em}
/* Beat the page-scoped .pav / .prod-emoji rules: those are sized for an emoji
   and, living in the page body, land after this stylesheet. */
.pav.t-prod,.pav.t-cat,.pav.t-free{font:700 15px var(--sans);letter-spacing:.01em}
.prod-emoji.t-prod,.prod-emoji.t-cat,.prod-emoji.t-free{
  font:700 22px var(--sans);letter-spacing:.01em}

/* ── a provider's error, on one line ─────────────────────── */
/* These are raw Telegram failures — one clause per blocked buyer, hundreds of
   them. Dumped whole they pushed every row three lines tall and buried the
   delivered/failed counts that are the point of the column. Clamped to a line,
   with the whole thing on hover. */
.errline{font:500 11.5px var(--mono);color:var(--text-3);margin-top:5px;
  max-width:46ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  cursor:help}

/* ── buttons: press ──────────────────────────────────── */
/* A single pixel of lift on hover and none on press. Enough to feel live,
   small enough that a row of them does not jump about. */
.btn{transition:background .15s ease,border-color .15s ease,color .15s ease,
  transform .12s ease}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn:disabled:hover,.btn[disabled]:hover{transform:none}
@media(prefers-reduced-motion:reduce){.btn:hover,.btn:active{transform:none}}


/* ── monogram: fixed size, centred on its label ───────────────── */
/* Sized in px, not em: at .74em inside 13.5px bold text the tile came out at
   10px and hung below the baseline. `.ename` makes the tile and the label one
   flex line, so they centre on each other whatever the surrounding font size. */
.emark{width:24px;height:24px;border-radius:7px;font:700 11.5px/1 var(--sans);
  margin-right:8px;vertical-align:middle}
.ename{display:inline-flex;align-items:center;gap:9px;min-width:0;
  vertical-align:middle}
.ename .emark{margin-right:0}
.ename .etxt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* The accordion header carries a little more weight than a table row. */
.catname .emark{width:26px;height:26px;font-size:12px;margin-right:0}


/* ── multi-select picker (see static/multipick.js) ────────────── */
/* The real <select multiple> stays in the form, hidden — `display:none` still
   submits, unlike `disabled` — and these rows drive it. */
.picker select[data-pick]{display:none}
.pk-list{max-height:250px;overflow-y:auto;padding:4px;
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:0 0 var(--r-sm) var(--r-sm);border-top:0}
.pk-row{display:flex;align-items:center;gap:10px;padding:7px 9px;border-radius:7px;
  cursor:pointer;font:13.5px var(--sans);color:var(--text-2);user-select:none;
  transition:background .12s,color .12s}
.pk-row:hover{background:var(--surface-3);color:var(--text)}
.pk-row.on{background:var(--accent-soft);color:var(--text)}
.pk-row .pk-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.pk-row.on::after{content:"";width:14px;height:14px;flex:none;
  background:var(--accent);
  clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%)}
.pk-list:empty::after{content:"Nothing matches that filter";display:block;
  padding:14px 10px;color:var(--text-3);font:13px var(--sans)}


/* ── buttons: vivid primary, honest disabled ────────────────── */
/* --accent-solid (#0d8563) was picked so *white* text would clear contrast on
   it, and the result read as muted teal rather than the brand green. That
   trade-off was backwards: white on #10a37f is 3.2:1 and fails, while the dark
   ink the palette already ships is 5.96:1 on the same green and passes. Full
   brightness is therefore both the more vivid choice and the more legible one. */
.btn.primary{background:var(--accent);color:var(--accent-ink);
  border-color:transparent;font-weight:650}
.btn.primary:hover{background:#14b88c}
.btn.primary:active{background:#0e9372}
.btn.primary svg{opacity:1;stroke-width:2.4}
.btn.btn-primary{background:var(--accent);color:var(--accent-ink);
  border-color:transparent}
/* .72 washed the glyph out on a filled button — the plus and the bell looked
   half-erased rather than quiet. */
.btn svg{opacity:.85}
.btn:hover svg{opacity:1}
/* A disabled button should look deliberately off, not like a faded photocopy of
   itself: a filled button at 45% opacity reads as a rendering fault. */
.btn:disabled,.btn[disabled]{opacity:1;background:var(--surface-2);
  color:var(--text-3);border-color:var(--line);cursor:not-allowed}
.btn.primary:disabled,.btn.primary[disabled]{background:var(--surface-3);
  color:var(--text-3);border-color:var(--line-2)}
.btn:disabled svg,.btn[disabled] svg{opacity:.45}
.btn:disabled:hover,.btn[disabled]:hover{background:var(--surface-2);
  border-color:var(--line);transform:none}
.btn.primary:disabled:hover,.btn.primary[disabled]:hover{background:var(--surface-3)}


/* ── discount form: the buyer a set price belongs to ───────────── */
/* Lifted while a set price is selected, because it stops being optional. */
.dsc-group.needs-buyer{border-top-color:rgba(var(--accent-rgb),.45)}
.dsc-group.needs-buyer > .eyebrow{color:var(--accent)}


/* ── activations: one table, no sideways scroll ──────────────── */
/* Eight columns, one of them free text, could not fit — so the page scrolled
   sideways and "Work it", the one thing you come here to press, sat off the
   right edge. Fixed layout with named widths, so the details column gives way
   instead of shoving the rest along. */
.acttable{table-layout:fixed;width:100%}
.acttable th,.acttable td{overflow:hidden}
.acttable .c-req{width:84px}
.acttable .c-buyer{width:15%}
.acttable .c-prod{width:22%}
.acttable .c-status{width:110px}
.acttable .c-when{width:84px}
.acttable .c-act{width:84px}
.acttable .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acttable .notecell{font:500 11px var(--sans);color:var(--text-3);margin-top:3px}
.acttable td.actions{padding-right:0}
.acttable td.actions .btn{width:100%;justify-content:center}
@media(max-width:1180px){
  .acttable .c-buyer{width:18%}
  .acttable .c-prod{width:26%}
}
