/* ============================================================
   NerdStack retro console theme — spec-ui-foundations.md
   Visual source of truth: NerdStack_Shell_Mockup_v2_Retro.html
   ============================================================ */

/* ---- self-hosted fonts (spec §2: no Google Fonts CDN in prod) ---- */
@font-face{
  font-family:'Press Start 2P';font-style:normal;font-weight:400;font-display:swap;
  src:url('/fonts/press-start-2p-400.woff2') format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('/fonts/ibm-plex-mono-400.woff2') format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('/fonts/ibm-plex-mono-500.woff2') format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:url('/fonts/ibm-plex-mono-600.woff2') format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url('/fonts/ibm-plex-mono-700.woff2') format('woff2');
}

/* ---- design tokens (spec §1) ---- */
:root{
  --accent:#b45bff;        /* nerd purple — active nav, links, primary buttons */
  --accent2:#4df3ff;       /* cyan — section headings, secondary actions        */
  --dex:#ff7bd5;           /* Dex pink — ✦ makes (drafts) / ◆ knows (explain)   */
  --good:#3ee06c; --warn:#ffd23e; --bad:#ff5b6a;
  --bg:#12121c;            /* deep console navy                                  */
  --panel:#1b1b28;
  --panel2:#222234;
  --line:#39395a;          /* chunky 2px borders                                */
  --text:#e8e6f2; --dim:#8f8cab;
  --shadow:#0a0a12;        /* hard offset shadow                                */
  --px:'Press Start 2P',monospace;               /* headings / flavor           */
  --mono:'IBM Plex Mono',Consolas,monospace;     /* data / body                 */
}

*{box-sizing:border-box;margin:0}
html,body{height:100%}
body{
  font-family:var(--mono);background:var(--bg);color:var(--text);
  min-height:100vh;font-size:16px;-webkit-font-smoothing:auto;
}
a{color:var(--accent2);text-decoration:none}

/* faint CRT scanline overlay — spec §1/§8: subtle, removable via .no-crt on <body> */
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:99;
  background:repeating-linear-gradient(0deg,rgba(255,255,255,.015) 0 1px,transparent 1px 3px);
}
body.no-crt::after{display:none}

/* pixel-corner panel helper — 2px border + hard offset shadow, zero radius */
.panel{background:var(--panel);border:2px solid var(--line);box-shadow:4px 4px 0 var(--shadow)}

/* ================= TOP BAR: brand + MODULE SELECT ================= */
.topbar{background:var(--panel);border-bottom:2px solid var(--line);display:flex;align-items:center;gap:0;position:sticky;top:0;z-index:10;
  padding:env(safe-area-inset-top) calc(16px + env(safe-area-inset-right)) 0 0}
/* logo box spans the 200px left-panel width (matches .frame's sidenav track) and centres the mark;
   with the topbar's left padding + gap removed, .modules then begins exactly at the sidenav edge. */
.logo{width:200px;flex:none;padding:15px 0;white-space:nowrap;display:flex;align-items:center;justify-content:center}
.logo img{height:26px;width:auto;display:block}
.logo span{color:var(--accent)}
.modules{display:flex;gap:2px;flex:1;overflow-x:auto}
.modules a{font-family:var(--px);font-size:10px;color:var(--dim);text-decoration:none;padding:18px 15px 14px;border-bottom:3px solid transparent;white-space:nowrap}
.modules a:hover{color:var(--text)}
.modules a.active{color:#fff;border-bottom-color:var(--accent);background:linear-gradient(180deg,transparent 60%,rgba(180,91,255,.12))}
.modules a.locked{opacity:.35;cursor:not-allowed}
/* DEX brand suffix — the "DEX" in every module label renders in Dex pink (--dex) while the prefix
   keeps its own colour. Shared by the top selector + the sidebar module-name header (.modname). */
.dex-sfx{color:var(--dex)}
.userchip{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--dim);white-space:nowrap}
.userchip .hp{color:var(--good)}
.userchip .hp.warn{color:var(--warn)}
.userchip .hp.bad{color:var(--bad)}
.userchip a{color:var(--dim)}
.avatar{width:30px;height:30px;background:var(--accent);color:#12121c;display:grid;place-items:center;font-family:var(--px);font-size:12px}

/* ================= LAYOUT: module sidebar + content ================= */
.frame{display:grid;grid-template-columns:200px 1fr;min-height:calc(100vh - 64px)}
.sidenav{background:var(--panel);border-right:2px solid var(--line);padding:16px 10px}
.sidenav .modname{font-family:var(--px);font-size:11px;color:#fff;padding:4px 8px 14px;letter-spacing:1px}
.sidenav a{display:flex;align-items:center;gap:10px;color:var(--dim);text-decoration:none;padding:9px 11px;font-size:14px;border-left:3px solid transparent;margin:2px 0}
.sidenav a:hover{color:var(--text);background:var(--panel2)}
.sidenav a.active{color:#fff;background:var(--panel2);border-left-color:var(--accent)}
.sidenav a.active::after{content:"\25C0";color:var(--accent);font-size:10px;margin-left:auto;font-family:var(--px)}
.sidenav .sep{border-top:2px dashed var(--line);margin:12px 6px}

/* pixel icon — crisp, no anti-alias blur (spec §5) */
.pix{width:16px;height:16px;flex:none;shape-rendering:crispEdges}

.content{padding:22px;max-width:1440px;min-width:0}
/* table-heavy screens (sync console, buy list, order queue): no max-width */
.content-wide{padding:22px;min-width:0}
.pagehead{display:flex;align-items:center;gap:14px;margin-bottom:18px;flex-wrap:wrap}
.pagehead h1{font-family:var(--px);font-size:17px;color:#fff}
.pagehead .sub{color:var(--dim);font-size:14.5px}
.pagehead .spacer{margin-left:auto}
/* 40px page-identity sprite (spec: page sprites) — sits before the h1 in a pagehead */
.pix.lg{width:40px;height:40px}
.syncchip{margin-left:auto;font-size:13.5px;color:var(--good);border:2px solid var(--line);padding:5px 11px;background:var(--panel)}
.syncchip.warn{color:var(--warn)} .syncchip.bad{color:var(--bad)}

/* ===== KPI cards ===== */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px;margin-bottom:18px}
.kpi{padding:13px 15px}
.kpi .label{font-size:14px;font-weight:700;color:var(--dim);text-transform:uppercase;letter-spacing:1px}
.kpi .value{font-family:var(--px);font-size:19px;margin-top:9px;color:#fff}
.kpi .delta{font-size:13.5px;margin-top:7px;color:var(--dim)}
.up{color:var(--good)} .down{color:var(--bad)} .flat{color:var(--dim)}

/* ===== generic card ===== */
.card{padding:16px 18px;margin-bottom:14px}
.card h3{font-family:var(--px);font-size:11.5px;color:var(--accent2);margin-bottom:16px;letter-spacing:.5px}
.grid2{display:grid;grid-template-columns:1.35fr 1fr;gap:14px}
/* PO detail: give the left column (wide LINE ITEMS table) more room; right column holds the
   narrower detail + payment cards. Defined before the ≤ mobile media query so .grid2{1fr} still
   collapses it to a single column on small screens. */
.grid2.po-grid{grid-template-columns:1.85fr 1fr}

/* ===== HP-bar (budget/quota pacing) ===== */
.hp{margin-bottom:14px}
.hp .row{display:flex;justify-content:space-between;font-size:14.5px;margin-bottom:5px;gap:10px;flex-wrap:wrap}
.hp .row b{color:#fff}
.bar{height:16px;background:#0d0d16;border:2px solid var(--line);position:relative}
.bar .fill{height:100%;image-rendering:pixelated;
  background:repeating-linear-gradient(90deg,var(--good) 0 8px,#2fbf59 8px 10px)}
.bar .fill.warn{background:repeating-linear-gradient(90deg,var(--warn) 0 8px,#d8ae23 8px 10px)}
.bar .fill.crit{background:repeating-linear-gradient(90deg,var(--bad) 0 8px,#d4414f 8px 10px)}
.hp .hint{font-size:13px;color:var(--dim);margin-top:4px}

/* ===== quest log ===== */
.quest{display:flex;gap:10px;padding:11px 6px;border-bottom:2px dashed var(--line);align-items:baseline}
.quest:last-child{border-bottom:none}
.quest .mark{font-family:var(--px);font-size:14px;width:24px}
.q-bad .mark{color:var(--bad)} .q-warn .mark{color:var(--warn)} .q-ok .mark{color:var(--good)}
.quest .txt{flex:1;font-size:15px}
.quest .txt small{display:block;color:var(--dim);margin-top:3px;font-size:13px}
.quest a{color:var(--accent2);font-size:14px}

/* ===== table ===== */
table{width:100%;border-collapse:collapse;font-size:15px}
th{color:var(--dim);font-weight:600;text-align:left;padding:8px;border-bottom:2px solid var(--line);font-size:12.5px;text-transform:uppercase;letter-spacing:1px}
td{padding:10px 8px;border-bottom:1px solid #2a2a40;vertical-align:middle}
tr:last-child td{border-bottom:none}
td.r,th.r{text-align:right}
td.c,th.c{text-align:center}
/* List-table headers stay on one line ("30d Units", "Weight (g)" wrapping ragged the header row).
   Scoped to .reporttable — the wide list screens — so narrow panel tables can still wrap. No mobile
   overflow risk: .reporttable is swapped for the card list below 700px. */
.reporttable th{white-space:nowrap}
tr.failed{background:rgba(255,91,106,.06)}
tr.sel{background:rgba(180,91,255,.09);outline:2px solid var(--accent)}

/* ===== buttons — console font, not pixel font (spec §2) ===== */
.btn{font-family:var(--mono);font-weight:700;letter-spacing:.8px;text-transform:uppercase;font-size:13px;color:#12121c;background:var(--accent2);border:2px solid var(--line);padding:8px 14px;cursor:pointer;box-shadow:3px 3px 0 var(--shadow);text-decoration:none;display:inline-block;line-height:1.2}
.btn:hover{filter:brightness(1.08)}
.btn:active{box-shadow:1px 1px 0 var(--shadow);transform:translate(2px,2px)}
.btn:disabled{opacity:.45;cursor:not-allowed;transform:none;box-shadow:3px 3px 0 var(--shadow)}
.btn.primary{background:var(--accent);color:#fff}
/* SAVE/CREATE is purple only when there are unsaved changes; grey while the form is clean */
.btn.primary.clean{background:var(--line);color:var(--dim)}
.btn.secondary{background:var(--panel2);color:var(--text)}
.btn.good{background:var(--good);color:#12121c}
.btn.dex{background:var(--dex);color:#12121c}
.btn.small{font-size:11.5px;padding:4px 9px;box-shadow:2px 2px 0 var(--shadow)}

/* ===== status tags ===== */
.status{font-family:var(--px);font-size:8.5px;padding:5px 8px;display:inline-block}
.s-ok{color:var(--good)} .s-run{color:var(--accent2)} .s-fail{color:var(--bad)} .s-off{color:var(--dim)}
.src{font-size:11.5px;color:var(--dim);border:1px solid var(--line);padding:2px 7px;display:inline-block}

/* ===== run log (admin drill-down) ===== */
.runlog{font-size:13.5px;line-height:1.85;color:var(--dim);background:#0d0d16;border:2px solid var(--line);padding:12px 14px;overflow-x:auto;white-space:pre-wrap;word-break:break-word}
.runlog b{color:var(--text)}
.runlog .err{color:var(--bad)}

/* ===== filter chips ===== */
.filters{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap}
.chip{font-size:12.5px;border:2px solid var(--line);background:var(--panel);color:var(--dim);padding:6px 12px;text-decoration:none;cursor:pointer}
.chip.on{color:#fff;border-color:var(--accent);background:var(--panel2)}

/* ===== form fields ===== */
.field{margin-bottom:14px}
.field label{display:block;font-size:12.5px;color:var(--dim);text-transform:uppercase;letter-spacing:1px;margin-bottom:6px}
.field input,.field select,.field textarea{width:100%;background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:15px;padding:9px 11px;outline:none}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent)}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* ===== empty / placeholder state ===== */
.placeholder{padding:60px 22px;text-align:center;color:var(--dim)}
.placeholder .big{font-family:var(--px);font-size:15px;color:var(--accent);margin-bottom:14px}
.placeholder .lock{font-size:34px;margin-bottom:14px}

/* ===== sign-in screen ===== */
.signin-wrap{min-height:100vh;display:grid;place-items:center;padding:20px}
.signin{width:min(420px,100%);padding:34px 30px;text-align:center}
.signin .logo{width:auto;padding:0;margin-bottom:24px;display:flex;justify-content:center}
.signin .logo img{height:34px;width:auto}
.signin .tag{color:var(--dim);font-size:18px;margin-bottom:26px}
.signin .err{color:var(--bad);font-size:13.5px;margin-bottom:16px;border:2px solid var(--bad);padding:10px}

/* ================= MOBILE (≤840px) ================= */
.tabbar{display:none}
@media (max-width:840px){
  .frame{grid-template-columns:1fr}
  .sidenav{display:none}
  .grid2{grid-template-columns:1fr}
  .logo{width:auto;justify-content:flex-start;padding-left:calc(12px + env(safe-area-inset-left))}
  .logo img{height:21px}
  .userchip .uname{display:none}
  .content,.content-wide{padding:14px 12px 100px}
  /* bottom bar = ACTIVE MODULE's sections + MORE */
  .tabbar{display:flex;position:fixed;bottom:0;left:0;right:0;background:var(--panel);border-top:2px solid var(--line);justify-content:space-around;padding:8px 2px calc(10px + env(safe-area-inset-bottom));z-index:20}
  .tabbar a{color:var(--dim);text-decoration:none;font-size:10.5px;font-family:var(--px);display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;min-width:0;flex:1}
  .tabbar a .tico{font-size:20px;font-family:var(--mono)}
  .tabbar a .pix{width:20px;height:20px}
  .tabbar a.active{color:var(--accent)}
}

/* ================= GearDex Products / Campaigns screens ================= */
/* (spec §6 archetypes; mockups NerdStack_Mock_Products.html + NerdStack_Mock_Campaigns.html) */

/* lifecycle / status tags — pixel font. products: active/draft/review/arch · campaigns: live/plan/done/kill */
.tag{font-family:var(--px);font-size:8px;padding:4px 7px;display:inline-block}
.t-active{color:var(--good)} .t-draft{color:var(--warn)} .t-review{color:var(--accent2)} .t-arch{color:var(--dim)}
.t-live{color:var(--good)} .t-plan{color:var(--accent2)} .t-done{color:var(--dim)} .t-kill{color:var(--bad)}
.vbadge{font-size:12px;color:var(--accent2);border:1px solid var(--line);padding:2px 8px;background:#0d0d16}
.vbadge.single{color:var(--dim)}
.brand{font-size:12px;color:var(--dim)}

/* filter dropdowns */
.fsel{font-family:var(--mono);font-size:12.5px;border:2px solid var(--line);background:var(--panel);color:var(--text);padding:6px 10px;outline:none}
.fsel:focus{border-color:var(--accent)}

/* clickable list rows */
tr.clickable:hover{background:var(--panel2);cursor:pointer}

/* PO detail: recorded payments as cards (readable in the narrow right column, vs a cramped table) */
.paycards{display:flex;flex-direction:column;gap:8px;margin-top:6px}
.paycard{border:2px solid var(--line);background:#0d0d16;padding:10px 12px}
.paycard-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.paycard-amt{font-family:var(--mono);font-size:15px;color:var(--text);font-weight:bold}
.paycard-actions{display:flex;gap:12px;flex:none}
.paycard-actions .pencil{cursor:pointer;color:var(--warn);font-size:14px}
.paycard-meta{font-size:12px;color:var(--dim);margin-top:4px}
.paycard-note{font-size:12.5px;color:var(--text);opacity:.8;margin-top:6px;word-break:break-word}
/* detail two-column (wider left) + inner duo */
.pdetail{display:grid;grid-template-columns:1.35fr .65fr;gap:14px}
.duo{display:grid;grid-template-columns:1fr 1.15fr;gap:14px;align-items:start}
/* customs/dims validation hint (Products detail) */
.field .hint{display:block;font-size:11.5px;color:var(--dim);margin-top:5px}
.field input:invalid{border-color:var(--bad)}
.field input:invalid + .hint{color:var(--bad)}
/* editable product-title header (✎) */
.edithead{display:flex;align-items:center;gap:8px}
.edithead .pencil{font-size:16px;color:var(--warn);cursor:pointer;background:none;border:none;padding:0}
.edithead input{background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:16px;padding:6px 10px;flex:none;width:min(540px,calc(100vw - 220px))}
.edithead .ponum{flex:none;white-space:nowrap}
/* inline-editable variant price cell */
/* Base: .priceedit was only ever defined under .vtable, so the same class on a modal input (the
   transfer confirms) fell back to the raw browser default — an unstyled grey box in a retro panel.
   Centred here; the in-table variant below re-aligns right to sit under its numeric column. */
input.priceedit{width:74px;background:#0d0d16;border:2px solid var(--line);color:var(--text);
  font-family:var(--mono);font-size:14px;padding:5px 8px;text-align:center}
input.priceedit:focus{border-color:var(--accent);outline:none}
.vtable input.priceedit{text-align:right}
/* lightweight retro modal (transfer / push confirm / add variant) */
.gdmodal-back{position:fixed;inset:0;background:rgba(6,6,12,.66);z-index:200;display:grid;place-items:center;padding:16px}
.gdmodal{background:var(--panel);border:2px solid var(--accent);box-shadow:6px 6px 0 #0a0a12;padding:18px 20px;max-width:440px;width:100%}
.gdmodal h3{font-family:var(--px);font-size:11.5px;color:var(--accent2);margin-bottom:14px}
.gdmodal .actions{display:flex;gap:8px;justify-content:flex-end;margin-top:16px;flex-wrap:wrap}
.gdmodal p.err{color:var(--bad);font-size:12.5px;margin-top:8px}
th.sortable{cursor:pointer;user-select:none}
.reporttable.nowrapth th{white-space:nowrap}
th.sortable:hover{color:var(--text)}
/* Expand/collapse row toggles (▸/▾) — enlarged globally for a clearer click affordance. */
.expander{font-size:22px;line-height:1;vertical-align:-3px}
/* ===== responsive list pattern (≤700px): table → tappable cards ===== */
.cardlist{display:none}
@media(max-width:700px){
  .reporttable{display:none}
  .cardlist{display:flex;flex-direction:column;gap:10px}
}
.rcard{display:block;background:var(--panel2);border:2px solid var(--line);box-shadow:3px 3px 0 #0a0a12;padding:12px 14px;text-decoration:none;color:var(--text)}
.rcard:active{background:var(--panel)}
.rcard .top{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.rcard .sku{font-weight:700;color:var(--accent2)}
.rcard .name{display:block;font-size:12.5px;color:var(--dim);margin-top:2px;font-weight:400}
.rcard .metrics{margin-top:9px;font-size:14px}
.rcard .metrics b{color:var(--text)}
.rcard .metrics .lbl{color:var(--dim)}
.rcard .meta{margin-top:6px;font-size:12px;color:var(--dim)}
/* Card that navigates on tap but carries its own controls (buy-list select) — mirrors tr.sel */
.rcard.tap{cursor:pointer}
.rcard.sel{background:rgba(180,91,255,.09);outline:2px solid var(--accent)}
.rcard .pick{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--dim)}
/* On-hand mobile: per-location breakdown line inside the card */
.rcard .locs{margin-top:8px;font-size:12.5px;color:var(--dim);line-height:1.6}
.rcard .locs b{color:var(--text)}
/* Wide matrix (desktop): freeze the SKU column, scroll the numeric columns */
.matrixwrap{overflow-x:auto}
.matrixwrap table{min-width:640px}
.matrixwrap th.stick,.matrixwrap td.stick{position:sticky;left:0;background:var(--panel);z-index:1}
.matrixwrap tr:hover td.stick{background:var(--panel2)}

/* list thumbnail with hover-expand */
.thumbwrap{position:relative;display:inline-block}
.thumb{width:44px;height:44px;object-fit:cover;border:2px solid var(--line);background:#0d0d16;display:block}
.thumb.ph{display:grid;place-items:center;color:var(--dim);font-size:10px;font-family:var(--px)}
.thumbbig{display:none;position:absolute;left:56px;top:-30px;width:230px;height:230px;object-fit:cover;border:2px solid var(--accent);box-shadow:6px 6px 0 var(--shadow);z-index:50;background:#0d0d16}
.thumbwrap:hover .thumbbig{display:block}

/* hover popups (on-hand by warehouse / velocity) */
.ohwrap{position:relative;display:inline-block;cursor:help;border-bottom:1px dotted var(--dim)}
.ohpop{display:none;position:absolute;right:0;top:24px;z-index:60;background:var(--panel);border:2px solid var(--accent);box-shadow:6px 6px 0 var(--shadow);padding:10px 12px;min-width:190px;text-align:left}
.ohwrap:hover .ohpop{display:block}
.ohpop table{font-size:12.5px}
.ohpop td{padding:3px 6px;border-bottom:1px dashed #2a2a40}
.ohpop tr:last-child td{border-bottom:none;color:var(--accent2);font-weight:700}
.ohpop .own{color:var(--good);font-size:10px}

/* media gallery */
.gallery{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start}
.gmain{width:200px;height:200px;object-fit:cover;border:2px solid var(--line);background:#0d0d16}
/* Variant media card: the variant image and the product image side by side, actions under the
   variant one only (the product image is not editable from here). */
.vmedia{display:flex;gap:14px;flex-wrap:wrap}
.vslot{display:flex;flex-direction:column;gap:6px;width:150px}   /* pin to the image: otherwise the buttons/label widen the slot and .vmedia wraps */
.vslotlabel{font-family:var(--px);font-size:8px;letter-spacing:1px;color:var(--accent2);white-space:nowrap}
.vslotlabel.dim{color:var(--dim)}
.vimgtools{display:flex;gap:6px;margin-top:8px}
/* Icon-only actions — bigger tap target than .btn.small, and two of them can never wrap out of
   the 150px slot the way the text buttons did. */
.ibtn{width:36px;height:36px;display:grid;place-items:center;padding:0;line-height:1;font-size:16px;
  font-family:var(--mono);color:var(--dim);background:var(--panel2);border:2px solid var(--line);cursor:pointer}
.ibtn:hover{color:var(--accent);border-color:var(--accent)}
.ibtn.bad:hover{color:var(--bad);border-color:var(--bad)}
.ibtn:disabled{opacity:.35;cursor:not-allowed;color:var(--dim);border-color:var(--line)}
/* 2-column grid of secondary images, each its own hover-controlled cell. */
.gstrip{display:grid;grid-template-columns:repeat(2,72px);gap:8px;align-content:start}
.gcell{position:relative;width:72px;height:72px;line-height:0}
.gcell.primary .gthumb{border-color:var(--accent)}
.gthumb{width:72px;height:72px;object-fit:cover;border:2px solid var(--line);background:#0d0d16;cursor:zoom-in;display:block}
/* Marks position 0 without needing a legend — this is the list thumbnail + Shopify push source. */
.gprimary{position:absolute;top:1px;left:3px;color:var(--warn);font-size:11px;line-height:1;pointer-events:none;text-shadow:0 0 3px #000,0 0 3px #000}
/* Per-thumbnail controls: a bar across the BOTTOM only, so the rest of the cell stays a lightbox
   target. Revealed on hover; also on focus-within so keyboard users can reach them. */
.gcelltools{position:absolute;left:2px;right:2px;bottom:2px;display:none;background:rgba(10,10,18,.92);border-top:2px solid var(--line)}
.gcell:hover .gcelltools,.gcell:focus-within .gcelltools{display:flex}
.gcelltools button{flex:1;min-width:0;background:none;border:none;color:var(--dim);font-family:var(--mono);
  font-size:10px;line-height:1;padding:4px 0;cursor:pointer}
.gcelltools button:hover:not(:disabled){color:var(--accent);background:rgba(180,91,255,.2)}
.gcelltools button.bad:hover:not(:disabled){color:var(--bad);background:rgba(255,91,106,.2)}
.gcelltools button:disabled{opacity:.3;cursor:not-allowed}
.gadd{width:72px;height:72px;border:2px dashed var(--line);color:var(--dim);display:grid;place-items:center;font-size:11px;font-family:var(--px);cursor:pointer;text-decoration:none}
/* Click-to-enlarge affordance on a gallery main image (Lightbox.razor). */
.gmain.zoom{cursor:zoom-in}
.lightbox{position:fixed;inset:0;z-index:2000;display:grid;place-items:center;padding:24px;
  background:rgba(10,10,18,.92);cursor:zoom-out}
.lightbox img{max-width:min(92vw,640px);max-height:88vh;object-fit:contain;background:#0d0d16;
  border:2px solid var(--accent);box-shadow:8px 8px 0 var(--shadow)}
.lbclose{position:absolute;top:18px;right:22px}

/* variants inline-edit table */
.vtable input{background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:14px;padding:5px 8px}

/* dashed section divider */
.divider{border:none;border-top:2px dashed var(--line);margin:34px 0 26px}

/* variant switcher list (variant edit page) */
.vswitch{max-height:250px;overflow-y:auto;border:2px solid var(--line);background:#0d0d16}
.vswitch a{display:flex;justify-content:space-between;padding:8px 11px;color:var(--dim);text-decoration:none;font-size:13.5px;border-top:1px dashed #2a2a40}
.vswitch a:first-child{border-top:none}
.vswitch a:hover{color:var(--text);background:var(--panel2)}
.vswitch a.active{color:#fff;background:var(--panel2);border-left:3px solid var(--accent)}

/* ---- Buy List: tabs, engine-run chip, class tags, two-line SKU cell ---- */
.tabs{display:flex;gap:2px;margin-bottom:14px;flex-wrap:wrap}
.tabs a{font-family:var(--mono);font-weight:700;letter-spacing:.6px;font-size:13.5px;color:var(--dim);text-decoration:none;padding:10px 14px;border:2px solid var(--line);border-bottom:none;background:var(--panel);cursor:pointer}
.tabs a.on{color:#fff;background:var(--panel2);border-color:var(--accent)}
/* ===== marketing tab: tag chips, feature bullets, channel listings ===== */
.tagchip{display:inline-block;font-size:12.5px;border:1px solid var(--line);background:#0d0d16;color:var(--text);padding:3px 9px;margin:0 5px 6px 0}
.tagchip i{font-style:normal;color:var(--dim);margin-left:5px;cursor:pointer}
.tagchip i:hover{color:var(--bad)}
.tagadd{display:flex;gap:6px;margin:2px 0 4px}
.tagadd input{flex:1;background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:13.5px;padding:6px 9px;outline:none}
.tagadd input:focus{border-color:var(--accent)}
.blt{display:flex;gap:8px;align-items:center;margin-bottom:7px}
.blt input{flex:1;background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:14px;padding:7px 10px;outline:none}
.blt input:focus{border-color:var(--accent)}
.blt a{color:var(--bad);text-decoration:none;font-size:14px}
.chl{border:2px solid var(--line);background:#0d0d16;padding:10px 12px;margin-bottom:10px}
.chl .chead{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.chl .cname{font-family:var(--px);font-size:9px;color:#fff}
.chl .cmeta{font-size:12.5px;color:var(--dim);line-height:1.55}
.chl .cmeta b{color:var(--text);font-weight:600}
/* ===== DEX✦ DESCRIBE draft state (pink) ===== */
.dexdraft-bar{display:flex;align-items:center;gap:10px;border:2px solid var(--dex);background:#2a1626;color:var(--dex);font-size:12.5px;padding:8px 11px;margin-bottom:12px}
.dexdraft-bar b{color:var(--dex)}
.panel.card.dexdraft .field input,.panel.card.dexdraft .field textarea{border-color:var(--dex)}
.panel.card.dexdraft .tagchip{border-color:var(--dex)}
.runchip{margin-left:auto;font-size:12.5px;color:var(--dim);border:2px solid var(--line);padding:5px 11px;background:var(--panel);white-space:nowrap}
.runchip b{color:var(--good)}
.topup{font-family:var(--px);font-size:8px;color:var(--warn)}
.t-a{color:var(--bad)} .t-b{color:var(--warn)} .t-c{color:var(--dim)}
/* two-line SKU cell (locked table standard 2026-07-12) */
.skucell a{color:var(--accent2);text-decoration:none}
.skucell .sub{display:block;font-size:12px;color:var(--dim);margin-top:2px}

/* ---- Overview: freshness banner + drill-through KPI tiles + WoW deltas ---- */
.freshness{display:flex;align-items:center;gap:12px;background:var(--panel);border:2px solid var(--good);padding:10px 14px;margin-bottom:16px;font-size:13.5px}
.freshness.stale{border-color:var(--warn)} .freshness.bad{border-color:var(--bad)}
.freshness .dot{width:10px;height:10px;background:var(--good);flex:none}
.freshness.stale .dot{background:var(--warn)} .freshness.bad .dot{background:var(--bad)}
.freshness .runnow{margin-left:auto;flex:none;background:none;border:2px solid var(--dex);color:var(--dex);font:inherit;font-size:12px;padding:4px 10px;cursor:pointer;letter-spacing:.5px}
.freshness .runnow:hover:not(:disabled){background:var(--dex);color:var(--panel)}
.freshness .runnow:disabled{border-color:var(--dim);color:var(--dim);cursor:default}
.kpi .sub2{font-size:12px;color:var(--dim);margin-top:4px}
/* Clickable panels (dashboard KPI tiles + Reports cards): hand cursor, hover lift, blue GO marker. */
a.panel{display:block;text-decoration:none;color:inherit;position:relative;cursor:pointer}
a.panel:hover{background:var(--panel2);border-color:var(--accent2)}
a.panel .go{position:absolute;top:11px;right:13px;font-size:11px;color:var(--accent2)}
.d-up{color:var(--good)} .d-dn{color:var(--bad)} .d-flat{color:var(--dim)}
.bar .fill.cash{background:repeating-linear-gradient(90deg,var(--accent) 0 8px,#9a3fe0 8px 10px)}

/* ---- Paula's mobile Receive screen (390px phone frame) ---- */
.phone{width:390px;max-width:100%;border:3px solid var(--line);box-shadow:8px 8px 0 var(--shadow);margin:0 auto;background:var(--bg)}
.ptop{background:var(--panel);border-bottom:2px solid var(--line);padding:12px;display:flex;justify-content:space-between;align-items:center}
.ptop .t{font-family:var(--px);font-size:11px;color:#fff}
.pbody{padding:12px}
.pfield{margin-bottom:11px}
.pfield label{display:block;font-size:11.5px;color:var(--dim);text-transform:uppercase;letter-spacing:1px;margin-bottom:5px}
.pfield input,.pfield select{width:100%;background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:16px;padding:11px;outline:none}
.pfield input:focus,.pfield select:focus{border-color:var(--accent)}
.bigbtn{display:block;width:100%;text-align:center;font-family:var(--mono);font-weight:700;letter-spacing:.8px;font-size:15px;color:#12121c;background:var(--good);border:2px solid var(--line);padding:14px;box-shadow:3px 3px 0 var(--shadow);text-decoration:none;margin-top:6px;cursor:pointer}
.bigbtn:disabled{opacity:.5;cursor:not-allowed}
.bigbtn.adjust{background:var(--warn)} .bigbtn.count{background:var(--accent2)}
.ptabs{display:flex;position:sticky;bottom:0;background:var(--panel);border-top:2px solid var(--line);justify-content:space-around;padding:8px 2px 10px}
.ptabs a{color:var(--dim);text-decoration:none;font-size:10px;font-family:var(--px);display:flex;flex-direction:column;align-items:center;gap:5px;cursor:pointer}
.ptabs a.active{color:var(--accent)}

/* campaign stats grid */
.meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-bottom:4px}
.meta .m .k{font-size:11.5px;color:var(--dim);text-transform:uppercase;letter-spacing:1px}
.meta .m .v{font-size:15px;margin-top:3px;color:#fff}

/* barcode label preview */
.barcode{border:2px solid var(--line);background:#fff;padding:8px 10px;margin-bottom:10px;text-align:center}
.barcode .bars{height:34px;background:repeating-linear-gradient(90deg,#000 0 2px,#fff 2px 4px,#000 4px 5px,#fff 5px 8px)}
.barcode .bcimg{line-height:0}
.barcode .bcimg svg{max-width:100%;height:auto}
.barcode .code{font-family:var(--mono);color:#000;font-size:11px;margin-top:3px}

/* ================= GearDex Ops: POs · Shipments · Forecast · Capital ================= */
/* (mockups NerdStack_Mock_POs.html + NerdStack_Mock_Forecast_Capital.html) */

/* inline edit inputs — PO/shipment line grids (finput) + forecast lever cells (tinput) */
.finput{font-family:var(--mono);font-size:14px;border:2px solid var(--line);background:#0d0d16;color:var(--text);padding:8px 10px;outline:none;width:100%}
.finput:focus{border-color:var(--accent)}
/* variant typeahead (shipment add-line pickers) — classic lookup with thumbnails */
.vpick{position:relative;display:inline-block}
.vpick-menu{position:absolute;top:100%;left:0;right:auto;min-width:480px;max-width:calc(100vw - 32px);z-index:50;background:#0d0d16;border:2px solid var(--accent);border-top:none;max-height:340px;overflow-y:auto;box-shadow:4px 4px 0 var(--shadow)}
.vpick-head{display:flex;justify-content:space-between;align-items:center;padding:5px 10px;border-bottom:1px solid var(--line);background:#101019;font-size:10px;letter-spacing:1px;text-transform:uppercase;color:var(--dim);position:sticky;top:0}
.vpick-head b{color:var(--accent2);font-weight:700}
.vpick-item{display:flex;align-items:center;gap:10px;padding:6px 10px;cursor:pointer;border-bottom:1px solid var(--line)}
.vpick-item:last-child{border-bottom:none}
.vpick-item:hover,.vpick-item.active{background:var(--panel2)}
.vpick-item.active{box-shadow:inset 3px 0 0 var(--accent)}
.vpick-thumb{width:30px;height:30px;flex:0 0 30px;object-fit:cover;border:1px solid var(--line);background:#0d0d16}
.vpick-thumb.ph{display:grid;place-items:center;color:var(--dex);font-size:14px;background:#151521}
.vpick-text{display:flex;flex-direction:column;gap:1px;min-width:0}
.vpick-sku{font-family:var(--mono);font-size:15px;color:var(--text);font-weight:600;white-space:nowrap}
.vpick-name{font-size:13px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vpick-empty{padding:9px 10px;font-size:12px;color:var(--dim)}
.tinput{font-family:var(--mono);font-size:13px;border:2px solid var(--line);background:#0d0d16;color:var(--text);padding:3px 6px;width:70px;text-align:right;outline:none}
.tinput:focus{border-color:var(--accent)}

/* key/value grid (summary + details panels) */
.kv{display:grid;grid-template-columns:auto 1fr;gap:8px 16px;font-size:14px;align-items:center}
.kv .k{color:var(--dim)}

/* validation warn box */
.warnbox{border:2px solid var(--warn);background:rgba(255,210,62,.06);padding:10px 12px;font-size:13px;margin-bottom:12px}

/* status timeline strip (PO / shipment detail) */
.timeline{display:flex;margin-bottom:14px;text-align:center}
.timeline .tl{flex:1;padding:10px 6px;border-right:2px dashed var(--line)}
.timeline .tl:last-child{border-right:none}
.timeline .tl.on{background:var(--panel2)}
.timeline .tl.future{opacity:.5}
/* the actionable next-step cell (holds the workflow button, e.g. CONFIRM PO) is not dimmed */
.timeline .tl.future.next{opacity:1}
.timeline .tl .s{font-family:var(--px);font-size:9px}
.timeline .tl.done .s{color:var(--good)} .timeline .tl.on .s{color:var(--accent2)} .timeline .tl.future .s{color:var(--dim)}
.timeline .tl .d{font-size:12px;color:var(--dim);margin-top:5px}

/* section header with inline actions (■ TITLE ......... [btn][btn]) */
.cardhead{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:14px;gap:8px;flex-wrap:wrap}
.cardhead h3{margin-bottom:0}
.cardhead .acts{display:flex;gap:8px}

/* Dex explain sub-row (row-◆ EXPLAIN on the buy list) — pink left border, tinted */
.dexrow td{border-left:3px solid var(--dex);background:rgba(255,123,213,.05);font-size:13px;color:var(--dim);padding:10px 12px}
.dexrow .lead{color:var(--dex)}
.dex-glyph{color:var(--dex);text-decoration:none;font-size:12px}

/* forecast family/category drill-down rows */
tr.fam{background:rgba(180,91,255,.07);cursor:pointer}
tr.fam td:first-child::before{content:"\25B8 ";color:var(--accent)}   /* ▸ */
tr.fam.open td:first-child::before{content:"\25BE ";color:var(--accent)} /* ▾ */
tr.cat td:first-child{padding-left:34px;color:var(--dim)}
tr.cat.clickable:hover{background:var(--panel2)}
.auto{font-size:10px;color:var(--dim)}   /* the read-only "auto" trend marker */

/* sparkline (the month position table drawn small) */
.spark{display:inline-flex;gap:2px;align-items:flex-end;height:22px}
.spark i{width:6px;background:var(--accent);display:block}
.spark i.neg{background:var(--bad)}

/* forecast-accuracy err cells */
.err-ok{color:var(--good)} .err-warn{color:var(--warn)} .err-bad{color:var(--bad)}

/* cash calendar segmented bar (committed PO / planned buy / forecast) */
.cashbar{height:16px;background:#0d0d16;border:2px solid var(--line);display:flex;margin-top:2px}
.seg-po{height:100%;background:repeating-linear-gradient(90deg,var(--bad) 0 6px,#cc4855 6px 8px)}
.seg-plan{height:100%;background:repeating-linear-gradient(90deg,var(--warn) 0 6px,#d1ad33 6px 8px)}
.seg-fc{height:100%;background:repeating-linear-gradient(90deg,var(--accent) 0 6px,#9a3fe0 6px 8px)}
.legend{display:flex;gap:16px;font-size:12.5px;color:var(--dim);margin-bottom:12px;flex-wrap:wrap}
.legend b{display:inline-block;width:12px;height:12px;vertical-align:-1px;margin-right:5px}
.cashmonth{margin-bottom:12px}
.cashmonth .row{display:flex;justify-content:space-between;font-size:13.5px;margin-bottom:4px;gap:10px;cursor:pointer}
.cashmonth .rows{width:auto;min-width:min(480px,100%);font-size:13px;margin:8px 0 4px 16px}

/* runchip variant used on ops pages (not right-pinned) */
.runchip.inline{margin-left:0}

@media (max-width:840px){
  .pdetail{grid-template-columns:1fr}
  .duo{grid-template-columns:1fr}
  .timeline{flex-wrap:wrap}
  .timeline .tl{min-width:45%}
}

/* ================= Blazor Server reconnection UI ================= */
/* Hidden until blazor.web.js drops the circuit; -show = retrying, -failed/-rejected = gone.
   .nerd-circuit-stalled is ours, not Blazor's: the circuit never STARTED (see App.razor). */
#components-reconnect-modal{display:none}
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected,
#components-reconnect-modal.nerd-circuit-stalled{
  display:grid;place-items:center;position:fixed;inset:0;z-index:1000;padding:20px;
  background:rgba(10,10,18,.82)}
.reconnect-box{width:min(430px,100%);padding:26px 28px;text-align:center;background:var(--panel)}
.reconnect-title{font-family:var(--px);font-size:13px;color:var(--accent);margin-bottom:12px}
.reconnect-box p{color:var(--dim);font-size:14px;margin-bottom:16px;line-height:1.5}
.reconnect-box p.fix{color:var(--text);font-size:13px}
.reconnect-retry,.reconnect-reload,.reconnect-stalled{display:none}
#components-reconnect-modal.components-reconnect-show .reconnect-retry{display:block}
#components-reconnect-modal.components-reconnect-failed .reconnect-reload,
#components-reconnect-modal.components-reconnect-rejected .reconnect-reload{display:block}
#components-reconnect-modal.nerd-circuit-stalled .reconnect-stalled{display:block}

/* ---- destructive action + confirm overlay (reference-data CRUD) ------------ */
/* Deliberately not a MudDialog: the shell is the retro console, and a Material
   dialog reads as a different app. Same panel/btn vocabulary as everything else. */
.btn.danger{background:var(--bad);color:#fff}
.modalwrap{position:fixed;inset:0;z-index:200;background:rgba(10,10,18,.72);display:grid;place-items:center;padding:16px}
.modalwrap>.panel{width:100%;margin:0}

/* Outbound reference links in a list cell (supplier Alibaba/Website). The row itself is clickable,
   so these are the only anchors inside it — keep them visually distinct from the row's own hit area. */
td.links a{color:var(--accent2);text-decoration:none;margin-right:10px;white-space:nowrap}
td.links a:last-child{margin-right:0}
td.links a:hover{text-decoration:underline}
td.links span{color:var(--dim)}

/* ---- Transfers tables ------------------------------------------------------ */
/* "Why" rationale as a hover tooltip instead of a text column (Transfers > Region Moves). */
.whyicon{display:inline-grid;place-items:center;width:22px;height:22px;border:2px solid var(--line);
  background:var(--panel2);color:var(--dim);font-family:var(--mono);font-size:12px;line-height:1;cursor:help}
.whyicon:hover{color:var(--accent2);border-color:var(--accent2)}

/* Region Moves: every column centres except the SKU. Scoped to this table on purpose —
   .reporttable is shared by 9 GearDex pages, so a bare .reporttable rule would restyle them all.
   Beats .r (0,1,1) on specificity (0,2,1), so leftover .r classes can't fight it. */
.rmoves th:not(:first-child),.rmoves td:not(:first-child){text-align:center}

/* Location Moves — same scoping rationale as .rmoves.
   Everything centres except SKU / Variant. Class-driven on purpose: rowspans mean the SKU cell is
   not at a fixed child index, so :nth-child() would centre it on every continuation row. */
.lmoves th,.lmoves td{text-align:center}
.lmoves th.skuh,.lmoves td.skucell{text-align:left}
/* Zebra alternates per LANE (From→To), not per row: the lane is the unit TRANSFER acts on, so the
   block should read as one thing. Applied to td (not tr) — a tr background sits behind cell
   backgrounds and rowspan'd group cells would punch through it. */
.lmoves tr.alt td{background:rgba(180,91,255,.07)}
.lmoves .grpcell{vertical-align:middle;border-right:2px solid var(--line);font-size:13px}
/* FROM spans exactly ONE lane (repeated per lane rather than centred across a tall source group),
   so it sits inside the band and takes the zebra like everything else. */
.lmoves .grpcell.fromcell{color:var(--text)}
/* A rule across the top of each lane's opening row makes the block boundary explicit even where two
   same-tone bands would otherwise meet. */
.lmoves tr.laneopen td{border-top:2px solid var(--line)}

/* KPI corner sprite (GearDex Overview). The corner already belonged to the GO chevron, so the two
   share it: sprite at rest, GO → on hover. Scoped to .iconkpi — a.panel .go is also used on POs and
   Reports, where the chevron must stay put. */
.iconkpi .kpicon{position:absolute;top:10px;right:12px;width:44px;height:44px;opacity:.85}
.iconkpi:hover .kpicon{display:none}
.iconkpi .go{display:none}
.iconkpi:hover .go{display:block}

/* ============ MarketDex Performance (Slice 4) ============ */
/* Chart.js host — fills a fixed-height box (charts run maintainAspectRatio:false). */
.nerd-chart{position:relative;width:100%}
.nerd-chart canvas{width:100%!important}

/* Date/preset bar: preset chips + custom range inputs + compare toggle. */
.datebar{display:flex;gap:8px;align-items:center;margin-bottom:16px;flex-wrap:wrap}
.datebar input[type=date],.datebar input.dtin{background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:13px;padding:6px 9px;outline:none}
.datebar .lbl{font-size:12px;color:var(--dim);text-transform:uppercase;letter-spacing:1px}

/* Horizontal-bar breakdown (revenue by channel). */
.hrow{display:flex;align-items:center;gap:10px;font-size:13.5px;margin-bottom:9px}
.hrow .nm{width:118px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:none}
.hrow .hb{flex:1;height:14px;background:#0d0d16;border:1px solid var(--line);min-width:0}
.hrow .hb div{height:100%}
.hrow .val{width:160px;text-align:right;white-space:nowrap;flex:none}

/* 1.15/0.85 split used by ROAS+funnel and pacing+attribution rows. */
.grid31{display:grid;grid-template-columns:1.15fr .85fr;gap:14px}

/* Pixel badge (NEW / partial markers). */
.badge{font-family:var(--px);font-size:8px;padding:4px 7px;display:inline-block}

@media (max-width:840px){.grid31{grid-template-columns:1fr}}

/* MarketDex CRUD forms (Events / Ad Budgets). */
.dtin{background:#0d0d16;border:2px solid var(--line);color:var(--text);font-family:var(--mono);font-size:13px;padding:6px 9px;outline:none;width:100%}
.evform{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.evform label,.bform label{display:flex;flex-direction:column;gap:5px;font-size:12px;color:var(--dim);text-transform:uppercase;letter-spacing:.6px}
.evform label.wide{grid-column:1/-1}
.bform{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap}
.bform label{min-width:130px}

/* ============ MarketDex LIVE (semi-live pulse) ============ */
/* Per-channel freshness chips — one per order-bearing feed. Green border = fresh, warn = stale
   (last success older than 2× the cadence). Mirrors the .freshness bar, one pill per feed. */
.updated{font-family:var(--mono);font-size:12px;color:var(--dim)}
.livechips{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px}
.livechip{display:inline-flex;align-items:center;gap:8px;background:var(--panel);border:2px solid var(--good);padding:7px 11px;font-size:13px}
.livechip.stale{border-color:var(--warn)}
.livechip .dot{width:9px;height:9px;background:var(--good);flex:none}
.livechip.stale .dot{background:var(--warn)}
.livechip .meta{color:var(--dim);font-size:12px}
.livechip .q{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border:1px solid var(--line);
  background:var(--panel2);color:var(--dim);font-family:var(--mono);font-size:11px;line-height:1;cursor:help;flex:none}
.livechip .q:hover{color:var(--accent2);border-color:var(--accent2)}

/* ---- WS-7 RoyalDex terms CRUD forms (adjustments · licensors · deals · designs · rates/rules) ----
   Reuses the shell's .field/.finput/.fsel/.kv/.grid2/.chip/.tag; adds the form grid, the basis
   toggle, and the inline rule banners. Auto-fit → single column at ≤380px (forms stack, spec §10). */
.fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:13px 16px}
.fgrid .field{margin-bottom:0;min-width:0}
.fgrid .span2{grid-column:span 2}
.fgrid .wide{grid-column:1/-1}
.field .req{color:var(--bad)}
.toggle{display:flex;gap:0}
.toggle button{font-family:var(--mono);font-weight:700;letter-spacing:.8px;text-transform:uppercase;font-size:12px;
  padding:7px 13px;cursor:pointer;border:2px solid var(--line);background:var(--panel2);color:var(--dim)}
.toggle button.on{background:var(--accent);color:#fff}
.toggle button:disabled{opacity:.5;cursor:not-allowed}
.banner{border:2px solid var(--warn);background:rgba(255,210,62,.06);padding:10px 14px;font-size:13.5px;
  margin:12px 0;display:flex;gap:10px;align-items:baseline}
.banner.bad{border-color:var(--bad);background:rgba(255,91,106,.07)}
.banner.info{border-color:var(--accent2);background:rgba(77,243,255,.05)}
.banner .bang{font-family:var(--px);font-size:11px;color:var(--warn);flex:none}
.banner.bad .bang{color:var(--bad)}
.banner.info .bang{color:var(--accent2)}
@media (max-width:840px){.fgrid .span2,.fgrid .wide{grid-column:auto}}
/* ===== OrderDex (hub / mto / shipments / exceptions) ===== */
tr.tap{cursor:pointer}
tr.tap:hover{background:rgba(180,91,255,.06)}
.pager{display:flex;align-items:center;gap:14px;margin-top:14px;justify-content:center}
.pager .sub{color:var(--dim);font-size:13px}
/* mto board: design-grouped grid of job cards, mobile-first (single column at 380px) */
.mtogroup{margin-bottom:22px}
.mtogroup h2{font-family:var(--px);font-size:11.5px;color:var(--accent2);margin:0 0 10px;display:flex;align-items:center;gap:10px}
.jobgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px}
@media(max-width:380px){.jobgrid{grid-template-columns:1fr}}
.jobcard{background:var(--panel2);border:2px solid var(--line);box-shadow:3px 3px 0 #0a0a12;padding:12px 13px}
.jobcard.sel{outline:2px solid var(--accent);background:rgba(180,91,255,.09)}
.jobcard .thumb{width:44px;height:44px;border:2px solid var(--line);background:var(--panel);object-fit:cover;flex:none}
.jobcard .jtop{display:flex;gap:10px;align-items:flex-start}
.jobcard .adv{width:100%;margin-top:10px}
.timeline{list-style:none;margin:0;padding:0}
.timeline li{position:relative;padding:6px 0 6px 20px;border-left:2px solid var(--line);margin-left:5px}
.timeline li .mk{position:absolute;left:-6px;top:9px;width:9px;height:9px;background:var(--accent2)}
.timeline li .tt{color:var(--dim);font-size:12px}
.ratecard{display:flex;justify-content:space-between;align-items:center;border:2px solid var(--line);background:var(--panel2);padding:9px 12px;margin-bottom:8px;cursor:pointer}
.ratecard.sel{outline:2px solid var(--accent);border-color:var(--accent);background:rgba(180,91,255,.09)}
/* OrderDex detail/shipments/settings tables have NO card variant — instead of the global
   reporttable→cardlist hide at ≤700px (which would blank them), keep them and let the table itself
   scroll horizontally inside its box (no page-level horizontal scroll at 380px). Two-class specificity
   beats the global .reporttable{display:none}. */
@media(max-width:700px){ .reporttable.odx{display:block;overflow-x:auto;white-space:nowrap} }

/* ================= DEX✦ INSIGHTS (spec §9) — namespaced dex- to avoid the global .chip/.meta ================= */
.dex-insight-card{padding:24px 26px}
.dex-ihead{display:flex;justify-content:space-between;align-items:flex-start;gap:18px;flex-wrap:wrap;
  margin-bottom:22px;padding-bottom:16px;border-bottom:2px solid var(--line)}
.dex-ihead .left{display:flex;align-items:baseline;gap:11px}
.dex-ihead .tick{color:var(--dex);font-family:var(--px);font-size:13px}
.dex-period{font-family:var(--px);font-size:12px;color:#fff;letter-spacing:.5px}
.dex-range{color:var(--dim);font-size:13.5px;margin-top:9px}
.dex-meta{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.dex-chip{font-size:11.5px;color:var(--dim);border:2px solid var(--line);background:var(--panel2);
  padding:4px 9px;letter-spacing:.4px;white-space:nowrap}
.dex-chip.on{color:var(--dex);border-color:rgba(255,123,213,.45)}

.dex-insight-body{max-width:70ch}
.dex-insight-body h3{font-family:var(--px);font-size:10.5px;letter-spacing:.5px;color:var(--accent2);
  text-transform:uppercase;margin:26px 0 12px;padding-top:19px;border-top:2px dashed var(--line);
  display:flex;align-items:center;gap:9px}
.dex-insight-body h3::before{content:"\2726";color:var(--dex)}
.dex-insight-body h3:first-child{margin-top:0;padding-top:0;border-top:0}
.dex-insight-body p{margin:0 0 11px;font-size:14.5px;line-height:1.7;color:var(--text)}
.dex-insight-body p:last-child{margin-bottom:0}
.dex-insight-body h3:first-child + p{font-size:16.5px;line-height:1.55;color:#fff}
.dex-insight-body strong{font-weight:600;color:#fff}
.dex-insight-body ul{list-style:none;padding:0;margin:4px 0 0;display:flex;flex-direction:column;gap:10px}
.dex-insight-body li{position:relative;padding-left:22px;font-size:14.5px;line-height:1.55}
.dex-insight-body li::before{content:"\25B8";color:var(--dex);font-family:var(--px);font-size:10px;position:absolute;left:0;top:2px}

.dex-ifoot{margin-top:22px;padding-top:14px;border-top:2px dashed var(--line);
  color:var(--dim);font-size:12.5px;display:flex;gap:9px;flex-wrap:wrap;align-items:center}
.dex-ifoot .fdex{color:var(--dex)}
@media (max-width:840px){ .dex-insight-card{padding:18px 15px} }
