/* ============================================================================
   NovaSolo Business OS — design system.
   Monochrome, sharp corners, Nunito Sans, uppercase letter-spaced labels.
   Aligned to novasolo.com: pure black on white, radius 0, letter-spaced grotesk.

   P0 (2026-09-09): lifted out of the base.html <style> block so there is ONE
   token contract every stylesheet answers to. Before this, production.css and
   tracker.css were written against a DIFFERENT vocabulary (--foreground,
   --card, --border, --muted-foreground: the shadcn/Tailwind names) that this
   file never defined — two of those were live dead declarations. The NovaSolo
   names below are now the only ones. If you need a token, add it HERE; never
   re-declare a palette value inside a component or a page stylesheet.

   Load order: os.css, then the page stylesheet (production.css / tracker.css).
   ========================================================================= */
:root {
  /* --- surface + ink ------------------------------------------------- */
  --bg: #ffffff;
  --panel: #f6f6f4;
  --ink: #0a0a0a;
  --ink-2: #2b2b2b;
  --muted: #6d6d6a;          /* ~4.9:1 on white */
  --line: #e6e6e2;
  --field: #ffffff;

  /* --- quiet status tints -------------------------------------------- */
  --ok-bg: #e8f0e9;   --ok-ink: #2c5738;
  --info-bg: #eaeef2; --info-ink: #34485c;
  --warn-bg: #f6eddb; --warn-ink: #855012;
  --stop-bg: #f4e9e6; --stop-ink: #8a382c;
  --neutral-bg: #ededea; --neutral-ink: #52524e;

  /* --- shape + motion ------------------------------------------------ */
  --radius: 0px;             /* the system is square. Do not hard-code a radius. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --font: "Nunito Sans", -apple-system, system-ui, "Segoe UI", Arial, sans-serif;
  --topbar-h: 3.3rem;        /* fixed top bar height (full-bleed pages rely on it) */

  /* --- space scale (P0) ---------------------------------------------- */
  /* 4px steps. Use these instead of inventing .32rem / .34rem / .38rem. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px;

  /* --- touch + control sizing (P1) ------------------------------------ */
  --tap: 44px;               /* Apple HIG minimum. Every control on a phone. */
  --tap-sm: 36px;            /* compact desktop-only control (>= 900px) */
  --field-font: 16px;        /* iOS Safari force-zooms any input below 16px */
}

/* ---------------------------------------------------------------------------
   BREAKPOINTS — the OS has exactly three. Media queries cannot read custom
   properties, so these are literals; this comment is the contract.

 600px   sm   phone            single column, cards, 44px taps
 900px   md   tablet / nav     sidebar becomes the drawer
1240px   lg   wide             multi-pane layouts relax

   Anything else (the old 520 / 700 / 720 / 820 / 1000 / 1050 / 1099 / 1100 /
   1250 / 1400 set) is legacy and is being migrated tier by tier. Do NOT add a
   new width. Two components reflowing at 1099 and 1100 is how layouts end up
   half-collapsed in the gap.
   ------------------------------------------------------------------------ */
* { box-sizing: border-box; }
html { color-scheme: light; }
/* Soft-nav affordance: the page-state region dims while an htmx swap is in flight. */
#page-state { transition: opacity .12s ease; }
#page-state.soft-nav-loading { opacity: .45; pointer-events: none; }
/* Buyer Service full-bleed chat: the wrapper must stay in the flex height chain. */
main.full-bleed > #page-state { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
main.full-bleed > #page-state > .chat-wrap { flex: 1 1 auto; min-height: 0; }
body {
  font-family: var(--font); color: var(--ink); background: var(--bg);
  margin: 0; font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--ink); }

/* --- brand strip + header --- */
.topstrip {
  background: var(--ink); color: #fff; text-align: center;
  font-size: .62rem; font-weight: 800; letter-spacing: .28em;
  text-transform: uppercase; padding: .45rem 1rem;
}
/* ---------- App shell: fixed left sidebar + content column ---------- */
body { display: flex; min-height: 100vh; }
.sidebar {
  width: 15rem; flex: 0 0 15rem; background: var(--panel);
  border-right: 1px solid var(--line); position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden;
  transition: width .18s var(--ease), flex-basis .18s var(--ease); z-index: 50;
}
html.nav-compact .sidebar { width: 3.75rem; flex-basis: 3.75rem; }
.sidebar .brand { display: flex; align-items: center; gap: .5rem; padding: .95rem .85rem;
                  border-bottom: 1px solid var(--line); }
.wordmark { text-decoration: none; letter-spacing: .12em; font-size: 1rem; white-space: nowrap;
            flex: 1; min-width: 0; overflow: hidden; }
.wordmark b { font-weight: 900; }
.wordmark span { font-weight: 400; color: var(--muted); margin-left: .35rem; }
html.nav-compact .wordmark { display: none; }
/* P3: `.btn.btn--quiet.btn--sm.btn--icon` — only the shrink guard is local. */
.nav-toggle { flex-shrink: 0; }
.nav-toggle svg { width: 15px; height: 15px; }
html.nav-compact .nav-toggle svg { transform: rotate(180deg); }
.sidenav { padding: .5rem 0 1.2rem; flex: 1; }
.nav-group { margin-bottom: .1rem; }
.nav-group-label { font-size: .56rem; font-weight: 900; text-transform: uppercase;
                   letter-spacing: .13em; color: var(--muted); padding: .85rem .95rem .3rem; }
html.nav-compact .nav-group-label { display: none; }
/* --- chips (P5: one component) ----------------------------------------
   ONE status chip. Twenty systems collapsed here: .badge, .status,
   .severity, .sc-status, .st-pill, .p-chip, .p-person-chip, .p-ot-dot,
   .dot, .dot-badge, .filter-dot, .fc-filter-badge, .fc-status and the
   .badge.fc-* family, plus the tagfield token.

   The colour comes from ONE attribute, never from a class per domain word:
     .chip[data-state=ok|warn|stop|info|neutral]
   Templates map their own vocabulary with the `chip_state` Jinja filter
   (app/templating.py) — one table, not twenty stylesheet rules. Sales
   Control's five stock bands are DATA in exactly this way: same chip,
   different state value, no .sc-* classes.

   shapes  (default)      the filled label
           .chip--outline hairline + coloured text (a threshold, not a state)
           .chip--dot     the compact indicator, no text
           .chip--count   a numeric badge on another control
           .chip--mini    a superscript marker riding on a table cell
   ---------------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .15rem .5rem; border: 1px solid transparent; border-radius: var(--radius);
  font-size: .62rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .06em; white-space: nowrap; line-height: 1.35;
  background: var(--neutral-bg); color: var(--neutral-ink);
}
.chip b, .chip .n { font-variant-numeric: tabular-nums; font-weight: 800; opacity: .75; }

/* the five states — the only place a chip colour is decided ------------- */
.chip[data-state="ok"]      { background: var(--ok-bg);      color: var(--ok-ink); }
.chip[data-state="warn"]    { background: var(--warn-bg);    color: var(--warn-ink); }
.chip[data-state="stop"]    { background: var(--stop-bg);    color: var(--stop-ink); }
.chip[data-state="info"]    { background: var(--info-bg);    color: var(--info-ink); }
.chip[data-state="neutral"] { background: var(--neutral-bg); color: var(--neutral-ink); }

/* outline: a threshold or a band, where the fill would shout ------------ */
.chip--outline { background: transparent; border-color: currentColor; color: var(--muted); }
.chip--outline[data-state="ok"]   { color: var(--ok-ink); }
.chip--outline[data-state="warn"] { color: var(--warn-ink); }
.chip--outline[data-state="stop"] { color: var(--stop-ink);
  background: color-mix(in srgb, var(--stop-ink) 7%, transparent); }
.chip--outline[data-state="info"] { color: var(--info-ink); }
.chip--outline[data-state="neutral"] { color: var(--muted); }
/* a weaker outline still: "we inferred this" */
.chip--outline.is-weak { border-style: dashed; color: var(--muted); }

/* dot: the compact form. Same five states, no text --------------------- */
.chip--dot { width: .45rem; height: .45rem; min-width: .45rem; padding: 0;
             border-radius: 50%; gap: 0; vertical-align: middle; }
.chip--dot[data-state="ok"]      { background: var(--ok-ink); }
.chip--dot[data-state="warn"]    { background: var(--warn-ink); }
.chip--dot[data-state="stop"]    { background: var(--stop-ink); }
.chip--dot[data-state="info"]    { background: var(--info-ink); }
.chip--dot[data-state="neutral"] { background: var(--neutral-bg);
                                   border-color: var(--muted); }
/* an in-flight dot pulses hollow until it resolves */
.chip--dot.is-pending { background: transparent; border: 1.5px solid var(--muted);
                        animation: dotpulse 1s linear infinite; }
@keyframes dotpulse { 50% { opacity: .3; } }

/* count: a number riding on another control ---------------------------- */
.chip--count { min-width: 1.05rem; height: 1.05rem; padding: 0 .25rem;
               justify-content: center; font-size: .58rem; font-weight: 900;
               letter-spacing: 0; background: var(--ink); color: #fff; }
.chip--count[data-state="info"] { background: var(--info-ink); color: #fff; }

/* mini: a superscript marker on a dense table cell --------------------- */
.chip--mini { font-size: .56rem; font-weight: 900; letter-spacing: .05em;
              padding: .05rem .28rem; vertical-align: super; margin-left: .35rem; }
.chip--mini[data-state="warn"] { background: var(--warn-ink); color: #fff; }
.chip--mini[data-state="stop"] { background: var(--stop-ink); color: #fff; }

/* sentence-case chips: an ID, a count or a note is not a status word ---- */
.chip--text { text-transform: none; letter-spacing: 0; font-weight: 700; }

/* P5: Sales Control's five stock bands are DATA on the one chip
   (`data-state`), not five classes with their own hex colours. */
/* The segmented group now lives with the button component (P3). */
.nav-item { display: flex; align-items: center; gap: .6rem; padding: .45rem .95rem;
            text-decoration: none; color: var(--ink-2); font-size: .8rem; font-weight: 700;
            border-left: 3px solid transparent; white-space: nowrap; }
.nav-item:hover { background: var(--bg); color: var(--ink); }
.nav-item.active { background: var(--bg); color: var(--ink); border-left-color: var(--ink); }
.nav-item svg { width: 17px; height: 17px; flex-shrink: 0; }
/* --- nav drawers (Robin, 2026-09-12) ----------------------------------
   Every icon row that OWNS sub-links is a compacted drawer instead of an
   always-open list. The row is a <button> — it toggles, it does not
   navigate, because the row's own page is already its first sub-link; that
   keeps every destination one click away while the menu stays short. The
   row carries a discreet muted chevron at its right edge, flipped when open.
   One drawer open at a time; the row you are on is server-rendered open
   (`.nav-sub.open` + aria-expanded), so first paint never flickers and a
   no-JS load still shows the complete menu.

   SPECIFICITY — do not raise this selector. `button.nav-item` (0,1,1) must
   stay BELOW `.nav-item.active` (0,2,0) and `.nav-item:hover` (0,2,0) so the
   active fill and left border are not restated here; and below
   `html.nav-compact .nav-item` (0,2,1) so the icon rail still wins. ----- */
button.nav-item {
  width: 100%; min-height: 0; background: none; cursor: pointer;
  border: 0; border-left: 3px solid transparent;
  justify-content: flex-start; text-align: left;
  padding: .45rem .95rem; gap: .6rem;
  font: inherit; font-size: .8rem; font-weight: 700;
  text-transform: none; letter-spacing: 0;
}
/* The chevron exists only where JS can drive it; with JS off the menu is
   simply open (see the .nav-sub rule below) and an inert affordance would
   lie. The compact-rail hide sits LATER in this file on purpose — equal
   specificity, so source order is what makes the rail win. */
.nav-chev { display: none; margin-left: auto; align-items: center;
            color: var(--muted); transition: transform .16s var(--ease); }
html.nav-js .nav-chev { display: inline-flex; }
.nav-chev svg { width: 13px; height: 13px; stroke-width: 2.4; }
.nav-item[aria-expanded="true"] .nav-chev { transform: rotate(180deg); color: var(--ink-2); }
html.nav-compact .nav-item { justify-content: center; padding: .55rem 0; gap: 0; }
html.nav-compact .nav-item .lbl { display: none; }
/* The drawer body. The DEFAULT is open — that is the no-JS posture and it is
   the menu as it was before the drawers existed. `html.nav-js` (set by an
   inline script in <head>, before first paint) is what switches the menu into
   the compacted rail of drawers, so a browser with JS disabled still gets
   every link one click away instead of a wall of dead chevrons.
   `:not(.nav-compact)` keeps the icon rail's own display:none honest. */
.nav-sub { display: flex; flex-direction: column; }
html.nav-js .nav-sub { display: none; }
html.nav-js:not(.nav-compact) .nav-sub.open { display: flex; }
.nav-sub a { text-decoration: none; color: var(--muted); font-size: .74rem; font-weight: 600;
             padding: .3rem .95rem .3rem 2.55rem; border-left: 3px solid transparent; }
.nav-sub a:hover { color: var(--ink); background: var(--bg); }
.nav-sub a.active { color: var(--ink); font-weight: 800; background: var(--bg);
                    border-left-color: var(--muted); }
/* The icon rail has no room for a chevron and no drawer to open: a compact
   row click expands the whole sidebar instead (see navDrawer() in base.html).
   The rule below outranks `.nav-sub.open` (0,2,1 vs 0,2,0) — deliberately. */
html.nav-compact .nav-chev { display: none; }
html.nav-compact .nav-sub { display: none; }
/* Top bar inside the content column */
.app { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  border-bottom: 1px solid var(--line); padding: .7rem 1.5rem;
  display: flex; align-items: center; gap: 1rem;
  position: sticky; top: 0; background: rgba(255,255,255,.93);
  backdrop-filter: saturate(180%) blur(6px); z-index: 40;
  height: var(--topbar-h); flex-shrink: 0;
}
.topbar .spacer { flex: 1; }
.topbar .page-title { font-weight: 900; font-size: .8rem; text-transform: uppercase;
                      letter-spacing: .1em; }
header { display: contents; }
.topbar .market-toggle { display: inline-flex; border: 1px solid var(--line); }
.topbar .market-toggle a { text-decoration: none; color: var(--muted); font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em; font-size: .62rem; padding: .34rem .6rem; }
.topbar .market-toggle a.active { background: var(--ink); color: #fff; }
.topbar .market-toggle a:hover:not(.active) { color: var(--ink); background: var(--panel); }
.topbar .whoami { color: var(--muted); font-size: .72rem; text-transform: uppercase;
                  letter-spacing: .08em; font-weight: 700; }
header .whoami { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; }
header .gearlink { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); transition: color .15s, transform .25s var(--ease); }
header .gearlink:hover { color: var(--ink); transform: rotate(35deg); }
header .gearlink.active { color: var(--ink); }
header .gearlink svg { width: 19px; height: 19px; display: block; }
header .market-toggle { display: inline-flex; border: 1px solid var(--line); }
header .market-toggle a { text-decoration: none; color: var(--muted); font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em; font-size: .62rem; padding: .34rem .6rem;
  transition: background .15s, color .15s; }
header .market-toggle a.active { background: var(--ink); color: #fff; }
header .market-toggle a:hover:not(.active) { color: var(--ink); background: var(--panel); }

main {
  max-width: 78rem; margin: 1.25rem auto 2rem; padding: 0 1.5rem; width: 100%;
  animation: rise .4s var(--ease) both;
}
/* Pages that need the whole viewport (Buyer Service chat workspace): the panes scroll
   internally instead of the page, so the composer and list headers stay put. */
main.full-bleed { max-width: none; margin: 0; padding: 0; animation: none;
                  height: calc(100vh - var(--topbar-h)); overflow: hidden;
                  display: flex; flex-direction: column; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

h1 { font-size: 1.7rem; font-weight: 900; letter-spacing: -0.02em; margin: 0 0 .2rem; text-wrap: balance; }
.page-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.page-head .grow { flex: 1; }
.crumb { color: var(--muted); text-decoration: none; font-size: .72rem; font-weight: 700;
         text-transform: uppercase; letter-spacing: .1em; }
.crumb:hover { color: var(--ink); }

/* --- tabs --- */
.tabs { display: flex; gap: 0; border-bottom: 1px solid var(--line); margin-bottom: .85rem;
        overflow-x: auto; }
.tabs a {
  padding: .7rem 1.1rem; text-decoration: none; color: var(--muted);
  text-transform: uppercase; letter-spacing: .1em; font-size: .72rem; font-weight: 800;
  border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .15s, border-color .15s;
}
.tabs a:hover { color: var(--ink); }
.tabs a.active { color: var(--ink); border-bottom-color: var(--ink); }

/* --- table --- */
table { border-collapse: collapse; width: 100%; }
thead th {
  text-align: left; text-transform: uppercase; letter-spacing: .07em; font-size: .64rem;
  color: var(--muted); font-weight: 800; padding: .5rem .8rem; border-bottom: 1px solid var(--ink);
}
tbody td { padding: .8rem .8rem; border-bottom: 1px solid var(--line); font-size: .88rem; vertical-align: middle; }
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--panel); }
td.part { font-weight: 800; letter-spacing: .02em; }
.num { font-variant-numeric: tabular-nums; text-align: center; }
td.col-key { background: var(--panel); }
td.col-strong { background: var(--neutral-bg); }
.table-wrap thead th.col-key, .table-wrap thead th.col-strong { background: var(--neutral-bg); }
tbody tr:hover td.col-key { background: var(--neutral-bg); }
tbody tr:hover td.col-strong { background: #e6e6e2; }
.rowlink { text-decoration: none; color: var(--muted); font-weight: 800; text-transform: uppercase;
           letter-spacing: .08em; font-size: .66rem; }
.rowlink:hover { color: var(--ink); }
/* #b4b4ae on white is ~2.1:1 — an unreadable "Unknown". A missing value is a real
   operational state and has to be legible; --muted clears 4.5:1. */
.empty { color: var(--muted); font-style: italic; }
.quiet { color: var(--muted); font-size: .7rem; }

/* --- flags (badges are `.chip`, P5) --- */

.flags { display: inline-flex; gap: .35rem; }
/* An unreleased market must still be readable, so the "off" flag uses --muted and is
   struck through: the state does not depend on a colour difference alone. */
.flag { font-size: .64rem; font-weight: 800; letter-spacing: .06em; color: var(--muted);
        text-decoration: line-through; }
.flag.on { color: var(--ink); text-decoration: none; }

/* --- buttons (P3: one component) --------------------------------------
   ONE button. Every control in the OS is a `.btn` plus at most one intent,
   one size and one shape. Nothing outside this block may set padding,
   font-size or border-radius on a control — that is what produced 20
   variants (12 paddings, 12 font sizes, radii 0/3/4/5px) before P3.

     intent   .btn--primary    ink fill        the one committing action
              .btn--secondary  hairline        alternate / safe actions
              .btn--quiet      panel fill      toolbar + filter chrome
              (a bare <button> with no intent is --primary, so existing
               markup and every `.secondary` keep working unchanged)
     size     (default)        var(--tap) 44px  every control, every width
              .btn--sm         var(--tap-sm)    36px, desktop+mouse ONLY
     shape    .btn--icon       square, glyph only (nav toggle, row +/-)
              .btn--round      circular icon (the deliberate quiet "+",
                               Robin 2026-09-03 — a circle is not a radius)
              .btn--link       a text link that happens to POST

   Radius is var(--radius) (0). Do not hard-code one. -------------------- */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  box-sizing: border-box;
  background: var(--ink); color: #fff;
  border: 1px solid var(--ink); border-radius: var(--radius);
  padding: .5rem 1rem; min-height: var(--tap);
  cursor: pointer; font: inherit; font-weight: 800; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .1em; text-decoration: none;
  transition: background .15s, transform .1s var(--ease), color .15s, border-color .15s;
}
button:hover, .btn:hover { background: #000; }
button:active, .btn:active { transform: translateY(1px); }
button:disabled, .btn:disabled, .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; transform: none; }

/* intents ------------------------------------------------------------- */
.btn--primary { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn--primary:hover { background: #000; }

/* `.secondary` is the legacy spelling of --secondary and stays supported. */
.btn--secondary, .btn.secondary, button.secondary {
  background: var(--bg); color: var(--ink); border-color: var(--ink); }
.btn--secondary:hover, .btn.secondary:hover, button.secondary:hover {
  background: var(--panel); color: var(--ink); }

.btn--quiet {
  background: var(--panel); color: var(--ink-2); border-color: var(--line);
  font-weight: 700; letter-spacing: .06em; }
.btn--quiet:hover { background: var(--bg); color: var(--ink); border-color: var(--muted); }
/* A quiet control that is currently ON reads as filled ink — the same
   selected language the segmented group and the view dropdowns used. */
.btn--quiet.is-on, .btn--quiet[aria-pressed="true"], .btn--quiet.active {
  background: var(--ink); color: #fff; border-color: var(--ink); }

/* A destructive or cautionary action tints the outline, never the fill. */
.btn--warn { border-color: var(--warn-ink); color: var(--warn-ink); background: var(--bg); }
.btn--warn:hover { background: var(--warn-ink); color: #fff; }
.btn--stop { border-color: var(--stop-ink); color: var(--stop-ink); background: var(--bg); }
.btn--stop:hover { background: var(--stop-ink); color: #fff; }

/* size ----------------------------------------------------------------
   36px is a DESKTOP-WITH-MOUSE affordance only. On a phone, on a tablet,
   and on any coarse pointer --btn-sm is still a full 44px target: the
   media query below is the only place the height drops. */
.btn--sm { padding: .3rem .6rem; font-size: .66rem; }
@media (min-width: 901px) and (pointer: fine) {
  .btn--sm { min-height: var(--tap-sm); }
}

/* shape ---------------------------------------------------------------- */
.btn--icon { padding: 0; min-width: var(--tap); gap: 0;
             font-size: .95rem; letter-spacing: 0; text-transform: none; }
.btn--sm.btn--icon { font-size: .8rem; }
@media (min-width: 901px) and (pointer: fine) {
  .btn--sm.btn--icon { min-width: var(--tap-sm); }
}
/* The circular quiet "+" (Robin 2026-09-03: the row's add must look AND
   behave differently from the dark SAVE). A circle is a shape decision,
   not a corner radius — it is exempt from the radius-0 rule. */
.btn--round { border-radius: 50%; }

/* A control with no chrome at all: underlined text that submits a form. */
.btn--link, .link-button {
  background: transparent; border: 0; padding: 0; min-height: 0;
  color: var(--muted); text-decoration: underline; font-size: .62rem;
  font-weight: 700; text-transform: none; letter-spacing: 0; }
.btn--link:hover, .link-button:hover { background: transparent; color: var(--ink); }
.btn--link.danger, .link-button.danger { color: var(--stop-ink); font-weight: 700; }

/* segmented group — built from .btn--quiet, one hairline round the set.
   Its children carry CONTENT labels ("Turnover", "30d"), not action verbs,
   so the group opts out of the uppercase action language. */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius);
       overflow: hidden; background: var(--panel); }
.seg > .btn {
  border: 0; border-right: 1px solid var(--line); border-radius: var(--radius);
  text-transform: none; letter-spacing: .02em; }
.seg > .btn:last-child { border-right: 0; }

:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* --- forms --- */
label { display: block; text-transform: uppercase; letter-spacing: .06em; font-size: .64rem;
        color: var(--muted); font-weight: 800; margin: 0 0 .3rem; }
input, select, textarea {
  width: 100%; padding: .5rem .6rem; border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; font-size: .9rem; background: var(--field); color: var(--ink); transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px rgba(10,10,10,.08);
}
input::placeholder { color: #a9a9a3; }
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem 1rem; }
.grid.two { grid-template-columns: repeat(2, 1fr); }
.field { display: flex; flex-direction: column; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); margin: 0 0 1rem; padding: 1.1rem 1.2rem 1.3rem; }
legend { font-weight: 900; text-transform: uppercase; letter-spacing: .1em; font-size: .68rem;
         padding: 0 .45rem; color: var(--ink); }

/* --- messages --- */
.error { background: var(--stop-bg); color: var(--stop-ink); padding: .7rem .9rem; border-radius: var(--radius);
         margin: .6rem 0; font-size: .85rem; font-weight: 600; }
.notice { background: var(--ok-bg); color: var(--ok-ink); padding: .7rem .9rem; border-radius: var(--radius);
          margin: .6rem 0; font-size: .85rem; font-weight: 600; }
.muted { color: var(--muted); }

/* --- Business OS reporting --- */
.kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 1px;
            background: var(--line); border: 1px solid var(--line); margin: 0 0 1.25rem; }
.kpi-grid.three { grid-template-columns: repeat(3, minmax(0,1fr)); }
.kpi-grid.five { grid-template-columns: repeat(5, minmax(0,1fr)); }
.kpi { background: var(--bg); padding: 1rem; min-height: 6.2rem; }
.kpi-label { color: var(--muted); text-transform: uppercase; letter-spacing: .08em;
             font-size: .62rem; font-weight: 800; }
.kpi-value { font-size: 1.55rem; line-height: 1.2; font-weight: 900; margin-top: .45rem;
             font-variant-numeric: tabular-nums; }
.kpi-sub { color: var(--muted); font-size: .72rem; margin-top: .25rem; }
.metric-help { margin-top: .55rem; border-top: 1px solid var(--line); padding-top: .4rem; }
.metric-help summary { cursor: pointer; color: var(--muted); font-size: .63rem;
                       font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.metric-help > div { display: grid; grid-template-columns: 5rem 1fr; gap: .4rem;
                     margin-top: .35rem; font-size: .68rem; line-height: 1.35; }
.metric-help > div b { text-transform: uppercase; letter-spacing: .04em; font-size: .58rem; }
.metric-help .rowlink { display: inline-block; margin-top: .45rem; }
.source-bar { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center;
              border: 1px solid var(--line); background: var(--panel); padding: .65rem .75rem;
              margin-bottom: 1rem; font-size: .72rem; }
.source { display: inline-flex; gap: .35rem; align-items: center; text-transform: uppercase;
          letter-spacing: .06em; font-size: .61rem; font-weight: 800; }
.source::before { content: ""; width: .45rem; height: .45rem; background: var(--neutral-ink); }
.source.current::before { background: var(--ok-ink); }
.source.stale::before { background: var(--warn-ink); }
.source.not_connected::before { background: var(--stop-ink); }
.toolbar { display: flex; align-items: end; flex-wrap: wrap; gap: .65rem; margin: 0 0 1rem; }
.toolbar .field { min-width: 15rem; }
.table-wrap { overflow: auto; max-height: calc(100vh - 12rem); border: 1px solid var(--line); }
.table-wrap table { min-width: 62rem; }
.table-wrap thead th { background: var(--panel); position: sticky; top: 0; z-index: 2; box-shadow: inset 0 -1px 0 var(--ink); }
.money-stack { display: flex; flex-direction: column; align-items: flex-end; gap: .05rem;
               font-variant-numeric: tabular-nums; }
.money-stack span { white-space: nowrap; }
.issue-list { display: flex; flex-wrap: wrap; gap: .25rem; }
.issue { background: var(--warn-bg); color: var(--warn-ink); padding: .1rem .35rem;
         text-transform: uppercase; font-size: .56rem; letter-spacing: .05em; font-weight: 800; }
.section-title { display: flex; justify-content: space-between; align-items: baseline;
                 gap: 1rem; margin: 1.5rem 0 .65rem; }
.section-title h2 { margin: 0; font-size: 1rem; text-transform: uppercase; letter-spacing: .08em; }
details.record { border-bottom: 1px solid var(--line); }
details.record > summary { list-style: none; cursor: pointer; display: grid;
  grid-template-columns: minmax(10rem,1.4fr) repeat(5,minmax(7rem,1fr)); gap: .75rem;
  align-items: center; padding: .8rem; font-size: .82rem; }
details.record > summary::-webkit-details-marker { display: none; }
details.record > summary:hover { background: var(--panel); }
.record-detail { padding: 0 .8rem 1rem; background: var(--panel); overflow-x: auto; }
.record-detail table { min-width: 58rem; }

/* --- voyage rail: four stops joined by thick bars, on the Inbound tab --- */
.voyage { display: flex; align-items: flex-start; gap: 0; max-width: 34rem; }
.voyage-stop { display: flex; flex-direction: column; align-items: center; flex: 1 1 0; min-width: 0; }
.voyage-marks { display: flex; align-items: center; width: 100%; }
.voyage-line { flex: 1; height: 6px; background: var(--neutral-bg); }
.voyage-stop:first-child .voyage-line:first-child,
.voyage-stop:last-child .voyage-line:last-child { background: transparent; }
.voyage-dot { width: 1.15rem; height: 1.15rem; border-radius: 50%; flex: 0 0 auto;
              background: var(--neutral-bg); display: flex; align-items: center;
              justify-content: center; }
.voyage-dot svg { width: .7rem; height: .7rem; display: none; }
.voyage-label { font-size: .55rem; font-weight: 700; letter-spacing: .04em;
                text-transform: uppercase; color: var(--muted); margin-top: .4rem;
                text-align: center; line-height: 1.2; }
/* A passed stop is solid and ticked, and the bar INTO it is solid too, so the
   filled portion of the rail reads as distance covered. */
.voyage-stop.done .voyage-dot { background: var(--ink); }
.voyage-stop.done .voyage-dot svg { display: block; }
.voyage-stop.done .voyage-line:first-child,
.voyage-stop.current .voyage-line:first-child { background: var(--ink); }
.voyage-stop.done .voyage-label { color: var(--ink-2); }
.voyage-stop.current .voyage-label { color: var(--ink); font-weight: 800; }
/* Condition colours the CURRENT stop only: the history did happen, it is the
   present position that is in trouble. */
.voyage.on_track .voyage-stop.current .voyage-dot { background: var(--info-ink); }
.voyage.delayed .voyage-stop.current .voyage-dot { background: var(--warn-ink); }
.voyage.delayed .voyage-stop.current .voyage-label { color: var(--warn-ink); }
.voyage.overdue .voyage-stop.current .voyage-dot { background: var(--stop-ink); }
.voyage.overdue .voyage-stop.current .voyage-label { color: var(--stop-ink); }
.voyage.arrived .voyage-stop.current .voyage-dot { background: var(--ok-ink); }
.voyage.arrived .voyage-stop.current .voyage-dot svg { display: block; }
.voyage.arrived .voyage-stop.current .voyage-label { color: var(--ok-ink); }
/* Inferred = CIN7 says so, the carrier has not. Hollow stops and a hatched bar,
   so an unconfirmed position never looks like a tracked one. */
.voyage.inferred .voyage-stop.done .voyage-dot,
.voyage.inferred .voyage-stop.current .voyage-dot {
  background: var(--bg); box-shadow: inset 0 0 0 3px var(--muted); }
.voyage.inferred .voyage-stop.done .voyage-dot svg,
.voyage.inferred .voyage-stop.current .voyage-dot svg { display: none; }
.voyage.inferred .voyage-stop.done .voyage-line:first-child,
.voyage.inferred .voyage-stop.current .voyage-line:first-child {
  background: repeating-linear-gradient(90deg, var(--muted) 0 5px, transparent 5px 10px); }
.voyage-legend { font-size: .6rem; color: var(--muted); }
.facts { display: flex; flex-wrap: wrap; gap: .15rem 1.4rem; margin: .1rem 0 .5rem; }
.fact { font-size: .68rem; }
.fact b { display: block; font-size: .55rem; letter-spacing: .07em; text-transform: uppercase;
          color: var(--muted); font-weight: 800; margin-bottom: .1rem; }
.operational-state { display: inline-flex; width: max-content; padding: .16rem .4rem;
                     text-transform: uppercase; letter-spacing: .05em; font-size: .58rem;
                     font-weight: 900; background: var(--neutral-bg); color: var(--neutral-ink); }
.operational-state.ok { background: var(--ok-bg); color: var(--ok-ink); }
.operational-state.info { background: var(--info-bg); color: var(--info-ink); }
.operational-state.warn { background: var(--warn-bg); color: var(--warn-ink); }
.operational-state.stop { background: var(--stop-bg); color: var(--stop-ink); }
/* ---------- Orders scan table ----------
   Fixed layout with declared column widths. Under auto layout the first column took
   636px while "age / value" got 63px and wrapped to four lines, because the expandable
   detail in the last cell fed its own content width back into the outer table. */
.orders-scan table { min-width: 62rem; table-layout: fixed; }
.orders-scan col.col-order  { width: 8.5rem; }
.orders-scan col.col-party  { width: 14rem; }
.orders-scan col.col-state  { width: 10rem; }
.orders-scan col.col-supply { width: 10rem; }
.orders-scan col.col-risk   { width: 8rem; }
.orders-scan col.col-owner  { width: 9rem; }
.orders-scan col.col-action { width: auto; }
.orders-scan td { vertical-align: top; padding-top: .5rem; padding-bottom: .5rem; }
.orders-scan tr:hover td { background: var(--panel); }
/* Never reuse Home's .action-row on a <tr>: that class is display:grid and turns the
   row into a 4-column grid, so the cells stop lining up with <thead>. Actionable rows
   carry no extra decoration — the chip in "Next action" is already the signal, and on
   the Next actions and Backorders views every row qualifies, so a row marker there
   would mark everything and mean nothing. */
.cell-name { display: block; font-weight: 700; overflow-wrap: anywhere; }
.cell-sub { display: block; color: var(--muted); font-size: .66rem; line-height: 1.35;
            margin-top: .16rem; }
/* The count line carries the view's source contract, so it holds a <details>. */
.result-count { color: var(--muted); font-size: .72rem; margin: 0 0 .5rem;
                display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.result-count .metric-help { margin-top: 0; border-top: 0; padding-top: 0; }

/* ---------- Headline metrics (replaces the KPI card wall) ---------- */
.headline-row { display: grid; grid-template-columns: repeat(4, minmax(0,1fr));
                gap: 1px; background: var(--line); border: 1px solid var(--line);
                margin-bottom: .85rem; }
.headline { background: var(--bg); padding: .6rem .8rem; }
.headline-label { display: block; color: var(--muted); font-size: .6rem; font-weight: 900;
                  text-transform: uppercase; letter-spacing: .1em; }
.headline-value { display: block; font-size: 1.35rem; font-weight: 900; line-height: 1.15;
                  margin-top: .1rem; font-variant-numeric: tabular-nums; }
.headline-sub { display: block; color: var(--muted); font-size: .68rem; margin-top: .05rem; }
.band-chips { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
              margin: 0 0 .8rem; }
/* P5/P3: the band filters are `.btn--quiet.btn--sm` + `.is-on`. */
.band-note { color: var(--muted); font-size: .68rem; margin-left: .25rem; }

/* ---------- Filters: four primary controls, the rest behind a disclosure ---------- */
.orders-filters, .product-filters { align-items: flex-end; }
.orders-filters .field { min-width: 9rem; }
.orders-filters .field.grow { flex: 1; min-width: 14rem; }
.more-filters { flex-basis: 100%; border-top: 1px solid var(--line); padding-top: .5rem; }
.more-filters > summary { cursor: pointer; color: var(--muted); font-size: .63rem;
  font-weight: 900; text-transform: uppercase; letter-spacing: .08em; }
.more-filters > summary:hover { color: var(--ink); }
.more-filters-grid { display: grid; gap: .65rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); margin-top: .65rem; }
.toolbar-actions { display: flex; gap: .5rem; align-items: flex-end; }

/* ---------- Expandable order detail (a grid, never a nested <table>) ---------- */
.order-detail { margin-top: .4rem; }
.order-detail > summary { cursor: pointer; color: var(--muted); font-size: .65rem;
                          font-weight: 800; }
.order-detail > summary:hover { color: var(--ink); }
.order-detail-body { margin-top: .5rem; padding: .7rem; background: var(--panel);
                     display: grid; gap: .7rem; }
.detail-alert { margin: 0; color: var(--stop-ink); background: var(--stop-bg);
                padding: .35rem .5rem; font-size: .7rem; }
.night-order-markers { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 .65rem; }
.night-order-marker { display: inline-flex; align-items: center; padding: .28rem .45rem;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  font-size: .66rem; font-weight: 700; text-decoration: none; }
.night-order-marker:hover { border-color: var(--ink); }
.night-order-marker.urgent { border-color: var(--stop-ink); color: var(--stop-ink); }
.detail-facts { display: grid; grid-template-columns: auto minmax(0,1fr); gap: .2rem .7rem;
                margin: 0; font-size: .72rem; }
.detail-facts dt { color: var(--muted); white-space: nowrap; }
.detail-facts dd { margin: 0; overflow-wrap: anywhere; }
.detail-lines { display: grid; gap: .3rem; }
.detail-line { display: grid; grid-template-columns: 6rem minmax(0,1.4fr) minmax(0,1.4fr) minmax(0,1fr);
               gap: .5rem; font-size: .7rem; padding: .3rem 0;
               border-top: 1px solid var(--line); align-items: baseline; }
.detail-line-name { font-weight: 700; overflow-wrap: anywhere; }
.detail-line-qty, .detail-line-eta { color: var(--muted); }
.accountability-form { display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-end;
                       border-top: 1px solid var(--line); padding-top: .6rem; }
.accountability-form label { display: grid; gap: .2rem; font-size: .6rem; font-weight: 900;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.accountability-form select, .accountability-form input { min-width: 9rem;
  padding: .3rem .35rem; font-size: .7rem; }
.priority-note { border-left: 3px solid var(--ink); padding-left: .7rem; }
/* Data-quality counts are filters, so they read as chips rather than headline cards. */
.quality-chips { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem;
                 margin: 0 0 .85rem; font-size: .7rem; }
.quality-chips-label { color: var(--muted); font-weight: 900; text-transform: uppercase;
                       letter-spacing: .08em; font-size: .6rem; margin-right: .15rem; }
/* P5/P3: the data-quality filters are `.btn--quiet.btn--sm` + `.is-on`. */
.product-filters .field, .schema-filters .field { min-width: 10rem; }
.product-filters .field:first-of-type, .schema-filters .field:first-of-type {
  min-width: 15rem;
}
.filter-chips { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem;
                margin: -.35rem 0 1rem; font-size: .68rem; }
.filter-chips > span { color: var(--muted); font-weight: 800; text-transform: uppercase;
                       letter-spacing: .06em; margin-right: .2rem; }
.filter-chips a { border: 1px solid var(--line); padding: .25rem .45rem; }
.product-workbench table { min-width: 62rem; table-layout: fixed; }
.product-workbench col.col-sku     { width: 5.5rem; }
.product-workbench col.col-name    { width: auto; }
.product-workbench col.col-coll    { width: 8rem; }
.product-workbench col.col-type    { width: 9rem; }
.product-workbench col.col-status  { width: 7.5rem; }
.product-workbench col.col-markets { width: 5.75rem; }
.product-workbench col.col-quality { width: 9rem; }
.product-workbench col.col-msrp    { width: 6rem; }
.product-workbench col.col-edit    { width: 3.5rem; }
.product-workbench td { vertical-align: top; }
.product-workbench td, .product-workbench th { overflow-wrap: anywhere; }
.product-component-toggle { appearance: none; border: 0; background: transparent; color: var(--ink);
                            padding: 0; text-align: left; font: inherit; font-weight: 900;
                            cursor: pointer; width: 100%; }
.product-component-toggle:hover > span:first-child,
.product-component-toggle[aria-expanded="true"] > span:first-child { text-decoration: underline; }
.component-toggle-meta { display: block; color: var(--info-ink); font-size: .58rem;
                         font-weight: 800; letter-spacing: .03em; margin-top: .15rem; }
.product-component-row > td { background: var(--panel); padding: 0; }
.product-component-drawer { max-height: 0; opacity: 0; overflow: hidden;
                            transform: translateY(-.4rem);
                            transition: max-height .22s var(--ease), opacity .16s ease,
                                        transform .22s var(--ease); }
.product-component-row.is-open .product-component-drawer { max-height: 38rem; opacity: 1;
                                                            transform: translateY(0); }
.component-drawer-head { display: flex; justify-content: space-between; gap: 1rem;
                         align-items: flex-start; padding: .8rem 1rem .65rem; }
.component-drawer-head strong { display: block; font-size: .78rem; }
.component-drawer-head span { display: block; color: var(--muted); font-size: .68rem; }
.component-drawer-head a { font-size: .68rem; white-space: nowrap; }
.component-drawer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
                         gap: 1px; background: var(--line); border-top: 1px solid var(--line);
                         border-bottom: 1px solid var(--line); }
.component-card { background: var(--bg); padding: .7rem 1rem; }
.component-card code, .component-card strong, .component-card span { display: block; }
.component-card strong { font-size: .7rem; margin-top: .15rem; }
.component-card span { color: var(--muted); font-size: .64rem; margin-top: .1rem; }
.component-contract, .component-evidence { margin: .55rem 1rem; font-size: .66rem; }
.component-evidence { color: var(--muted); }
.component-exceptions { margin-top: .65rem; padding: .65rem 1rem .8rem;
                        background: var(--warn-bg); color: var(--warn-ink); font-size: .67rem; }
.component-exceptions > strong { display: block; }
.component-exceptions p { margin: .25rem 0 0; }
/* ---- stock tab drawers (2026-09-10; restyled same day on Robin's feedback):
   Available → per-warehouse SUB-ROWS aligned to the parent table's own columns
   (no header, no nested table); On order → container list in a drawer panel.
   Trigger = style A: plain number + tiny muted caret, underline on hover only. ---- */
.stock-drawer-parent > td { border-bottom-color: transparent; }
/* On-order keeps the drawer-panel look (Robin: "on order all good, no changes"). */
.stock-drawer-row > td { background: var(--panel); padding: 0; }
.stock-drawer { max-height: 0; opacity: 0; overflow: hidden;
                transform: translateY(-.4rem);
                transition: max-height .22s var(--ease), opacity .16s ease,
                            transform .22s var(--ease); }
.stock-drawer-row.is-open .stock-drawer { max-height: 30rem; opacity: 1;
                                          transform: translateY(0); }
.stock-drawer .drawer-head { display: flex; justify-content: space-between;
                             gap: 1rem; align-items: baseline;
                             padding: .7rem 1rem .45rem; font-size: .72rem; }
.stock-drawer table { min-width: 0; margin: 0 1rem .8rem; font-size: .8125rem; }
.stock-drawer td { padding: .3rem .6rem; border-bottom: 1px solid var(--line); }
.stock-drawer tr:last-child > td { border-bottom: 0; }
/* Availability: aligned sub-rows, no header, no nested table. */
.stock-drawer-subrow > td { background: var(--panel); font-size: .72rem;
                            border-bottom: 0; padding-top: .15rem; padding-bottom: .15rem; }
.stock-drawer-subrow:first-of-type > td { border-top: 1px dashed var(--line); }
.stock-drawer-subrow:last-of-type > td { border-bottom: 1px dashed var(--line); }
.stock-drawer-subrow td:first-child { border-right: 1px solid var(--line); }
.stock-drawer-subrow .stock-drawer-links { font-size: .68rem; text-align: right; }
.stock-drawer-subrow .muted-cell { color: var(--muted); }
/* Style A (Robin, 2026-09-10): no chrome at all — number stays plain text,
   a tiny muted caret is the only affordance, underline only on hover. Must
   beat the global `button, .btn` rule, hence the specificity. */
button.stock-drawer-toggle.num-toggle { display: inline !important; appearance: none !important;
    border: 0 !important; background: none !important; color: inherit !important;
    font: inherit !important; font-weight: inherit !important;
    padding: 0 !important; min-height: 0 !important; max-height: none !important;
    cursor: pointer; text-transform: none !important;
    letter-spacing: normal !important; gap: 0 !important;
    border-radius: var(--radius); box-shadow: none !important;
    transition: none !important; }
button.stock-drawer-toggle.num-toggle:hover, button.stock-drawer-toggle.num-toggle:active {
    background: none !important; transform: none !important; }
.stock-drawer-toggle:hover > strong,
.stock-drawer-toggle[aria-expanded="true"] > strong { text-decoration: underline;
    text-underline-offset: 2px; }
.drawer-caret { display: inline-block; margin-left: .3rem; font-size: .8rem;
                color: var(--muted); transition: transform .18s var(--ease); }
.stock-drawer-toggle[aria-expanded="true"] .drawer-caret { transform: rotate(180deg); }
.onorder-table td:first-child { font-weight: 800; }
/* On-order container rows (Robin 09-10): parent-table sub-rows so the qty sits
   under On order. Left/right padding deliberately untouched — that is what keeps
   the numbers in the parent's columns. Text keeps the drawer's size/weight. */
.stock-drawer-subrow.onorder-sub > td { font-size: .8125rem; padding-top: .3rem;
                                        padding-bottom: .3rem; }
.stock-drawer-subrow.onorder-sub td:first-child { border-right: 0; }
.onorder-row > td:first-child { font-weight: 800; }
.onorder-row > td.onorder-eta { white-space: nowrap; }
.onorder-head .drawer-head { display: flex; justify-content: space-between; gap: 1rem;
                             align-items: baseline; padding-top: .4rem; font-size: .72rem; }
.onorder-more button { appearance: none; border: 0; background: transparent;
                       color: var(--info-ink); font: inherit; font-size: .68rem;
                       font-weight: 800; cursor: pointer; padding: .2rem 0; }
.onorder-more button:hover { text-decoration: underline; }
.group-row td { background: var(--ink); color: var(--bg); font-size: .65rem;
                font-weight: 900; letter-spacing: .09em; text-transform: uppercase;
                position: sticky; left: 0; }
.attribute-schema table { min-width: 105rem; }
.attribute-schema td { vertical-align: top; line-height: 1.4; }
.pager { display: flex; align-items: center; gap: .6rem; margin: 1rem 0; flex-wrap: wrap; }
.pager .spacer { flex: 1; }
/* ---- Buyer Service: full-bleed chat workspace (list | conversation | customer) ---- */
.chat-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
/* Compact metrics strip */
.chat-metrics { display: flex; gap: 0; border-bottom: 1px solid var(--line);
                background: var(--panel); flex-wrap: wrap; }
.chat-metrics .m { padding: .45rem .95rem; border-right: 1px solid var(--line);
                   display: flex; align-items: baseline; gap: .45rem; }
.chat-metrics .m .v { font-weight: 900; font-size: .95rem; }
.chat-metrics .m .k { font-size: .6rem; font-weight: 800; text-transform: uppercase;
                      letter-spacing: .09em; color: var(--muted); }
.chat-metrics .m.warn .v { color: var(--stop-ink); }
.chat-metrics .src { margin-left: auto; padding: .45rem .95rem; font-size: .66rem;
                     color: var(--muted); align-self: center; }
/* Three panes filling the viewport */
.chat { display: grid; grid-template-columns: 21rem minmax(0,1fr) 19rem;
        flex: 1; min-height: 0; background: var(--line); gap: 1px; }
.chat > * { background: var(--bg); min-width: 0; display: flex; flex-direction: column;
            min-height: 0; }
/* Search lives in the top bar, on the right */
.topbar-search { display: flex; align-items: center; gap: .35rem; }
.topbar-search input { font-family: var(--font); font-size: .76rem; width: 15rem;
                       padding: .35rem .55rem; border: 1px solid var(--line);
                       background: var(--panel); color: var(--ink); }
.topbar-search input:focus { outline: none; border-color: var(--ink); background: var(--bg); }
@media (max-width: 1240px) { .topbar-search input { width: 8rem; } }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0;
           margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0);
           white-space: nowrap; border: 0; }
.chat-filters { display: flex; align-items: center; gap: .45rem; padding: .5rem .7rem;
                border-bottom: 1px solid var(--line); position: relative; }
.chat-filter-form { display: flex; align-items: center; gap: .45rem; flex: 1; min-width: 0; }
.chat-filter-form select { flex: 1; min-width: 0; border: 1px solid var(--line);
                           background: var(--bg); color: var(--ink); font: inherit;
                           font-size: .72rem; font-weight: 800; padding: .38rem .5rem; }
.status-filter { position: relative; flex: 0 0 auto; }
.status-filter summary { width: 4.35rem; height: 2.15rem; padding: 0 .55rem;
                         border: 1px solid var(--line); border-radius: var(--radius);
                         background: var(--bg); display: flex; align-items: center;
                         justify-content: space-between; cursor: pointer; list-style: none; }
.status-filter summary::-webkit-details-marker { display: none; }
.status-filter summary:hover, .status-filter[open] summary {
  border-color: var(--ink); background: var(--panel);
}
.status-filter summary img { width: 1.15rem; height: 1.15rem; opacity: .72; }
.status-filter summary img:last-child { width: 1.25rem; height: 1.25rem; }
.status-filter-menu { position: absolute; z-index: 30; top: calc(100% + .4rem); right: 0;
                      width: 13rem; padding: .3rem; border: 1px solid var(--line);
                      background: var(--bg); box-shadow: 0 .6rem 1.4rem rgba(0,0,0,.12); }
.status-filter-menu a { display: flex; align-items: center; justify-content: space-between;
                        gap: 1rem; padding: .48rem .55rem; color: var(--ink-2);
                        text-decoration: none; font-size: .72rem; font-weight: 750; }
.status-filter-menu a:hover { background: var(--panel); color: var(--ink); }
.status-filter-menu a.on { background: var(--ink); color: #fff; }
.status-filter-menu b { font-size: .66rem; opacity: .7; }
/* P5/P3: the Buyer Service lane pills are `.btn--quiet.btn--sm` + `.is-on`. */
.chat-list { overflow-y: auto; flex: 1; }
.chat-row { display: flex; gap: .6rem; padding: .6rem .7rem; text-decoration: none;
            color: var(--ink); border-bottom: 1px solid var(--line); align-items: flex-start; }
.chat-row:hover { background: var(--panel); }
.chat-row.active { background: var(--panel); box-shadow: inset 3px 0 0 var(--ink); }
.chat-av { width: 2.2rem; height: 2.2rem; border-radius: 50%; flex-shrink: 0;
           background: var(--neutral-bg); color: var(--neutral-ink); font-weight: 900;
           font-size: .72rem; display: flex; align-items: center; justify-content: center;
           text-transform: uppercase; }
.chat-row.unread .chat-av { background: var(--info-bg); color: var(--info-ink); }
.chat-main { flex: 1; min-width: 0; }
.chat-r1 { display: flex; align-items: baseline; gap: .4rem; }
.chat-name { font-weight: 800; font-size: .82rem; flex: 1; min-width: 0; overflow: hidden;
             text-overflow: ellipsis; white-space: nowrap; }
.chat-time { font-size: .64rem; color: var(--muted); flex-shrink: 0; }
.chat-row.unread .chat-time { color: var(--info-ink); font-weight: 800; }
.chat-sub { font-size: .74rem; color: var(--ink-2); overflow: hidden;
            text-overflow: ellipsis; white-space: nowrap; margin-top: .1rem; }
.chat-prev { font-size: .72rem; color: var(--muted); overflow: hidden;
             text-overflow: ellipsis; white-space: nowrap; }
.chat-tags { display: flex; gap: .25rem; margin-top: .25rem; align-items: center;
             flex-wrap: wrap; }
/* Pane 2 — the conversation itself */
.chat-head { display: flex; align-items: center; gap: .65rem; padding: .55rem .9rem;
             border-bottom: 1px solid var(--line); background: var(--panel); }
.chat-head .who { flex: 1; min-width: 0; }
.chat-head .who b { display: block; font-size: .88rem; }
.chat-head .who span { font-size: .68rem; color: var(--muted); display: block;
                       overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-scroll { flex: 1; overflow-y: auto; padding: 1rem 1.2rem 1.4rem;
                 background: var(--panel); min-height: 0; }
.day-sep { text-align: center; margin: 1rem 0 .8rem; }
.day-sep span { background: var(--bg); border: 1px solid var(--line); color: var(--muted);
                font-size: .62rem; font-weight: 800; text-transform: uppercase;
                letter-spacing: .08em; padding: .18rem .6rem; }
/* Chat bubbles: customer on the left, us on the right */
.bub-row { display: flex; margin-bottom: .5rem; }
.bub-row.out { justify-content: flex-end; }
.bub { max-width: min(46rem, 78%); background: var(--bg); border: 1px solid var(--line);
       padding: .5rem .7rem; }
.bub-row.out .bub { background: var(--ok-bg); border-color: #cfe0d4; }
.bub .bub-from { font-size: .68rem; font-weight: 900; color: var(--info-ink);
                 margin-bottom: .15rem; }
.bub-row.out .bub .bub-from { color: var(--ok-ink); }
.bub .bub-addr { font-size: .63rem; color: var(--muted); margin-bottom: .3rem;
                 overflow-wrap: anywhere; }
.bub .bub-text { font-size: .82rem; line-height: 1.5; color: var(--ink-2);
                 white-space: pre-wrap; overflow-wrap: anywhere; }
.bub .bub-meta { font-size: .62rem; color: var(--muted); text-align: right; margin-top: .25rem; }
.bub .bub-text a { color: var(--info-ink); text-decoration: underline;
                   text-underline-offset: 2px; overflow-wrap: anywhere; }
.bub-row.out .bub .bub-text a { color: var(--ok-ink); }
.bub .quote-toggle summary { cursor: pointer; color: var(--muted); font-size: .66rem;
                             list-style: none; border: 1px solid var(--line);
                             padding: .02rem .35rem; display: inline-block; margin-top: .35rem; }
.bub .quote-toggle summary::-webkit-details-marker { display: none; }
.bub .quote-toggle .bub-text { color: var(--muted); font-size: .76rem; margin-top: .3rem;
                               padding-left: .5rem; border-left: 2px solid var(--line); }
/* Composer */
.composer { border-top: 1px solid var(--line); background: var(--bg); padding: .6rem .9rem;
            display: flex; gap: .5rem; align-items: center; }
.composer input { flex: 1; font-family: var(--font); font-size: .82rem; padding: .55rem .7rem;
                  border: 1px solid var(--line); background: var(--panel); color: var(--ink); }
.composer .note { font-size: .66rem; color: var(--muted); }
.ord-card { border: 1px solid var(--line); padding: .45rem .55rem; margin-bottom: .4rem; }
.ord-top { display: flex; justify-content: space-between; gap: .5rem; font-size: .8rem; }
.ord-meta { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .25rem;
            font-size: .66rem; align-items: center; }
/* Pane 3 — customer profile */
.chat-side { overflow-y: auto; }
.profile { padding: .9rem; }
.profile h3 { margin: 0 0 .1rem; font-size: 1rem; }
.profile .facts { color: var(--muted); font-size: .74rem; margin: 0 0 .7rem;
                  overflow-wrap: anywhere; }
.profile .empty, .chat-empty { color: var(--muted); padding: 2.5rem 1rem; text-align: center;
                               font-size: .82rem; }
.chat-empty { margin: auto; }
.other-thread { display: block; padding: .35rem 0; border-top: 1px solid var(--line);
                text-decoration: none; color: var(--ink); font-size: .76rem; }
.other-thread:hover { color: var(--info-ink); }
.other-thread .when { color: var(--muted); font-size: .66rem; }
@media (max-width: 1240px) { .chat { grid-template-columns: 18rem minmax(0,1fr); }
                             .chat-side { display: none; } }
@media (max-width: 900px) { .chat { grid-template-columns: 1fr; }
                            .chat-list-col { max-height: 40vh; } }
.delay { color: var(--stop-ink); font-weight: 800; }
.module-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 1px;
               background: var(--line); border: 1px solid var(--line); margin-bottom: 1.5rem; }
.module-card { background: var(--bg); padding: 1rem; min-height: 10rem; display: flex;
               flex-direction: column; gap: .55rem; text-decoration: none; }
.module-card:hover { background: var(--panel); }
.module-card h2 { font-size: 1rem; margin: 0; }
.module-card p { color: var(--muted); font-size: .78rem; margin: 0; }
.module-card .rowlink { margin-top: auto; }
.action-list { border: 1px solid var(--line); margin-bottom: 1.5rem; }
.action-row { display: grid; grid-template-columns: 6rem minmax(11rem,1fr) minmax(12rem,1.4fr) auto;
              gap: .8rem; align-items: center; padding: .75rem .85rem; border-bottom: 1px solid var(--line);
              text-decoration: none; font-size: .8rem; }
.action-row:last-child { border-bottom: 0; }
.action-row:hover { background: var(--panel); }
.integration-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr));
                    border: 1px solid var(--line); margin-bottom: 1.5rem; }
.integration { padding: .7rem .8rem; border-right: 1px solid var(--line);
               border-bottom: 1px solid var(--line); font-size: .72rem; }
.integration strong { display: block; margin-bottom: .25rem; }
/* --- Home: evidence-backed management control tower --- */
.control-kpi-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr));
                    border: 1px solid var(--line); margin-bottom: 1.5rem; }
.control-kpi { padding: .9rem 1rem; min-height: 8.4rem; border-right: 1px solid var(--line);
               display: flex; flex-direction: column; min-width: 0; }
.control-kpi:nth-child(3n) { border-right: 0; }
.control-kpi-label { font-size: .62rem; font-weight: 900; color: var(--muted);
                     text-transform: uppercase; letter-spacing: .09em; }
.control-kpi-value { font-size: 1.75rem; font-weight: 900; line-height: 1.15;
                     margin: .45rem 0 .25rem; font-variant-numeric: tabular-nums; }
.control-kpi-sub { color: var(--muted); font-size: .7rem; margin-top: auto;
                   display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.control-kpi-sub a { color: inherit; }
.control-kpi.is-blocked { background: var(--panel); }
.control-kpi.is-blocked .control-kpi-value { color: var(--muted); font-size: 1.2rem; }
.control-kpi .metric-help { margin-top: .5rem; }
.control-actions { border: 1px solid var(--line); margin-bottom: 1.5rem; }
.control-action-head, .control-action {
  display: grid; grid-template-columns: minmax(12rem,1.2fr) minmax(14rem,1.45fr)
                minmax(8rem,.75fr) minmax(12rem,1fr); gap: .8rem;
}
.control-action-head { padding: .45rem .75rem; background: var(--panel);
                       color: var(--muted); text-transform: uppercase;
                       letter-spacing: .07em; font-size: .58rem; font-weight: 900;
                       border-bottom: 1px solid var(--ink); }
.control-action { padding: .72rem .75rem; border-bottom: 1px solid var(--line);
                  text-decoration: none; font-size: .76rem; align-items: start; }
.control-action:last-child { border-bottom: 0; }
.control-action:hover { background: var(--panel); }
.control-action > span { min-width: 0; display: grid; gap: .18rem; }
.control-action small { display: block; color: var(--muted); font-size: .67rem;
                        line-height: 1.35; overflow-wrap: anywhere; }
.control-action-identity .chip { margin-bottom: .1rem; }
.blocked-panel { border: 1px solid var(--line); background: var(--panel);
                 padding: 1rem; margin-bottom: 1.5rem; }
.blocked-panel p { max-width: 78ch; margin: .35rem 0 0; color: var(--ink-2);
                   font-size: .8rem; }
.sales-channel-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
                      border: 1px solid var(--line); margin-bottom: .55rem; }
.sales-channel-card { min-width: 0; padding: .9rem; }
.sales-channel-card + .sales-channel-card { border-left: 1px solid var(--line); }
.sales-channel-head { display: flex; align-items: baseline; justify-content: space-between;
                      gap: .75rem; margin-bottom: .7rem; }
.sales-channel-head h3 { margin: 0; font-size: 1.05rem; }
.sales-channel-source { color: var(--muted); font-size: .66rem; text-align: right;
                        flex-shrink: 0; display: inline-flex; align-items: baseline;
                        gap: .4rem; flex-wrap: wrap; justify-content: flex-end; }
.sales-period-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
                     border: 1px solid var(--line); }
.sales-period { padding: .75rem; min-width: 0; }
.sales-period + .sales-period { border-left: 1px solid var(--line); }
.sales-period-head { display: flex; align-items: flex-start; justify-content: space-between;
                     gap: .5rem; }
.sales-period-head > div { display: grid; min-width: 0; }
.sales-window { color: var(--muted); font-size: .59rem; font-weight: 900;
                letter-spacing: .09em; text-transform: uppercase; }
.sales-period-head strong { font-size: 1.18rem; font-variant-numeric: tabular-nums;
                            overflow-wrap: anywhere; }
.trend-change { flex-shrink: 0; padding: .18rem .34rem; font-size: .66rem; font-weight: 900;
                font-variant-numeric: tabular-nums; white-space: nowrap; }
.trend-change.up, .trend-change.new { color: var(--ok-ink); background: var(--ok-bg); }
.trend-change.down { color: var(--stop-ink); background: var(--stop-bg); }
.trend-change.flat { color: var(--neutral-ink); background: var(--neutral-bg); }
.sales-comparison { display: block; color: var(--muted); font-size: .64rem;
                    margin-top: .16rem; }
.sales-chart { height: 5.8rem; display: flex; align-items: end; gap: 2px;
               border-bottom: 1px solid var(--line); padding-top: .55rem; margin-top: .25rem; }
.sales-bar { height: 100%; min-width: 1px; flex: 1; display: flex; align-items: end; }
.sales-bar i { display: block; width: 100%; min-height: 2px; background: var(--ink);
               transition: height .25s var(--ease); }
.sales-bar:hover i { background: var(--muted); }
.sales-dates { display: flex; justify-content: space-between; color: var(--muted);
               font-size: .58rem; margin-top: .18rem; }
.sales-unavailable { min-height: 9rem; display: flex; flex-direction: column;
                     justify-content: center; background: var(--panel); padding: .8rem; }
.sales-unavailable span { color: var(--muted); font-size: .72rem; }
.sales-method { margin-bottom: 1.5rem; }
/* Growth Control. Charts reuse .sales-chart so a bar means the same thing everywhere. */
.growth-charts { display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
                 border: 1px solid var(--line); margin-bottom: 1.5rem; }
.growth-chart { padding: .8rem; min-width: 0; }
.growth-chart + .growth-chart { border-left: 1px solid var(--line); }
.growth-chart-head { display: flex; align-items: baseline; justify-content: space-between;
                     gap: .6rem; flex-wrap: wrap; }
.growth-chart-head strong { font-size: .72rem; text-transform: uppercase;
                            letter-spacing: .09em; }
.growth-chart-head .muted { font-size: .68rem; }
/* A loss reads downward from the axis rather than as another tall bar. */
.sales-bar.negative { align-items: start; }
.sales-bar.negative i { background: var(--stop-ink); }
/* The expander is a quiet affordance under its week, not a second visible row. */
.growth-detail-row > td { padding: 0 !important; border-top: 0 !important; }
.growth-detail-row details.record { margin: 0; border: 0; }
.growth-detail-row details.record > summary { padding: .15rem .75rem; font-size: .66rem;
                                              color: var(--muted); letter-spacing: .04em;
                                              text-transform: uppercase; }
.growth-detail-row details.record[open] > summary { color: var(--ink); }
/* --- Growth · spend input (calendar + per-channel rows) --- */
.growth-input-nav { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap;
                    margin: .8rem 0 .6rem; }
.growth-month { font-size: 1.05rem; letter-spacing: -.01em; }
.growth-counts { margin-left: auto; font-size: .75rem; }
/* P4: the Growth month grid and week list are the system calendar
   (.cal / .cal-list). `.growth-ch` is now `.cal-ch`. */
/* P4: the legend swatches are `.cal-key i[data-state]` — one treatment,
   mirroring the cell, defined once with the calendar. */
.growth-channel-rows { width: 100%; border-collapse: collapse; }
.growth-channel-rows th { font-size: .62rem; font-weight: 900; text-transform: uppercase;
                          letter-spacing: .13em; color: var(--muted); text-align: left;
                          padding: .35rem .5rem; border-bottom: 1px solid var(--line); }
.growth-channel-rows th.num, .growth-channel-rows td.num { text-align: right; }
.growth-channel-rows td { padding: .45rem .5rem; border-bottom: 1px solid var(--line); }
.growth-note-row td { border-bottom: 0; padding-top: .7rem; }
/* ? help popover (inline <details>): quiet circle, overlay panel on open */
/* P6: ONE disclosure. `metric-help` was the block form under a card and
   `help-pop` a second, inline `?` — two patterns for the same job, with 14
   uses between them against 120 blocks of always-visible prose. There is now
   one component with two placements:
     .metric-help            block: a "Method" line under a card or a table
     .metric-help--inline    inline: the `?` disc beside a heading
   The rule the July Home/Orders pass set: a page shows its title, its numbers
   and its actions; how a number was derived lives behind one `?`. Methodology
   is NEVER deleted here, only demoted — this is a finance-adjacent OS. */
.metric-help--inline { position: relative; display: inline-block; margin: 0 0 0 .25rem;
                       border-top: 0; padding-top: 0; vertical-align: middle; }
.metric-help--inline > summary {
  list-style: none; cursor: pointer; width: 1.15rem; height: 1.15rem;
  border: 1px solid var(--line); border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: .62rem; font-weight: 900;
  color: var(--muted); background: var(--bg); text-transform: none; letter-spacing: 0; }
.metric-help--inline > summary::-webkit-details-marker { display: none; }
.metric-help--inline > summary:hover { color: var(--ink); border-color: var(--ink); }
.metric-help--inline[open] > summary { background: var(--ink); color: #fff; border-color: var(--ink); }
.metric-help--inline > div {
  position: absolute; z-index: 30; top: calc(100% + .4rem); left: 0;
  display: block; grid-template-columns: none; width: 20rem; max-width: 74vw;
  padding: .6rem .7rem; border: 1px solid var(--ink); background: var(--bg);
  box-shadow: 0 .6rem 1.4rem rgba(0,0,0,.14);
  font-size: .7rem; line-height: 1.45; color: var(--ink-2); font-weight: 400;
  text-transform: none; letter-spacing: 0; }
.metric-help--inline > div a { color: var(--ink); }
/* On a phone the popover would run off the right edge of a narrow heading. */
@media (max-width: 600px) {
  .metric-help--inline > div { left: auto; right: 0; width: min(20rem, 88vw); }
}
/* Seg control inline in a page h1 (Growth Week/Day): keep system proportions, not h1 scale. */
h1 .seg { vertical-align: middle; margin-left: .6rem; }
h1 
/* Readable bars: a stated scale down the left, value labels on top, dates underneath. */
.growth-plot { display: grid; grid-template-columns: auto minmax(0,1fr); gap: .5rem;
               align-items: stretch; }
.growth-axis { display: flex; flex-direction: column; justify-content: space-between;
               padding: .55rem 0 0; color: var(--muted); font-size: .58rem;
               font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.growth-bars { height: 8.5rem; gap: 3px; }
.growth-bars .sales-bar { position: relative; flex-direction: column;
                          justify-content: flex-end; }
.bar-value { position: absolute; top: -.85rem; left: 50%; transform: translateX(-50%);
             font-size: .55rem; font-weight: 800; color: var(--muted);
             font-variant-numeric: tabular-nums; white-space: nowrap; }
.sales-bar:hover .bar-value { color: var(--ink); }
.growth-xaxis { display: flex; gap: 3px; margin-left: 3.6rem; padding-top: .25rem;
                color: var(--muted); font-size: .55rem; }
.growth-xaxis > span { flex: 1; min-width: 0; text-align: center; overflow: hidden;
                       white-space: nowrap; }
/* Past ~10 bars the labels collide, so show every other one. */
.growth-xaxis > span:nth-child(even) { visibility: hidden; }
.growth-kpis { grid-template-columns: repeat(4,minmax(0,1fr)); }
/* Six cards, so three columns fill both rows exactly; a dead cell reads as a gap. */
.growth-kpis.three { grid-template-columns: repeat(3,minmax(0,1fr)); }
.growth-block-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
                     margin: 1rem 0 .5rem; }
.growth-block-head strong { font-size: .72rem; text-transform: uppercase;
                            letter-spacing: .09em; }
.growth-block-head .muted { font-size: .68rem; }
@media (max-width: 1240px) {
  .growth-kpis, .growth-kpis.three {
    grid-template-columns: repeat(2,minmax(0,1fr));
  }
}
.spend-form { margin-bottom: .6rem; }
.spend-grid { display: grid; grid-template-columns: repeat(5,minmax(0,1fr));
              gap: .6rem; margin-bottom: .6rem; }
@media (max-width: 900px) {
  .growth-charts, .spend-grid { grid-template-columns: 1fr; }
  .growth-chart + .growth-chart { border-left: 0; border-top: 1px solid var(--line); }
}
.supply-source-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr));
                      border: 1px solid var(--line); margin-bottom: .75rem; }
/* The whole card is the drilldown, so it needs no repeated "view exact records" link. */
.supply-source { padding: .8rem; border-right: 1px solid var(--line);
                 display: grid; gap: .2rem; min-width: 0; text-decoration: none; }
.supply-source:last-child { border-right: 0; }
a.supply-source:hover { background: var(--panel); }
.supply-source > strong { font-size: 1.05rem; }
.supply-source > span:not(.control-kpi-label) { color: var(--muted); font-size: .7rem; }
.supply-source .eta-list { display: grid; gap: .12rem; margin-top: .2rem; }
.supply-source .eta-list small { color: var(--muted); font-size: .66rem; }
.supply-source .eta-list small.overdue { color: var(--stop-ink); font-weight: 700; }
.warehouse-strip { display: grid; grid-template-columns: repeat(auto-fit,minmax(13rem,1fr));
                   border: 1px solid var(--line); margin-bottom: .75rem; }
.warehouse-strip > a { padding: .65rem .75rem; border-right: 1px solid var(--line);
                       text-decoration: none; display: grid; gap: .1rem; }
.warehouse-strip > a:hover { background: var(--panel); }
.warehouse-strip span, .warehouse-strip small { color: var(--muted); font-size: .68rem; }
.risk-register { display: grid; grid-template-columns: repeat(2,minmax(0,1fr));
                 border: 1px solid var(--line); margin-bottom: 1.5rem; }
.risk-register > a, .risk-register > .risk-static {
  display: grid; grid-template-columns: minmax(0,1fr) auto auto;
  align-items: center; gap: .75rem; padding: .55rem .7rem;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  text-decoration: none; font-size: .75rem;
}
.risk-register > a:hover { background: var(--panel); }
.risk-register .risk-static { background: var(--panel); color: var(--muted); }
.risk-register strong { font-variant-numeric: tabular-nums; }
@media (max-width: 900px) {
  /* The three KPIs go straight from 3-up to 1-up at the sm tier. There is
     deliberately NO 2-up step: a two-up grid leaves a dead third cell (Home
     minimalist pass, CLAUDE.md). P3 moved this boundary 700px -> 600px. */
  .control-action-head { display: none; }
  .control-action { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .sales-channel-grid { grid-template-columns: 1fr; }
  .sales-channel-card + .sales-channel-card { border-left: 0;
                                               border-top: 1px solid var(--line); }
}
@media (max-width: 600px) {
  .control-kpi-grid, .supply-source-grid, .risk-register { grid-template-columns: 1fr; }
  .control-kpi, .control-kpi:nth-child(n), .supply-source,
  .risk-register > a { border-right: 0; }
  .control-kpi { border-bottom: 1px solid var(--line); }
  .control-kpi:last-child { border-bottom: 0; }
  .control-action { grid-template-columns: 1fr; gap: .55rem; }
  .warehouse-strip { grid-template-columns: 1fr; }
  .sales-period-grid { grid-template-columns: 1fr; }
  .sales-period + .sales-period { border-left: 0; border-top: 1px solid var(--line); }
}
.readiness-grid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 1rem; }
.readiness-panel { border: 1px solid var(--line); padding: 1rem; }
.readiness-panel h2 { margin: 0 0 .65rem; font-size: .78rem; text-transform: uppercase;
                      letter-spacing: .08em; }
.readiness-panel ul { margin: 0; padding-left: 1.15rem; color: var(--ink-2); font-size: .82rem; }
.readiness-panel li + li { margin-top: .45rem; }

/* --- Knowledge Center --- */
/* ---------- Knowledge handbook: browse before you search ---------- */
/* Bordered cards with a real gap, not the 1px-gap-over-a-tinted-container trick: nine
   topics in a four-track grid leaves empty cells, and those would show as grey blocks. */
.topic-grid { display: grid; gap: .7rem; margin-bottom: 1.5rem;
              grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.topic-card { background: var(--bg); border: 1px solid var(--line);
              padding: .9rem 1rem; text-decoration: none;
              display: flex; flex-direction: column; gap: .3rem; }
.topic-card:hover { background: var(--panel); }
.topic-card strong { font-size: .95rem; }
.topic-count { font-size: 1.5rem; font-weight: 900; line-height: 1;
               font-variant-numeric: tabular-nums; }
.topic-card.is-empty .topic-count { color: var(--muted); }
.topic-blurb { color: var(--muted); font-size: .74rem; line-height: 1.45; }
.topic-flags { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: auto;
               padding-top: .4rem; }
.topic-head { margin-bottom: 1rem; }
.topic-head h2 { margin: .3rem 0 .15rem; font-size: 1.15rem; }
.topic-head p { margin: 0; font-size: .8rem; }

/* One answer per line: scannable, and the short answer is visible without a click. */
.answer-list { border: 1px solid var(--line); margin-bottom: 1.5rem; display: grid; }
.answer-row { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between;
              padding: .7rem .9rem; border-bottom: 1px solid var(--line);
              text-decoration: none; }
.answer-row:last-child { border-bottom: 0; }
.answer-row:hover { background: var(--panel); }
.answer-row-main { display: grid; gap: .15rem; min-width: 0; }
.answer-row-main strong { font-size: .88rem; }
.answer-row-answer { color: var(--muted); font-size: .76rem; line-height: 1.45;
                     max-width: 70ch; }
.answer-row-meta { display: flex; align-items: center; gap: .45rem; flex-shrink: 0; }

/* ---------- Answer finder: the search is the page ---------- */
.answer-search { border: 1px solid var(--line); padding: 1rem; margin-bottom: 1.25rem; }
.answer-search > label { display: block; font-size: .6rem; font-weight: 900;
  text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin-bottom: .35rem; }
.answer-search-row { display: flex; gap: .5rem; flex-wrap: wrap; }
.answer-search-row input { flex: 1; min-width: 15rem; font-size: 1rem; padding: .6rem .7rem; }
.answer-search .more-filters { margin-top: .8rem; }
.answer-card { border: 1px solid var(--line); padding: 1rem; background: var(--bg); }
.answer-list .answer-card { border: 0; border-bottom: 1px solid var(--line); }
.answer-card-head { display: flex; justify-content: space-between; gap: 1rem;
                    align-items: baseline; flex-wrap: wrap; }
.answer-card-head h2 { margin: 0; font-size: 1rem; }
.answer-card-head h2 a { color: var(--ink); text-decoration: none; }
.answer-card-head h2 a:hover { text-decoration: underline; text-underline-offset: 3px; }
.answer-card-actions { display: flex; gap: .45rem; flex-wrap: wrap; align-items: center; }

.knowledge-list { display: grid; gap: .75rem; }
.knowledge-card { border: 1px solid var(--line); padding: 1rem; background: var(--bg); }
.knowledge-card-head { display: flex; justify-content: space-between; gap: 1rem;
                       align-items: flex-start; }
.knowledge-card h2 { margin: .15rem 0 0; font-size: 1rem; }
.knowledge-card h2 a { color: var(--ink); text-decoration: none; }
.knowledge-card h2 a:hover { text-decoration: underline; text-underline-offset: 3px; }
.knowledge-id { color: var(--muted); font-size: .64rem; font-weight: 900;
                letter-spacing: .08em; text-transform: uppercase; }
.knowledge-badges { display: flex; flex-wrap: wrap; gap: .3rem; justify-content: flex-end; }
.approved-answer { margin: .8rem 0; font-size: .96rem; line-height: 1.55; max-width: 70rem; }
.knowledge-actions { display: flex; gap: .45rem; flex-wrap: wrap; align-items: flex-start; }
.inline-gap { position: relative; }
.inline-gap > summary { border: 1px solid var(--line); padding: .52rem .7rem;
                        text-transform: uppercase; letter-spacing: .06em; font-size: .66rem;
                        font-weight: 800; cursor: pointer; list-style: none; }
.inline-gap > summary::-webkit-details-marker { display: none; }
.inline-gap form { display: grid; gap: .5rem; margin-top: .5rem; min-width: 20rem; }
.inline-gap textarea, .richard-compose textarea { min-height: 6rem; }
.empty-panel { border: 1px dashed var(--line); padding: 2rem; text-align: center;
               color: var(--muted); }
.empty-panel h2 { color: var(--ink); margin: 0 0 .35rem; font-size: 1rem; }
.empty-panel p { margin: 0; }
.empty-panel p + p { margin-top: .6rem; }
.empty-panel.wide { text-align: left; padding: 1.5rem; }
.empty-panel.wide p { max-width: 70ch; }
.empty-panel .button-row, .empty-panel .btn { margin-top: .9rem; }

/* ---------- Night Shift Log ---------- */
/* ---------- Night shift: related-party tags ---------- */
.tagfield { display: flex; flex-direction: column; gap: .3rem; }
.tagfield-label { font-size: .62rem; font-weight: 800; text-transform: uppercase;
                  letter-spacing: .08em; color: var(--muted); }
.tagfield-box { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center;
                border: 1px solid var(--line); background: var(--field);
                padding: .35rem .4rem; min-height: 2.1rem; cursor: text; }
.tagfield-box:focus-within { border-color: var(--ink); }
.tagfield-chips { display: contents; }
.tagfield-chip { display: inline-flex; align-items: center; gap: .3rem;
                 background: var(--ink); color: #fff; font-size: .68rem; font-weight: 700;
                 padding: .15rem .2rem .15rem .4rem; }
.tagfield-chip button { background: none; border: 0; color: #fff; opacity: .65;
                        min-height: 0; min-width: 0;
                        font-size: .8rem; line-height: 1; padding: 0 .2rem; cursor: pointer; }
.tagfield-chip button:hover { opacity: 1; }
.tagfield-input { flex: 1 1 7rem; min-width: 5rem; border: 0; outline: none;
                  background: none; font: inherit; font-size: .78rem; padding: .1rem; }
.party-row { display: flex; flex-wrap: wrap; gap: .25rem; margin: .3rem 0 .1rem; }
.party { font-size: .64rem; font-weight: 700; letter-spacing: .02em; padding: .1rem .35rem;
         background: var(--neutral-bg); color: var(--neutral-ink); }
.party.lead { background: none; color: var(--ink); font-weight: 800;
              box-shadow: inset 0 0 0 1px var(--line); }

.night-jump { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
              border: 1px solid var(--line); background: var(--panel);
              padding: .45rem .6rem; margin-bottom: 1rem; font-size: .72rem; }
.night-jump label { font-size: .62rem; font-weight: 800; text-transform: uppercase;
                    letter-spacing: .08em; color: var(--muted); }
.night-jump input { font: inherit; font-size: .74rem; padding: .2rem .3rem;
                    border: 1px solid var(--line); background: var(--field);
                    width: auto; max-width: 10rem; flex: 0 0 auto; }
.night-jump-hint { margin-left: auto; color: var(--muted); }
.written-late { font-style: normal; font-size: .6rem; font-weight: 800;
                text-transform: uppercase; letter-spacing: .06em;
                background: var(--warn-bg); color: var(--warn-ink); padding: .05rem .25rem; }
.detail-actions { display: flex; align-items: center; gap: .4rem; flex-shrink: 0; }
a.cal-cell[data-state="neutral"]:hover .cal-n { color: var(--ink); }

/* ---------- Night shift: month calendar ---------- */
/* ======================================================================
   CALENDAR (P4: one component)
   ======================================================================
   ONE month grid. Four implementations collapsed here:
     .p-calendar   2rem cells, gap .2rem, centred number, round dot
     .cal-day      4.4rem cells, gap 1px on a rule, top-left number, marks
     .growth-day   3.1rem cells
     .growth-cal-row  a three-column LIST, not a grid
   The state COLOURS were already unified on 2026-09-09; P4 unifies the
   GEOMETRY, which is what Robin actually saw ("all have a different pattern").

   DENSITY IS A MODIFIER, NOT A SECOND COMPONENT (Robin's call, 2026-09-09).
   The Indonesia cell is the default: most compact, clearest state dots, best
   on a phone. Night-shift opts into `.cal--roomy` because its cell carries two
   marks plus a note count — and only on desktop. Below the md tier --roomy
   collapses back to the compact cell and the count rides next to the number,
   so a phone never renders a 4.4rem grid.

   states  data-state = ok | warn | stop | info | neutral
           .is-on     = the selected cell (hard ink border, the same selection
                        language as every other on-state in the OS)
   ---------------------------------------------------------------------- */
.cal {
  --cal-cell: 2rem;                 /* compact: the Indonesia geometry */
  --cal-num: .7rem;
  border: 1px solid var(--line); background: var(--field);
  max-width: 34rem;
}
.cal--wide { max-width: none; }
@media (min-width: 901px) {
  .cal--roomy { --cal-cell: 4.4rem; --cal-num: .74rem; }
}

/* header: title, stepper, selects, count -------------------------------- */
.cal-bar { display: flex; align-items: center; gap: var(--s2);
           padding: .55rem .6rem; border-bottom: 1px solid var(--line);
           background: var(--panel); font-size: .72rem; }
.cal-bar b { font-weight: 800; }
.cal-bar select { font: inherit; font-size: .76rem; font-weight: 700;
                  padding: .2rem .3rem; border: 1px solid transparent;
                  background: none; cursor: pointer; color: var(--ink); }
.cal-bar select:hover { border-color: var(--line); background: var(--bg); }
.cal-count { margin-left: auto; font-size: .62rem; font-weight: 800;
             text-transform: uppercase; letter-spacing: .08em;
             color: var(--muted); white-space: nowrap; }

/* the grid -------------------------------------------------------------- */
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
            gap: var(--s1); padding: var(--s2); }
.cal-head { font-size: .58rem; font-weight: 800; text-transform: uppercase;
            letter-spacing: .08em; color: var(--muted); text-align: center;
            padding-bottom: .15rem; }

/* one cell -------------------------------------------------------------- */
.cal-cell {
  position: relative; box-sizing: border-box;
  min-height: var(--cal-cell);
  display: grid; place-items: center;
  padding: .15rem;
  border: 1px solid transparent; border-radius: var(--radius);
  font-size: var(--cal-num); color: var(--ink); text-decoration: none;
  transition: background .16s var(--ease), color .16s;
}
a.cal-cell:hover { background: var(--panel); border-color: var(--line); }
a.cal-cell:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.cal-cell.is-empty { cursor: default; border-color: transparent; background: none; }
.cal-cell.is-out .cal-n { opacity: .3; }
.cal-cell.is-weekend { background: var(--panel); }
.cal-cell.is-today .cal-n { box-shadow: inset 0 0 0 1px var(--ink); padding: 0 .25rem; }
/* Selected: hard ink border on the day's own fill. Same language as every
   other on-state in the OS (Robin 2026-09-09: one calendar code). */
.cal-cell.is-on, a.cal-cell.is-on:hover { border-color: var(--ink); font-weight: 900; }
.cal-n { font-variant-numeric: tabular-nums; font-weight: 700; line-height: 1; }

/* the state dot — one mark, bottom-centre, in the compact cell ----------- */
.cal-dot { position: absolute; bottom: .2rem; left: 50%; transform: translateX(-50%);
           width: .36rem; height: .36rem; border-radius: 50%; }

/* state colours (unified 2026-09-09 — do not re-invent these) ------------
   complete -> ok · draft/partial/in-progress -> warn · missing -> stop ·
   future/no-data -> neutral. Draft and missing are deliberately a FILLED
   SQUARE with a hard outline, not a second dot: two lookalike dots told
   Robin nothing (screenshot 2026-09-02, resolved 2026-09-03). */
.cal-cell[data-state="ok"] .cal-dot { background: var(--ok-ink); }
.cal-cell[data-state="warn"] { background: var(--warn-bg); }
.cal-cell[data-state="warn"] .cal-dot { background: var(--warn-bg);
  border: 1.5px solid var(--warn-ink); border-radius: var(--radius); }
.cal-cell[data-state="stop"] { background: color-mix(in srgb, var(--muted) 22%, var(--field));
  border-color: var(--ink); }
.cal-cell[data-state="stop"] .cal-dot { background: color-mix(in srgb, var(--muted) 22%, var(--field));
  border: 1.5px solid var(--ink); border-radius: var(--radius); }
.cal-cell[data-state="info"] { background: var(--info-bg); }
.cal-cell[data-state="info"] .cal-dot { background: var(--info-ink); }
.cal-cell[data-state="neutral"] { color: var(--muted); }
.cal-cell[data-state="neutral"]:hover { color: var(--ink); }
a.cal-cell[data-state="warn"]:hover, a.cal-cell[data-state="stop"]:hover { filter: brightness(.96); }

/* marks + count — the roomy cell only ------------------------------------
   Below the md tier the cell is compact, so the marks row is inline next to
   the number instead of a second line, and the grid never grows. */
/* Compact cells still SHOW the marks — the collapse must not lose the note
   count. The cell grows a little (2rem -> ~2.6rem) only on days that have
   marks; a day with none stays exactly the Indonesia cell. */
.cal-marks { display: inline-flex; align-items: center; justify-content: center;
             gap: .2rem; line-height: 1; }
.cal-cell:has(.cal-marks) { grid-auto-flow: row; align-content: center; gap: .15rem; }
.cal-cell:has(.cal-marks) .cal-dot { display: none; }
.cal-marks i { width: .4rem; height: .4rem; display: inline-block; flex: 0 0 auto; }
.cal-marks i.urgent { background: var(--stop-ink); }
.cal-marks i.open { box-shadow: inset 0 0 0 1px var(--warn-ink); }
.cal-marks b { font-size: .62rem; font-weight: 700; font-variant-numeric: tabular-nums;
               line-height: 1; color: var(--muted); }
@media (min-width: 901px) {
  .cal--roomy .cal-cell { display: flex; flex-direction: column;
                          justify-content: space-between; align-items: stretch;
                          padding: .35rem .45rem; }
  .cal--roomy .cal-n { align-self: flex-start; }
  .cal--roomy .cal-dot { display: none; }
  .cal--roomy .cal-cell:has(.cal-marks) { display: flex; gap: 0; }
  .cal--roomy .cal-marks { display: flex; align-items: center;
                           justify-content: space-between; gap: .25rem; }
  .cal--roomy .cal-marks b { order: 2; }
}

/* legend ---------------------------------------------------------------- */
.cal-key { display: flex; flex-wrap: wrap; gap: .9rem; margin: 0;
           padding: .5rem .6rem; border-top: 1px solid var(--line);
           font-size: .62rem; color: var(--muted); }
.cal-key span { display: inline-flex; align-items: center; gap: .35rem; }
.cal-key b { color: var(--muted); font-variant-numeric: tabular-nums; font-weight: 700; }
.cal-key i { width: .45rem; height: .45rem; display: inline-block; flex: 0 0 auto; }
/* legend swatches mirror the cell treatment exactly */
.cal-key i[data-state="ok"] { background: var(--ok-ink); border: 1.5px solid var(--ok-ink);
                              border-radius: 50%; }
.cal-key i[data-state="warn"] { background: var(--warn-bg); border: 1.5px solid var(--warn-ink); }
.cal-key i[data-state="stop"] { background: color-mix(in srgb, var(--muted) 22%, var(--field));
                                border: 1.5px solid var(--ink); }
.cal-key i[data-state="info"] { background: var(--info-ink); border-radius: 50%; }
.cal-key i[data-state="neutral"] { background: var(--neutral-bg); border: 1.5px solid var(--line); }
.cal-key i.urgent { background: var(--stop-ink); }
.cal-key i.open { box-shadow: inset 0 0 0 1px var(--warn-ink); }
.cal-key.empty-month { font-size: .72rem; gap: .35rem; }
.cal-key.empty-month a { font-weight: 700; }

/* Growth's WEEK view stays a list — a week is a different object from a day
   (Robin) — but it adopts the same cell chrome, states and legend. */
.cal-list { border: 1px solid var(--line); background: var(--field); }
.cal-list-row { display: grid; grid-template-columns: 1fr auto 7rem; gap: .75rem;
                align-items: center; padding: .5rem .8rem;
                border-bottom: 1px solid var(--line); text-decoration: none;
                color: var(--ink); font-size: .76rem; }
.cal-list-row:last-child { border-bottom: 0; }
a.cal-list-row:hover { background: var(--panel); }
.cal-list-row.is-on { outline: 2px solid var(--ink); outline-offset: -2px; }
.cal-list-head { font-size: .62rem; font-weight: 900; text-transform: uppercase;
                 letter-spacing: .08em; color: var(--muted); background: var(--panel); }
.cal-list-key { font-weight: 700; }
.cal-list-key .chip { margin-left: .4rem; }
.cal-list-state { font-size: .72rem; font-weight: 800; text-transform: uppercase;
                  letter-spacing: .06em; text-align: right; }
.cal-list-row[data-state="ok"] .cal-list-state { color: var(--ok-ink); }
.cal-list-row[data-state="warn"] .cal-list-state { color: var(--warn-ink); }
.cal-list-row[data-state="stop"] .cal-list-state { color: var(--ink); }
.cal-list-row[data-state="neutral"] .cal-list-state { color: var(--muted); }
/* per-channel ticks, shared by the list row and the roomy cell */
.cal-ch { display: inline-flex; gap: .3rem; }
.cal-ch i { width: .45rem; height: .45rem; background: var(--line); display: inline-block; }
.cal-ch i.on { background: var(--ok-ink); border-radius: 50%; }

.cal-layout { display: grid; grid-template-columns: minmax(24rem, 1.2fr) minmax(19rem, 1fr);
              gap: 1rem; align-items: start; }

/* ---------- Night shift: selected-night pane ---------- */
.night-detail { border: 1px solid var(--line); min-height: 12rem; }
.detail { animation: detail-in .18s cubic-bezier(.22,1,.36,1) both; }
@keyframes detail-in { from { opacity: 0; transform: translateX(.5rem); } }
.detail-head { display: flex; justify-content: space-between; align-items: start; gap: .75rem;
               padding: .8rem .9rem; border-bottom: 1px solid var(--line); }
.detail-head h2 { margin: 0; font-size: .95rem; }
.detail-sub { margin: .15rem 0 0; font-size: .7rem; color: var(--muted); }
.urgent-text { color: var(--stop-ink); }
.recap { padding: .8rem .9rem; border-bottom: 1px solid var(--line); background: var(--panel); }
.recap h3, .detail-notes h3 { margin: 0 0 .4rem; font-size: .6rem; font-weight: 800;
                              text-transform: uppercase; letter-spacing: .1em;
                              color: var(--muted); }
.recap-body { margin: 0; font-size: .8rem; white-space: pre-wrap; }
.recap-trail { margin: .45rem 0 0; font-size: .66rem; color: var(--muted); }
.recap-none { margin: 0; font-size: .76rem; color: var(--muted); }
.recap-workbench { margin: 0 0 1rem; border: 1px solid var(--line); background: var(--panel); }
.recap-workbench > .section-head { padding: .8rem .9rem; border-bottom: 1px solid var(--line); }
.recap-workbench .section-head p { margin: .18rem 0 0; color: var(--muted); font-size: .7rem; }
.recap-edit { padding: .9rem; display: grid; gap: .5rem; }
.recap-edit label { font-size: .66rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .08em; }
.recap-edit textarea { width: 100%; resize: vertical; font: inherit; }
.recap-approve { padding: .75rem .9rem; border-top: 1px solid var(--line); display: flex;
  align-items: center; justify-content: space-between; gap: 1rem; }
.recap-approve p { margin: 0; color: var(--muted); font-size: .72rem; }
.recap-locked { margin: 0; padding: .9rem; white-space: pre-wrap; }
.recap-locked + .muted { margin: 0; padding: 0 .9rem .9rem; }
.detail-notes { padding: .8rem .9rem; display: flex; flex-direction: column; gap: .9rem; }
.detail-note > header { display: flex; flex-wrap: wrap; gap: .4rem; align-items: baseline;
                        font-size: .66rem; color: var(--muted); }
.detail-note > header b { font-size: .74rem; color: var(--ink);
                          font-variant-numeric: tabular-nums; }
.detail-note > p { margin: .3rem 0 .4rem; font-size: .8rem; white-space: pre-wrap; }
.detail-empty { padding: 2rem 1rem; text-align: center; color: var(--muted); font-size: .8rem; }
.detail-empty p { margin: 0 0 .2rem; }
@media (max-width: 900px) { .cal-layout { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .detail { animation: none; }
  .cal-cell { transition: none; }
}

.batch-preview { border: 1px solid var(--line); margin-top: .8rem; }
.batch-preview-head { margin: 0; padding: .5rem .75rem; background: var(--panel);
                      border-bottom: 1px solid var(--line); font-size: .64rem; font-weight: 800;
                      text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.batch-preview-row { padding: .65rem .75rem; border-bottom: 1px solid var(--line); }
.batch-preview-row:last-child { border-bottom: 0; }
.batch-preview-meta { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
                      margin-bottom: .3rem; font-size: .78rem; }
.batch-preview-row p { margin: 0; font-size: .76rem; color: var(--muted);
                       white-space: pre-wrap; max-height: 4.6em; overflow: hidden; }
.night-layout { display: grid; grid-template-columns: minmax(20rem,.8fr) minmax(28rem,1.2fr);
                gap: 1rem; align-items: start; }
.night-compose, .night-log { border: 1px solid var(--line); padding: 1rem; }
.section-head { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline;
                border-bottom: 1px solid var(--line); padding-bottom: .75rem; margin-bottom: .9rem; }
.section-head h2 { margin: .1rem 0 0; font-size: 1rem; }
.night-count { font-size: .7rem; color: var(--muted); font-weight: 800;
               text-transform: uppercase; letter-spacing: .08em; white-space: nowrap; }
/* `display: grid` on the class outranks the browser's own [hidden] rule, so the attribute
   has to be honoured explicitly or a hidden form stays on screen. */
.night-note-form[hidden], .night-inline-form[hidden] { display: none; }
.night-note-form, .night-inline-form { display: grid;
                                      grid-template-columns: repeat(2,minmax(0,1fr));
                                      gap: .75rem; }
.night-note-form > label, .night-inline-form > label, .night-tag-fields > label {
  display: grid; gap: .25rem; font-size: .62rem; font-weight: 900; text-transform: uppercase;
  letter-spacing: .07em; align-content: start; }
.night-note-form .span-2, .night-inline-form .span-2, .night-tag-fields .span-2 {
  grid-column: span 2; }
.night-note-form textarea, .night-inline-form textarea { font-family: var(--font);
                                                         resize: vertical; }
.night-tag-fields { grid-column: span 2; border: 1px solid var(--line); padding: .75rem;
                    display: grid; grid-template-columns: minmax(0,1.4fr) minmax(0,1fr);
                    gap: .65rem; margin: 0; }
.night-tag-fields legend { padding: 0 .35rem; font-size: .62rem; font-weight: 900;
                           text-transform: uppercase; letter-spacing: .08em;
                           color: var(--muted); }
.urgent-check { display: flex !important; grid-auto-flow: column; justify-content: start;
                align-items: center; align-self: end; min-height: 2.2rem; }
.urgent-check input { width: auto; }
.night-order-results { border: 1px solid var(--line); display: grid; }
.night-order-result { background: var(--bg); color: var(--ink); border: 0;
                      border-bottom: 1px solid var(--line); text-align: left; padding: .55rem;
                      display: grid; grid-template-columns: 6rem minmax(0,1fr) auto; gap: .6rem;
                      align-items: baseline; text-transform: none; letter-spacing: 0; }
.night-order-result:last-child { border-bottom: 0; }
.night-order-result:hover { background: var(--panel); }
.night-order-result span, .night-order-result small { color: var(--muted); font-size: .7rem; }
.night-entry-list { display: grid; gap: .65rem; }
.night-entry { border: 1px solid var(--line); padding: .8rem; }
.night-entry > header { display: flex; justify-content: space-between; gap: .75rem;
                        color: var(--muted); font-size: .7rem; }
.night-entry > header strong { color: var(--ink); font-size: .8rem; }
.night-entry-body { white-space: pre-wrap; margin: .6rem 0; line-height: 1.55; }
.night-tags { display: flex; flex-wrap: wrap; gap: .35rem; }
.night-tag { border: 1px solid var(--line); background: var(--panel); padding: .3rem .45rem;
             display: flex; align-items: center; gap: .35rem; font-size: .68rem; }
.night-tag.urgent { border-color: var(--stop-ink); background: var(--stop-bg); }
.night-tag a, .night-tag b { font-weight: 900; }
.night-tag em { color: var(--stop-ink); font-style: normal; font-weight: 900;
                text-transform: uppercase; font-size: .58rem; letter-spacing: .08em; }
.night-tag small { color: var(--muted); }
.unresolved { color: var(--warn-ink); font-weight: 800; }
.night-entry-delete { border-top: 1px solid var(--line); margin-top: .6rem; padding-top: .6rem; }
/* P3: .link-button is defined with the button component, as .btn--link. */
.night-entry-tools { margin-top: .65rem; border-top: 1px solid var(--line);
                     padding-top: .55rem; }
.night-entry-tools > summary { color: var(--muted); font-size: .68rem; cursor: pointer; }
.night-inline-form { margin-top: .7rem; border: 1px solid var(--line); padding: .7rem; }
.night-inline-form.add-tag { background: var(--panel); }
.night-inline-form button { justify-self: start; }
.night-submit { display: flex; justify-content: space-between; gap: 1rem; align-items: center;
                border-top: 1px solid var(--line); margin-top: 1rem; padding-top: 1rem; }
.night-submit div { display: grid; }
.night-submit span { color: var(--muted); font-size: .72rem; }
.night-history td { vertical-align: top; }

/* ---------- Knowledge entry form ---------- */
.entry-form { display: grid; gap: 1rem; max-width: 60rem; }
.form-block { border: 1px solid var(--line); padding: 1rem; }
.form-block h2 { margin: 0 0 .8rem; font-size: .75rem; text-transform: uppercase;
                 letter-spacing: .09em; color: var(--muted); }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: .8rem; }
.form-grid > label { display: grid; gap: .25rem; align-content: start;
  font-size: .62rem; font-weight: 900; text-transform: uppercase; letter-spacing: .07em; }
.form-grid > label.span-2 { grid-column: span 2; }
.form-grid input, .form-grid select, .form-grid textarea { width: 100%; }
.form-grid textarea { font-family: var(--font); font-size: .82rem; line-height: 1.5;
                      resize: vertical; }
.field-hint { text-transform: none; letter-spacing: 0; font-weight: 400;
              color: var(--muted); font-size: .72rem; }
.field-hint code { font-size: .7rem; background: var(--panel); padding: 0 .2rem; }
.form-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.onboarding-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 1rem; }
.onboarding-path { border: 1px solid var(--line); padding: 1rem; }
.onboarding-path h2 { margin: .15rem 0 0; font-size: 1rem; }
.onboarding-path-head { display: flex; justify-content: space-between; gap: 1rem;
                        align-items: baseline; }
.path-progress { font-weight: 900; font-variant-numeric: tabular-nums; white-space: nowrap; }
.onboarding-steps { margin: 1rem 0 0; padding: 0; list-style: none; counter-reset: onboard; }
.onboarding-steps li { counter-increment: onboard; display: grid;
                       grid-template-columns: minmax(0,1fr) auto; gap: .75rem;
                       border-top: 1px solid var(--line); padding: .75rem 0;
                       align-items: center; }
.onboarding-steps li > div::before { content: counter(onboard) ". "; font-weight: 900; }
.onboarding-steps li a { color: var(--ink); font-weight: 800; }
.onboarding-steps li span:not(.operational-state) { display: block; color: var(--muted);
                                                    font-size: .72rem; margin-top: .15rem; }
.richard-compose { border: 1px solid var(--line); padding: 1rem; display: grid; gap: .6rem;
                   margin-bottom: 1.25rem; }
.richard-compose label, .governance-action label { font-size: .68rem; font-weight: 900;
                                                   text-transform: uppercase;
                                                   letter-spacing: .06em; }
.draft-body { white-space: pre-wrap; background: var(--panel); border: 1px solid var(--line);
              padding: .8rem; line-height: 1.5; font-family: var(--font); font-size: .82rem; }
.citation-list { display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0; }
.citation-list a { border: 1px solid var(--line); padding: .25rem .45rem; color: var(--ink);
                   font-size: .7rem; text-decoration: none; }
.button-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: end;
              margin-top: .65rem; }
.button-row form { margin: 0; }
.button-row label { display: grid; gap: .3rem; font-size: .68rem; font-weight: 900;
                    text-transform: uppercase; letter-spacing: .06em; }
.escalation-list { color: var(--stop-ink); font-size: .8rem; }
.knowledge-detail-grid { display: grid; grid-template-columns: minmax(0,1fr) 20rem;
                         gap: 1.5rem; align-items: start; }
.knowledge-primary { display: grid; gap: 1.5rem; }
.knowledge-primary section { border-top: 1px solid var(--line); padding-top: 1rem; }
.knowledge-primary h2, .knowledge-governance h2 { margin: 0 0 .65rem; font-size: .9rem;
                                                   text-transform: uppercase;
                                                   letter-spacing: .06em; }
.answer-hero { border: 1px solid var(--line); padding: 1.1rem; background: var(--panel); }
.answer-hero p { font-size: 1.08rem; line-height: 1.6; margin: .45rem 0 .8rem; }
.long-answer { white-space: pre-wrap; line-height: 1.65; max-width: 70rem; }
.knowledge-governance { border: 1px solid var(--line); padding: 1rem; position: sticky; top: 5rem; }
.knowledge-governance dl, .product-fact-grid dl { display: grid;
                                                  grid-template-columns: 7.5rem 1fr;
                                                  gap: .45rem .65rem; font-size: .76rem; }
.knowledge-governance dt, .product-fact-grid dt { color: var(--muted); }
.knowledge-governance dd, .product-fact-grid dd { margin: 0; overflow-wrap: anywhere; }
.knowledge-governance h3 { margin: 1rem 0 .4rem; font-size: .72rem; text-transform: uppercase;
                           letter-spacing: .06em; }
.knowledge-governance ul { padding-left: 1rem; font-size: .76rem; }
.governance-action { display: grid; gap: .4rem; border-top: 1px solid var(--line);
                     padding-top: .75rem; margin-top: .75rem; }
.wide { width: 100%; }
.product-fact-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: .75rem; }
.product-fact-grid article { border: 1px solid var(--line); padding: .85rem; }
.product-fact-grid h3 { margin: .2rem 0 .65rem; font-size: .92rem; }
.evidence-list { padding: 0; list-style: none; display: grid; gap: .5rem; }
.evidence-list li { border: 1px solid var(--line); padding: .7rem; display: grid; gap: .25rem; }
.evidence-list code { overflow-wrap: anywhere; }
.evidence-list span { color: var(--muted); font-size: .72rem; }
.version-list { padding-left: 1.3rem; }
.version-list li { padding: .35rem 0; }
.version-list span { display: block; color: var(--muted); font-size: .7rem; }
.notice.stop { background: var(--stop-bg); color: var(--stop-ink); }

/* --- price preview --- */
.price-table td { padding: .42rem 0; border-bottom: 1px solid var(--line); font-size: .84rem; }
.price-table tr:last-child td { border-bottom: 0; }
.price-table td:first-child { color: var(--muted); text-transform: uppercase; letter-spacing: .05em;
                              font-size: .66rem; font-weight: 800; }
.price-table td:last-child { text-align: right; font-variant-numeric: tabular-nums; font-weight: 700; }
code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: .82em;
       background: var(--panel); padding: .05rem .3rem; }

@media (prefers-reduced-motion: reduce) {
  *, main { animation: none !important; transition: none !important; }
}
/* --- Mobile nav (≤900px): the sidebar becomes an off-canvas drawer. --- */
/* Robin 2026-09-07: the old phone layout collapsed to an icon rail that set
   .nav-sub { display: none }, so phone users could not reach ANY sub-tab
   (production Shipments/Ready stock/HR/Analysis included). On phones the
   drawer now carries the FULL desktop nav — labels AND sub-tabs — opened
   from the topbar hamburger; the desktop collapse rail is untouched. */
.nav-burger { display: none; }
.nav-backdrop { display: none; }
@media (max-width: 900px) {
  /* P3: the topbar used to wrap at 720px. 720 is not a tier, so the wrap moves
     up to md — nothing is lost in the 600-720 band the old rule covered. */
  .topbar { flex-wrap: wrap; gap: .75rem; }
  .nav-burger { display: inline-flex; flex-shrink: 0; }
  .nav-burger svg { width: 16px; height: 16px; }
  .brand .nav-toggle { display: none; } /* the burger owns nav open/close on phones */
  .sidebar { position: fixed; left: 0; top: 0; bottom: 0; height: 100vh; height: 100dvh;
             width: 15rem; flex-basis: 15rem; transform: translateX(-100%);
             transition: transform .18s var(--ease); z-index: 100; }
  body.nav-open .sidebar { transform: translateX(0); box-shadow: 0 0 2rem rgba(0,0,0,.25); }
  body.nav-open .nav-backdrop { display: block; position: fixed; inset: 0;
                                background: rgba(0,0,0,.4); z-index: 90; }
  /* A saved 'compact' preference must never re-hide the ROW LABELS inside the
     phone drawer — force the full nav regardless of html.nav-compact.
     The drawer system (2026-09-12) now owns the sub-tabs at every width, so
     `.nav-sub` is never force-opened here: a row opens its own drawer on tap,
     and the row the phone lands on arrives already open from the server. */
  html.nav-compact .sidebar { width: 15rem; flex-basis: 15rem; }
  html.nav-compact .wordmark { display: block; }
  html.nav-compact .nav-group-label { display: block; }
  html.nav-compact .nav-item { justify-content: flex-start; padding: .45rem .95rem; gap: .6rem; }
  html.nav-compact .nav-item .lbl { display: inline; }
  html.nav-compact .nav-chev { display: inline-flex; }
  /* A saved desktop 'compact' preference must never re-break sub-tab
     reachability on a phone (the 2026-09-07 bug): inside the phone drawer the
     rows open their own drawer even under html.nav-compact. Outranks the
     top-level `html.nav-compact .nav-sub { display: none }`. */
  html.nav-js.nav-compact .nav-sub.open { display: flex; }
  .kpi-grid.five { grid-template-columns: repeat(3, minmax(0,1fr)); }
  .knowledge-detail-grid { grid-template-columns: 1fr; }
  .knowledge-governance { position: static; }
  .headline-row { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .detail-line { grid-template-columns: 6rem minmax(0,1fr); }
  .night-layout { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  .grid, .grid.two { grid-template-columns: 1fr 1fr; }
  .kpi-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .kpi-grid.three, .kpi-grid.five { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .module-grid, .integration-grid, .readiness-grid { grid-template-columns: 1fr; }
  .action-row { grid-template-columns: 1fr; gap: .25rem; }
  details.record > summary { grid-template-columns: 1fr 1fr; }
  .onboarding-grid, .product-fact-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .form-grid > label.span-2 { grid-column: auto; }
  .night-note-form, .night-inline-form, .night-tag-fields { grid-template-columns: 1fr; }
  .night-note-form .span-2, .night-inline-form .span-2, .night-tag-fields .span-2,
  .night-tag-fields { grid-column: auto; }
  .answer-row { flex-direction: column; gap: .4rem; }
  .headline-row { grid-template-columns: 1fr; }
  .headline.span-2 { grid-column: auto; }
  .detail-facts { grid-template-columns: 1fr; }
  .detail-facts dt { margin-top: .3rem; }
  .knowledge-card-head { display: grid; }
  .knowledge-badges { justify-content: flex-start; }
}
@media (max-width: 600px) {
  /* Keep the fixed-height shell controls on one row. The user/role label remains available
     above this breakpoint; hiding it here prevents Logout from colliding with page headings.
     P3: was 520px — folded into the sm tier. */
  .topbar { flex-wrap: nowrap; gap: .35rem; padding: .5rem .65rem; }
  .topbar .whoami, .topbar .page-title { display: none; }
  .topbar-search input { width: 5rem; }
  .topbar .market-toggle a { padding: .3rem .42rem; font-size: .56rem; }
}

/* ===========================================================================
   P1 (2026-09-09) — TOUCH. Robin: "many elements are not displaying properly
   on mobile". The single largest cause was not layout at all: every field in
   the OS was .9rem = 14.4px, and iOS Safari force-zooms the viewport when you
   focus an input under 16px AND does not restore the zoom on blur. On a
   data-entry OS that fires on the first tap of the day, after which every
   element is off-screen and nothing lines up with the sticky chrome.

   Scoped to `pointer: coarse` (a real touch device, at any width — an iPad in
   landscape is 1024px and still zooms) OR the sm tier. Mouse-driven desktops
   keep the dense .9rem sizing the tables were designed around, so this cannot
   regress the factory's desktop board.
   ======================================================================== */
@media (pointer: coarse), (max-width: 900px) {
  /* --- the zoom fix. Nothing else here matters if this is missing. ---
     `!important` is deliberate and is limited to the two platform constraints.
     Ten module rules set a competing size at higher specificity — chiefly
     `.p-input-form input[type="number"] { font: inherit }` (0,2,1), which
     silently reverted this to 13-14px in the Indonesia input grid, the exact
     surface the fix exists for. A 16px field is not a style preference; it is
     the condition under which iOS does not zoom. Anything that wants to look
     smaller must do it above the md tier, not here. */
  input, select, textarea {
    font-size: var(--field-font) !important;   /* 16px */
    min-height: var(--tap) !important;
    padding: .5rem .65rem;
  }
  input[type="checkbox"], input[type="radio"] {
    min-height: 0 !important; width: 1.35rem; height: 1.35rem;
    accent-color: var(--ink);
  }
  /* A date input on iOS renders its own control; let it size to the tap target. */
  input[type="date"] { min-height: var(--tap); }

  /* --- 44px on everything tappable ------------------------------------
     After P3 every control is a `.btn`, so this is one selector instead of
     the 18 module-specific ones it used to have to name. `.btn--sm` only
     drops to 36px under (min-width:901px) and (pointer:fine), so it is a
     full target here too. */
  button, .btn, .cal-step, .col-menu-btn, .tagfield-chip button {
    min-height: var(--tap);
    display: inline-flex; align-items: center; justify-content: center;
  }
  /* Icon-only controls need the width too, or the target is a 44px-tall sliver. */
  .btn--icon, .cal-step, .col-menu-btn { min-width: var(--tap); }
  /* ...but a text link with no chrome must not become a 44px block. */
  .btn--link, .link-button { min-height: 0; }

  /* A tap target inside a table cell must not force the cell to bleed. */
  td button, td .btn { max-width: 100%; }

  /* --- links used as controls ----------------------------------------- */
  .rowlink, .tabs a, .nav-item, .nav-sub a, .topbar .market-toggle a,
  header .market-toggle a { min-height: var(--tap); display: flex;
                            align-items: center; }
  .tabs a { padding-top: 0; padding-bottom: 0; }
}

/* Compact controls are a DESKTOP affordance only. Above the md tier a mouse is
   precise enough for 36px; below it, the rule above wins. */
@media (min-width: 901px) and (pointer: fine) {
  .col-menu-btn { min-height: var(--tap-sm); }
}

/* --- P1: page gutter. `main` held a fixed 0 1.5rem at EVERY width while the
   production module used .65rem, so moving between modules shifted every left
   edge by ~14px. Both now meet at the sm tier. --- */
@media (max-width: 600px) {
  main { padding: 0 .9rem; margin-top: .9rem; }
}

/* ===========================================================================
   P2 (2026-09-09) — TABLES. 24 of the 40 table pages had no scroll container,
   so a wide table widened the DOCUMENT: the page dragged sideways underneath a
   sticky top bar that stayed at viewport width, and the content no longer lined
   up with the chrome. That is the "buttons and cells are not aligned" report.

   Two strategies, chosen by what the table IS:
     RECORD  (one row = one thing: a shipment, an employee, a channel)
             -> `.table-wrap fit t-cards`, becomes one card per row under 600px.
     MATRIX  (columns are positions: the month board, the heatmap, the input
             grid) -> `.table-wrap fit stick-1`, keeps the grid and scrolls, with
             the row label pinned so it survives the scroll.

   `.table-wrap` itself is unchanged — the 30 scan tables that already relied on
   its 62rem min-width and max-height keep it. `.fit` is what the newly wrapped
   (mostly small) tables use so they are NOT forced to 62rem on desktop.
   ======================================================================== */
.table-wrap.fit { max-height: none; }
.table-wrap.fit > table, .table-wrap.fit table { min-width: 0; }

/* Pin the first column on a matrix so the division/date label stays visible. */
.table-wrap.stick-1 th:first-child,
.table-wrap.stick-1 td:first-child {
  position: sticky; left: 0; z-index: 1; background: var(--bg);
  box-shadow: inset -1px 0 0 var(--line);
}
.table-wrap.stick-1 thead th:first-child { z-index: 3; background: var(--panel); }
.table-wrap.stick-1 tbody tr:hover td:first-child { background: var(--panel); }

@media (max-width: 600px) {
  /* --- RECORD tables become cards ------------------------------------- */
  .t-cards { border: 0; overflow: visible; }
  .t-cards table { display: block; width: 100%; }
  .t-cards thead { display: none; }
  .t-cards tbody { display: flex; flex-direction: column; gap: var(--s2); }
  .t-cards tbody tr {
    display: grid; grid-template-columns: minmax(0, 1fr);
    border: 1px solid var(--line); background: var(--bg); padding: var(--s2);
  }
  .t-cards tbody tr:hover { background: var(--bg); }
  .t-cards tbody td {
    display: grid; grid-template-columns: 9rem minmax(0, 1fr);
    gap: var(--s1) var(--s3); align-items: center; justify-items: start;
    padding: var(--s1) 0; border-bottom: 1px solid var(--line);
    font-size: .88rem; text-align: left;
  }
  /* The first column is the record's identity in almost every table here
     (division, employee, SKU, shipment). As a labelled row it reads as just
     another field; as the card's heading it gives the stack a spine. */
  .t-cards tbody td:first-child {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
    font-weight: 800; font-size: .95rem;
    padding-bottom: var(--s2); margin-bottom: var(--s1);
    border-bottom: 1px solid var(--ink);
  }
  .t-cards tbody td:first-child::before { content: none; }
  .t-cards tbody td:first-child > form { margin: 0; }
  .t-cards tbody td:last-child { border-bottom: 0; }
  .t-cards tbody td::before {
    content: attr(data-label);
    font-size: .58rem; font-weight: 900; text-transform: uppercase;
    letter-spacing: .09em; color: var(--muted); line-height: 1.3;
  }
  /* A cell with no header label (control columns) spans the full card width. */
  .t-cards tbody td:not([data-label]) { grid-template-columns: minmax(0, 1fr); }
  .t-cards tbody td:not([data-label])::before { content: none; }
  /* `.num` centres for a grid; inside a card it reads as a labelled value. */
  .t-cards tbody td.num { text-align: left; }
  .t-cards tbody td > input, .t-cards tbody td > select, .t-cards tbody td > textarea {
    width: 100%; justify-self: stretch;
  }
  /* Must restate the width: the generic `.t-cards tbody td > input` rule above
     is (0,1,3) and outranks the P1 `input[type=checkbox]` (0,1,1) sizing. */
  .t-cards tbody td > input[type="checkbox"],
  .t-cards tbody td > input[type="radio"] {
    width: 1.35rem; justify-self: start;
  }
  .t-cards tbody td > button, .t-cards tbody td > .btn { justify-self: start; }
  /* Rows that span (overtime detail, per-person drawer, "no records") are not
     records — leave them as one full-width block inside the card stack. */
  .t-cards tbody tr[data-rowspan] { display: block; padding: var(--s2); }
  .t-cards tbody tr[data-rowspan] td { display: block; border-bottom: 0; }
  .t-cards tbody tr[data-rowspan] td::before { content: none; }
  .t-cards tbody tr[data-rowspan] td:empty { display: none; }

  /* --- MATRIX tables keep the grid, lose the forced desktop width ------- */
  .table-wrap.stick-1 { max-height: none; }
  .table-wrap.stick-1 td, .table-wrap.stick-1 th { white-space: nowrap; }
}
/* The card head keeps the metric name left and its window toggle right (Robin
   2026-09-11). The toggle is the system segmented group, only smaller — it never
   changes the value's size or the card's height. The head owns the gap above the
   value, so the number clears both the card edge and the toggle. */
.control-kpi-head { display: flex; align-items: center; justify-content: space-between;
                    gap: .6rem; min-height: 1.4rem; margin-bottom: .7rem; }
.control-kpi-head .control-kpi-label { min-width: 0; }
.control-kpi-head .seg { flex-shrink: 0; }
.control-kpi-head .seg > .btn { padding: .2rem .5rem; font-size: .6rem; }
