
  /* OBSIDIAN v5 tokens. --acc* slots are planet-owned (set inline on <html> by the
     v8: planet picker retired; --acc* slots remain as reference-only fallbacks. */
  :root{
    /* Content tones. The former comment incorrectly called FBFBFB the reference
       rail and F4F5F6 its active row. The rail has its own measured roles below. */
    --ink-0:#FFFFFF;--ink-05:#FBFBFB;--ink-08:#F4F5F6;--ink-20:#EEEFF1;--ink-45:#737373;--ink-70:#404040;--ink-100:#232529;
    /* attio-ref.png: ground (400,1700), active fill (300,943), identical label
       cores (306,462)/(433,929). Secondary chevron (649,2714), outline (400,2679).
       Boundary at y1700: x728=080808, x729=777777, x730=E6E6E6, x731=FAFAFA;
       this is an antialiased step, not a divider. Hover reuses the measured fill. */
    --rail-bg:#080808;--rail-active:#2B2B2B;--rail-hover:var(--rail-active);--rail-ink:#D9D9D9;--rail-muted:#999999;--rail-line:#262626;--rail-edge:0px;
    /* Oscar's sanctioned accessibility accommodation: active ink is white,
       rather than the reference's unchanged D9D9D9. The fill stays exact. */
    --rail-selected-ink:#FFFFFF;
    --bg:var(--ink-05);--fg:var(--ink-100);--muted:var(--ink-45);--line:var(--ink-20);--band:var(--ink-08);--card:var(--ink-0);--card-line:var(--ink-20);
    --hbg:var(--ink-08);--hfg:var(--ink-45);--hline:var(--ink-20);--sbg:var(--ink-100);--sfg:var(--ink-0);
    --pin-fg:var(--ink-100);--pord-fg:var(--ink-70);
    --btn-bg:var(--ink-0);--btn-fg:var(--ink-100);--btn-line:var(--ink-20);--input-bg:var(--ink-0);
    /* Light controls retain the Reports blue. The dark Hyperline reference below
       uses neutral controls so chart colour carries the visual emphasis. */
    --accent:#266DF0;--accent-2:#266DF0;--accent-h:#1D5AD0;--accent-glow:rgba(38,109,240,.25);--accent-emph:#266DF0;--accent-fg:#FFFFFF;
    --sel:rgba(38,109,240,.08);--sel:color-mix(in srgb,var(--accent) 9%,transparent);--pop:#FFFFFF;
  }
  body.dark{
    /* hyperline-dark.jpg, colour only: 9×9 patch medians give page 141414
       (100,100), rail 0D0D0D (280,625), panels 191919 (375,404)/(700,550).
       No geometry is taken from this skewed render. One lifted-surface token
       owns both panels and rail hover, as Oscar requested. Text and internal
       hairlines reuse the measured Hyperline inks; selection stays 2B/white. */
    --surface-raised:#191919;
    --ink-0:var(--surface-raised);--ink-05:#141414;--ink-08:var(--surface-raised);--ink-20:#2B2B2B;--ink-45:#999999;--ink-70:#D9D9D9;--ink-100:#D9D9D9;
    --rail-bg:#0D0D0D;--rail-active:#2B2B2B;--rail-hover:var(--surface-raised);--rail-ink:#D9D9D9;--rail-muted:#999999;--rail-line:#262626;--rail-edge:0px;
    --bg:var(--ink-05);--fg:var(--ink-100);--muted:var(--ink-45);--line:var(--ink-20);--band:var(--ink-08);--card:var(--surface-raised);--card-line:var(--ink-20);
    --hbg:var(--ink-08);--hfg:var(--ink-45);--hline:var(--ink-20);--sbg:var(--ink-100);--sfg:var(--ink-05);
    --pin-fg:var(--ink-100);--pord-fg:var(--ink-70);
    --btn-bg:var(--ink-0);--btn-fg:var(--ink-100);--btn-line:var(--ink-20);--input-bg:var(--ink-05);
    --accent:#D9D9D9;--accent-2:#D9D9D9;--accent-h:#FFFFFF;--accent-glow:transparent;--accent-emph:#D9D9D9;--accent-fg:#141414;
    --sel:rgba(217,217,217,.14);--sel:color-mix(in srgb,var(--accent) 14%,transparent);--pop:var(--surface-raised);
  }
  *{box-sizing:border-box}
  body{color-scheme:light}
  body.dark{color-scheme:dark}
  /* v11: no drafting-dot tile on the ground. */
  /* no wrong-chrome flash while auth/config resolves: chrome hidden until the first view lands */
  body.booting .topbar{visibility:hidden}
  /* boot loader: the PQB box mark masks the whole page until the first real view is painted,
     so the app shell (bottom bar / "Exit · change code") never flashes on refresh */
  #bootmark{position:fixed;inset:0;z-index:450;display:flex;align-items:center;justify-content:center;background:var(--bg);opacity:1;transition:opacity var(--t-med,.28s) var(--e-out,ease)}
  #bootmark.done{opacity:0;pointer-events:none}
  /* v11 (Oscar): the three-tread P·Q·B logo, same geometry as the login and the favicon.
     The glow is gone with the rest of the softening -- hard edges, one flat colour. */
  .mk{display:block;fill:currentColor;shape-rendering:crispEdges}
  /* The staircase, built in place: one tread, then two, then three, each rising off the floor. */
  #bootmark .bm-box{position:relative;width:36px;height:36px;display:flex;align-items:flex-end;color:var(--fg)}
  #bootmark .bm-step{display:block;width:calc(100% / 3);background:currentColor;transform-origin:bottom center;transform:scaleY(0);animation-duration:1.8s;animation-timing-function:linear;animation-iteration-count:infinite}
  #bootmark .bm-step:nth-child(1){height:calc(100% / 3);animation-name:bm1}
  #bootmark .bm-step:nth-child(2){height:calc(200% / 3);animation-name:bm2}
  #bootmark .bm-step:nth-child(3){height:100%;animation-name:bm3}
  @keyframes bm1{0%{transform:scaleY(0)}12%{transform:scaleY(1)}88%{transform:scaleY(1)}100%{transform:scaleY(0)}}
  @keyframes bm2{0%,12%{transform:scaleY(0)}35%{transform:scaleY(1)}88%{transform:scaleY(1)}100%{transform:scaleY(0)}}
  @keyframes bm3{0%,35%{transform:scaleY(0)}70%{transform:scaleY(1)}88%{transform:scaleY(1)}100%{transform:scaleY(0)}}
  @media (prefers-reduced-motion:reduce){#bootmark .bm-step{animation:none;transform:none}}
  body{color:var(--fg);background:var(--bg)}
  .topbar,.controls,.markupbar,.gate,.rev-table{transition:background-color var(--t-med) ease,color var(--t-med) ease,border-color var(--t-med) ease}
  @media (prefers-reduced-motion:reduce){body,.topbar,.controls,.markupbar,.gate,.wizardnav,.rev-table{transition:none}}
  :root{--topbar-h:0px;--controls-h:0px}
  .topbar{justify-content:space-between;position:-webkit-sticky;position:sticky;top:0;z-index:50;background:var(--bg)}
  .topactions{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;justify-content:flex-end;min-width:0}
  .topactions .primary{background:var(--accent);color:var(--accent-fg);border:1px solid var(--accent);border-radius:var(--radius-sm);padding:0 var(--s4);font:inherit;font-weight:var(--fw-med);cursor:pointer;white-space:nowrap}
  .topactions .primary:hover{filter:brightness(1.06)}
  /* ---- four-region top bar (SPEC-NAV-CHARTS §1–2; same DOM order + class names as the staff shell; tokens only) ---- */
  :root{--top-h:52px}
  .topbar{display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,420px) auto;align-items:center;gap:12px;min-height:var(--top-h)}
  .tb-switch,.tb-left{display:flex;align-items:center;gap:12px;min-width:0}
  .tb-title{min-width:0}
  .tb-mid{display:flex;justify-content:center;min-width:0}
  .topactions .tt,.topactions .primary,.siteswitch,.finder{min-height:40px}
  .tt.icon{width:40px;padding:0;display:inline-grid;place-items:center}
  body.dark #theme .ic-moon,body:not(.dark) #theme .ic-sun{display:none}
  .siteswitch{display:inline-flex;align-items:center;gap:12px;padding:0 12px;border:1px solid var(--btn-line);background:var(--btn-bg);color:var(--fg);border-radius:var(--radius-sm);font:inherit;cursor:pointer}
  .siteswitch:hover{filter:brightness(.97)}
  .ss-tile{width:16px;height:16px;background:var(--fg);display:inline-block;flex:none}
  .ss-text{display:flex;flex-direction:column;align-items:flex-start;line-height:var(--lh-tight);white-space:nowrap}
  .ss-text b{font-size:var(--fs-base);font-weight:var(--fw-semi);letter-spacing:var(--tr-snug)}
  .ss-text small{color:var(--muted)}
  .ss-chev{color:var(--muted);flex:none}
  .sitemenu{position:fixed;inset:auto;margin:0;top:calc(var(--top-h) + 8px);left:16px;min-width:280px;max-width:min(92vw,360px);background:var(--card);color:var(--fg);border:1px solid var(--card-line,var(--line));border-radius:var(--radius-sm);padding:8px;box-shadow:0 12px 32px rgba(0,0,0,.16)}
  .sitemenu::backdrop{background:transparent}
  .sm-eb{color:var(--muted);padding:6px 8px}
  .acctmenu{left:auto;right:16px}
  .sm-act{display:block;width:100%;text-align:left;font:inherit;font-size:var(--fs-base);color:var(--fg);background:none;border:0;border-top:1px solid var(--line);margin-top:6px;padding:12px 8px;min-height:40px;cursor:pointer}
  .sm-act:hover{background:var(--btn-bg)}
  #sitelist{list-style:none;margin:0;padding:0}
  .sm-row{display:flex;align-items:center;gap:12px;padding:8px;border-radius:var(--radius-sm);color:inherit;text-decoration:none}
  a.sm-row:hover{background:var(--btn-bg)}
  .sm-row.cur{opacity:.72}
  .sm-mark{width:26px;height:26px;flex:none;display:grid;place-items:center;background:var(--fg);color:var(--bg);font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat)}
  .sm-row b{display:block;font-size:var(--fs-base);font-weight:var(--fw-semi)}
  .sm-row small{display:block;font-size:var(--fs-fine);color:var(--muted)}
  .sm-foot{color:var(--muted2,var(--muted));padding:8px 8px 2px;border-top:1px solid var(--line);margin-top:6px}
  .finder{display:inline-flex;align-items:center;gap:8px;width:100%;max-width:420px;padding:0 12px;border:1px solid var(--btn-line);background:var(--btn-bg);color:var(--muted);border-radius:var(--radius-sm);font:inherit;font-size:var(--fs-base);cursor:pointer;text-align:left}
  .finder:hover{color:var(--fg)}
  .finder svg{flex:none}
  .finder kbd{margin-left:auto;font-family:var(--font-mono);font-size:var(--fs-micro);border:1px solid var(--line);padding:1px 5px;border-radius:0;color:var(--muted)}
  .tb-ini{width:34px;height:34px;display:none;place-items:center;border:1px solid var(--btn-line);border-radius:0;font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-flat);color:var(--fg);background:var(--btn-bg)}
  body.repshell .tb-ini:not(:empty){display:grid}
  body:not(.repshell) .tb-mid,body:not(.repshell) .tb-switch{display:none}
  /* WS15-C C3: with the switcher and finder gone, the title and actions are the only two cells — without this the actions fell
     into the 1fr cell and the empty 420px finder column held them ~440px short of the content's right edge */
  body:not(.repshell) .topbar{grid-template-columns:minmax(0,1fr) auto}
  #savebtn{background:var(--accent);border-color:var(--accent);color:var(--accent-fg);transition:filter var(--t-fast) ease}
  #savebtn:hover{filter:brightness(1.08);animation:none}

  /* z-order: document overlay 600 < dialogs 700 < toasts 760.
     Dialogs must outrank #docview — "Email invoice" opens a prompt from inside it. */
  /* ── THE SHEET — a right-anchored panel ───────────────────────────────────────────────
     Oscar: "Use a sidebar on the right when needed (maybe for creating a quote) lightboxes
     too if needed." Named .sheet, not .drawer: body.drawer is already the MOBILE RAIL and two
     things called drawer is how one of them breaks. It is also the word his distributor portal
     uses for exactly this component (PayeeSheet), so the vocabulary is already his.
     Use a SHEET when the work is secondary to the page behind it and the page is worth keeping
     in view — starting a quote from the dashboard, an order's detail, a customer's book.
     Use a MODAL when the page behind must not be acted on until this is answered. */
  .sheet-scrim{position:fixed;inset:0;z-index:690;background:rgba(15,17,21,.44);opacity:0;pointer-events:none;transition:opacity var(--t-med) var(--e-out)}
  .sheet-scrim.on{opacity:1;pointer-events:auto}
  .sheet{position:fixed;top:0;right:0;bottom:0;z-index:700;width:min(480px,100vw);display:flex;flex-direction:column;
    background:var(--card);border-left:1px solid var(--line);box-shadow:var(--shadow-lg);
    transform:translateX(100%);transition:transform var(--t-med) var(--e-out);will-change:transform}
  .sheet.on{transform:none}
  /* The closed sheet's author-level flex display otherwise overrides hidden,
     leaving its off-screen shadow painted over the dashboard's right edge. */
  .sheet[hidden]{display:none}
  .sheet-h{display:flex;align-items:flex-start;gap:12px;padding:16px 16px 12px;border-bottom:1px solid var(--line);flex:none}
  .sheet-h .t{font-size:var(--fs-title);font-weight:var(--fw-med);letter-spacing:var(--tr-snug);line-height:var(--lh-tight)}
  .sheet-h .s{display:block;margin-top:3px;font-size:var(--fs-base);color:var(--muted)}
  .sheet-x{margin-left:auto;width:32px;height:32px;min-height:32px;display:grid;place-items:center;flex:none;
    border:1px solid transparent;border-radius:var(--radius-btn);background:none;color:var(--muted);cursor:pointer}
  .sheet-x:hover{background:var(--band);color:var(--fg)}
  .sheet-b{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:var(--sec-gap)}
  .sheet-f{flex:none;display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--line);background:var(--card)}
  @media (max-width:560px){ .sheet{width:100vw;border-left:0} }
  @media (prefers-reduced-motion:reduce){ .sheet,.sheet-scrim{transition:none} }
  .modal{position:fixed;inset:0;z-index:700;display:none;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,.55);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
  .modal.open{display:flex;animation:modalFade .2s ease both}
  .modal-card{background:var(--card);color:var(--fg);border:1px solid var(--card-line);max-width:430px;width:100%;padding:32px 32px;text-align:center;animation:modalPop .3s var(--e-pop) both}
  .modal-title{font-size:var(--fs-title);font-weight:var(--fw-reg);margin-bottom:8px}
  /* pre-line so dialog copy can use blank lines for paragraphs — the message is
     escaped (it renders rep-supplied names), so markup is not an option */
  .modal-sub{font-size:var(--fs-base);color:var(--muted);margin:0 0 20px;line-height:var(--lh-ui);white-space:pre-line}
  .modal-code{font-size:var(--fs-kpi);font-weight:var(--fw-med);padding:16px 12px;border:2px dashed var(--btn-line);margin-bottom:20px;color:var(--fg)}
  .modal-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
  .modal-copy{font:inherit;font-weight:var(--fw-med);font-size:var(--fs-body);color:var(--accent-fg);background:var(--accent);border:1px solid var(--accent);border-radius:var(--radius-sm);padding:12px 20px;cursor:pointer;transition:transform var(--t-fast) ease,filter var(--t-fast) ease}
  .modal-copy:hover{filter:brightness(1.08)}
  .modal-close{font:inherit;font-weight:var(--fw-med);font-size:var(--fs-body);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:12px 20px;cursor:pointer}
  .modal-note{font-size:var(--fs-fine);color:var(--muted);margin-top:16px;min-height:14px}
  /* ---- in-design dialogs (toast + confirm + prompt; replace native alert/confirm/prompt) ---- */
  /* WS16-D: toasts live at the BOTTOM right, newest nearest the edge — never over a header action (the topbar's and the page
     head's actions are top right, where the stack used to sit for up to 6 s). In the builder they clear the fixed review bar,
     and with the cart open they sit beside it (desktop) or under its head (phone), never over its actions. */
  #pqb-toasts{position:fixed;top:auto;right:16px;bottom:calc(16px + env(safe-area-inset-bottom,0px));z-index:760;display:flex;flex-direction:column-reverse;gap:8px;max-width:min(92vw,380px);pointer-events:none}
  body.builder-active:not(.builder-cart-open) #pqb-toasts{bottom:calc(var(--builder-bar-h,88px) + env(safe-area-inset-bottom,0px))}
  @media(min-width:768px){body.builder-active.builder-cart-open #pqb-toasts{right:calc(min(100%,440px) + 16px)}}
  /* v7 (Codex #44 R1 / R2): on a phone the open cart fills the screen, so a toast there takes its own place IN the cart — at the top of
     its sticky footer, right above Save (#builder-cart-toasts, app-main v11): visible at any scroll, over no field. The fixed stack is
     hidden meanwhile (a live toast moves into the cart and back out on close) */
  @media(max-width:767px){body.builder-active.builder-cart-open #pqb-toasts{display:none}}
  #builder-cart-toasts{display:flex;flex-direction:column;gap:8px;margin:0 0 var(--s3,12px)}
  #builder-cart-toasts:empty{display:none}
  #builder-cart-toasts .pqb-toast{max-width:none}
  .pqb-toast{pointer-events:auto;cursor:pointer;font-family:var(--font-mono);font-size:var(--fs-base);line-height:var(--lh-ui);color:var(--fg);background:var(--card);border:1px solid var(--line);border-left:3px solid var(--muted);border-radius:var(--radius-sm);padding:12px 16px;box-shadow:0 10px 30px -12px rgba(0,0,0,.4);opacity:0;transform:translateY(-6px);transition:opacity var(--t-med) var(--e-out),transform var(--t-med) var(--e-out)}
  .pqb-toast.in{opacity:1;transform:none}
  .pqb-toast.ok{border-left-color:var(--pin-fg,#111114)}
  .pqb-toast.err{border-left-color:var(--pord-fg)}
  .pqb-toast.info{border-left-color:var(--accent)}
  .pqb-dialog .modal-card{max-width:440px;text-align:left}
  .pqb-dialog .modal-sub{margin-bottom:16px}
  .pqb-dialog .modal-actions{justify-content:flex-end}
  .modal-copy.danger{background:var(--pord-fg);border-color:var(--pord-fg);color:var(--bg)}
  .pqb-prompt-label{display:block;color:var(--muted);margin:2px 0 6px}
  .pqb-prompt-field input,.pqb-prompt-field textarea{display:block;width:100%;font:inherit;font-size:var(--fs-body);padding:12px 12px;border:1px solid var(--btn-line);border-radius:var(--radius-sm);background:var(--input-bg,var(--card));color:var(--fg);resize:vertical}
  .pqb-prompt-field input:focus,.pqb-prompt-field textarea:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  @media print{#pqb-toasts,.pqb-dialog{display:none !important}}
  @keyframes modalFade{from{opacity:0}to{opacity:1}}
  @keyframes modalPop{from{opacity:0;transform:translateY(14px) scale(.96)}to{opacity:1;transform:none}}
  .brandlogo{max-height:44px;max-width:220px;display:none;margin-bottom:8px}
  .title{color:var(--fg)}
  .subtitle{margin:3px 0 16px}
  .tt{font:inherit;font-weight:var(--fw-med);font-size:var(--fs-fine);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:6px 12px;cursor:pointer}
  .gate{max-width:430px;margin:52px auto;padding:32px 24px;border:1px solid var(--card-line);background:var(--card);text-align:center}
  .gate h2{margin:0 0 6px;color:var(--fg)}
  .gate p{font-size:var(--fs-base);color:var(--muted);margin:0 0 20px}
  .gate input{font:inherit;text-align:center;color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);width:100%;margin-bottom:12px}
  .gate button{font:inherit;font-weight:var(--fw-med);color:var(--accent-fg);background:var(--accent);border:none;cursor:pointer}
  .gate .err{font-size:var(--fs-base);font-weight:var(--fw-med);margin-top:12px;min-height:15px;color:var(--fg)}   /* WS15-C C3: no underline — a message, not a link (no text in the app is underlined) */
  .qa{display:flex;flex-wrap:wrap;margin:0 0 12px}
  .qa div{flex:1;min-width:180px}
  .qa b{display:block;color:var(--fg)}.qa span{font-size:var(--fs-fine);color:var(--muted)}.qa .ck{color:var(--fg);margin-right:5px}
  /* quiet & precise: one calm easing everywhere — no bounce, scale, rotate, or glow */
  .qa div{transition:padding var(--t-med) var(--e-out)}
  .qa div>span{display:block;max-height:18px;opacity:1;transition:max-height var(--t-med) var(--e-out),opacity var(--t-med) var(--e-out);overflow:hidden}
  .qa.dockable{cursor:pointer;position:relative;padding-right:24px}
  .qa.dockable::after{content:'▸';position:absolute;right:8px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:var(--fs-fine);transition:transform var(--t-med) var(--e-out);pointer-events:none}
  .qa.dockable:not(.min)::after{transform:translateY(-50%) rotate(90deg)}
  .qa.min div{padding:6px 12px;min-width:0}
  .qa.min b{font-size:var(--fs-micro);letter-spacing:var(--tr-flat);transition:font-size var(--t-med) var(--e-out)}
  .qa.min div>span{max-height:0;opacity:0}
  @keyframes qaRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  .qa.animate div{animation:qaRise .28s var(--e-out) both}
  .qa.animate div:nth-child(1){animation-delay:0s}
  .qa.animate div:nth-child(2){animation-delay:.04s}
  .qa.animate div:nth-child(3){animation-delay:.08s}
  @media (prefers-reduced-motion:reduce){.qa.animate div{animation:none}.qa.dockable::after,.qa div,.qa div>span,.qa.min b{transition:none}}
  .notes{display:flex;gap:12px;flex-wrap:wrap;margin:0 0 16px}
  .notes span{color:var(--fg);background:var(--band);border:1px solid var(--card-line);border-radius:var(--radius-sm);padding:6px 12px}
  .saved{display:none;margin:0 0 16px;padding:16px 16px;border:2px solid var(--accent);border-radius:var(--radius-sm);background:var(--card);font-size:var(--fs-base);color:var(--fg)}
  .saved b{font-size:var(--fs-title);letter-spacing:var(--tr-caps)}
  .saved button{font:inherit;font-weight:var(--fw-med);font-size:var(--fs-fine);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:5px 12px;cursor:pointer;margin-left:12px}
  .chdr{display:none;gap:16px;flex-wrap:wrap;margin:0 0 16px;padding:12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
  .chdr label{font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--fg);display:flex;flex-direction:column;gap:4px}
  .chdr input{font:inherit;font-size:var(--fs-body);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:7px 12px;min-width:240px}
  .chdr input:read-only{background:transparent;border-color:transparent;padding-left:0}
  .controls{display:flex;flex-wrap:wrap;align-items:center;margin:0 0 12px;padding:12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
  .controls input[type=text],.controls select{font:inherit;font-size:var(--fs-base);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:8px 12px}
  .controls input[type=text]{min-width:220px;flex:1}.controls select{cursor:pointer}
  .controls button{font:inherit;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:8px 12px;cursor:pointer}
  .controls button:hover{filter:brightness(.94)}.controls button.primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
  .controls label.chk,.markupbar label.chk{display:inline-flex;align-items:center;gap:6px;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--fg)}
  .controls .count{font-size:var(--fs-fine);color:var(--muted);margin-left:auto}
  /* builder: pin the search/filter bar under the top bar so you can always filter the long list */
  body.buildmode #controls{position:-webkit-sticky;position:sticky;top:var(--topbar-h);z-index:20;box-shadow:0 1px 0 var(--line)}
  .bar{display:flex;align-items:center;gap:12px;margin:0 0 12px;font-size:var(--fs-fine);color:var(--muted)}
  .bar button{font:inherit;font-weight:var(--fw-med);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:6px 12px;cursor:pointer}
  table{border-collapse:collapse;width:100%}
  th{background:var(--hbg);color:var(--hfg);text-align:center}
  th.l{text-align:left}
  td{padding:7px 8px;border:1px solid var(--line);color:var(--fg)}
  td.c{text-align:center}td.num{color:var(--muted);width:30px;font-size:var(--fs-fine)}
  td.prod{text-align:left}td.price{font-weight:var(--fw-med)}
  tr.b td{background:var(--band)}
  /* the measured reference: the substrate is five greys and ink is for TEXT. This separator used to be a
     full-width black band — the heaviest thing on the page. It recedes now: ink-05 ground, a mono
     micro label in ink-45, one hairline above. Attio separates a group; it does not shout one. */
  tr.sec td{background:var(--ink-05);color:var(--ink-45);padding:7px 12px;border-top:1px solid var(--ink-20)}
  /* collapsible product groups (builder/wizard): one header per multi-strength product — cells line up with data rows */
  tr.grp{cursor:pointer}
  tr.grp>td{border-top:1px solid var(--line)}
  td.grphead{text-align:left;padding:12px 8px;font-size:var(--fs-base);white-space:nowrap}
  .gchev{display:inline-block;color:var(--muted);font-size:var(--fs-micro);margin-right:7px;transition:transform var(--t-fast) var(--e-out)}
  tr.grp.open .gchev{transform:rotate(90deg)}
  .gname{font-weight:var(--fw-med);color:var(--fg)}
  .gcount{color:var(--muted);font-size:var(--fs-fine);margin-left:6px}
  td.gstr{color:var(--muted);font-size:var(--fs-fine)}
  td.gstr>span{display:inline-block;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
  td.gav .st{font-size:var(--fs-micro);padding:2px 7px}
  td.grptail{text-align:right}
  .gactive{color:var(--fg);font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:var(--radius-sm);padding:2px 7px}
  tr.grp-child.collapsed{display:none}
  .rowdot{color:var(--muted)}
  .qadd{font:inherit;font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--muted);background:transparent;border:1px dashed var(--btn-line);border-radius:var(--radius-sm);padding:4px 12px;cursor:pointer;white-space:nowrap;transition:color var(--t-fast) ease,border-color var(--t-fast) ease,background-color var(--t-fast) ease}
  .qadd:hover{color:var(--accent);border-color:var(--accent);border-style:solid}
  .qna{display:inline-block;font-size:var(--fs-fine);font-style:italic;color:var(--danger);white-space:nowrap}
  /* ===== paper documents (client-facing quote PDF + invoice) =====
     Two hosts share one stylesheet via .prdoc: #proposal is the print target
     (screen-hidden, revealed only by @media print) and #dv-doc is the on-screen
     preview inside the document overlay. Both are ALWAYS the light paper palette —
     a printed or previewed document never inherits the app's dark theme. */
  #proposal{display:none}
  .prdoc{--fw-reg:400;--fw-med:500;--fw-semi:500;--fw-bold:500;font-family:var(--font-sans);color:#111114;background:#fff;max-width:720px;margin:0 auto;padding:4px 2px}
  .prdoc .pr-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;padding-bottom:16px;border-bottom:2px solid #111114;margin-bottom:20px}
  .prdoc .pr-logo{max-height:52px;max-width:240px;object-fit:contain;display:block}
  .prdoc .pr-brand{font-size:var(--fs-title);font-weight:var(--fw-semi);letter-spacing:var(--tr-snug)}
  .prdoc .pr-doc{font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-code);color:#666;padding-top:6px;white-space:nowrap;text-align:right}
  .prdoc .pr-meta{display:flex;flex-wrap:wrap;gap:12px 32px;margin-bottom:20px}
  .prdoc .pr-meta div{display:flex;flex-direction:column;gap:3px}
  .prdoc .pr-meta span{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:#777}
  .prdoc .pr-meta b{font-size:var(--fs-base);font-weight:var(--fw-semi)}
  .prdoc .pr-tbl th{font-family:var(--font-sans);text-transform:none}
  .prdoc .pr-chip{display:block;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:#6E6E76;margin-top:2px}
  .prdoc .pr-valid{margin-top:20px;font-size:var(--fs-fine);color:#555}
  .prdoc .pr-legal{margin-top:16px;font-size:var(--fs-micro);color:#555}
  .prdoc .pr-ruo{margin-top:12px;font-size:var(--fs-micro);color:#777;border-top:1px solid #ededed;padding-top:12px}
  .prdoc .pr-empty{padding:24px;color:#777;font-size:var(--fs-base)}
  /* ===== invoice anatomy =====
     An invoice is a financial instrument, so it gets the conventions people expect:
     a document type + number masthead, FROM / BILL TO parties, a mono meta grid, a
     right-aligned totals stack ending in an inverted balance-due bar, and terms in a
     callout. The quote proposal keeps its lighter layout — these are invoice-only. */
  .prdoc .pr-paid{display:inline-block;border:1px solid #1B7A54;color:#1B7A54;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-code);padding:7px 12px;margin-bottom:16px}
  .prdoc .pr-doctype{font-size:var(--fs-title);font-weight:var(--fw-semi);letter-spacing:var(--tr-snug);line-height:var(--lh-tight);text-align:right}
  .prdoc .pr-docno{display:block;font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-caps-wide);color:#111114;margin-top:6px}
  /* hairline under the parties so they read as a distinct block from the meta grid */
  .prdoc .pr-parties{display:flex;gap:40px;margin:0 0 20px;padding-bottom:16px;border-bottom:1px solid #ededed}
  .prdoc .pr-parties>div{flex:1 1 0;min-width:0}
  .prdoc .pr-plabel{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:#777;margin-bottom:4px}
  .prdoc .pr-pname{font-size:var(--fs-base);font-weight:var(--fw-semi);line-height:var(--lh-ui)}
  .prdoc .pr-pline{font-size:var(--fs-fine);color:#555;line-height:var(--lh-ui)}
  .prdoc .pr-totals{width:300px;max-width:100%;margin:16px 0 0 auto}
  .prdoc .pr-trow{display:flex;justify-content:space-between;gap:16px;font-size:var(--fs-base);padding:8px 12px;border-bottom:1px solid #ededed}
  .prdoc .pr-trow span{color:#555}
  .prdoc .pr-trow b{font-weight:var(--fw-semi)}
  .prdoc .pr-tfinal{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
    background:#111114;color:#fff;padding:12px 12px;margin-top:3px;
    -webkit-print-color-adjust:exact;print-color-adjust:exact}
  .prdoc .pr-tfinal span{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:#fff}
  .prdoc .pr-tfinal b{font-size:var(--fs-title);font-weight:var(--fw-semi)}
  .prdoc .pr-terms{margin-top:20px;background:#F4F4F2;border-left:2px solid #111114;padding:12px 16px;
    font-size:var(--fs-fine);line-height:var(--lh-text);color:#444;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .prdoc .pr-terms b{color:#111114}
  .prdoc .pr-attest{margin-top:12px;font-size:var(--fs-fine);color:#777;line-height:var(--lh-ui)}
  /* how to pay — the block that makes an invoice actionable */
  .prdoc .pr-pay{margin-top:20px;background:#F4F4F2;border-left:2px solid #111114;padding:12px 16px;
    -webkit-print-color-adjust:exact;print-color-adjust:exact}
  .prdoc .pr-pay .pl{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:var(--tr-caps-wide);
    text-transform:none;color:#777;margin-bottom:4px}
  .prdoc .pr-pay .pm{font-size:var(--fs-base);font-weight:var(--fw-semi);margin-top:7px}
  .prdoc .pr-pay .pd{font-size:var(--fs-base);line-height:var(--lh-text);color:#555;white-space:pre-line}
  .prdoc .pr-pay .pn{font-size:var(--fs-fine);line-height:var(--lh-ui);color:#777;margin-top:8px;white-space:pre-line}
  @media print{
    
    body *{visibility:hidden !important}
    #proposal,#proposal *{visibility:visible !important}
    #proposal{display:block !important;position:absolute;left:0;top:0;width:100%}
  }
  /* ===== document overlay (on-screen invoice / quote preview) ===== */
  /* backdrop is deliberately heavy: at lower opacity the app's own topbar buttons
     stayed legible behind the sheet and read as a second set of controls */
  #docview{position:fixed;inset:0;z-index:600;display:none;background:rgba(10,10,12,.88);padding:24px 16px;overflow:auto;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
  #docview.on{display:block}
  .dv-shell{max-width:788px;margin:0 auto}
  .dv-bar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end;margin-bottom:12px}
  .dv-title{flex:1;font-family:var(--font-sans);font-size:var(--fs-fine);letter-spacing:0;text-transform:none;color:#fff}
  .dv-bar button{font-family:var(--font-sans);font-size:var(--fs-fine);letter-spacing:0;text-transform:none;padding:12px 16px;border-radius:var(--radius-sm);cursor:pointer;border:1px solid rgba(255,255,255,.34);background:transparent;color:#fff}
  .dv-bar button:hover{background:rgba(255,255,255,.13)}
  .dv-bar button.primary{background:#fff;color:#111114;border-color:#fff}
  #dv-doc{background:#fff;padding:32px 32px 32px;box-shadow:0 24px 64px rgba(0,0,0,.4);max-width:none}
  /* on narrow screens the actions matter more than the label, which otherwise
     wraps onto two lines and crowds the buttons */
  @media (max-width:600px){#dv-doc{padding:20px 16px}#docview{padding:16px 12px}.dv-title{display:none}.dv-bar{justify-content:space-between}}
  @media print{#docview{display:none !important}}
  @media (prefers-reduced-motion:reduce){.gchev,.qadd{transition:none}}
  .controls.addonly .chk,.controls.addonly #grpall,.controls.addonly #selvis,.controls.addonly #clearsel,.controls.addonly #clearall,.controls.addonly #brandtoggle,.controls.addonly .count{display:none}
  .wadd{display:flex;flex-direction:column;gap:20px;margin-top:4px}
  .wadd-h{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted);margin:0 0 8px;display:flex;align-items:center;gap:8px}
  .wadd-n{display:inline-flex;min-width:18px;height:18px;padding:0 5px;align-items:center;justify-content:center;border-radius:9px;background:var(--accent);color:var(--accent-fg);font-size:var(--fs-micro);font-weight:var(--fw-med)}
  .wadd-empty{font-size:var(--fs-base);color:var(--muted);padding:16px 12px;border:1px dashed var(--card-line);border-radius:var(--radius-sm);background:var(--card)}
  .wadd-list{border:1px solid var(--card-line);border-radius:var(--radius-sm);background:var(--card);overflow:hidden}
  .wadd-row{display:flex;align-items:center;gap:12px;padding:12px 12px;border-top:1px solid var(--line)}
  .wadd-row:first-child{border-top:0}
  .wadd-row:hover{background:var(--band)}
  .wadd-nm{flex:1;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--fg);min-width:0}
  .wadd-nm em{font-style:normal;color:var(--muted);font-weight:var(--fw-reg);margin-left:5px}
  .wadd-row .st{flex:none}
  /* THE QUOTE — four progressively revealed sections. House values: 24px section gap, 32px card
     padding, a mono drafting eyebrow per head, no box-shadow anywhere (tone carries elevation). */
  .qs{padding:0 0 24px;margin:0 0 24px;border-bottom:1px solid var(--line)}
  .qs:last-of-type{border-bottom:0}
  .qs[hidden]{display:none}
  /* The 01/02/03/04 sections are the BUILDER's progressive disclosure. Nothing hid them on the
     client surfaces, so a saved quote — the document a reseller sends their own customer —
     rendered an eyebrow reading "01 CUSTOMER" above an empty band, then "02 PRODUCTS". The
     customer's details are already in the masthead; the section chrome is scaffolding and must
     not ship with the building. buildmode is set only for MODE=='custom' (render(), :5751). */
  body:not(.buildmode) .qs-h{display:none}
  body:not(.buildmode) #qs1{display:none}
  body:not(.buildmode) .qs{padding:0;margin:0;border-bottom:0}
  .qs-h{display:flex;align-items:baseline;gap:12px;margin:0 0 16px;font-family:var(--font-sans);
    font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:0;text-transform:none;color:var(--muted)}
  .qs-h>span{color:var(--fg)}
  /* the terminal panel: the form is replaced by what happened, then the two things to do next */
  #qdone{border:1px solid var(--fg);padding:32px}
  #qdone .qd-t{font-size:var(--fs-title);font-weight:var(--fw-reg);color:var(--fg);margin:0 0 8px}
  #qdone .qd-s{font-size:var(--fs-base);color:var(--muted);margin:0 0 20px;line-height:var(--lh-ui)}
  #qdone .qd-code{font-family:var(--font-mono);font-size:var(--fs-display);letter-spacing:var(--tr-code);color:var(--fg);margin:0 0 20px}
  #qdone .qd-btns{display:flex;gap:12px;flex-wrap:wrap}
  #qdone button{font:inherit;font-size:var(--fs-fine);min-height:40px;padding:0 16px;border:1px solid var(--fg);background:var(--bg);color:var(--fg);cursor:pointer}
  #qdone button.pri{background:var(--fg);color:var(--bg)}
  /* THE QUOTE — the cart. Ink and paper, straight edges, 40px targets, tabular numerals. */
  #cart{margin:0 0 16px}
  .cart-empty{border:1px solid var(--line);padding:20px 16px;font-size:var(--fs-base);color:var(--muted)}
  .cart-h{display:flex;align-items:center;gap:8px 20px;flex-wrap:wrap;border:1px solid var(--fg);border-bottom:0;padding:12px 16px}
  .cart-t{font-size:var(--fs-body);font-weight:var(--fw-med);color:var(--fg)}
  .cart-n{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted)}
  .cart-sp{flex:1}
  .cart-f{display:flex;flex-direction:column;gap:2px;min-width:92px}
  .cart-f>span,.cr-f>span{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted)}
  .cart-f>b,.cr-f>b{font-size:var(--fs-body);font-weight:var(--fw-med);color:var(--fg)}
  .cart-clear{font:inherit;font-size:var(--fs-fine);min-height:40px;padding:0 16px;border:1px solid var(--line);background:var(--btn-bg);color:var(--fg);cursor:pointer}
  .cart-clear:hover{border-color:var(--fg)}
  .cart-hold{border:1px solid var(--fg);border-bottom:0;background:var(--fg);color:var(--bg);padding:8px 16px;font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none}
  .cart-row{display:flex;align-items:center;gap:8px 16px;flex-wrap:wrap;border:1px solid var(--line);border-bottom:0;padding:8px 16px}
  .cart-row:last-child{border-bottom:1px solid var(--line)}
  .cart-row.below{border-left:3px solid var(--fg)}
  .cr-nm{flex:1 1 190px;min-width:150px;font-size:var(--fs-body);color:var(--fg)}
  .cr-nm em{font-style:normal;color:var(--muted)}
  .cr-f{display:flex;flex-direction:column;gap:2px;min-width:78px}
  .cr-q,.cr-p{font:inherit;font-size:var(--fs-body);width:88px;min-height:40px;padding:0 8px;border:1px solid var(--btn-line);background:var(--input-bg);color:var(--fg)}
  .cr-q:focus,.cr-p:focus{outline:2px solid var(--fg);outline-offset:-2px}
  .cr-ovr,.cr-x{font:inherit;width:40px;height:40px;display:grid;place-items:center;border:1px solid var(--btn-line);background:var(--btn-bg);color:var(--muted);cursor:pointer}
  .cr-ovr:hover,.cr-x:hover{color:var(--fg);border-color:var(--fg)}
  .cr-ovr.on{background:var(--fg);color:var(--bg);border-color:var(--fg)}
  .cr-ovr[hidden]{display:none}   /* the ⚑ exception exists only on a line under 500 vials */
  .cr-warn{flex:1 1 100%;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-caps);color:var(--fg);padding-top:2px}
  @media(max-width:700px){.cr-nm{flex-basis:100%}.cr-q,.cr-p{width:100%}.cr-f{flex:1 1 44%}}
  .wadd-btn{font:inherit;font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--accent);background:transparent;border:1px solid var(--accent);border-radius:var(--radius-sm);padding:5px 12px;cursor:pointer;white-space:nowrap;transition:background-color var(--t-fast) ease,color var(--t-fast) ease}
  .wadd-btn:hover{background:var(--accent);color:var(--accent-fg)}
  .wdel{background:none;border:0;color:var(--muted);font-size:var(--fs-base);cursor:pointer;padding:4px 6px;line-height:var(--lh-flat)}
  .wdel:hover{color:var(--pord-fg)}
  @media (prefers-reduced-motion:reduce){.wadd-btn{transition:none}}
  .st{display:inline-block;;white-space:nowrap;border:1px solid transparent}
  /* AVAILABILITY — the one chip that gates an action, so it is FILLED (a fact about the row), not ink.
     "In Stock" is routine and wears NO hue: here colour means "you cannot add this". */
  .st-in{background:var(--band);color:var(--fg);border-color:var(--card-line)}
  .st-ord{background:var(--held-bg);color:var(--held);border-color:var(--held-bd)}
  .st-na{background:var(--danger-bg);color:var(--danger);border-color:var(--danger-bd)}
  .pick{width:32px}.pick input{cursor:pointer;width:15px;height:15px}
  tr.selrow td{background:var(--sel) !important}
  .dol{color:var(--muted);margin-right:2px}
  .foot{margin-top:16px;font-size:var(--fs-fine);color:var(--muted)}
  .msg{padding:24px;border:1px dashed var(--card-line);border-radius:var(--radius-sm);background:var(--card);color:var(--fg);font-size:var(--fs-body);line-height:var(--lh-text)}
  .msg b{color:var(--fg)}
  .bpanel{display:none;margin:20px 24px 0}
  .bpanel.grid{display:grid;grid-template-columns:minmax(320px,430px) 1fr}
  @media(max-width:900px){.bpanel.grid{grid-template-columns:1fr}}
  .bp-cell{background:var(--card);padding:20px;min-width:0}
  .bp-label{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted);margin-bottom:16px}
  .bprev-sheet{border:1px solid var(--line);border-radius:0;overflow:hidden}
  .bprev-brand{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--line)}
  .bprev-brand img{max-height:22px;max-width:110px;display:none}
  .bprev-brand b{font-size:var(--fs-body);font-weight:var(--fw-med);color:var(--fg);letter-spacing:var(--tr-snug)}
  .bprev-head{display:flex;gap:0;background:var(--hbg);border-bottom:1px solid var(--hline)}
  .bprev-head span{flex:1;padding:7px 12px;color:var(--hfg)}
  .bprev-head span:last-child{text-align:right}
  .bprev-sec{background:var(--sbg);color:var(--sfg);padding:6px 12px}
  .bprev-row{display:flex;justify-content:space-between;padding:12px 12px;border-bottom:1px solid var(--line);font-size:var(--fs-base);color:var(--fg)}
  .bprev-row .m{font-family:var(--font-mono);font-size:var(--fs-fine)}
  .bprev-row .m em{font-style:normal;color:var(--accent)}
  .bprev-foot{display:flex;justify-content:flex-end;padding:12px 12px}
  .bprev-btn{color:var(--accent-fg);background:var(--accent);border-radius:0;padding:7px 12px}
  .bprev-note{color:var(--muted2,var(--muted));margin-top:12px}
  input[type=color]::-webkit-color-swatch{border:0;border-radius:0}
  input[type=color]::-webkit-color-swatch-wrapper{padding:2px}
  #blogo{position:absolute;width:1px;height:1px;opacity:0;overflow:hidden;clip:rect(0 0 0 0)}
  .bbtn.upl{display:inline-block;cursor:pointer}
  .bpanel h2{font-size:var(--fs-body);margin:0 0 4px}.bpanel .lead{font-size:var(--fs-base);color:var(--muted);margin:0 0 20px}
  .bfield{margin-bottom:16px}
  .bfield label{display:block;font-size:var(--fs-fine);font-weight:var(--fw-med);margin-bottom:6px}
  .bfield input[type=text]{font:inherit;font-size:var(--fs-body);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:12px 12px;width:100%}
  .crow{display:flex;align-items:center;gap:12px}
  .crow input[type=color]{width:46px;height:38px;border:1px solid var(--btn-line);border-radius:var(--radius-sm);background:none;cursor:pointer;padding:2px}
  .crow input[type=text]{flex:1;max-width:140px;text-transform:uppercase}
  .logobox{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
  .logoprev{max-height:56px;max-width:200px;border:1px dashed var(--card-line);padding:6px;background:var(--bg);display:none}
  .bhint{font-size:var(--fs-fine);color:var(--muted);margin-top:6px}
  .bpanel .row{display:flex;gap:12px;align-items:center;margin-top:6px}
  .bbtn{font:inherit;font-weight:var(--fw-med);font-size:var(--fs-base);border-radius:var(--radius-sm);padding:12px 16px;cursor:pointer;border:1px solid var(--btn-line);background:var(--btn-bg);color:var(--btn-fg)}
  .bbtn.primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
  .bstatus{font-size:var(--fs-base);color:var(--muted);margin-left:4px}
  @media print{
    :root{--bg:#fff;--fg:#111114;--muted:#5C6370;--line:#CACACA;--band:#EFEFED;--card:#FFFFFF;--card-line:#CACACA;--hbg:#EFEFED;--hfg:#5C6370;--hline:#CACACA;--sbg:#111114;--sfg:#F7F7F5;--pin-fg:#111114;--pord-fg:#3A3A40;--accent:#111114;--accent-2:#111114;--accent-glow:transparent;--accent-fg:#fff}
    body.dark{--bg:#fff;--fg:#111114;--muted:#5C6370;--line:#CACACA;--band:#EFEFED;--card:#FFFFFF;--card-line:#CACACA;--hbg:#EFEFED;--hfg:#5C6370;--hline:#CACACA;--sbg:#111114;--sfg:#F7F7F5;--btn-bg:#EFEFED;--btn-fg:#111114;--btn-line:#CACACA;--input-bg:#fff;--sel:rgba(61,99,232,.08);--accent:#111114;--accent-2:#111114;--accent-glow:transparent;--accent-h:#111114;--accent-emph:#111114;--accent-fg:#fff;--pin-fg:#111114;--pord-fg:#3A3A40;--row-hover:#EFEFED;--shadow-sm:none;--shadow-md:none}
    .controls,.bar,.topbar .tt,.topactions,.saved button{display:none !important}
    tr.selrow td{background:transparent !important}.chdr{border:none;background:transparent;padding:0}
  }
  /* ---- Clerk-style microinteractions: transitions, hover, focus ---- */
  :root{--ring:rgba(127,127,134,.45);--ring:color-mix(in srgb, var(--accent) 28%, transparent);--shadow-sm:0 1px 2px rgba(17,17,20,.05),0 2px 8px rgba(17,17,20,.07);--shadow-md:0 8px 24px rgba(17,17,20,.10);--shadow-lg:0 24px 64px rgba(17,17,20,.16);--row-hover:#ECECEA;--row-hover:color-mix(in srgb,var(--accent) 7%,var(--bg));--hoverwash:rgba(17,17,20,.08);--hoverwash:color-mix(in srgb,var(--accent) 8%,transparent);--ok:#1B7A54;
    /* CHIP PALETTE v11.1 (docs/briefs/2026-09-20-CHIP-COLOUR.md) — two hues, semantic, ink register.
       HELD = a human must act · STOP = blocked or over. NO AMBER: the amber token is retired, name and hue. */
    /* ── SEMANTIC CHIP FAMILIES (law v2 §5, rewritten 2026-09-21) ──────────────────────────
       Oscar: "Chips should be multicolor and relevant to status. Chip, charts, alerts are open
       for color coding." That overturns the monochrome routine-ladder this file used to carry.
       Six families, one per meaning, each an ink + a tint. MEASURED, not chosen:
         · every ink-on-tint pair clears WCAG AA — worst is 4.83 light / 4.74 dark
         · amber is BACK. It was banned because dark amber and dark red were dE 2.4 apart under
           deuteranopia — opposite meanings, identical colour. Trading lightness inside both hue
           families (#F5C86B / #E85C68) takes that to 7.7 while both stay above AA.
       What still collapses, recorded rather than hidden: neutral/good is dE 3.3 under protanopia
       (light). "Dormant" and "won" are not opposites and both always carry their word, so it is
       an accelerator that fades, not a signal that lies. §5's rule stands and is what makes this
       safe: THE WORD IS THE SIGNAL, the tint only speeds it up. */
    --c-neutral:#55606B;--c-neutral-bg:#F1F3F5;
    --c-info:#1D5AD0;--c-info-bg:#EAF1FE;
    --c-warn:#8A5A0E;--c-warn-bg:#FEF4E3;
    --c-good:#0E7A52;--c-good-bg:#E7F7EF;
    --c-bad:#B4232F;--c-bad-bg:#FDECEE;
    --c-held:#6B3FBF;--c-held-bg:#F2ECFD;
    --held:#763EBD;--held-bg:rgba(118,62,189,.10);--held-bd:rgba(118,62,189,.38);
    --danger:#99001C;--danger-bg:rgba(153,0,28,.09);--danger-bd:rgba(153,0,28,.34);
    /* the --chip-* contract (first declared for the retired verdict chip) left open for a semantic palette:
       ok = routine (main's inverted ink chip, unchanged) · danger = STOP · unknown = HELD */
    --chip-danger-fg:var(--danger);--chip-danger-bg:var(--danger-bg);--chip-danger-bd:var(--danger-bd);
    --chip-unknown-fg:var(--held);--chip-unknown-bg:var(--held-bg);--chip-unknown-bd:var(--held-bd)}
  body.dark{--shadow-sm:inset 0 1px 0 rgba(240,240,242,.04),0 1px 2px rgba(0,0,0,.4),0 2px 10px rgba(0,0,0,.3);--shadow-md:inset 0 1px 0 rgba(240,240,242,.05),0 8px 24px rgba(0,0,0,.45);--shadow-lg:inset 0 1px 0 rgba(240,240,242,.05),0 24px 64px rgba(0,0,0,.55);--row-hover:#1A1A1D;--row-hover:color-mix(in srgb,var(--accent) 7%,var(--bg));--hoverwash:rgba(240,240,242,.10);--hoverwash:color-mix(in srgb,var(--accent) 10%,transparent);--ok:#3FC98E;
    /* dark: same six meanings, re-measured against the dark page — not the light set dimmed */
    --c-neutral:#A8B0BA;--c-neutral-bg:#23262B;
    --c-info:#7FB0FF;--c-info-bg:#16243C;
    --c-warn:#F5C86B;--c-warn-bg:#2E2413;
    --c-good:#4FCF97;--c-good-bg:#122A20;
    --c-bad:#E85C68;--c-bad-bg:#321A1C;
    --c-held:#C0A3FF;--c-held-bg:#241C39;
    --held:#C6A5FF;--held-bg:rgba(198,165,255,.14);--held-bd:rgba(198,165,255,.34);
    --danger:#FF7472;--danger-bg:rgba(255,116,114,.14);--danger-bd:rgba(255,116,114,.32);
    --chip-danger-fg:var(--danger);--chip-danger-bg:var(--danger-bg);--chip-danger-bd:var(--danger-bd);
    --chip-unknown-fg:var(--held);--chip-unknown-bg:var(--held-bg);--chip-unknown-bd:var(--held-bd)}
  body{transition:background-color var(--t-med) ease,color var(--t-med) ease}
  th,tr.sec td{transition:background-color var(--t-med) ease,color var(--t-med) ease}
  .tt,.bar button,.controls button,.bbtn,.gate button,.saved button{transition:transform var(--t-fast) var(--e-out),box-shadow var(--t-fast) ease,background-color var(--t-fast) ease,border-color var(--t-fast) ease,filter var(--t-fast) ease}
  .tt:hover,.bar button:hover,.controls button:hover,.bbtn:hover,.saved button:hover{background:var(--band);border-color:var(--muted)}
  .tt:active,.bar button:active,.controls button:active,.bbtn:active,.gate button:active,.saved button:active{filter:brightness(.97)}
  .gate button:hover{filter:brightness(1.05)}
  .controls button.primary:hover,.bbtn.primary:hover{filter:brightness(1.08)}
  /* catch-all: any focusable control without a bespoke ring (wizard cards, <summary>,
     modal close buttons, links) gets a visible outline. Component rules below set
     outline:none + box-shadow and win on specificity, so no double rings. */
  :focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .wcust:focus-visible{outline:none;box-shadow:0 0 0 2px var(--accent)}
  .controls input[type=text],.controls select,.chdr input,.gate input,.pin,.bfield input[type=text],.crow input[type=text]{transition:border-color var(--t-fast) ease,box-shadow var(--t-fast) ease,background-color var(--t-fast) ease}
  .controls input[type=text]:focus,.controls select:focus,.chdr input:focus,.gate input:focus,.pin:focus,.bfield input[type=text]:focus,.crow input[type=text]:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  .qa div,.bpanel,.saved,.chdr{transition:border-color var(--t-fast) ease,box-shadow var(--t-fast) ease,transform var(--t-fast) ease}

  tbody tr td{transition:background-color var(--t-fast) ease}
  /* hover = a translucent wash overlaid via background-image, so it composites over the row's
     own color (zebra band, base, or override tint) and reads identically on every row */
  tbody tr:not(.sec):hover td{background-image:linear-gradient(var(--hoverwash),var(--hoverwash))}
  tr.selrow:hover td{background:var(--sel) !important}
  .crow input[type=color]{transition:transform var(--t-fast) ease,box-shadow var(--t-fast) ease}
  .crow input[type=color]:hover{transform:scale(1.05)}
  .st{transition:background-color var(--t-fast) ease,color var(--t-fast) ease}
  .brandlogo,.logoprev{transition:opacity var(--t-med) ease}
  @media (prefers-reduced-motion:reduce){*{transition:none !important;animation:none !important}}
  @media print{*{transition:none !important;box-shadow:none !important;transform:none !important}}
  /* ---- Quick markup buttons (custom quote builder) ---- */
  .markupbar{display:none;gap:8px;flex-wrap:wrap;align-items:center;margin:0 0 12px;padding:12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
  .markupbar .mlabel{font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--fg);letter-spacing:var(--tr-flat);margin-right:4px}
  .markupbar .mbtn{font:inherit;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--btn-fg);background:var(--btn-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:7px 12px;cursor:pointer;transition:transform var(--t-fast) var(--e-out),box-shadow var(--t-fast) ease,background-color var(--t-fast) ease,border-color var(--t-fast) ease,filter var(--t-fast) ease}
  .markupbar .mbtn:hover{background:var(--band);border-color:var(--muted)}
  .markupbar .mbtn:active{filter:brightness(.97)}
  .markupbar .mbtn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--ring)}
  .markupbar .mbtn.active{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
  .markupbar .mreset{margin-left:auto}
  .markupbar .mksel{font:inherit;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:7px 12px;cursor:pointer}
  .markupbar .mkor{font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--muted);letter-spacing:var(--tr-flat)}
  .markupbar .mkcustom{display:inline-flex;align-items:center;gap:6px}
  .markupbar .mknum{width:104px;font:inherit;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:7px 12px}
  .markupbar .mkscope{flex-basis:100%;display:flex;align-items:center;flex-wrap:wrap;gap:6px 16px;padding-top:12px;margin-top:2px;border-top:1px solid var(--line)}
  .markupbar .mkscope-lbl{font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--muted);letter-spacing:var(--tr-flat);margin-right:-4px}
  .markupbar .mkscope-n{color:var(--muted)}
  .markupbar .mkscope.locked{opacity:.55}
  .markupbar label.chk input{accent-color:var(--accent);margin:0}          /* the accent IS the ink — no browser blue in the chrome */
  .markupbar .mkovr{flex-basis:100%}
  .markupbar .mkovr input{accent-color:var(--danger)}                      /* overwriting entered prices is the risky gesture */
  .markupbar .mhint{flex-basis:100%;font-size:var(--fs-fine);color:var(--muted);margin-top:2px}
  @media print{.markupbar{display:none !important}}
  /* ---- guided multi-step quote builder ---- */
  .wizardnav{display:none;flex-direction:column;gap:12px;margin:0 0 16px;padding:16px 16px;border:1px solid var(--line);border-radius:var(--radius,3px);background:var(--card);position:relative}
  @media (prefers-reduced-motion:no-preference){
    .wizardnav.wizenter{animation:wizIn .45s var(--e-out) both}
    @keyframes stepRise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
    @keyframes sparkle{0%{opacity:0;transform:scale(0) rotate(0deg)}45%{opacity:1;transform:scale(1.25) rotate(45deg)}100%{opacity:0;transform:scale(.4) rotate(90deg)}}
  }
  /* ---- Quote options + quantity/total columns (custom builder) ---- */
  td.linetot{text-align:center;font-weight:var(--fw-med);color:var(--fg)}
  tr.totrow td{background:var(--band);font-weight:var(--fw-med)}
  tr.totrow .totlabel{text-align:right;letter-spacing:var(--tr-caps);font-size:var(--fs-fine)}
  .linetot .ltt{display:block;font-size:var(--fs-micro);font-weight:var(--fw-med);color:var(--muted);letter-spacing:var(--tr-flat);margin-top:1px;white-space:nowrap}
  /* ---- per-line vial options (PLAN-LINE-OPTIONS §5): Add-ons column, Unit sub-line, chips, the Apply-to-all strip ---- */
  .addcell{white-space:nowrap}
  #out th.addh,#out td.addcell{padding-left:6px;padding-right:6px}
  .addctl{display:inline-flex;flex-direction:column;align-items:flex-start;gap:3px}
  .fillsel{font:inherit;font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:2px 4px;min-height:var(--input-h);max-width:100%}
  .addcell.nofill .fillsel{border-color:var(--err,#B42318);color:var(--err,#B42318)}   /* P25-B01: no configured fill is offered for this SKU — the row says so and the save refuses it */
  .fillsel:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  .fillsel option:disabled{color:var(--muted)}
  .lblchk{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-fine);font-weight:var(--fw-med);color:var(--fg);cursor:pointer;-webkit-user-select:none;user-select:none;min-height:20px;white-space:nowrap}
  .lblchk input{accent-color:var(--accent);margin:0}
  .lblsur{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);letter-spacing:var(--tr-flat)}
  .optchip{display:block;font-family:var(--font-mono);font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:var(--tr-flat);color:var(--muted);margin-top:2px;white-space:nowrap;text-align:left}
  .optchip.legacy{color:var(--held)}
  td.prod .optchip.client{font-size:var(--fs-fine)}
  .addall{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 12px;padding:8px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);max-width:100%;box-sizing:border-box}
  .addall .fillsel{min-height:var(--input-h);font-size:var(--fs-base);padding:4px 6px}
  .addall .lblchk{min-height:28px;font-size:var(--fs-base)}
  .addall-t{color:var(--muted)}
  .addall-st{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);letter-spacing:var(--tr-flat)}
  @media print{.addall{display:none !important}}
  @media(max-width:767px){
    #out td.addcell{white-space:normal}
    #out td.addcell .addctl{flex-direction:column;align-items:stretch;gap:6px;width:186px}
    .fillsel{height:40px;min-height:40px;padding:6px 32px 6px 12px;font-size:var(--fs-body)}   /* P24-S02: WebKit ignores min-height on a native select */
    .lblchk,#allapply{min-height:40px}
    .lblchk input{width:18px;height:18px}
    .addall{margin:0 12px 12px}
    #out td.prod .optchip{white-space:normal}
  }

  /* ===================== v2 — refined UI · responsive · print-fit ===================== */
  html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
  body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:var(--lh-ui);margin:0 auto}
  *{-webkit-tap-highlight-color:transparent}
  button,input,select,label{touch-action:manipulation}
  .subtitle{margin-bottom:20px}

  .controls,.markupbar,.chdr,.saved,.bpanel{border-radius:var(--radius)}.qa div{border-radius:var(--radius-sm)}
  .controls{gap:12px 12px}

  .controls input[type=text],.chdr input,.gate input,.pin,.qin,.bfield input[type=text],.crow input[type=text]{-webkit-appearance:none;appearance:none}

  #out{position:relative;overflow-x:auto;-webkit-overflow-scrolling:touch;border:0;background:var(--card);border-radius:var(--radius-card);box-shadow:var(--shadow-sm);animation:tblin .32s var(--e-out) both}
  #out.plain{background:transparent;box-shadow:none;border-radius:0;overflow:visible;animation:none}
  @keyframes tblin{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
  #out table{min-width:880px}
  table{font-size:var(--fs-base)}
  th{position:-webkit-sticky;position:sticky;top:0;z-index:3;border:0;border-bottom:1px solid var(--hline)}
  td{border-left:0;border-right:0;border-top:0;border-bottom:1px solid var(--line);white-space:nowrap}
  td.prod{white-space:normal;min-width:165px;line-height:var(--lh-ui)}
  tr.sec td{border-left:0;border-right:0;border-bottom:0}
  tbody tr:last-child td{border-bottom:0}
  tr.totrow td{border-bottom:0}

  /* ---------------- tablet ---------------- */
  @media (max-width:1023px){
    body{padding:24px 20px}
    #out table{min-width:840px}
  }
  /* ---------------- phone ---------------- */
  @media (max-width:767px){
    body{padding:16px 12px}
    .title{font-size:var(--fs-title)}
    .topbar{gap:12px}
    /* 16px controls stop iOS focus-zoom; taller tap targets (44px target) */
    .controls input[type=text],.controls select,.chdr input,.gate input,.pin,.qin,.bfield input[type=text],.crow input[type=text]{font-size:var(--fs-body)}
    .controls button,.bar button,.bbtn,.gate button,.markupbar .mbtn,.markupbar .mksel,.markupbar .mknum,.tt{min-height:42px}
    .controls label.chk,.markupbar label.chk{min-height:38px}
    .controls input[type=text]{min-width:0;flex:1 1 100%}
    .controls .count{margin-left:0;flex:1 1 100%}
    .markupbar .mreset{margin-left:0}
    .qa div{min-width:0;flex:1 1 100%}
    .qa.dockable::after{top:14px;transform:none}.qa.dockable:not(.min)::after{transform:rotate(90deg)}
    .chdr input{min-width:0;width:100%}
    #out table{min-width:760px}
  }

  /* ---------------- PRINT — fit on US Letter ---------------- */
  @media print{
    /* PORTRAIT: since the pro-proposal rewrite, the only thing that prints is the paper
       document (#proposal) — a 5-column portrait artifact. Landscape was tuned for the
       old wide 4-tier price-sheet print, which no longer goes to paper. */
    @page{size:Letter portrait;margin:0.5in}
    html,body{background:#fff !important}
    body{margin:0}
    *{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important}
    .topbar,.controls,.markupbar,.bar,.topbar .tt,.topactions,.saved{display:none !important}
    /* keep the pick column as an empty zero-width cell so section bars & totals stay aligned */
    .pick{display:table-cell !important;width:0 !important;max-width:0 !important;padding:0 !important;border:0 !important}
    .pick input{display:none !important}
    #out{overflow:visible !important;border:0 !important;border-radius:0 !important;animation:none !important}
    table{font-size:var(--fs-micro)}
    th,td{padding:5px 6px !important;white-space:normal !important}
    td.prod{min-width:0 !important}
    thead{display:table-header-group}
    tfoot{display:table-row-group}
    tr{break-inside:avoid;page-break-inside:avoid}
    tr.sec{break-after:avoid;page-break-after:avoid}
    tr.totrow td{border-top:2px solid #111114 !important}
    .notes{margin-bottom:8px}
    .chdr label{flex:1 1 0}
    .chdr input{width:100% !important;min-width:0 !important;text-overflow:ellipsis}
    input[type=date]::-webkit-calendar-picker-indicator{display:none !important}
  }
  /* ===================== Access-code landing — in-card dot matrix + animated words ===================== */
  :root{--dot:rgba(0,0,0,.16)}
  body.dark{--dot:rgba(255,255,255,.16)}
  #bgfx{position:fixed;inset:0;z-index:-1;display:none;pointer-events:none;opacity:0;transition:opacity .6s ease;
    -webkit-mask-image:radial-gradient(125% 95% at 50% 32%,#000 30%,transparent 80%);
    mask-image:radial-gradient(125% 95% at 50% 32%,#000 30%,transparent 80%)}
  #bgfx.on{opacity:1}
  @media print{#bgfx{display:none !important}}
  /* on the login screen, hide the header bar; the toggle lives below the box */
  body.onlogin .topbar{display:none}
  .gate button.gatetheme{display:inline-block;width:auto;max-width:none;background:var(--btn-bg);color:var(--btn-fg);border:1px solid var(--btn-line);border-radius:var(--radius-sm);font-size:var(--fs-fine);font-weight:var(--fw-med);letter-spacing:var(--tr-flat);padding:6px 16px;margin:20px auto 0;overflow:visible;animation:gateUp .55s .72s both}
  .gate button.gatetheme::after{display:none !important}
  .gate button.gatetheme:hover{filter:brightness(.97)}
  .gate h2{font-family:var(--font-sans);font-style:normal;font-weight:var(--fw-reg);font-size:var(--fs-title);letter-spacing:var(--tr-flat)}
  .gate h2 span{display:inline-block;transition:color var(--t-med) ease;animation:wordIn .6s var(--e-out) both}
  .gate h2 span:nth-child(1){animation-delay:.12s}
  .gate h2 span:nth-child(2){animation-delay:.20s}
  .gate h2 span:nth-child(3){animation-delay:.28s}
  .gate h2 span:nth-child(4){animation-delay:.36s}
  @keyframes wordIn{from{opacity:0;transform:translateY(11px);filter:blur(5px)}to{opacity:1;transform:none;filter:blur(0)}}
  .gate p{animation:gateUp .55s .44s both}
  .gate input{font-size:var(--fs-body);letter-spacing:var(--tr-code);padding:16px 16px;animation:gateUp .55s .52s both;transition:border-color var(--t-fast) ease,box-shadow var(--t-med) ease,transform var(--t-fast) ease}
  .gate input::placeholder{letter-spacing:var(--tr-caps)}
  .gate input:focus{transform:none}
  .gate button{font-size:var(--fs-body);letter-spacing:var(--tr-caps);padding:16px 20px;position:relative;overflow:hidden;display:block;width:100%;max-width:324px;margin:0 auto;animation:gateUp .55s .60s both}
  @keyframes gateUp{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
  @media (max-width:767px){
    .gate{margin:clamp(20px,7vh,64px) auto 40px;padding:32px 20px;border-radius:var(--radius-sm)}
  }
  /* ===================== segmented 6-char code entry ===================== */
  .codewrap{animation:gateUp .55s .52s both}
  .code{position:relative;display:flex;gap:12px;justify-content:center;margin:0 auto 16px;width:100%;max-width:324px}
  .code .cell{position:relative;flex:1 1 0;min-width:0;aspect-ratio:1/1}
  .gate .code .cell input{width:100%;height:100%;margin:0;padding:0;line-height:var(--lh-flat);text-align:center;font-size:var(--fs-title);font-weight:var(--fw-med);letter-spacing:var(--tr-flat);
    border-radius:0 !important;border:1px solid var(--cell-bd);background:var(--input-bg);font-family:var(--font-mono);
    transition:background-color var(--t-med) ease,color var(--t-med) ease,border-color var(--t-med) ease;
    color:var(--fg);background:var(--input-bg);border:1px solid var(--btn-line);caret-color:transparent;
    box-shadow:none;animation:none;transition:border-color var(--t-fast),box-shadow var(--t-med)}
  .gate .code .cell input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring);transform:none}
  .code .cell.filled input{transform:none}
  .code .cell.pop input{animation:cellpop .26s var(--e-pop)}
  @keyframes cellpop{0%{transform:scale(.72);opacity:.25}100%{transform:scale(1);opacity:1}}
  .gate .code .cell input.pulse{background:rgba(127,127,134,.14);background:color-mix(in srgb,var(--fg) 9%,var(--input-bg))}
  .gate .code .cell input.filled,.cell.filled input{background:var(--fg) !important;color:var(--bg) !important;border-color:var(--fg) !important}
  .code .hl{position:absolute;top:-3px;left:-3px;width:52px;height:62px;pointer-events:none;opacity:0;
    --ckl:var(--fg);
    background:
      linear-gradient(var(--ckl),var(--ckl)) top left/11px 1.5px,
      linear-gradient(var(--ckl),var(--ckl)) top left/1.5px 11px,
      linear-gradient(var(--ckl),var(--ckl)) top right/11px 1.5px,
      linear-gradient(var(--ckl),var(--ckl)) top right/1.5px 11px,
      linear-gradient(var(--ckl),var(--ckl)) bottom left/11px 1.5px,
      linear-gradient(var(--ckl),var(--ckl)) bottom left/1.5px 11px,
      linear-gradient(var(--ckl),var(--ckl)) bottom right/11px 1.5px,
      linear-gradient(var(--ckl),var(--ckl)) bottom right/1.5px 11px;
    background-repeat:no-repeat;
    transition:transform var(--t-med) var(--e-out),width var(--t-med) ease,height var(--t-med) ease,opacity var(--t-med) ease}
  .code .hl.on{opacity:1}
  .gate input.codehidden{display:none;animation:none}
  .gate.altcode .codewrap{display:none}
  .gate.altcode input.codehidden{display:block;max-width:324px;margin-left:auto;margin-right:auto}
  .linkbtn{display:inline-block;width:auto !important;margin:12px auto 0 !important;padding:4px 6px !important;background:none !important;border:none !important;
    color:var(--muted) !important;font-size:var(--fs-fine) !important;font-weight:var(--fw-med) !important;letter-spacing:var(--tr-flat) !important;cursor:pointer;text-decoration:underline;animation:gateUp .55s .66s both;overflow:visible !important}
  .linkbtn:hover{color:var(--fg) !important}
  .linkbtn::after{display:none !important}
  @media (max-width:420px){.code{max-width:300px;gap:7px}.gate .code .cell input{border-radius:var(--radius-sm)}}
  /* ===== neoneo: matrix easter-egg ===== */
  #matrixrain{position:fixed;inset:0;width:100%;height:100%;z-index:-1;display:none;pointer-events:none}
  body.matrix #matrixrain{display:block}
  #matrixboot{position:fixed;inset:0;z-index:400;display:none;background:#000;color:#00ff41;font:var(--fs-body)/1.7 var(--font-sans);align-items:center;justify-content:flex-start;flex-direction:column;padding:14vh 0 0;opacity:1;transition:opacity .55s ease}
  #matrixboot.fade{opacity:0}
  #matrixboot pre{margin:0;padding:0 24px;text-shadow:0 0 8px rgba(0,255,65,.65);white-space:pre-wrap;max-width:720px;width:100%}
  body.matrix{background:#000!important;color:#00ff41;--muted:#fff}
  body.matrix .mlabel{color:#fff!important}
  body.matrix,body.matrix *{font-family:var(--font-sans)!important}
  body.matrix #bg,body.matrix #bggrid,body.matrix #bgfx{display:none!important}
  /* v11 design law (2026-09-20, Oscar: "No dots in the main sections"): the light-trace lattice belongs to the
     access-code screen and NOWHERE else. Enforced structurally rather than by call order — #bgfx is started by
     showGate() and was stopped only by enterMorph(), so every other way of revealing the app (a reload with a
     live session) left it animating behind the product. The JS stop() is fixed too; this rule is what makes it
     impossible to re-leak. !important because bgfx sets display inline. */
  body:not(.onlogin) #bgfx{display:none !important}
  body.matrix .topbar{background:rgba(0,0,0,.82)!important;border-bottom:1px solid rgba(0,255,65,.28)!important}
  body.matrix .title{color:#7CFFA0!important;text-shadow:0 0 10px rgba(0,255,65,.55);letter-spacing:var(--tr-flat)}
  body.matrix .subtitle{color:#0c0!important;opacity:.9}
  body.matrix .qa div,body.matrix .controls,body.matrix .markupbar,body.matrix .chdr,body.matrix .foot,body.matrix #pfoot,body.matrix #review,body.matrix .rev-table,body.matrix .savedbox{background:#000!important;border-color:rgba(0,255,65,.34)!important;color:#00ff41!important;box-shadow:0 0 0 1px rgba(0,255,65,.12),0 0 20px rgba(0,0,0,.9)!important}
  body.matrix #out{border:1px solid rgba(0,255,65,.34)!important;border-radius:var(--radius-sm);overflow:hidden;box-shadow:0 0 0 1px rgba(0,255,65,.12),0 0 20px rgba(0,0,0,.9)}
  body.matrix table{background:#000!important;border:0!important;box-shadow:none!important;color:#00ff41!important}
  body.matrix .qa div{border-left:3px solid #00ff41!important}
  body.matrix .qa b,body.matrix .qa .ck{color:#7CFFA0!important}
  body.matrix label,body.matrix th,body.matrix .rev-table th{color:#7CFFA0!important}
  body.matrix table th{background:#04110a!important;border-color:rgba(0,255,65,.16)!important;text-shadow:0 0 6px rgba(0,255,65,.4)}
  body.matrix table td{background:#000!important;border-color:rgba(0,255,65,.14)!important;color:#3bff77!important}
  body.matrix tbody tr{background:#000!important}
  body.matrix tbody tr:hover td{background:rgba(0,255,65,.07)!important}
  body.matrix input,body.matrix select,body.matrix .qin{background:#000!important;color:#7CFFA0!important;border:1px solid rgba(0,255,65,.4)!important}
  body.matrix input::placeholder{color:rgba(0,255,65,.4)!important}
  body.matrix button,body.matrix .toggle{background:rgba(0,255,65,.1)!important;color:#7CFFA0!important;border:1px solid rgba(0,255,65,.5)!important;text-shadow:0 0 5px rgba(0,255,65,.4)}
  body.matrix button:hover,body.matrix .toggle:hover{background:rgba(0,255,65,.2)!important}
  body.matrix #savebtn,body.matrix .modal-copy,body.matrix .wbtn.primary.saveblue{background:rgba(0,255,65,.16)!important;border-color:#00ff41!important;color:#daffe7!important;box-shadow:0 0 16px rgba(0,255,65,.4)!important;animation:none!important}
  body.matrix a{color:#3bff77!important}
  body.matrix ::selection{background:rgba(0,255,65,.3);color:#dfffe9}
  @media (prefers-reduced-motion:reduce){#matrixboot{transition:none}}


  /* the solved stops, shown back to the tenant with their measured ratios — square, mono, no chrome */
  .bstops{display:flex;flex-wrap:wrap;gap:6px 16px;margin:12px 0 2px;font-family:var(--mono);font-size:var(--fs-micro);
    letter-spacing:.6px;text-transform:none;color:var(--muted)}
  .bstops .bstop{display:inline-flex;align-items:center;gap:6px}
  .bstops .bstop i{width:11px;height:11px;border:1px solid var(--line);flex:none}
  .bstops .bstop-n{color:var(--fg);letter-spacing:1px}
  .bstops .bstop-note{display:flex;align-items:flex-start;gap:7px;width:100%;color:var(--fg);text-transform:none;
    letter-spacing:.3px;line-height:var(--lh-ui)}   /* WS15-C C1: the scale's UI line height, not a bare 1.5 */
  .bstops .bstop-note em{width:8px;height:8px;background:var(--fg);flex:none;margin-top:3px}
  .bstops .bstop-note.bad em{background:var(--fg)}   /* never red — the login's error grammar, one language */
  .bmatch{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:12px 0 2px;font-family:var(--mono);
    font-size:var(--fs-micro);letter-spacing:.8px;text-transform:none;color:var(--muted)}
  .bmatch-l{margin-right:2px}
  .bmatch-b{display:inline-flex;align-items:center;gap:6px;font:inherit;color:var(--fg);background:var(--btn-bg);
    border:1px solid var(--btn-line);border-radius:0;padding:5px 8px;cursor:pointer}
  .bmatch-b:hover{border-color:var(--fg)}
  .bmatch-b i{width:10px;height:10px;flex:none}

  /* ---- theme presets (validated: >=3:1 as accent on paper, >=4.5:1 contrast() fg on fill) ----
     SQUARE, and selected by a 3px ink bar. These were 26px circles with a halo-ring selected state
     until 2026-09-20; the circle went with the straight-edge ruling and the ring went with the
     bracket ruling, which killed corner-tick marks everywhere including here. ---- */
  .presetrow{display:grid;grid-template-columns:repeat(6,26px);gap:8px;margin:2px 0 12px;justify-content:start}
  .preset{width:26px;height:26px;border-radius:0;cursor:pointer;border:1px solid var(--line);
    position:relative;transition:transform var(--t-fast) ease}
  body.dark .preset{border-color:var(--line)}
  .preset:hover{transform:scale(1.12)}
  /* SELECTED = a 3px solid ink bar, flush under the cell, full width — the language the product
     already speaks on .rail-item.on::before. It sits OUTSIDE the chip deliberately: the chip's fill
     is the tenant's own colour, so a bar drawn inside it would vanish on GRAPHITE and INK. Entrance
     The 3px GROUND GAP must not be closed: `bottom` resolves against the PADDING box, so a flush
     -3px bar overlaps the chip's border and, on GRAPHITE (#111114 on #111114), merges into it —
     the selected default becomes indistinguishable from an unselected chip. */
  .preset::after{content:'';position:absolute;left:0;right:0;bottom:-7px;height:3px;background:var(--fg);
    transform:scaleX(0);transform-origin:left center;transition:transform 140ms var(--e-pop);pointer-events:none}
  .preset.on::after{transform:scaleX(1)}
  .preset:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
  @media (prefers-reduced-motion: reduce){.preset:hover{transform:none}.preset::after{transition:none}}
  /* ===================== PQB SKIN — design layer only (palette/type/geometry) ===================== */
  /* Inter is the interface face. Metadata and labels use 12px; controls and
     rows use 14px; prose/panel titles use 16px. The measured 28/32/48 figures
     remain available for actual hierarchy. Numeric alignment is tabular,
     without switching to a monospaced face (Oscar, 2026-09-22). */
  *{font-synthesis-weight:none;font-synthesis:none}
  :root{
    /* Every stack ends in a real system face: the subset carries Latin, and a glyph it
       does not carry (✓ ✕ ⟶ ⌘ ⚠ ▪) must draw from the fallback, never as tofu. */
    --font-sans:'Inter','Helvetica Neue',Helvetica,'Segoe UI',Roboto,Arial,sans-serif;
    /* Compatibility alias for numeric classes and immutable chart assets. */
    --font-mono:var(--font-sans);
    --font-serif:'Instrument Serif','Iowan Old Style',Georgia,'Times New Roman',serif;
    /* the measured reference — seven steps, and a step that is not on this list does not exist.
       MEASURED on the reference: Hyperline's dominant body size is 16px and its interface
       size is 14px (390 and 131 occurrences respectively); Attio's page title is ~28px.
       So base moves 13->14 and body 15->16: the old ramp was a size tighter than the thing
       Oscar picked, which is most of why our pages read denser and cheaper than his.
       Legacy names below alias onto them so no call site breaks; they die in the sweep. */
    --fs-micro:12px;--fs-fine:12px;--fs-base:14px;--fs-body:16px;
    --fs-title:28px;--fs-kpi:32px;--fs-hero:48px;
    --fs-paper:var(--fs-micro);--fs-tick:var(--fs-micro);--fs-lead:var(--fs-body);
    --fs-display:var(--fs-title);--fs-band:var(--fs-kpi);--fs-mega:var(--fs-hero);
    /* tracking in em, so it rides the ramp instead of fighting it */
    --tr-caps:.06em;--tr-caps-wide:.06em;--tr-code:.16em;
    --tr-flat:0;--tr-snug:-.01em;--tr-tight:-.02em;--tr-tighter:-.03em;
    --lh-flat:1;--lh-tight:1.15;--lh-ui:1.45;--lh-text:1.6;
    /* TWO WEIGHTS. Measured across hyperline.co: 400 (569 elements) and 500 (383) and
       NOTHING ELSE — no 600, no 700, anywhere on the page. The light typographic colour
       that gives the reference its calm is mostly this. --fw-semi and --fw-bold are kept
       as NAMES so the ~200 call sites do not churn, but both now resolve to 500. */
    --fw-reg:400;--fw-med:500;--fw-semi:500;--fw-bold:500;
  }
  /* OPTICAL WEIGHT: paper-white on near-black irradiates — the same stroke reads heavier
     and blurrier than its inverse, which is what made the dark dashboard shout. Archivo is
     variable down to 350, so dark asks the face for a genuinely lighter instance (−25 on
     every step) rather than faking it with opacity. The mono stays put: at 10px the
     difference is sub-pixel and antialiasing already carries it. */
  body.dark{--fw-reg:400;--fw-med:500;--fw-semi:500;--fw-bold:500}
  body{font-family:var(--font-sans);font-weight:var(--fw-reg)}
  /* Form controls do not inherit a family. Hundreds of them — the rail's own buttons, the
     login form's input — were silently rendering in the UA's Arial while every rule around
     them said otherwise. Family only; size and weight stay with each control's own rule. */
  /* FIGURES ALIGN. Money and counts sit in columns all over this product and the alignment
     was declared in 20 scattered places, so half the columns ragged. Stated once, here, for
     every numeric surface. The mono needs no entry — it is monospaced, so its figures are
     already tabular; these are the SANS surfaces plus every table. */
  .bstops,.qt,.reg-tbl,.prdoc .pr-tbl,.prdoc .pr-trow,.prdoc .pr-tfinal b,.prdoc .pr-due b,.d-kpi .v,.d-kpi .n,.pipe-n,.an-metric .v,.an-sales-big,.an-tc .r .v,.crm-col-h .n,.rc-k b,.clienthead .ch-cell .v,.rail-item .cnt,.num,td.num,td.price,td.linetot,.qtycell,.pin,.qin,.mknum,.markupbar .mkscope-n,.linetot,.totsum,#totqty,.saved b,.modal-code,.st,.qfchip .qfc,.tm-mix-n,.gcount,.cart-f>b,.cr-f>b,.cr-q,.cr-p,.ord-t,.ord-det dd,.ov-hero,.ov-fig .v,.ov-fig .d,.ov-row .f,.ov-bar .v,.ov-wait .c{font-variant-numeric:tabular-nums}
  button,input,select,textarea,optgroup{font-family:inherit}
  /* Labels share the text face, 12px, sentence case, without tracking. */
  .ml,.ss-text small,.sm-eb,.sm-foot,.pqb-prompt-label,.bprev-head span,.bprev-sec,.bprev-btn,.bprev-note,.addall-t,.pipe-l,.pipe-hd .t,.snap::after,.fu-list.snap::before,.fu-why,.d-sec-head .ml2,.cust .op,#custedit label,.qt th,.qfchip,.asub,.tm-mix-l,#ce-prices .ce-prices-head .t,.ce-notes-lbl,.cust-note,.tacc summary,.cmdk-row .kind,.clienthead .ch-cell .k,.qstat,.coh-l .coh-s,.npop-h,.npop-clear,.an-t,.ab-shiphead,.cm-frow label,.cm-state,.cm-hist-row .act,.d-band .ml,.d-kpi .sf,.rc-a,.rc-row .age,.rc-row .val,.rc-k,.na-kick,.na-meta,.na-open,.na-foot,.na-menu .na-mh,.na-list.snap::before,.d-utag,.an-metric .l,.an-metric .d,.reg-tbl td.m,.crm-col-h .nm,.crm-chip,.crm-sel,.crm-open,.crm-sel,.stag,.reg-foot,.ph-eb,.sitemenu .sm-grp,.va-ro{font-family:var(--font-sans);font-size:var(--fs-fine);font-weight:var(--fw-med);letter-spacing:0;text-transform:none}
  /* RADIUS — one owner, and it is assets/fam.v7.css. The comment that used to sit here
     claimed the inline fallback "now AGREES" with fam.v3.css. It did not: this block said 0
     on five tokens, fam.v3 said 4/4/8/4/4, and fam.v3 wins because it loads last. Worse, it
     loads AFTER the @media print re-zero below, so the radii leaked into printed documents
     despite the print shield. Both are fixed: these values now match fam.v4 exactly, and the
     print block no longer pretends it can re-zero them.
     Oscar requested less capsule-like chips: 4px replaces the reference pill.
     Panels use 8px within the measured 8–12px range; controls remain 6px. */
  :root{--radius:6px;--radius-sm:6px;--radius-card:8px;--radius-btn:6px;--radius-input:6px;--radius-pill:4px;
  --t-fast:.15s;--t-med:.25s;--t-slow:.45s;--e-out:cubic-bezier(.2,.8,.2,1);--e-exit:cubic-bezier(.22,1,.36,1);--e-pop:cubic-bezier(.2,.9,.3,1.4)}
  .subtitle,.wtitle,.count,.bar,.foot,.rev-meta,.bstatus,.bhint,.mhint,.modal-note,
  .notes span,.mlabel,.chdr label,.bfield label,.controls label.chk,
  th,.st,.pin,.qin,.dol,.totlabel,.mknum,.mksel,.mkor,.modal-code,.saved b{font-family:var(--font-mono)}
  .tt,.bar button,.controls button,.bbtn,.gate button,.saved button,.topactions .primary,
  .modal-copy,.modal-close,.wbtn,.markupbar .mbtn{font-family:var(--font-sans);font-weight:var(--fw-med);text-transform:none;letter-spacing:0}
  .subtitle{font-size:var(--fs-micro);text-transform:none;color:var(--muted);margin-top:5px}
  .title{font-weight:var(--fw-med)}
  th{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none}
  tr.sec td{font-weight:var(--fw-med);text-transform:none}
  .st{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;padding:3px 12px}
  .totlabel{letter-spacing:var(--tr-caps-wide)}
  .chdr label,.bfield label{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted)}
  .controls label.chk,.markupbar label.chk{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none}
  .mlabel{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted)}
  .notes span{font-weight:var(--fw-med);font-size:var(--fs-micro);letter-spacing:0;text-transform:none}
  .count,.bar{font-size:var(--fs-micro);letter-spacing:0;text-transform:none}
  .qa b{font-weight:var(--fw-med)}.qa .ck{font-weight:var(--fw-med)}
  .rev-client{font-weight:var(--fw-med)}
  .modal-title,.gate h2,.bpanel h2{font-weight:var(--fw-reg)}
  td.prod{font-weight:var(--fw-med)}td.price,.pin,.qin,td.linetot{font-weight:var(--fw-med)}
    td.price.hi{color:var(--accent-emph)}
  .num,td.num,td.price,td.linetot,.qtycell,.pin,.qin,.modal-code,.totsum,#totqty,  .modal-copy,.modal-close,.gate button,.gate input,.crow input[type=color]{border-radius:var(--radius-sm)}
  .gate .code .cell input{border-radius:0}
  .code .hl{border-radius:0}
  .modal-code{border-radius:var(--radius-sm);letter-spacing:var(--tr-code)}
  .logoprev{border-radius:var(--radius-sm)}
  /* v11: the app dot-grid canvas rule is retired (it was already overridden below). */
  @media print{body{background-image:none !important}}
  tr.totrow td{border-top:2px solid var(--fg)}
  tr.totrow .totsum span{color:var(--accent-emph)}

  /* header buttons: primary = ink, save = accent (already via #savebtn) */
  .topactions .tt,.topactions .primary{font-size:var(--fs-base)}   /* WS15-C C3: header actions (Copy link, Print) are page-level buttons: the button type (14px), like every d-btn / bbtn */
  /* Print is filled only when it is the primary action; builder Save leads. */
  #print.primary{background:var(--sbg);border-color:var(--sbg);color:var(--sfg)}
  th{padding:12px 8px}
  @media print{.st{border:1px solid var(--card-line) !important}}


  /* ===================== REP DASHBOARD — drafted industrial ===================== */
  #dash{display:none;padding:0 var(--page-pad) var(--s8)}
  .d-actions{display:flex;gap:8px}
  .d-btn{font-family:var(--font-sans);font-weight:var(--fw-med);font-size:var(--fs-base);letter-spacing:0;text-transform:none;
    height:36px;padding:0 16px;border-radius:var(--radius-sm);border:1px solid var(--btn-line);background:transparent;
    color:var(--fg);cursor:pointer;white-space:nowrap}
  .d-btn:hover{background:var(--band)}
  .d-btn.acc{background:var(--accent);border-color:var(--accent);color:var(--accent-fg)}
  .d-kpi{border-right:1px solid var(--line)}
  .d-kpi:last-child{border-right:0}
  @media(max-width:899px){.d-kpi:nth-child(2n){border-right:0}.d-kpi:nth-child(-n+2){border-bottom:1px solid var(--line)}}
  .d-kpi .l{font-family:var(--font-sans);text-transform:none;color:var(--muted)}
  .d-kpi .v{color:var(--fg)}
  /* INSTRUMENT BOUNDARY: a KPI value is text, and text wears text tokens. These carried
     var(--accent) until 2026-09-20 — a tenant's brand reading as a data encoding. .d-kpi .v is
     already var(--fg); the label carries the distinction, never the colour. ---- */
  
  .d-kpi .v.real{color:var(--ok)} .d-kpi .v.pipev{color:var(--fg)} .d-kpi .v.wr{color:var(--fg)}
  .earn-real{color:var(--ok)} .earn-pot{color:var(--muted);opacity:.75} .earn-neg{color:var(--danger)}
  .d-kpi .v.real.neg{color:var(--danger)}
  .wr-loss{display:block;margin-top:6px;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--danger)}
  .bf-badge{color:var(--danger);font-size:var(--fs-fine);cursor:default}
  .team-rowlink{cursor:pointer} .team-rowlink:hover td{background:var(--band)}
  /* ---- reserved-semantic status signals (amber/red/green = state, never decoration) ---- */
  .d-kpi .v.att{color:var(--muted);transition:color var(--t-fast)}
  .d-kpi .v.att.hot{color:var(--fg)}   /* v11: the hot state is ink, not amber */
  tr.qatt-warn>td:first-child{box-shadow:inset 3px 0 0 var(--held)}
  tr.qatt-danger>td:first-child{box-shadow:inset 3px 0 0 var(--danger)}
  tr.qatt-ok>td:first-child{box-shadow:inset 3px 0 0 var(--fg)}
  .qfchip .qfc{margin-left:5px;opacity:.55}
  .qfchip.att-warn:not(.on){color:var(--held);border-color:var(--held-bd)}
  .qfchip.att-danger:not(.on){color:var(--danger);border-color:var(--danger-bd)}
  .qfchip.att-warn:not(.on) .qfc,.qfchip.att-danger:not(.on) .qfc{opacity:.85}
  /* ---- INSTRUMENT BOUNDARY (docs/DECISION-2026-09-20-chart-blue.md) ----------------------------
     "No element inside a chart card may carry --brand-*. .an-card, figure and any chart container
     are instrument housings: internal chrome is greyscale and the only colour inside the frame is
     the data ramp. Outside the frame, tenant colour is unrestricted."
     A TOKEN FIREWALL, not a list of exceptions: each housing re-declares every tenant token to a
     substrate token, so anything rendered inside is neutral BY CONSTRUCTION — including a shared
     class such as .qfchip, whose out-of-frame styling is legitimately the tenant's colour, and
     including a control nobody has written yet. --ring is re-declared explicitly because its
     :root value resolved var(--accent) at :root and descendants inherit that resolved value. ---- */
  /* ---- CHART PALETTE: owned by the kit (assets/pqb-charts.v10.css, --k1..--k5 — four validated hues plus
     ink, both themes). BRAND IS INK, DATA IS PIGMENT: a chart never takes a tenant token. ---- */
  .an-card,.an-grid,.pipe,.tm-mix,.d-kpi{
    --accent:var(--fg);--accent-fg:var(--bg);--accent-2:var(--fg);--accent-glow:transparent;
    --ring:var(--muted);--hbg:var(--fg);--hfg:var(--bg);--hline:var(--fg);--sbg:var(--fg);--sfg:var(--bg)}

  /* ---- DOCUMENT BOUNDARY (docs/briefs/2026-09-20-CHIP-COLOUR.md) — the mirror of the boundary above.
     The client document is the one surface carrying the tenant's brand, so it is the one surface where
     a chip hue could be read AS that brand (a Forest tenant beside a green chip). Same mechanism: it
     re-declares every CHIP token to a substrate token, so chips inside are greyscale BY CONSTRUCTION —
     apart on fill and edge, not hue. Brand is the only colour the client ever sees. ---- */
  #clienthead,#out,#acceptbar{
    --held:var(--muted);--held-bg:transparent;--held-bd:var(--card-line);
    --danger:var(--fg);--danger-bg:transparent;--danger-bd:var(--fg);--ok:var(--fg);
    --chip-danger-fg:var(--fg);--chip-danger-bg:transparent;--chip-danger-bd:var(--fg);
    --chip-unknown-fg:var(--muted);--chip-unknown-bg:transparent;--chip-unknown-bd:var(--card-line)}

  .pipe{display:flex;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden;background:var(--card);margin:0 0 16px}
  .pipe-stage{flex:1;min-width:0;text-align:left;padding:12px 16px 12px;border:0;border-right:1px solid var(--line);background:transparent;cursor:pointer;font:inherit;color:inherit;transition:background var(--t-fast)}
  .pipe-stage:last-child{border-right:0}
  .pipe-stage:hover{background:var(--band)}
  .pipe-stage.on{background:var(--band);box-shadow:inset 0 -2px 0 var(--fg)}
  .pipe-stage:focus-visible{outline:none;box-shadow:0 0 0 3px var(--muted)}
  .pipe-n{display:block;font-size:var(--fs-title);letter-spacing:var(--tr-tighter);color:var(--fg);line-height:var(--lh-flat)}
  .pipe-l{display:flex;align-items:center;gap:6px;color:var(--muted);margin-top:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .pipe-dot{width:6px;height:6px;border-radius:1px;flex:none}
  .pipe-bar{display:block;height:3px;border-radius:0;background:var(--line);margin-top:12px;overflow:hidden}
  .pipe-bar>i{display:block;height:100%;border-radius:0;min-width:2px}
  .pipe-conv{display:block;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--muted);margin-top:6px}
  .pipe-hd{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 8px}
  .pipe-hd .t{color:var(--muted)}
  .pipe-wr{font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-flat);color:var(--fg)} .pipe-wr b{font-weight:var(--fw-semi)} .pipe-wr.muted{color:var(--muted)}
  @media(max-width:720px){.pipe{flex-wrap:wrap}.pipe-stage{flex:1 1 33%;border-bottom:1px solid var(--line)}}
  .fu-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden;background:var(--card)}
  /* Perf (3) — skeleton + refreshing states. A skeleton is token-only (band → button line → band), shimmer off under
     prefers-reduced-motion; never a spinner. A card painted from the local snapshot carries .snap: a mono "refreshing…"
     microlabel top-right until its live answer replaces it in place, and any WRITE action inside it is stale (dimmed, inert). */
  .skel-b{display:block;height:12px;border-radius:0;background:linear-gradient(90deg,var(--band) 25%,var(--btn-line) 50%,var(--band) 75%);background-size:400% 100%;animation:skel 1.4s ease-in-out infinite}
  @keyframes skel{0%{background-position:100% 0}100%{background-position:0 0}}
  .d-kpi.skel .skel-b.l{width:38%;height:9px;margin-top:2px}.d-kpi.skel .skel-b.v{width:62%;height:24px;margin-top:12px}.d-kpi.skel .skel-b.s{width:100%;height:22px;margin-top:16px;opacity:.55}
  .fu-row.skel{gap:16px}.fu-row.skel .skel-b{height:10px}.fu-row.skel .skel-b.a{width:34%}.fu-row.skel .skel-b.b{width:22%;opacity:.7}.fu-row.skel .skel-b.c{width:44px;margin-left:auto}
  .an-card.skel canvas{visibility:hidden}.an-card.skel .an-chart{position:relative}.an-card.skel .an-chart::after{content:'';position:absolute;inset:6px 0 0;border-radius:0;background:linear-gradient(90deg,var(--band) 25%,var(--btn-line) 50%,var(--band) 75%);background-size:400% 100%;animation:skel 1.4s ease-in-out infinite;opacity:.8}
  .an-card.skel .an-sum::before{content:'';display:block;width:70%;height:10px;border-radius:0;background:var(--band)}
  .snap{position:relative}
  .snap::after{content:'refreshing…';position:absolute;top:10px;right:12px;color:var(--muted);opacity:.9;pointer-events:none}
  .fu-list.snap::after{content:none}.fu-list.snap::before{content:'refreshing…';display:block;padding:6px 16px;color:var(--muted);background:var(--band);border-bottom:1px solid var(--line)}   /* the list gets a slim strip instead of a corner label that would sit on the last row's buttons */
  .snap [data-w]{opacity:.4;pointer-events:none;filter:grayscale(1)}   /* write actions are stale inside a snapshot-painted card; read / navigate actions stay live */
  .perf-line{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--muted);padding:16px 24px;border-top:1px solid var(--line);margin-top:20px}
  @media (prefers-reduced-motion: reduce){.skel-b,.an-card.skel .an-chart::after{animation:none;background:var(--band)}}
  .fu-row{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line)}
  .fu-row:first-child{border-top:0}
  .fu-dot{width:7px;height:7px;border-radius:2px;flex:none;background:var(--muted)}
  .fu-warn .fu-dot{background:var(--held)} .fu-danger .fu-dot{background:var(--danger)} .fu-muted .fu-dot{background:var(--muted)}
  .fu-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
  .fu-client{font-size:var(--fs-body);color:var(--fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .fu-why{color:var(--muted)}
  .fu-danger .fu-why{color:var(--danger)} .fu-warn .fu-why{color:var(--held)}
  .fu-code{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);letter-spacing:var(--tr-caps);flex:none}
  .fu-acts{display:flex;gap:6px;flex:none}
  @media(max-width:600px){.fu-code{display:none}.fu-row{flex-wrap:wrap}.fu-main{min-width:0;flex:1 1 100%}.fu-client{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;max-width:100%}.fu-acts{flex:1 1 100%;justify-content:flex-end;flex-wrap:wrap}}
  /* ---- the measured reference DENSITY — the Attio tell. Tight type, generous hit area: a 38px row with a
     full-height clickable cell gives a 38px target at a 13px voice. Never shrink the target to buy
     density; under a coarse pointer the row grows to 44 instead. ---- */
  /* ---- THE SPACING SCALE. Measured, not chosen.
     Source: attio-ref.png, the Hyperline app screenshot. DPR 2 (its 1px hairlines
     land on exactly 2 device px). Its nav label cap-height is 27 device px, and
     cap/0.7275 puts its base type at 37.1 device px — so every distance below is
     expressed as a multiple of that reference type size, then re-struck at our 14px.
     Device px -> em -> our px:
        rail width          527 -> 14.20em -> 200   (in assets/fam.v7.css)
        nav row pitch        95 ->  2.56em ->  36  (HELD AT 40: the house 40px target wins)
        list / table row    110 ->  2.96em ->  42
        panel padding        54 ->  1.46em ->  20
        gap between panels   57 ->  1.54em ->  24  (snapped from 22)
        gap between sections 138 -> 3.72em ->  52
     Before this, --sec-gap was 20px and --card-pad 16px, and neither token was
     wired to anything: --sec-gap had 2 uses, --card-pad had 0. Section rhythm was
     hardcoded at 20-26px in eight places, against a measured 52. That — not colour,
     not type — is why the app read as cramped next to the reference.
     Everything below steps on 4px. Component internals (<= 8px) are left alone;
     they are not what reads as density at arm's length. ---- */
  :root{
    --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:20px;--s6:24px;--s7:32px;--s8:40px;--s9:52px;--s10:64px;--s11:80px;
    --row-h:42px;--nav-h:40px;--btn-h:32px;--btn-h-primary:40px;--input-h:36px;
    --card-pad:var(--s5);        /* 20 — measured 1.46em */
    --panel-gap:var(--s6);       /* 24 — measured 1.54em */
    --sec-gap:var(--s9);         /* 52 — measured 3.72em */
    --page-pad:var(--s6);        /* 24 */
  }
  @media (pointer: coarse){:root{--row-h:44px;--nav-h:44px;--btn-h:44px}}
  .reg-tbl td{height:var(--row-h);padding-top:0;padding-bottom:0}
  .qt td,.reg-tbl td{border-radius:0}   /* §3: 0 on table cells */
  .rail-item{min-height:var(--nav-h)}
  .d-btn,.codebtn{min-height:var(--btn-h)}
  .d-btn.acc,.topactions .primary{min-height:var(--btn-h-primary)}
  input:not([type=checkbox]):not([type=radio]),select,textarea{min-height:var(--input-h)}
  .d-sec{margin-bottom:var(--sec-gap)}
  /* §3 ELEVATION — a card hovers by DARKENING ITS HAIRLINE and moving nothing. box-shadow is for
     floating layers only (popover, sheet, dialog, toast), never a card. */
  .an-card,.d-kpi,.reg-card{box-shadow:none;transition:border-color var(--t-fast) ease}
  .an-card:hover,.d-kpi:hover,.reg-card:hover{border-color:var(--ink-45);transform:none}
  .d-sec-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--s4)}
  .d-sec-head .ml2{color:var(--muted)}
  .cust-grid{display:grid;grid-template-columns:1fr;gap:12px}
  @media(min-width:760px){.cust-grid{grid-template-columns:1fr 1fr}}
  @media(min-width:1100px){.cust-grid{grid-template-columns:1fr 1fr 1fr}}
  .cust{display:flex;align-items:center;flex-wrap:wrap;gap:12px 12px;padding:16px 16px;
    border-right:1px solid var(--line);border-bottom:1px solid var(--line);min-width:0}
  .cust .logo{width:38px;height:38px;flex:none;border:1px solid var(--line);
    display:flex;align-items:center;justify-content:center;overflow:hidden;background:var(--bg);
    font-family:var(--font-mono);font-size:var(--fs-base);color:var(--muted)}
  .cust .logo img{max-width:100%;max-height:100%;object-fit:contain}
  .cust .who{min-width:0;flex:1 1 120px}
  .cust .nm{font-size:var(--fs-body);color:var(--fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:7px}
  .cust .nm .dot{width:8px;height:8px;border-radius:50%;flex:none;border:1px solid var(--line)}
  .cust .ct{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
  .cust .ops{display:flex;gap:6px;flex:none;margin-left:auto}
  .cust .op{border:1px solid var(--btn-line);background:transparent;color:var(--fg);border-radius:var(--radius-sm);padding:6px 12px;cursor:pointer}
  .cust .op:hover{background:var(--band)}
  .cust .op.acc{border-color:var(--accent);color:var(--accent)}
  .d-empty{padding:24px;border:1px dashed var(--line);background:var(--card);
    font-size:var(--fs-base);color:var(--muted)}
  #custedit{display:none;margin-bottom:24px;padding:20px}
  #custedit .row{display:flex;gap:16px;flex-wrap:wrap;align-items:flex-end}
  #custedit label{display:block;color:var(--muted);margin-bottom:6px}
  #custedit input[type=text]{font:inherit;font-size:var(--fs-body);color:var(--fg);background:var(--input-bg);
    border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:12px 12px;min-width:220px}
  #custedit .cpresets{display:flex;gap:7px;align-items:center}
  /* square, for the same reason as .preset — same table, same law */
  #custedit .cp{width:22px;height:22px;border-radius:0;border:1px solid var(--btn-line);cursor:pointer;position:relative}
  #custedit .cp::after{content:'';position:absolute;left:0;right:0;bottom:-7px;height:3px;background:var(--fg);
    transform:scaleX(0);transform-origin:left center;transition:transform 140ms var(--e-pop);pointer-events:none}
  #custedit .cp.on::after{transform:scaleX(1)}
  .qt-wrap{border:0;border-radius:var(--radius-card);background:var(--card);box-shadow:var(--shadow-sm);overflow-x:auto;overflow-y:hidden}
  .qt td.qt-ops{white-space:normal}.qt td.qt-ops .codebtn{margin:2px 0 2px 2px}
  .qt{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
  .qt th{color:var(--muted);text-align:left;padding:12px 12px;background:var(--band);border-bottom:1px solid var(--line)}
  .qt td{padding:12px 12px;border-bottom:1px solid var(--line-soft,var(--line));color:var(--fg)}
  .qt tr:last-child td{border-bottom:0}
  .qt tbody tr:hover td{background:var(--band)}
  .qt .mono{font-family:var(--font-mono);font-size:var(--fs-fine)}
  .qt .r{text-align:right}
  .qt .earn{color:var(--fg);font-weight:var(--fw-med)}  /* an earnings figure is text; text wears text tokens */
  .qt .codebtn,.qbulk .codebtn{font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-caps);border:1px solid var(--btn-line);
    background:transparent;color:var(--fg);border-radius:var(--radius-sm);padding:4px 8px;cursor:pointer}
  .qt .codebtn:hover,.qbulk .codebtn:hover{background:var(--band)}
  @media(max-width:760px){.qt .hidesm{display:none}}
  .qftools{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:12px}
  .qfsearch{flex:1 1 200px;min-width:160px;font:inherit;font-size:var(--fs-base);padding:8px 12px;border:1px solid var(--line);
    border-radius:var(--radius-sm);background:var(--card);color:var(--fg)}
  .qfsearch::placeholder{color:var(--muted)}
  .qfsearch:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  .op:focus-visible,.codebtn:focus-visible,.qfchip:focus-visible,.qfclient button:focus-visible,.cust .op:focus-visible{outline:none;box-shadow:0 0 0 3px var(--ring)}
  .qfchips{display:flex;gap:4px;flex-wrap:wrap}
  .qfchip{color:var(--muted);background:transparent;border:1px solid var(--btn-line,var(--line));border-radius:var(--radius-sm);padding:6px 12px;cursor:pointer;transition:color var(--t-fast),border-color var(--t-fast),background var(--t-fast)}
  .qfchip:hover{color:var(--fg)}
  .qfchip.on{color:var(--accent-fg);background:var(--accent);border-color:var(--accent)}  /* tenant colour OUTSIDE the frame; inside a housing the firewall above resolves these to ink/paper */
  body:not(.dark) .qfchip.on{color:var(--accent-fg)}
  .qfclient{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--fg);background:var(--band);
    border:1px solid var(--line);border-radius:var(--radius-sm);padding:5px 6px 5px 12px;display:inline-flex;align-items:center;gap:8px}
  .qfclient button{border:0;background:transparent;color:var(--muted);cursor:pointer;font-size:var(--fs-base);line-height:var(--lh-flat);padding:2px 5px;border-radius:0}
  .qfclient button:hover{color:var(--fg);background:var(--line)}
  .qfsum{font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--muted);margin:-4px 0 12px}
  .qfsum b{color:var(--fg);font-weight:var(--fw-med)}
  /* ===================== PQB SKIN v2 — industrial: rails, joined grids, clean lines ===================== */
  body{max-width:1320px;padding:0 0 40px}
  body.onlogin{border-left:0;border-right:0;max-width:none;padding:0}
  .topbar{border-bottom:1px solid var(--line)}
  body:not(.repshell) .topbar{margin:0 -1px}   /* the seam joins the bordered client body; the borderless rep shell keeps margin 0 so the document is never wider than the viewport (P29-S02) */
  #app>#priceui,#portalview{padding:20px 24px 0}   /* WS15-C C3: the portal takes the quote page's gutter (it sits outside #app) */
  #app>.bar{padding:0 24px}
  /* [SOFT INSTRUMENT] the Clean Room flatness enforcer that lived here was deliberately removed — see the SOFT INSTRUMENT section at the end of the stylesheet */
  .qa{gap:12px;counter-reset:qa}
  .qa div{border:0;background:var(--card);padding:16px 16px 12px}
  .qa div:last-child{border-right:0}
  .qa div::before{counter-increment:qa;content:"0" counter(qa);display:block;font-family:var(--font-mono);color:var(--muted);margin-bottom:6px;max-height:14px;transition:opacity var(--t-med) ease,max-height var(--t-med) ease,margin var(--t-med) ease;overflow:hidden}
  .qa.min div::before{opacity:0;max-height:0;margin:0}
  .qa div:hover{transform:none;box-shadow:none;border-color:var(--line)}
  .tt,.bar button,.controls button,.bbtn,.saved button,.markupbar .mbtn,.wbtn{border-radius:var(--radius-btn)}
  .controls input[type=text],.controls select,.chdr input,.markupbar .mksel,.markupbar .mknum,
  .bfield input[type=text],.crow input[type=text],.pin,.qin{border-radius:var(--radius-input)}
  .tt:hover,.bar button:hover,.controls button:hover,.bbtn:hover,.saved button:hover,.markupbar .mbtn:hover{transform:none;box-shadow:none;background:var(--band)}
  .topactions .primary,#savebtn{border-radius:var(--radius-btn)}
  #savebtn:hover{background:var(--accent-h);border-color:var(--accent-h)}
  .wbtn:hover{transform:none}
  /* ===================== LOGIN PAGE — split industrial ===================== */
  body.onlogin .gate{display:grid !important;grid-template-columns:minmax(440px,46%) 1fr;grid-auto-rows:min-content;
    align-content:center;justify-items:start;text-align:left;
    position:fixed;inset:0;max-width:1440px;margin:0 auto;padding:0 0 0 clamp(32px,6vw,80px);
    border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);
    border-radius:0;background:var(--bg);box-shadow:none;overflow:hidden;animation:none}
  body.onlogin .gate > *{grid-column:1;width:100%;max-width:400px}
  /* v11 (Oscar): "drop the background", "no dots anywhere". The gate's cell-grid instrument
     is the motif the rep login just lost; it goes the same way. Plain ground on both. */
  .codewrap{position:relative}
  /* v11: group-level corner brackets removed — each cell wears only its own edge,
     and #codehl (.code .hl) is the single active-cell bracket frame. */
  /* THE ONE SIZE OFF THE RAMP, on purpose: this is the watermark GLYPH, a graphic drawn with a
     font at 3-6x the top step. Ramp steps up there would be tokens for a single caller. */
  body.onlogin .gate::after{content:'pqb';position:absolute;right:4%;bottom:-2%;z-index:0;
    font-family:var(--font-sans,inherit);font-weight:var(--fw-med);font-size:clamp(160px,24vw,340px);line-height:var(--lh-flat);
    letter-spacing:var(--tr-tighter);color:rgba(127,127,134,.16);color:color-mix(in srgb,var(--fg) 7%,transparent);pointer-events:none}
  /* v11: gate ground dots removed — clean paper; the right-panel cell grid is the only texture. */
  .gate-wm .mk{width:15px;height:15px;color:var(--accent);display:inline-block;margin-right:12px;transform:translateY(1px)}
  body.whitelabel .gate-wm{display:none}
  body.whitelabel .gate::after{display:none !important}
  body.whitelabel .rail-wm span{visibility:hidden}
  /* the identity that stands in for the hidden wordmark — same slot, same rhythm */
  .gate-id{margin-bottom:40px;line-height:var(--lh-tight)}
  .gate-id .gi-logo{max-height:38px;max-width:190px;object-fit:contain;display:block;margin-bottom:12px}
  .gate-id .gi-name{font-size:var(--fs-title);font-weight:var(--fw-med);letter-spacing:var(--tr-tight);color:var(--fg)}
  .gate-id .gi-sub{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted);margin-top:4px}
  .gate-trust{margin-top:20px;font-size:var(--fs-fine);line-height:var(--lh-text);color:var(--muted)}
  .gate-trust p{font-size:inherit;color:inherit;margin:0 0 5px}
  .gate-trust a{color:var(--fg);text-underline-offset:2px}
  body.onlogin .gate-id,body.onlogin .gate-trust{text-align:left}
  /* under 860 the split layout collapses and .gate centres itself; these two carry their own
     text-align, so without this they stayed flush left against a centred heading */
  @media(max-width:860px){
    body.onlogin .gate-id,body.onlogin .gate-trust{text-align:center}
    body.onlogin .gate-id .gi-logo{margin-left:auto;margin-right:auto}
  }
  .gate-wm{font-size:var(--fs-title);font-weight:var(--fw-med);letter-spacing:var(--tr-tight);color:var(--fg);margin-bottom:40px;line-height:var(--lh-flat)}
  .gate-wm span{display:block;font-family:var(--font-sans);font-size:var(--fs-tick);letter-spacing:0;text-transform:none;color:var(--muted);margin-top:3px}
  body.onlogin .gate h2{font-size:var(--fs-kpi);letter-spacing:var(--tr-snug);margin:0 0 8px}
  body.onlogin .gate p{margin:0 0 24px}
  body.onlogin .code{margin-left:0;justify-content:flex-start;max-width:400px}
  body.onlogin .gate button#codego{max-width:400px;margin:0;border-radius:0;background:var(--accent);color:var(--accent-fg)}
  /* paste-code field: match the boxes/ENTER column (flush-left 400px) in the split login layout */
  body.onlogin .gate.altcode input.codehidden{max-width:400px;margin-left:0;margin-right:0;text-align:left}
  body.onlogin .linkbtn{margin-left:0 !important;padding-left:0 !important;text-align:left}
  body.onlogin .gatetheme{position:fixed;top:clamp(24px,4vh,40px);right:clamp(24px,3vw,44px);z-index:5;
    width:auto !important;max-width:none !important;
    margin:0 !important;border-radius:var(--radius-btn) !important;animation:none !important}
  body.onlogin .gateerr{text-align:left}
  @media(max-width:860px){
    body.onlogin .gate{grid-template-columns:1fr;padding:0 24px;justify-items:center;text-align:center}
    body.onlogin .gate::after{display:none}
    body.onlogin .gate > *{justify-self:center}
    body.onlogin .linkbtn,body.onlogin .gateerr{text-align:center}
    body.onlogin .code{justify-content:center}
  }
  @media print{body{max-width:none}#app>#priceui,#app>.bpanel{padding:0;margin:0}}
  @media(max-width:1023px){body{padding:0 0 40px}}
  @media(max-width:767px){body{border-left:0;border-right:0}#app>#priceui,#portalview{padding:16px 16px 0}#dash{padding:0 16px}.bpanel{margin:16px 16px 0 !important}}

  /* ===================== ELEVATION — clean-room refinement ===================== */
  /* 1. v11: the dot field is gone from every view — the accent band over the data screens went with it */
  body:not(.onlogin):not(.matrix){background-image:none}
  #dash,#priceui{position:relative}
  #dash>*,#priceui>*{position:relative;z-index:1}
  .title{font-size:var(--fs-title);letter-spacing:var(--tr-tight)}
  .d-kpis{border:0;background:transparent;overflow:visible}
  .d-kpi{padding:20px 20px 20px;position:relative}
  .d-kpi .l{font-size:var(--fs-micro);letter-spacing:var(--tr-caps-wide)}
  .d-kpi .v{font-size:var(--fs-band);letter-spacing:var(--tr-tighter);margin-top:12px;line-height:var(--lh-flat);font-weight:var(--fw-med)}
  @media(min-width:1160px){.d-kpi .v{font-size:var(--fs-kpi);letter-spacing:var(--tr-tighter)}}  /* 6-up strip: keep fmt$ from overflowing */
  .d-kpi .v.earn{color:var(--fg)}   /* INSTRUMENT BOUNDARY — see the base rule above */
  .d-btn.acc{box-shadow:none}
  .d-btn.acc:hover{filter:brightness(1.08)}
  .d-sec-head .t{font-size:var(--fs-lead);letter-spacing:var(--tr-tight);text-transform:none;font-family:var(--font-sans);font-weight:var(--fw-med);color:var(--fg)}
  .d-sec-head{border-bottom:1px solid var(--line);padding-bottom:var(--s3)}
  tr.sec td{font-size:var(--fs-micro);letter-spacing:var(--tr-caps-wide)}
  tr.totrow td{padding:16px 12px}
  tr.totrow .totsum span{font-size:var(--fs-title);letter-spacing:var(--tr-tighter)}
  td.price.hi{font-weight:var(--fw-med)}
  .qa{border-radius:var(--radius-sm);box-shadow:none}
  .qa div::before{font-size:var(--fs-micro);letter-spacing:var(--tr-caps-wide)}
  .qa b{font-size:var(--fs-body);letter-spacing:var(--tr-snug)}
  .topbar{padding:16px 24px}
  .subtitle{letter-spacing:var(--tr-caps-wide)}
  @keyframes kpiUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
  .d-kpi .v{animation:kpiUp .5s var(--e-exit) both}
  .d-kpi:nth-child(1) .v{animation-delay:.02s}.d-kpi:nth-child(2) .v{animation-delay:.08s}
  .d-kpi:nth-child(3) .v{animation-delay:.14s}.d-kpi:nth-child(4) .v{animation-delay:.20s}.d-kpi:nth-child(5) .v{animation-delay:.26s}.d-kpi:nth-child(6) .v{animation-delay:.32s}
  @media (prefers-reduced-motion:reduce){.d-kpi .v{animation:none}}
  @media(max-width:767px){.d-kpi .v{font-size:var(--fs-kpi)}}
  /* ===================== REP SHELL — left rail + command palette (additive) ===================== */
  /* --rail-w / --rail-min are OWNED BY assets/fam.v3.css (232px / 48px). These were a second,
     disagreeing declaration -- 236 and 64 -- that lost silently to the external sheet, so the
     numbers written here had not described the running layout for some time. Fallbacks only. */
  :root{--rail-w:200px;--rail-min:48px}
  /* rail is fixed; shown only for rep-authenticated views via body.repshell */
  .rail{position:fixed;left:0;top:0;bottom:0;width:var(--rail-w);z-index:60;display:none;
    flex-direction:column;background:var(--bg);border-right:1px solid var(--line);transition:width var(--t-med) var(--e-out)}
  @media (prefers-reduced-motion:reduce){.rail{transition:none}}
  body.repshell .rail{display:flex}
  body.repshell{max-width:none;margin:0;padding-left:var(--rail-w);border-left:0;border-right:0;transition:padding-left var(--t-med) var(--e-out)}
  body.repshell #theme{display:inline-grid;place-items:center}
  @media(min-width:768px){body.repshell #dashback{display:none !important}}
  body.repshell.matrix{padding-left:0}
  body.repshell.matrix .rail{display:none}
  .rail-top{display:flex;align-items:center;justify-content:space-between;height:58px;padding:0 20px;border-bottom:1px solid var(--line);flex:none}
  .rail-wm{font-size:var(--fs-title);font-weight:var(--fw-med);letter-spacing:var(--tr-tighter);display:flex;align-items:baseline;gap:7px;color:var(--fg)}
  .rail-wm .mk{width:12px;height:12px;color:var(--accent);flex:none;transform:translateY(1px)}
  .rail-collapse{width:26px;height:26px;display:grid;place-items:center;color:var(--muted);border:1px solid transparent;border-radius:var(--radius-sm);cursor:pointer;background:none}
  .rail-collapse:hover{color:var(--fg);border-color:var(--line)}
  .rail-collapse svg{width:14px;height:14px;transition:transform var(--t-med) var(--e-out)}
  .rail-nav{flex:1;overflow-y:auto;overflow-x:hidden;padding:12px 0}
  .rail-item{display:flex;align-items:center;gap:12px;padding:12px 20px;text-align:left;
    background:none;border:0;color:var(--muted);cursor:pointer;position:relative;font-family:var(--font-sans);
    font-size:var(--fs-fine);letter-spacing:0;text-transform:none;transition:color var(--t-fast) ease,background var(--t-fast) ease}
  .rail-item .ix{font-size:var(--fs-micro);color:var(--muted);min-width:16px;transition:color var(--t-fast) ease;display:flex;align-items:center}
  .rail-item .ix svg{width:16px;height:16px;display:block}
  .rail-item .lbl{white-space:nowrap}
  /* No opacity rule here: the collapsed state sets display:none on .lbl further down, which wins
     outright, so an opacity transition beside it never plays and only reads as if it does. */
  .rail-item:hover{color:var(--fg);background:var(--band)}
  body.view-customers #d-kpis,body.view-customers #followup,body.view-customers #analytics,
  body.view-customers #sec-quotes,body.view-customers #adminsec,body.view-customers #teamsec,body.view-customers .onb{display:none !important}
  body.view-pipeline #d-kpis,body.view-pipeline #followup,body.view-pipeline #analytics,
  body.view-pipeline #sec-quotes,body.view-pipeline #adminsec,body.view-pipeline #teamsec,body.view-pipeline .onb,
  body.view-pipeline #sec-customers,body.view-pipeline #custedit{display:none !important}
  body.view-approvals #d-kpis,body.view-approvals #followup,body.view-approvals #analytics,
  body.view-approvals #sec-quotes,body.view-approvals #sec-customers,body.view-approvals #custedit,body.view-approvals #teamsec,body.view-approvals .onb{display:none !important}
  body.view-team #d-kpis,body.view-team #followup,body.view-team #analytics,body.view-team #sec-quotes,
  body.view-team #sec-customers,body.view-team #custedit,body.view-team #adminsec,body.view-team .onb,body.view-team #pending-banner{display:none !important}
  body:not(.view-pipeline) #sec-pipeline,
  body:not(.view-customers):not(.view-approvals) #sec-customers,
  body:not(.view-customers):not(.view-approvals) #custedit,
  body:not(.view-customers):not(.view-approvals) #adminsec{display:none !important}

  /* ---- Orders (feat/orders): the lifecycle a reseller can watch. Substrate only — every value here is an
     existing token. Chips reuse --ok / --held / --danger; there is no amber and no seventh state colour. ---- */
  body.view-orders #d-kpis,body.view-orders #followup,body.view-orders #analytics,body.view-orders #sec-quotes,
  body.view-orders #sec-customers,body.view-orders #custedit,body.view-orders #adminsec,body.view-orders #teamsec,
  body.view-orders #sec-pipeline,body.view-orders .onb,body.view-orders #pending-banner{display:none !important}
  body:not(.view-orders) #sec-orders{display:none !important}
  body.view-orders #sec-orders{display:block !important}
  body.view-orders #sec-orders>.d-sec-head>.t{display:none}
  .ord-t{width:100%;border-collapse:collapse;font-size:var(--fs-base)}
  .ord-t th{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;
            color:var(--muted);font-weight:var(--fw-med);text-align:left;padding:0 12px 8px;border-bottom:1px solid var(--line);white-space:nowrap}
  .ord-t td{border-bottom:1px solid var(--line);padding:0;height:38px;vertical-align:middle}
  .ord-t tbody tr:hover td{background:var(--bg)}
  .ord-t td>.cell{display:flex;align-items:center;height:38px;padding:0 12px;width:100%;box-sizing:border-box}
  /* the row target is the full height of the cell, not the text inside it */
  .ord-t td>button.cell{background:none;border:0;font:inherit;color:inherit;text-align:left;cursor:pointer}
  .ord-t td>button.cell:focus-visible{outline:2px solid var(--accent,currentColor);outline-offset:-2px}
  @media (pointer:coarse){.ord-t td{height:44px}.ord-t td>.cell{height:44px}}
  .ord-code{font-family:var(--font-mono);font-size:var(--fs-fine)}
  .ord-trk{font-family:var(--font-mono);font-size:var(--fs-fine);color:var(--muted)}
  .ord-dash{color:var(--muted)}
  /* the four lifecycle steps, greyscale-legible: the word carries the state, the tint only accelerates */
  .ord-chip{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-sans);
            font-size:var(--fs-micro);letter-spacing:0;text-transform:none;padding:3px 7px;border-radius:4px;
            border:1px solid var(--line);color:var(--muted);white-space:nowrap}
  .ord-chip.is-accepted{color:var(--txt,inherit)}
  .ord-chip.is-submitted{color:var(--held);background:var(--held-bg);border-color:var(--held-bd)}
  .ord-chip.is-production{color:var(--ok);border-color:var(--ok);border-color:color-mix(in srgb,var(--ok) 38%,transparent)}
  .ord-chip.is-shipped{color:var(--ok);background:var(--c-good-bg);background:color-mix(in srgb,var(--ok) 10%,transparent);
                       border-color:var(--ok);border-color:color-mix(in srgb,var(--ok) 38%,transparent);font-weight:var(--fw-med)}
  .ord-chip.is-stuck{color:var(--danger);background:var(--danger-bg);border-color:var(--danger-bd)}
  /* expand-in-place: the lightest of the four idioms, so a detail never costs a navigation */
  .ord-det td{padding:0;border-bottom:1px solid var(--line);background:var(--bg)}
  .ord-det .in{padding:16px 12px;display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:16px}
  .ord-det dt{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:var(--tr-caps);
              text-transform:none;color:var(--muted);margin:0 0 3px}
  .ord-det dd{margin:0;font-size:var(--fs-base)}
  .ord-note{grid-column:1/-1;font-size:var(--fs-fine);color:var(--muted);line-height:1.5}
  .ord-state{padding:20px 12px;font-size:var(--fs-base);color:var(--muted);line-height:1.6}
  .ord-state b{color:var(--txt,inherit);font-weight:var(--fw-med)}
  .ord-skel{height:38px;border-bottom:1px solid var(--line);background:linear-gradient(90deg,var(--bg),var(--card),var(--bg));
            background-size:200% 100%;animation:ordsk 1.2s linear infinite}
  @keyframes ordsk{0%{background-position:200% 0}100%{background-position:-200% 0}}
  @media (prefers-reduced-motion:reduce){.ord-skel{animation:none}}
  body:not(.view-team) #teamsec{display:none !important}
  body.view-team #teamsec{display:block !important}
  body:not(.view-leaderboard) #leaderboardsec{display:none !important}
  body.view-leaderboard #leaderboardsec{display:block !important}
  body.view-leaderboard #pending-banner,body.view-leaderboard .onb{display:none !important}
  body.view-updates #d-kpis,body.view-updates #followup,body.view-updates #analytics,body.view-updates #sec-quotes,body.view-updates #sec-customers,body.view-updates #custedit,body.view-updates #adminsec,body.view-updates #teamsec,body.view-updates .onb,body.view-updates #pending-banner{display:none !important}
  body:not(.view-updates) #updatessec{display:none !important}
  body.view-updates #updatessec{display:block !important}
  body.view-customers #sec-customers .d-sec-head,body.view-approvals #adminsec .d-sec-head{margin-top:6px}
  body.view-customers #pending-banner,body.view-approvals #pending-banner{display:none !important}
  /* ---- admin registers (docs: "Super admin view needs help"): five unrelated registers used to stack in
     one column, so finding anything meant scrolling past four you did not want. One findable surface each,
     each carrying the count that would make a super admin open it. ---- */
  .asubs{display:flex;flex-wrap:wrap;margin:0 0 20px;border:1px solid var(--line);background:var(--card)}
  .asub{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 16px;border:0;border-right:1px solid var(--line);border-radius:0;background:transparent;color:var(--muted);cursor:pointer;transition:color var(--t-fast),background var(--t-fast)}
  .asub:last-child{border-right:0}
  .asub:hover{color:var(--fg);background:var(--band)}
  .asub.on{color:var(--fg);background:var(--band);box-shadow:inset 0 -2px 0 var(--fg)}
  .asub:focus-visible{outline:none;box-shadow:0 0 0 3px var(--ring)}
  .asub-n{min-width:20px;padding:1px 6px;border:1px solid var(--line);font-weight:var(--fw-semi);color:var(--fg);text-align:center}
  .asub-n:empty{display:none}
  #adminsec .apane{display:none}
  #adminsec .apane.on{display:block}
  /* Every consequential admin control clears the house 40 px target (fam.v3.css:49). Approve and Reject
     used to sit six pixels apart on a 13 px row, separated by a space character. */
  #adminsec button.codebtn,#adminsec .d-btn{min-height:40px;display:inline-flex;align-items:center;justify-content:center;padding:4px 12px}
  #adminsec select.codebtn{min-height:40px}
  .rowacts{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end}
  @media(max-width:720px){.asubs{flex-direction:column}.asub{border-right:0;border-bottom:1px solid var(--line);justify-content:space-between}.asub:last-child{border-bottom:0}}
  .tl-bar{display:inline-block;width:54px;height:3px;border-radius:0;background:var(--line);margin-left:8px;vertical-align:middle;overflow:hidden}
  .tl-bar>i{display:block;height:100%;background:var(--ok);border-radius:0}
  .tl-att{font-family:var(--font-mono);font-size:var(--fs-fine);color:var(--held);font-weight:var(--fw-semi)}
  .tm-mix{display:flex;flex-direction:column;gap:8px}
  .tm-mix-row{display:flex;align-items:center;gap:12px}
  .tm-mix-l{color:var(--muted);width:130px;flex:none}
  .tm-mix-bar{flex:1;height:6px;border-radius:0;background:var(--line);overflow:hidden}
  .tm-mix-bar>i{display:block;height:100%;background:var(--fg);border-radius:0}  /* a bar is data, not chrome */
  .tm-mix-n{width:40px;text-align:right;flex:none;color:var(--fg)}
  .pending-banner{display:flex;align-items:center;gap:12px;margin:0 0 16px;padding:12px 16px;border-radius:var(--radius-card);cursor:pointer;font-size:var(--fs-body);color:var(--fg);transition:filter var(--t-fast);
    background:rgba(127,127,134,.1);background:color-mix(in srgb,var(--pord-fg) 12%,var(--card));
    border:1px solid rgba(127,127,134,.3);border:1px solid color-mix(in srgb,var(--pord-fg) 40%,transparent)}
  .pending-banner:hover{filter:brightness(.98)}
  .pending-banner .pb-warn{color:var(--pord-fg);font-size:var(--fs-body)}
  .pending-banner .pb-go{margin-left:auto;font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-flat);color:var(--accent);white-space:nowrap}
  .npop-row.pendrow{cursor:pointer;background:rgba(127,127,134,.06);background:color-mix(in srgb,var(--pord-fg) 8%,transparent)}
  .npop-row.pendrow .x{color:var(--fg)}
  .invbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:4px 0 16px}
  .invbar input{font:inherit;font-size:var(--fs-base);padding:8px 12px;border:1px solid var(--btn-line);border-radius:var(--radius-sm);background:var(--input-bg,var(--card));color:var(--fg);min-width:200px}
  .invbar input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  .invbar #inv-status{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted)}
  .rail-item.on .ix{color:var(--fg)}   /* the icon follows the label, not the accent (see .rail-item.on) */
  .rail-item:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--ring)}
  .tt:active,.d-btn:active,.codebtn:active,.bbtn:active,.wbtn:active,.mbtn:active,.qfchip:active,.rail-item:active{transform:translateY(1px)}
  .rail-sep{height:1px;background:var(--line);margin:12px 20px}
  .rail-glabel{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted);padding:2px 20px 6px}
  .rail-admin{display:none}
  body.role-super .rail-admin{display:block}   /* WS17-S2: the operator rail group (Team overview, Rep approvals, Catalog, Updates) is the platform owner's */
  .only-super{display:none!important}
  body.role-super .only-super{display:flex!important}
  .only-adm{display:none!important}
  body.role-admin .only-adm,body.role-super .only-adm{display:block!important}
  #ce-prices{margin-top:16px;padding:16px 16px;border:1px solid var(--card-line);border-radius:var(--radius-sm);background:var(--card)}
  #ce-prices .ce-prices-head{display:flex;align-items:center;gap:12px;margin-bottom:12px}
  #ce-prices .ce-prices-head .t{color:var(--fg)}
  #ce-prices .ce-prices-st{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);margin-left:auto}
  #ce-prices .ce-prices-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
  .ce-notes{margin-top:16px}
  .ce-notes-lbl{display:block;color:var(--muted);margin-bottom:6px}
  .ce-notes-hint{text-transform:none;letter-spacing:var(--tr-flat)}
  #ce-notes{width:100%;font:inherit;font-size:var(--fs-body);padding:12px 12px;border:1px solid var(--btn-line);border-radius:var(--radius-sm);background:var(--input-bg,var(--card));color:var(--fg);resize:vertical;line-height:var(--lh-ui)}
  #ce-notes:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--ring)}
  .ce-notes-st{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);margin-top:4px;display:inline-block}
  .cust-note{color:var(--muted);border:1px solid var(--line);border-radius:0;padding:1px 6px;margin-left:8px;white-space:nowrap;cursor:help}
  .qbulk{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:12px 0 4px;padding:12px 16px;border:1px solid var(--accent);border-radius:var(--radius-sm);background:var(--band)}
  .qb-n{font-family:var(--font-mono);font-size:var(--fs-fine);letter-spacing:var(--tr-flat);color:var(--fg);margin-right:auto}
  .qb-th,.qb-td{width:34px;text-align:center}
  .qbsel,#qbulk-all{cursor:pointer;accent-color:var(--accent)}
  .ce-uplabel{cursor:pointer;display:inline-flex;align-items:center}
  .inv-chip{font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted);display:inline-flex;align-items:center;gap:6px}
  .inv-chip .inv-x{cursor:pointer;color:var(--muted);font-size:var(--fs-base);line-height:var(--lh-flat);padding:0 2px}
  .inv-chip .inv-x:hover{color:var(--fg)}
  .only-super-i{display:none!important}
  body.role-super .only-super-i{display:inline-block!important}
  .rail-foot{border-top:1px solid var(--line);flex:none}
  .tacc{display:none;background:var(--card);border-radius:var(--radius-sm);box-shadow:var(--shadow-sm);margin:0 0 12px}
  .tacc summary{list-style:none;display:flex;align-items:center;gap:12px;padding:12px 16px;cursor:pointer;color:var(--fg);-webkit-user-select:none;user-select:none}
  .tacc summary::-webkit-details-marker{display:none}
  .tacc summary .st{color:var(--muted);margin-left:auto;letter-spacing:var(--tr-caps)}
  .tacc summary .chev{width:11px;height:11px;flex:none;color:var(--muted);transition:transform var(--t-med) ease}
  .tacc[open] summary .chev{transform:rotate(90deg)}
  .tacc summary:hover{background:var(--band);border-radius:var(--radius-sm)}
  .tacc>div{display:flex !important;background:transparent !important;box-shadow:none !important;border:0 !important;margin:0 !important;border-top:1px solid var(--line) !important;border-radius:0 !important}
  .tacc>div>.mlabel{display:none}
  @media print{.tacc{display:none !important}}
  /* guarantee cards stay on the web view but are omitted from the printed/PDF quote */
  @media print{.qa{display:none !important}}
  .rail-new{display:flex;align-items:center;gap:12px;width:100%;padding:16px 20px;background:none;border:0;
    border-bottom:1px solid var(--line);color:var(--accent);cursor:pointer;font-family:var(--font-sans);
    font-size:var(--fs-fine);letter-spacing:0;text-transform:none;transition:background var(--t-fast) ease,color var(--t-fast) ease}
  .rail-new .plus{min-width:16px;display:flex;align-items:center}
  .rail-new .plus svg{width:15px;height:15px;display:block}
  .rail-new:hover{background:var(--band)}
  .rail-new:not(.ghost):hover{color:var(--fg)}
  .rail-acct{display:flex;align-items:center;gap:12px;width:100%;padding:12px 20px;background:none;border:0;cursor:pointer;text-align:left;transition:background var(--t-fast) ease}
  .rail-acct:hover{background:var(--band)}
  .rail-new.ghost{color:var(--muted)}
  .rail-new.ghost:hover{color:var(--fg)}
  .rail-acct .ini{width:28px;height:28px;border:1px solid var(--line);display:grid;place-items:center;font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--fg);flex:none}
  .rail-acct .who{min-width:0;font-family:var(--font-mono);font-size:var(--fs-micro);letter-spacing:var(--tr-flat);color:var(--muted);line-height:var(--lh-ui);overflow:hidden}
  .rail-acct .who b{display:block;color:var(--fg);font-weight:var(--fw-med);font-size:var(--fs-fine);text-transform:none;letter-spacing:var(--tr-flat);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .rail-acct .who span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}

  body.railmin{padding-left:var(--rail-min)}
  body.railmin .rail{width:var(--rail-min)}
  body.railmin .rail-item{justify-content:center;padding:12px 0;gap:0}
  body.railmin .rail-item .lbl,
  body.railmin .rail-glabel,
  body.railmin .rail-new .lbl,
  body.railmin .rail-acct .who,
  body.railmin .rail-wm{display:none}
  body.railmin .rail-item .ix{min-width:0}
  body.railmin .rail-new,body.railmin .rail-acct{justify-content:center;padding-left:0;padding-right:0}
  body.railmin .rail-top{justify-content:center;padding:0}
  body.railmin .rail-top{flex-direction:column;gap:12px}
  body.railmin .rail-collapse{display:grid}
  body.railmin .rail-collapse svg{transform:rotate(180deg)}

  .rail-burger{display:none}
  body:not(.repshell) #tb-find{display:none}

  .cmdk{position:fixed;inset:0;z-index:300;display:none;align-items:flex-start;justify-content:center;padding-top:12vh;background:rgba(0,0,0,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
  .cmdk.open{display:flex}
  .cmdk-panel{width:min(600px,92vw);background:var(--bg);border:1px solid var(--line);overflow:hidden}
  .cmdk-in{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line)}
  .cmdk-in svg{width:17px;height:17px;color:var(--muted);flex:none}
  .cmdk-in input{flex:1;border:0;background:none;color:var(--fg);font-family:var(--font-sans);font-size:var(--fs-body)}
  .cmdk-in input:focus{outline:none}
  .cmdk-in input::placeholder{color:var(--muted)}
  .cmdk-in kbd{font-family:var(--font-mono);font-size:var(--fs-micro);border:1px solid var(--btn-line);border-radius:var(--radius-sm);padding:2px 6px;color:var(--muted)}
  .cmdk-list{max-height:52vh;overflow-y:auto;padding:6px 0}
  .cmdk-sec{font-family:var(--font-sans);font-size:var(--fs-micro);letter-spacing:0;text-transform:none;color:var(--muted);padding:12px 20px 5px}
  .cmdk-row{display:flex;align-items:center;gap:12px;width:100%;padding:12px 20px;text-align:left;background:none;border:0;color:var(--fg);cursor:pointer;font-size:var(--fs-body)}
  .cmdk-row .kind{color:var(--muted);min-width:72px}
  .cmdk-row .go{margin-left:auto;font-family:var(--font-mono);font-size:var(--fs-micro);color:var(--muted)}
  .cmdk-row .code{font-family:var(--font-mono)}
  .cmdk-row.sel,.cmdk-row:hover{background:var(--band)}
  .cmdk-empty{padding:24px 20px;font-family:var(--font-mono);font-size:var(--fs-fine);color:var(--muted)}

  .rail-scrim{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:55;display:none}
  @media(max-width:1023px){
    body.repshell{padding-left:var(--rail-min)}
    body.repshell:not(.drawer) .rail{width:var(--rail-min)}
    body.repshell:not(.drawer) .rail-item{justify-content:center;padding:12px 0;gap:0}
    body.repshell:not(.drawer) .rail-item .lbl,
    body.repshell:not(.drawer) .rail-glabel,
    body.repshell:not(.drawer) .rail-new .lbl,
    body.repshell:not(.drawer) .rail-acct .who,
    body.repshell:not(.drawer) .rail-wm span{display:none}
    body.repshell:not(.drawer) .rail-item .ix{min-width:0}
    body.repshell:not(.drawer) .rail-new,
    body.repshell:not(.drawer) .rail-acct{justify-content:center;padding-left:0;padding-right:0}
    body.repshell:not(.drawer) .rail-top{justify-content:center;padding:0}
    body.repshell:not(.drawer) .rail-collapse{display:none}
  }
  @media(max-width:720px){
    body.repshell{padding-left:0}
    body.repshell .rail-burger{display:inline-grid;place-items:center;width:40px;height:40px;flex:none;border:1px solid var(--btn-line);border-radius:var(--radius-sm);background:var(--btn-bg);color:var(--fg);cursor:pointer}   /* a 40 × 40 touch box that never shrinks (P29-B02) */
    .rail-burger svg{width:16px;height:16px}
    body.repshell .rail{transform:translateX(-100%);width:var(--rail-w);transition:transform var(--t-med) ease}
    body.drawer .rail{transform:none}
    body.drawer .rail-scrim{display:block}
      body.repshell .rail-item{justify-content:flex-start;padding:12px 20px;gap:12px}
    body.repshell .rail-item .lbl,
    body.repshell .rail-glabel,
    body.repshell .rail-new .lbl,
    body.repshell .rail-acct .who,
    body.repshell .rail-wm span{display:revert}
    body.repshell .rail-new,body.repshell .rail-acct{justify-content:flex-start;padding-left:20px;padding-right:20px}
    body.repshell .rail-top{justify-content:space-between;padding:0 20px}
  }
  @media print{.rail,.cmdk,.rail-scrim{display:none !important}body.repshell{padding-left:0}}

  /* ===== paper-document hardening — MUST STAY LAST IN THE STYLESHEET =====
     .prdoc renders a printed artifact (quote proposal / invoice), so it must not
     inherit the app's theme or table layout. Bare `table`/`th`/`td` selectors
     elsewhere in this stylesheet repaint it otherwise: in DARK theme the header
     took --hbg (a black band) and cells went grey-on-white, and the legacy
     @media print rules force `font-size:var(--fs-micro)` + `padding:5px 6px !important`.
     These declarations pin the light paper palette in every medium, so the
     on-screen preview and the printed PDF are the same document. */
  .prdoc .pr-tbl{border-collapse:collapse;width:100%;font-size:var(--fs-base);background:transparent}
  .prdoc .pr-tbl tr{background:transparent !important}
  .prdoc .pr-tbl th{background:transparent !important;color:#777 !important;border:0 !important;
    border-bottom:1px solid #ccc !important;position:static !important;text-align:left;font-weight:var(--fw-semi);
    padding:0 12px 8px !important;white-space:nowrap !important;letter-spacing:var(--tr-caps);font-size:var(--fs-micro)}
  .prdoc .pr-tbl td{background:transparent !important;color:#111114 !important;border:0 !important;
    border-bottom:1px solid #ededed !important;padding:12px 12px !important;white-space:normal !important;
    text-align:left;font-size:var(--fs-base)}
  .prdoc .pr-tbl .r{text-align:right !important}
  .prdoc .pr-tbl tfoot td{border-top:2px solid #111114 !important;border-bottom:0 !important;
    font-weight:var(--fw-bold);font-size:var(--fs-base);padding-top:12px !important}
  /* Narrow screens: tighten the document's own type scale rather than card-stacking it —
     an invoice must stay recognisable as a document. Five columns at the desktop scale
     overflow a 390px viewport by ~26px; this fits them. Screen only (print is Letter). */
  @media screen and (max-width:600px){
    .prdoc .pr-tbl th{padding:0 6px 7px !important;white-space:normal !important;font-size:var(--fs-micro);letter-spacing:var(--tr-caps)}
    .prdoc .pr-tbl td{padding:8px 6px !important;font-size:var(--fs-fine)}
    .prdoc .pr-tbl tfoot td{font-size:var(--fs-fine);padding-top:12px !important}
    .prdoc .pr-head{gap:12px}
    .prdoc .pr-brand{font-size:var(--fs-body)}
    .prdoc .pr-meta{gap:12px 20px}
    .prdoc .pr-parties{flex-wrap:wrap;gap:16px 24px}
    .prdoc .pr-parties>div{flex:1 1 40%}
    #dv-doc{overflow-x:auto}   /* safety net for very long product names */
  }

/* ---- WS15-C C1 (visual cohesion, ~/Projects/reports/ws15c-plan.md): measured drift, fixed on the declared system ----
   · the type system has two weights (400 / 500): a bare <b> / <strong> rendered the browser's 700 (Settings' payment note,
     the Team pricing product names) — they take the system's bold (--fw-bold, 500) like every styled emphasis already does.
   · Settings' "Upload logo" is a <label class="bbtn"> inside a .bfield, so it took the FIELD LABEL's 12px / muted look and a
     43px box beside 46px buttons — it is a button: the button type, colour and box. */
b,strong{font-weight:var(--fw-bold)}
.bfield label.bbtn{display:inline-flex;align-items:center;margin:0;font-size:var(--fs-base);font-weight:var(--fw-med);color:var(--btn-fg)}
