/* DSS Virtual Office — the steering surface.
 *
 * Replaces the palette adopted verbatim from the reference dashboard. That palette was a
 * third palette: neither the DSS brand (`dss-design-system`) nor a system of its own. Three things
 * changed here, and only these three:
 *
 *  1. TYPE HAS A FLOOR. Every persistent label used to sit at 8.5–10.6px, and the muted ink at 3.4:1
 *     contrast — below WCAG AA, and below what anything mainstream ships (12px is the floor at Linear,
 *     Stripe, GitHub, Vercel). Text at the edge of resolvability makes the eye re-focus, and that
 *     effort reads as clutter rather than as small text. Nothing persistent is under 12px now.
 *  2. THE ACCENT HAS ONE JOB. It marked links, tags, stars, runes, chart lines, rails and buttons —
 *     used everywhere, it signalled nothing. It now marks the selected state and the primary action.
 *     Semantic colour (good/warn/crit) is a separate axis and never doubles as the accent.
 *  3. LIGHT IS THE DEFAULT, dark is a preference. This surface is read by an MT and shown in a
 *     prospect conversation; dark-first is a developer-tool convention, not a boardroom one.
 *
 * Uppercase mono is no longer the label voice — it is reserved for figures, dates and ids, where a
 * fixed advance actually buys something.
 */

/* The DSS type (dss-design-system): Space Grotesk for headings and figures, Inter for text. Served from
   this app, not from a font CDN — a steering screen should not tell a third party who opened it. */
@font-face { font-family: "Inter"; src: url("fonts/Inter-Variable.ttf") format("truetype"); font-weight: 100 900; font-display: swap }
@font-face { font-family: "Space Grotesk"; src: url("fonts/SpaceGrotesk-400.ttf") format("truetype"); font-weight: 400 500; font-display: swap }
@font-face { font-family: "Space Grotesk"; src: url("fonts/SpaceGrotesk-700.ttf") format("truetype"); font-weight: 600 700; font-display: swap }

:root {
  color-scheme: light;

  /* Ground and ink — cool neutrals, biased toward the accent so they read as chosen, not defaulted. */
  /* The v5 ground (2026-09-16): dss-design-system "Papier" under white cards, warm ink. */
  --bg: #F9F6F0;  /* tokens.json color.base.papier */
  --surface: #FEFEFE;  /* the brand white is #FFFFFF (color.base.wit); this surface keeps #FEFEFE, invisible and fenced by the contrast test */
  --surface-2: #F1EEE7;
  --ink: #1A1410;  /* tokens.json color.text-on-light.ink */
  --ink-2: #4A4540;   /* tokens.json color.text-on-light.ink-2 */
  --ink-3: #5A6270;   /* tokens.json color.text-on-light.meta — the floor for muted labels, never lighter */
  --rule: #EDE8DC;  /* tokens.json color.base.papier-2 */
  --rule-2: #D9D2C3;

  /* Overlay separation, and why it is a token instead of a literal.
     The scrim used to be `rgba(10, 22, 40, .5)` in both themes — and in dark that is EXACTLY `--bg`,
     so it darkened nothing: a panel measured 1.07:1 against its own backdrop (light: 3.62:1). That is
     why the light theme read and the dark one did not.
     Dark-on-dark cannot reach 3:1 by luminance at all — no scrim/panel pair gets past ~1.4 — so there
     the separation comes from `--panel-edge`, which reaches 3.4:1 against both the panel and the
     scrimmed ground. `test/frontend-floors.test.js` measures both routes and fails below 3. */
  --scrim: rgba(19, 26, 36, .55);   /* panel 4.09:1 against the scrimmed ground */
  --panel-edge: #C9D1DA;

  /* One accent: selected state + primary action. `-fill` is the brand blue for bars and areas, where
     the contrast that matters is against the track, not against text.
     `--accent` has TWO grounds, not one. It was picked against `--surface` alone and sat at 5.17:1
     there — comfortable — while measuring 4.48:1 on `--accent-soft`, just under the floor. That is
     the ground it lands on in every selected state (`.domsw button.on`, `.pill.top`, `.iconbtn.on`,
     `.modal .oc.on`, `.mwho.app`), so the one place the accent is most used was the one place it did
     not qualify. Both grounds are held by `frontend-floors.test.js` now. */
  --accent: #205CE0;        /* tokens.json color.accent-ink-on-light.blauw; 5.72:1 on surface, 4.96:1 on --accent-soft — safe for small text on both */
  --accent-fill: #3B82F6;   /* tokens.json color.accent.blauw */
  --accent-soft: #E8EFFD;

  /* Semantic — a separate axis from the accent. Text tones meet AA; `-fill` tones are for bars/dots. */
  --good: #15803D;  --good-fill: #22C55E;  --good-soft: #E6F4EA;
  --warn: #9A5B06;  --warn-fill: #F59E0B;  --warn-soft: #FBF0DC;
  --crit: #B91C1C;  --crit-fill: #EF4444;  --crit-soft: #FBE9E9;
  --idle-fill: #94A3B8;
  /* The delivery window's two directions (2026-09-20; pull requests left for a neutral strip on
     2026-09-21, dss-virtual-office#227). Not the status trio: green and amber already mean good and
     warning here, and a series may never borrow a state's colour. Dark gets its OWN steps of the same
     hues, never an automatic flip: at the light values teal falls outside the dark lightness band. */
  --flow-issues: #3B82F6; --flow-closed: #14B8A6;

  --sans: "Inter", -apple-system, "Segoe UI", system-ui, sans-serif;
  --display: "Space Grotesk", -apple-system, "Segoe UI", system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* The scale. 12px is the floor for anything that stays on screen. */
  --t-micro: 12px; --t-sm: 13px; --t-base: 15px; --t-md: 16px;
  --t-lg: 19px; --t-xl: 24px; --t-2xl: 30px;

  --r: 10px; --r-s: 7px;
  /* Theme-independent: the Nacht sidebar and topbar (dark in both themes, the v5 frame), text on a
     filled accent or status, and the shadows. Named here so no rule below carries a literal colour. */
  --on-fill: #FFFFFF;
  --nav-bg: #0A1628; --nav-raise: #162032; --nav-rule: #1E293B; --nav-btn: #16243A;
  --nav-ink: #F1F5F9; --nav-ink-2: rgba(241, 245, 249, .78); --nav-ink-3: rgba(241, 245, 249, .72);
  --nav-meta: rgba(241, 245, 249, .6); --nav-accent: #3B82F6; --nav-scrim: rgba(10, 22, 40, .45);
  --sh-card: 0 1px 2px rgba(26, 20, 16, .04), 0 8px 24px rgba(26, 20, 16, .05);
  --sh-card-hover: 0 1px 2px rgba(26, 20, 16, .06), 0 12px 28px rgba(26, 20, 16, .09);
  --sh-soft: 0 4px 12px rgba(26, 20, 16, .04);
  --sh-hair: 0 1px 2px rgba(26, 20, 16, .04); --sh-hair-2: 0 1px 2px rgba(26, 20, 16, .06);
  --sh-seg: 0 1px 2px rgba(0, 0, 0, .12); --sh-menu: 0 12px 32px rgba(26, 20, 16, .18);
  --sh-overlay: 0 20px 60px rgba(0, 0, 0, .45); --sh-dialog: 0 24px 60px rgba(0, 0, 0, .28);
  --sh-login: 0 12px 40px rgba(19, 26, 36, .1);
  --shadow: 0 1px 2px rgba(19, 26, 36, .05), 0 1px 3px rgba(19, 26, 36, .04);
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg: #0A1628;            /* dss-design-system "Nacht" */
    --surface: #121D30;
    --surface-2: #18253A;
    --ink: #F1F5F9;
    --ink-2: #B4C0CE;
    --ink-3: #93A1B2;         /* 7.0:1 on Nacht — the old palette sat at 3.4:1 */
    --rule: #1E2C42;
    --rule-2: #33445E;
    --scrim: rgba(2, 5, 9, .70);   /* darker than the ground, so it actually darkens */
    --panel-edge: #5A7099;         /* 3.4:1 against the panel, 4.0:1 against the scrimmed ground */
    --accent: #7FB0FF;
    --accent-fill: #3B82F6;
    --accent-soft: #16273F;
    --good: #4ADE80;  --good-fill: #22C55E;  --good-soft: #10261A;
    --warn: #FBBF24;  --warn-fill: #F59E0B;  --warn-soft: #2A2011;
    --crit: #F87171;  --crit-fill: #EF4444;  --crit-soft: #2B1616;
    --idle-fill: #64748B;
    --flow-issues: #4F8DF7; --flow-closed: #0D9488;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .2);
  }
}

/* The explicit toggle must win over the OS preference in BOTH directions. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0A1628; --surface: #121D30; --surface-2: #18253A;
  --ink: #F1F5F9; --ink-2: #B4C0CE; --ink-3: #93A1B2;
  --rule: #1E2C42; --rule-2: #33445E;
  --scrim: rgba(2, 5, 9, .70); --panel-edge: #5A7099;
  --accent: #7FB0FF; --accent-fill: #3B82F6; --accent-soft: #16273F;
  --good: #4ADE80; --good-fill: #22C55E; --good-soft: #10261A;
  --warn: #FBBF24; --warn-fill: #F59E0B; --warn-soft: #2A2011;
  --crit: #F87171; --crit-fill: #EF4444; --crit-soft: #2B1616;
  --idle-fill: #64748B;
  --flow-issues: #4F8DF7; --flow-closed: #0D9488;
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 1px 3px rgba(0, 0, 0, .2);
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #F9F6F0; --surface: #FEFEFE; --surface-2: #F1EEE7;
  --ink: #1A1410; --ink-2: #4A4540; --ink-3: #5A6270;
  --rule: #EDE8DC; --rule-2: #D9D2C3;
  --scrim: rgba(19, 26, 36, .55); --panel-edge: #C9D1DA;
  --accent: #205CE0; --accent-fill: #3B82F6; --accent-soft: #E8EFFD;
  --good: #15803D; --good-fill: #22C55E; --good-soft: #E6F4EA;
  --warn: #9A5B06; --warn-fill: #F59E0B; --warn-soft: #FBF0DC;
  --crit: #B91C1C; --crit-fill: #EF4444; --crit-soft: #FBE9E9;
  --idle-fill: #94A3B8;
  --flow-issues: #3B82F6; --flow-closed: #14B8A6;
  --shadow: 0 1px 2px rgba(19, 26, 36, .05), 0 1px 3px rgba(19, 26, 36, .04);
}

* { box-sizing: border-box }
html, body { margin: 0 }
body {
  background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: var(--t-base); line-height: 1.5;
  -webkit-font-smoothing: antialiased; min-height: 100vh;
}
button, input, select, textarea { font-family: inherit }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important } }
.hidden { display: none !important }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0) }

.wrap { max-width: 1440px; margin: 0 auto; padding: 0 clamp(1rem, 3vw, 2rem) 4rem }

/* ── header ───────────────────────────────────────────────────────────────── */
.brand { display: flex; align-items: center; gap: .6rem; min-width: 0 }
.mark {
  width: 26px; height: 26px; flex: none; border-radius: 7px; display: grid; place-items: center;
  background: var(--accent-fill);
}
.mark::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--on-fill); transform: rotate(45deg) }
.brand h1 { font-family: var(--display); font-size: var(--t-md); font-weight: 650; letter-spacing: -.015em; margin: 0; white-space: nowrap }
.brand .sub { font-size: var(--t-micro); color: var(--ink-3); margin-top: 1px }

/* Segmented switches — the only place besides the primary button where the accent appears. */
.seg { display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--rule); border-radius: 8px; padding: 2px }
.seg button {
  font-size: var(--t-micro); font-weight: 550; color: var(--ink-3); background: none; border: none;
  border-radius: 6px; padding: .3rem .6rem; cursor: pointer; white-space: nowrap;
}
.seg button:hover { color: var(--ink) }
.seg button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow) }
.iconbtn {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--rule); background: var(--surface);
  color: var(--ink-2); font-size: var(--t-sm); cursor: pointer; flex: none; display: grid; place-items: center;
}
.iconbtn:hover { border-color: var(--rule-2); color: var(--ink) }
/* ⚙ stays lit while its page is open — the only thing in the header that says where you are, now that
   no surface tab claims it. */
.iconbtn.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent) }
.uchip { display: flex; align-items: center; gap: .5rem; font-size: var(--t-micro); color: var(--ink-3) }
.uchip .who { font-weight: 550; color: var(--ink-2) }
.uchip .role { background: var(--surface-2); border-radius: 5px; padding: .1rem .4rem }
.uchip .out { background: none; border: 1px solid var(--rule); border-radius: 6px; color: var(--ink-2); padding: .25rem .55rem; cursor: pointer; font-size: var(--t-micro) }
.uchip .out:hover { border-color: var(--rule-2); color: var(--ink) }

/* ── the four surfaces ─────────────────────────────────────────── */
.surfaces { display: flex; gap: .15rem; border-bottom: 1px solid var(--rule); margin-bottom: 1.5rem }
.surf {
  font-size: var(--t-base); font-weight: 550; color: var(--ink-3); background: none; border: none;
  border-bottom: 2px solid transparent; padding: .6rem .85rem; cursor: pointer; margin-bottom: -1px;
  display: flex; align-items: center; gap: .45rem;
}
.surf:hover { color: var(--ink) }
.surf.on { color: var(--ink); border-bottom-color: var(--accent) }
.surf .n { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }
.surf .flag { width: 6px; height: 6px; border-radius: 50%; background: var(--crit-fill) }

/* ── shared bits ──────────────────────────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: 1rem 1.1rem 1.05rem }
.eyebrow { font-size: var(--t-micro); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 .6rem }
.h2 { font-family: var(--display); font-size: var(--t-xl); font-weight: 680; letter-spacing: -.02em; margin: 0 0 .15rem; line-height: 1.2 }
.sub { font-size: var(--t-sm); color: var(--ink-3) }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--idle-fill); flex: none; display: inline-block }
.dot.good { background: var(--good-fill) } .dot.warn { background: var(--warn-fill) } .dot.crit { background: var(--crit-fill) }

/* State reads as a shape as well as a colour — a pill with a word, never colour alone. */
.pill { display: inline-flex; align-items: center; gap: .3rem; font-size: var(--t-micro); font-weight: 600; border-radius: 5px; padding: .1rem .42rem; white-space: nowrap }
.pill.good { background: var(--good-soft); color: var(--good) }
.pill.warn { background: var(--warn-soft); color: var(--warn) }
.pill.crit { background: var(--crit-soft); color: var(--crit) }
.pill.idle { background: var(--surface-2); color: var(--ink-3) }
.pill.top { background: var(--accent-soft); color: var(--accent) }
.tag { display: inline-flex; align-items: center; gap: .25rem; font-size: var(--t-micro); color: var(--ink-3); background: var(--surface-2); border-radius: 5px; padding: .1rem .42rem; white-space: nowrap; max-width: 22rem; overflow: hidden; text-overflow: ellipsis }
.btn { font-size: var(--t-sm); font-weight: 550; border-radius: 7px; padding: .38rem .75rem; cursor: pointer; border: 1px solid var(--rule); background: var(--surface); color: var(--ink-2) }
.btn:hover { border-color: var(--rule-2); color: var(--ink) }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-fill) }
.btn.primary:hover { filter: brightness(1.08); color: var(--on-fill) }
.btn.danger { border-color: var(--crit); color: var(--crit) }
.btn.sm { font-size: var(--t-micro); padding: .22rem .55rem }
/* A button that cannot be pressed must not look pressable. There was no rule for this, so a disabled
   button stayed fully lit and only stopped answering — the same "did my click land?" it is meant to
   prevent. `.primary` keeps its fill so the one that is working still reads as the active thing. */
.btn:disabled { cursor: default; opacity: .55 }
.btn:disabled:hover { border-color: var(--rule); color: var(--ink-2); filter: none }
.btn.primary:disabled { opacity: .8 }
.btn.primary:disabled:hover { color: var(--on-fill) }
.empty { border: 1px dashed var(--rule-2); border-radius: var(--r-s); color: var(--ink-3); text-align: center; padding: 1.1rem; font-size: var(--t-sm) }
.hint { font-size: var(--t-micro); color: var(--ink-3); text-align: center; margin-top: 1.5rem }

/* ── scorecard ────────────────────────────────────────────────────────────── */
.scorecard { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); margin-bottom: 1rem }
.tile { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: .9rem 1rem 1rem; display: flex; flex-direction: column }
.tile .th { display: flex; align-items: center; gap: .45rem; margin-bottom: .5rem }
.tile .nm { font-size: var(--t-sm); font-weight: 600; color: var(--ink-2) }
.tile .norm { margin-left: auto; font-size: var(--t-micro); color: var(--ink-3); font-family: var(--mono) }
.tile .v { font-family: var(--display); font-size: var(--t-2xl); font-weight: 680; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: .3rem }
.tile .v .unit { font-size: var(--t-md); font-weight: 550; color: var(--ink-3); letter-spacing: 0 }
.tile .say { font-size: var(--t-sm); color: var(--ink-2); margin-top: .5rem; line-height: 1.45 }
.tile .say b { font-weight: 650 }
.tile.good .v { color: var(--good) } .tile.warn .v { color: var(--warn) } .tile.crit .v { color: var(--crit) }
.track { height: 6px; border-radius: 3px; background: var(--surface-2); position: relative; overflow: hidden; margin-top: .6rem }
.track i { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--accent-fill) }
.track u { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink-2); border-radius: 2px }
.split { display: flex; height: 8px; border-radius: 4px; overflow: hidden; gap: 1px; background: var(--surface-2); margin: .5rem 0 .5rem }
/* The trend under a number: the line takes the row's colour, so direction is one signal
   and not two that can disagree. */
.trendrow { display: flex; align-items: center; gap: .5rem; margin-top: .5rem; font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }
.trendrow.good { color: var(--good) } .trendrow.crit { color: var(--crit) }
.trendrow span { white-space: nowrap }
.spark { width: 100%; height: 22px; flex: 1 1 auto; min-width: 40px }
.spark polyline { fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linejoin: round; vector-effect: non-scaling-stroke }
.spark circle { fill: currentColor }
.why { margin-top: .55rem }
.why button { font-size: var(--t-micro); background: none; border: none; color: var(--accent); padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 2px }
.why .ans { display: none; margin-top: .5rem; padding: .55rem .65rem; border-radius: var(--r-s); background: var(--surface-2); font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5 }
.why.open .ans { display: block }
.why .ans .src { display: block; margin-top: .35rem; font-size: var(--t-micro); color: var(--ink-3) }
.why .ans .warn { color: var(--warn) }

/* ── quarter band ─────────────────────────────────────────────────────────── */

/* ── the objective row — one home, one shape ───────────────────── */
.objlist { display: flex; flex-direction: column }
.obj { padding: .55rem 0; border-top: 1px solid var(--rule) }
.obj:first-child { border-top: none; padding-top: .2rem }
.obj.click { cursor: pointer; border-radius: var(--r-s); margin: 0 -.5rem; padding-left: .5rem; padding-right: .5rem }
.obj.click:hover { background: var(--surface-2) }
.obj .oh { display: flex; align-items: baseline; gap: .6rem }
.obj .t { font-size: var(--t-base); font-weight: 550; line-height: 1.35; flex: 1; min-width: 0 }
.obj .oval { font-family: var(--mono); font-size: var(--t-sm); color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap }
.obj .bar { height: 6px; border-radius: 3px; background: var(--surface-2); margin-top: .4rem; position: relative; overflow: hidden }
.obj .bar i { position: absolute; inset: 0 auto 0 0; border-radius: 3px }
.obj .bar i.good { background: var(--good-fill) } .obj .bar i.warn { background: var(--warn-fill) }
.obj .bar i.crit { background: var(--crit-fill) } .obj .bar i.idle { background: var(--idle-fill) }
.obj .bar u { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ink-3); border-radius: 2px }
.obj .meta { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: .35rem; font-size: var(--t-micro); color: var(--ink-3) }
.obj .meta .span { font-family: var(--mono) }
.obj .links { display: none; flex-direction: column; gap: .2rem; margin: .6rem 0 .15rem .2rem; padding-left: .8rem; border-left: 2px solid var(--rule) }
.obj.open .links { display: flex }
.obj .links .lh { font-size: var(--t-micro); font-weight: 600; color: var(--ink-3); margin-bottom: .15rem }
.olink { display: flex; align-items: center; gap: .5rem; font-size: var(--t-sm); color: var(--ink-2); cursor: pointer; border-radius: 6px; padding: .25rem .4rem; margin: 0 -.4rem; text-align: left; background: none; border: none; width: calc(100% + .8rem) }
.olink:hover { background: var(--surface-2); color: var(--ink) }
.olink .lt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.olink .lm { font-size: var(--t-micro); color: var(--ink-3); white-space: nowrap }

/* ── the strategy timeline — now that a span is real ──────────────────────── */
.tl { position: relative }
/* One row = one objective, and it has to READ as one. Before: labels were allowed to wrap to two lines
   inside a row that was exactly two lines tall, with no separator — so nine objectives ran together as a
   single block of text and you could not tell which label belonged to which bar. A timeline is scanned,
   not read: the label identifies, the bar carries the numbers, and the full text lives one panel below. */
.tl-row { display: grid; grid-template-columns: minmax(200px, 24rem) 1fr; align-items: center; gap: 1rem; min-height: 42px; padding: 0 .4rem; margin: 0 -.4rem; border-top: 1px solid var(--rule); border-radius: 6px }
.tl-row:hover { background: var(--surface-2) }
.tl-row.head, .tl-row:first-of-type { border-top: none }
.tl-row.head { min-height: 26px }
.tl-row.head:hover { background: none }
.tl-lab { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0 }
.tl-row:hover .tl-lab { color: var(--ink) }
.tl-track { display: grid; grid-template-columns: repeat(4, 1fr); position: relative; height: 100%; align-items: center }
.tl-track.head span { font-size: var(--t-micro); color: var(--ink-3); text-align: center; font-family: var(--mono) }
.tl-bar { position: relative; z-index: 2; height: 22px; border-radius: 6px; display: flex; align-items: center; overflow: hidden; min-width: 20px; border: 1px solid }
.tl-bar > i { position: absolute; left: 0; top: 0; bottom: 0 }
.tl-bar > b { position: relative; padding: 0 7px; font-family: var(--mono); font-size: var(--t-micro); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums }
.tl-bar.good { background: var(--good-soft); border-color: var(--good-fill); color: var(--good) } .tl-bar.good > i { background: color-mix(in srgb, var(--good-fill) 30%, transparent) }
.tl-bar.warn { background: var(--warn-soft); border-color: var(--warn-fill); color: var(--warn) } .tl-bar.warn > i { background: color-mix(in srgb, var(--warn-fill) 30%, transparent) }
.tl-bar.crit { background: var(--crit-soft); border-color: var(--crit-fill); color: var(--crit) } .tl-bar.crit > i { background: color-mix(in srgb, var(--crit-fill) 30%, transparent) }
.tl-bar.idle { background: var(--surface-2); border-color: var(--rule-2); color: var(--ink-3) } .tl-bar.idle > i { background: var(--rule-2) }
.tl-now { position: absolute; top: 1.8rem; bottom: 0; width: 0; border-left: 2px dashed var(--rule-2); z-index: 0 }

/* ── the board (Work) ─────────────────────────────────────────────────────── */
.domsw { display: flex; gap: .3rem; flex-wrap: wrap; margin-bottom: 1.1rem }
.domsw button {
  font-size: var(--t-sm); font-weight: 550; color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--rule); border-radius: 7px; padding: .35rem .7rem; cursor: pointer;
  display: flex; align-items: center; gap: .4rem;
}
.domsw button:hover { border-color: var(--rule-2) }
.domsw button.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent) }
.domsw .n { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }
.domsw button.on .n { color: var(--accent) }
.domsw .n.zero { opacity: .55 }

.bh { display: flex; align-items: flex-end; gap: 1rem 1.4rem; flex-wrap: wrap; margin-bottom: 1rem }

/* The board tabs of one department. This strip is the ONLY place the board's name appears
   — the boards drop their own h2 under it — so it is set in the h2's display type, not in the smaller
   type of the surface tabs above it. Same underline mechanic as those tabs, one level down: the page
   reads department (pills) → board (tabs) → columns. */
.bsw { display: flex; gap: .15rem; flex-wrap: wrap; border-bottom: 1px solid var(--rule); margin-bottom: 1.1rem }
.btab {
  font-family: var(--display); font-size: var(--t-lg); font-weight: 620; letter-spacing: -.015em;
  color: var(--ink-3); background: none; border: none; border-bottom: 2px solid transparent;
  padding: .1rem .7rem .5rem; margin-bottom: -1px; cursor: pointer;
  display: flex; align-items: baseline; gap: .45rem;
}
.btab:first-child { padding-left: 0 }
.btab:hover { color: var(--ink-2) }
.btab.on { color: var(--ink); border-bottom-color: var(--accent) }
.btab .n { font-family: var(--mono); font-size: var(--t-micro); font-weight: 500; color: var(--ink-3); font-variant-numeric: tabular-nums }
.btab .n.zero { opacity: .55 }

/* The view switch — one board, three jobs. Deliberately NOT another `.btab` row: on a department that
   has board tabs this sits directly under them, and two identical tab strips stacked read as one
   broken control. A segmented pill says "same thing, different question"; underlined tabs say
   "different thing". */
.vsw { display: inline-flex; gap: .15rem; padding: .2rem; margin-bottom: .5rem;
  background: var(--surface-2, var(--surface)); border: 1px solid var(--rule); border-radius: var(--r) }
.vtab { font: inherit; font-size: var(--t-sm); font-weight: 560; color: var(--ink-3);
  background: none; border: none; border-radius: var(--r-s); padding: .3rem .8rem; cursor: pointer;
  display: inline-flex; align-items: baseline; gap: .4rem }
.strip { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); margin-bottom: 1rem }

/* The register panel: the full open-issue list, read-only, red-first. */
.fcast { display: flex; gap: 1.6rem; flex-wrap: wrap; margin: 0 0 1rem }
.fcast span { display: flex; flex-direction: column; font-size: var(--t-micro); color: var(--ink-3) }
.fcast b { font-family: var(--display); font-size: var(--t-lg); font-weight: 650; color: var(--ink-2); margin-bottom: 2px; font-variant-numeric: tabular-nums }
.fcast .hi b { color: var(--accent) }

.cols { display: flex; gap: .7rem; overflow-x: auto; padding-bottom: .7rem; scroll-snap-type: x proximity }
/* Columns SHARE the row instead of each claiming a fixed slice. The old basis (min 250px, no shrink)
   pushed the last column off-screen on every board at 1440px — by 52px on a five-column board and by
   a full column on the six-column ones (sales, development), while every visible column still carried
   dead space. They now shrink to a 190px floor; below that the row scrolls, as it always did.

   That floor fitted SIX columns at 1280, and the arithmetic said so here until 2026-08-05. The
   development board has eight on Stroom since `live` was added and step-254 added `refining`, so
   the true fit is 6 at 1280 · 7 at 1470 · 8 at 1670, and at the 1280 this comment kept naming, 341px
   — Done and Cancelled — stood off the right edge with nothing saying so. Eight readable columns do
   not fit a laptop and 190px is already the floor for a card with a title on it, so the answer is not
   a narrower column: it is `.rail` below, which says the row continues. */
.col { flex: 1 1 0; min-width: min(190px, 100%); max-width: 420px; background: var(--surface-2); border: 1px solid var(--rule); border-radius: var(--r); padding: .6rem; display: flex; flex-direction: column; scroll-snap-align: start }
/* On a phone or a narrow tablet no board fits whole at any width, so a narrow column buys nothing —
   there you read one column at a time and it should stay comfortable. */
@media (max-width: 900px) { .col { min-width: min(250px, 100%) } }
/* Past the 1440px page the board — and only the board — keeps going to the right, up to the same 2rem
   gutter the page uses. Its LEFT edge stays put, under the heading and the tiles: the first column has
   to line up with the board's name, so the row grows away from the reader instead of sliding out from
   under the text. Prose keeps the reading width it was designed for; a kanban row has no such limit.
   The width is the arithmetic of that: half the viewport (100vw − left edge) plus half the page
   (1440/2) minus the two 2rem gutters. Six columns become ~267px instead of 220px on a 2000px screen,
   and .col's 420px ceiling stops them stretching into stripes on an ultrawide. */
@media (min-width: 1500px) { .rail { width: calc(50vw + 656px) } }
/* A column you have to scroll to find is a column you forget exists — the same sentence that applies
   to the boards themselves, and on a horizontal row the reader is not even told there is more. The
   scrollbar is hidden until it moves on macOS, so the row said nothing at all.

   A fade on the edge that HAS more, and none on the edge that does not: it appears exactly when there
   is something to find and disappears when you have found it, which is the difference between a hint
   and a decoration. `pointer-events: none` so it never eats a drag onto the last column. */
.rail { position: relative }
.rail::before, .rail::after {
  content: ''; position: absolute; top: 0; bottom: .7rem; width: 2.75rem; pointer-events: none;
  opacity: 0; transition: opacity .15s ease; z-index: 1 }
.rail::after  { right: 0; background: linear-gradient(to right, transparent, var(--bg)) }
.rail::before { left: 0;  background: linear-gradient(to left,  transparent, var(--bg)) }
.rail.more-r::after, .rail.more-l::before { opacity: 1 }
/* A folded record: a spine with the two things a record is read for, its name and its count. It is not
   a column of the flow, so it does not keep a column's width — `done` and `cancelled` held 90% of the
   cards and a quarter of the row while the columns somebody has to act on stood empty beside them.
   The whole spine is the control; the cursor says so, and the tooltip says which way it goes. */
.col.folded { flex: 0 0 2.9rem; min-width: 2.9rem; max-width: 2.9rem; padding: .6rem .35rem; cursor: pointer }
.col.folded .cx { display: block; margin: 0 }
.col.folded .agg, .col.folded .cb { display: none }
.col.folded .ch { writing-mode: vertical-rl; align-items: center; justify-content: flex-start;
                  gap: .5rem; padding: .1rem 0; height: 100% }
.col.folded:hover { border-color: var(--accent) }
/* …and the header of an OPEN record says it can go back, without shouting about it. */
.col:not(.folded) .ch { cursor: default }
/* The intake row is two or three columns, not eight, so the 420px ceiling that stops a column becoming
   a stripe on an ultrawide has nothing to do here — it only left slack at the right. What DOES bind is
   capacity: a column with a WIP limit can never hold more than that many cards, so it takes a smaller
   share and a lower ceiling than a list that can hold any number. Declared, stable, and it does not
   move when a card arrives. */
.cols.intake .col { max-width: none }
.col.drop { border-color: var(--accent); background: var(--accent-soft) }
.col.over { border-color: var(--warn-fill) }
/* The pool stands in the intake row without being a stage of it. No fill and a dashed edge:
   a holding place reads as one, and nothing measured starts here. */
.col.pool { background: none; border-style: dashed }
/* …and the commitment point is a line you can see, in front of the column that crosses it. Everything
   left of it is free; from here the clock runs. Drawn on the column so it survives any column order. */
.col.commit { position: relative }
.col.commit::before { content: ''; position: absolute; left: -.38rem; top: 0; bottom: 0;
                      border-left: 2px solid var(--rule) }
@media (max-width: 900px) { .col.commit::before { display: none } }
.ch { display: flex; align-items: center; gap: .45rem; padding: .25rem .35rem .6rem }
.ch .nm { font-size: var(--t-sm); font-weight: 600; color: var(--ink-2) }
.ch .ct { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }
.ch .win { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); opacity: .7; font-variant-numeric: tabular-nums }
.ch .agg { margin-left: auto; font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }
.ch .wip { font-size: var(--t-micro); color: var(--ink-3) }
/* "This column also stands on the other surface." Quiet to the point of nearly invisible: it answers a
 * question the reader only asks once, and a marker that keeps answering it becomes noise. */
.ch .wip.over { color: var(--warn); font-weight: 600 }
.ch .add { background: none; border: none; color: var(--ink-3); font-size: var(--t-md); line-height: 1; cursor: pointer; padding: 0 .15rem }
.ch .add:hover { color: var(--accent) }
.cb { display: flex; flex-direction: column; gap: .5rem; min-height: 40px }
.kard { position: relative; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-s); padding: .65rem .75rem .6rem; cursor: pointer; outline: none; box-shadow: var(--shadow) }
.kard:hover { border-color: var(--rule-2) }
.kard:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft) }
.kard.dragging { opacity: .45 }
/* Two readings, not three — and neither may use colour, which on a card means severity and nothing
   else. `proposed` is dashed: not yet real, and it carries the buttons that make it real. Everything
   a human has already said yes to is plain, whether the data calls it `approved` or `open`: those are
   two doors into the same room, and a third style here only taught the reader to look for a
   difference that does not exist. */
.kard .t { font-size: var(--t-sm); font-weight: 580; line-height: 1.35; color: var(--ink) }
.kard .m { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-top: .5rem; min-width: 0 }
/* A goal title can be a full sentence; inside a 250px column it must truncate, not spill. A flex item
   needs min-width:0 before overflow/ellipsis does anything at all. */
.kard .tag { display: block; max-width: 100%; min-width: 0; flex-shrink: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.kard .amt { margin-left: auto; font-family: var(--mono); font-weight: 650; font-size: var(--t-sm); font-variant-numeric: tabular-nums; color: var(--ink) }
.kard .amt.wtd { margin-left: .35rem; font-weight: 500; color: var(--ink-3) }
.kard .amt.lost { text-decoration: line-through; color: var(--ink-3); font-weight: 500 }
/* Two charts side by side where there is room, stacked where there is not — the narrow window is a
   size this is really used at, not an edge case. */
.cht { font-size: var(--t-micro); font-weight: 650; color: var(--ink-2); margin-bottom: .2rem;
       display: flex; align-items: center; gap: .55rem; flex-wrap: wrap }
.cht .leg { display: inline-flex; align-items: center; gap: .25rem; font-weight: 500; color: var(--ink-3);
            font-variant-numeric: tabular-nums }
.chart { width: 100%; height: auto; overflow: visible }
.chart .ax { stroke: var(--rule-2); stroke-width: 1 }
/* 12px, not the 9px this was drawn at first: the type floor applies to an axis label
   exactly as it applies to a card, and `frontend-floors` was right to refuse it. The charts have
   fewer ticks instead — the honest trade, since the alternative was readable-only-if-you-lean-in. */
/* One dot per card that actually went through the flow. Work that finished without ever passing a
   working column is NAMED under the chart and not drawn: a 200-day pool item closed in one gesture
   would set the y-axis, and every real cycle time would flatten into the baseline under it. */
.chart .dot { fill: var(--accent); opacity: .8 }
.chart .bar { fill: var(--accent); opacity: .75 }
/* One dot per card still underway, at its column (x) and its days-in-column (y). A card that has
   already outlasted p85 of finished work is coloured warn: the aging chart exists to point at the
   card that is stalling now, so that card must be the one the eye lands on. */
.kard .note { font-size: var(--t-micro); color: var(--ink-3); margin-top: .4rem; display: flex; align-items: center; gap: .3rem }
.kard .note.warn { color: var(--warn) }
/* The blocked flag, red and on the card wherever it stands. It used to be orange, which
 * was the right weight while the card also moved to a column named "Waiting" — the column carried the
 * message and the note merely annotated it. With the column retired this row IS the message: nothing
 * else on the board says this work has stopped, and a card sitting in the commitment column looking
 * exactly like the ones being worked is the failure mode this replaces. */
.kard .note.blocked { color: var(--crit); font-weight: 600 }
/* Why this card is where it is. A parked card showing only who must move and
 * since when is one nobody can decide about without reading git — which is the one thing the boards
 * exist to spare their reader. Clamped to three lines with the whole sentence in the tooltip: this is
 * a reason, not a document, and a card that grows to a paragraph stops being scannable. */
.kard .note.gr { color: var(--ink-3); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
                 overflow: hidden; font-style: italic }
.kard .agent { display: flex; align-items: center; gap: .35rem; margin-top: .5rem; padding-top: .45rem; border-top: 1px solid var(--rule); font-size: var(--t-micro); color: var(--accent) }
/* The two answers to a proposal, on the card itself. Pushed right so they do not read as part of the
 * provenance line they sit on, and both stop propagation in JS — the card body opens an editor. */
.kard .props button { font: inherit; font-size: var(--t-micro); padding: .06rem .45rem; cursor: pointer;
                      border: 1px solid var(--rule); border-radius: var(--r); background: var(--surface); color: var(--ink-3); }
/* The column header: the name row. It used to reserve a second row for a column's own policy line
 * (Definition of Ready, accepted transitions); no board declared either, and both left on 2026-09-21
 * (dss-virtual-office#224). The values below are what every live board already rendered. */
.col .cx { display: grid; grid-template-rows: auto; margin-bottom: 0 }
/* The owner's initials are the ONLY visible trace of who owns a card (the full name is a tooltip), so
   they are persistent text and the 12px floor applies. The circle grew with the type
   rather than the type shrinking to the circle — and `initials()` now stops at two letters, because
   three at 12px is what the 21px circle was really sized for. */
.av { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; font-size: var(--t-micro); font-weight: 700; color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--rule); flex: none }

/* ── portfolio ────────────────────────────────────────────────────────────── */
.pf { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)) }
.prog { background: var(--surface); border: 1px solid var(--rule); border-left: 3px solid var(--rag); border-radius: var(--r); padding: 1rem; box-shadow: var(--shadow) }
.prog .ph { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem }
.prog .pn { font-family: var(--display); font-size: var(--t-md); font-weight: 620; min-width: 0 }
.prog .av { margin-left: auto }

/* ── attention: decisions + exceptions + stucks ───────────────────────────── */
@media (max-width: 900px) { .attention { grid-template-columns: 1fr } }
.panel { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: .95rem 1.05rem 1rem }
.panel .ph { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem }
.panel .ph h4 { font-size: var(--t-sm); font-weight: 650; color: var(--ink-2); margin: 0 }
.panel .ph .n { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3) }
.panel .ph .act { margin-left: auto }
.ai { display: flex; gap: .6rem; align-items: flex-start; padding: .65rem 0; border-top: 1px solid var(--rule) }
.ai:first-of-type { border-top: none }
.atxt { display: flex; flex-direction: column; gap: .2rem; min-width: 0; flex: 1 }
.at { font-size: var(--t-sm); font-weight: 550; color: var(--ink); line-height: 1.35 }
.an { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.45 }
.am { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; font-size: var(--t-micro); color: var(--ink-3); margin-top: .15rem }
.am .src-link { color: var(--accent); cursor: pointer; background: none; border: none; padding: 0; font: inherit }
.am .src-link:hover { text-decoration: underline }
.ai.settled .at { color: var(--ink-3); font-weight: 500 }
.ao { font-size: var(--t-micro); align-self: center; flex: none; white-space: nowrap; display: inline-flex; align-items: center; gap: .3rem; color: var(--ink-3) }
.exrow { display: flex; gap: .5rem; align-items: baseline; font-size: var(--t-sm); color: var(--ink-2); line-height: 1.4; padding: .45rem 0; border-top: 1px solid var(--rule) }
.exrow:first-of-type { border-top: none }
.exrow .who { margin-left: auto; font-size: var(--t-micro); color: var(--ink-3); white-space: nowrap }
.quiet { display: flex; align-items: center; gap: .45rem; font-size: var(--t-sm); color: var(--ink-3) }

/* ── finance ──────────────────────────────────────────────────────────────── */
.fin-hero { display: flex; align-items: baseline; gap: .5rem; margin-top: .3rem }
.fin-big { font-family: var(--display); font-size: var(--t-2xl); font-weight: 680; letter-spacing: -.025em; color: var(--ink); font-variant-numeric: tabular-nums }
.fin-sub { color: var(--ink-2); font-size: var(--t-md) }
.fin-var { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.6; margin-top: .4rem }
.fin-var b { font-weight: 650 }
/* Two footnotes under the hero, told apart by their second class so a selector can address either:
   `fin-asof` is where the figures came from and how old they are, `fin-offyear` is which year you are
   actually looking at. Muted by default — these are footnotes, not warnings — and each takes the
   warning colour only on its own condition (a missed daily fetch; a fiscal year with no figures). */
.fin-note { font-size: var(--t-sm); color: var(--ink-3); margin-top: .4rem }
.fin-note.warn { color: var(--warn) }
.finchart { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: 1rem 1.2rem .9rem; margin-top: .8rem }
.finchart svg { display: block; width: 100%; height: auto }
/* Axis labels are read, not decoration — the floor applies to them like anything else. */
.finchart .ax { font-family: var(--sans); font-size: var(--t-micro); fill: var(--ink-3) }
.finlegend { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; margin-top: .8rem; font-size: var(--t-sm); color: var(--ink-2) }
.finlegend i { display: inline-block; width: 16px; height: 3px; border-radius: 2px; margin-right: .45rem; vertical-align: middle }
.fintab { width: 100%; border-collapse: collapse; font-size: var(--t-sm); color: var(--ink-2); margin-top: .6rem }
.fintab td { padding: .35rem 0; border-bottom: 1px solid var(--rule) }
.fintab tr:last-child td { border-bottom: none }
.fintab .lb i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: .5rem; vertical-align: -1px }
.fintab .v { text-align: right; color: var(--ink); font-weight: 620; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; padding-left: 1rem }
.fintab .pct { color: var(--ink-3); font-weight: 400; width: 3.2rem; font-family: var(--mono); text-align: right }
.finmix-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem 2.2rem; margin-top: 1.3rem }
@media (max-width: 700px) { .finmix-grid { grid-template-columns: 1fr } }
.split-lg { height: 12px; border-radius: 4px }

/* ── login ────────────────────────────────────────────────────────────────── */
.login { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg); padding: 1rem }
.login form { background: var(--surface); border: 1px solid var(--rule); border-radius: 14px; padding: 2rem; width: 340px; display: flex; flex-direction: column; gap: .85rem; box-shadow: var(--sh-login) }
.login .brand { justify-content: center; margin-bottom: .5rem }
.login label, .modal label { display: flex; flex-direction: column; gap: .3rem; font-size: var(--t-micro); font-weight: 600; color: var(--ink-2) }
.login input, .modal input, .modal select, .modal textarea {
  font: inherit; font-size: var(--t-sm); padding: .5rem .65rem; background: var(--surface);
  border: 1px solid var(--rule-2); border-radius: 7px; color: var(--ink); width: 100%;
}
.modal textarea { resize: vertical }
.login input:focus, .modal input:focus, .modal select:focus, .modal textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft) }
/* A field that cannot be edited must not look like one that can — the dossier id is fixed after
   creation, and until now it was indistinguishable from every other input on the form. */
.modal input:disabled { background: var(--surface-2); border-color: var(--rule); color: var(--ink-3); cursor: not-allowed }
.modal ::placeholder { color: var(--ink-3); opacity: .75 }
.login button[type=submit] { background: var(--accent); color: var(--on-fill); border: none; border-radius: 7px; padding: .6rem; font-weight: 650; font-size: var(--t-base); cursor: pointer }
.err { color: var(--crit); font-size: var(--t-sm); min-height: 1.1rem }

/* ── modal ────────────────────────────────────────────────────────────────── */
.modal { position: fixed; inset: 0; background: var(--scrim); display: grid; place-items: center; z-index: 20; padding: 1rem; overflow: auto }
.modal form { background: var(--surface); border: 1px solid var(--panel-edge); border-radius: 14px; padding: 1.4rem; width: 480px; max-width: 100%; display: flex; flex-direction: column; gap: .75rem; box-shadow: var(--sh-overlay) }
.modal h3 { font-family: var(--display); font-size: var(--t-lg); font-weight: 660; margin: 0 0 .2rem }
.modal .row { display: flex; gap: .7rem } .modal .row label { flex: 1; min-width: 0 }
.modal .acts { display: flex; justify-content: flex-end; gap: .5rem; margin-top: .4rem; align-items: center }
.modal label.ck { flex-direction: row; align-items: center; gap: .45rem; font-size: var(--t-sm); font-weight: 500; color: var(--ink-2) }
.modal label.ck input { width: auto; accent-color: var(--accent-fill) }
.modal .outc { display: flex; gap: .5rem }
.modal .oc { flex: 1; font: inherit; font-size: var(--t-sm); padding: .5rem; border: 1px solid var(--rule-2); border-radius: 7px; background: var(--surface); color: var(--ink-2); cursor: pointer }
.modal .oc.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); font-weight: 600 }
.modal .dsum { display: flex; flex-direction: column; gap: .25rem; padding: .6rem .75rem; background: var(--surface-2); border-radius: 8px; font-size: var(--t-sm) }
.modal .dsum b { font-weight: 650 }
.modal .dsum span { color: var(--ink-2) }
.dfield { display: flex; align-items: center; gap: .5rem }
.dfield input[type=checkbox] { width: auto; flex: none; accent-color: var(--accent-fill); cursor: pointer }
.dfield input[type=date] { flex: 1 }
.dfield .none { font-size: var(--t-sm); color: var(--ink-3) }
.fieldnote { font-size: var(--t-micro); font-weight: 400; color: var(--ink-3); margin: -.35rem 0 0; line-height: 1.45 }

/* ── the record editor (wide modal) ───────────────────────────────────────────
 * A form with four groups, five contact columns and a delete button does not fit the 480px dialog the
 * rest of the app uses for three fields. It gets a header and an action bar that stay put while the
 * middle scrolls: on a laptop the old form ran off the bottom of the viewport, so Save was something
 * you had to go and find. */
/* The overlay must not scroll: the form clamps itself to the viewport and scrolls its own middle, so
   any scroll left on the overlay only serves to drag the sticky header out of reach — which is exactly
   what the centring grid did (it sized its row to the form's *unclamped* content height).
   Scoped to the wide modal: the short dialogs have no max-height and must keep overflowing outward. */
.modal-wide { display: flex; align-items: center; justify-content: center; overflow: hidden }
.modal form.wide { width: min(780px, 100%); max-height: 100%; padding: 0; gap: 0 }
.modal form.wide .mhead { flex: none; padding: 1.15rem 1.5rem .95rem; border-bottom: 1px solid var(--rule) }
.modal form.wide .mhead h3 { margin: 0 }
.modal form.wide .msub { margin: .2rem 0 0; font-size: var(--t-sm); color: var(--ink-3) }
.modal form.wide .mbody { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 1.2rem 1.5rem 1.4rem }
.modal form.wide .mfoot {
  flex: none; display: flex; align-items: center; gap: .5rem; justify-content: flex-end;
  padding: .85rem 1.5rem; border-top: 1px solid var(--rule); background: var(--surface); border-radius: 0 0 14px 14px;
}
/* Delete sits at the far end of the bar, not one button away from Save. */
.modal form.wide .mfoot .err { flex: 1; min-height: 0; margin: 0; text-align: left }
.modal form.wide .mfoot label + .fieldnote, .modal label .fieldnote { margin-top: 0 }

/* Groups, not a stack: the hairline is what tells you "identity" ended and "recognition" began. */
.fgroup { display: flex; flex-direction: column; gap: .7rem }
.fgroup + .fgroup { margin-top: 1.3rem; padding-top: 1.3rem; border-top: 1px solid var(--rule) }
.fgroup .glabel { font-size: var(--t-micro); font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin: 0 }
.fgroup .gnote { font-size: var(--t-sm); color: var(--ink-2); margin: -.35rem 0 .1rem; line-height: 1.45 }
.fgroup > .row { gap: .7rem }

/* ── the handbook ─────────────────────────────────────────────────────────
   One page under Kantoor, and one link into it from every other page head. The three model cards
   (.hcards/.hcard/.hlinks) are the overlay this replaced, kept intact as the first chapter. */
.hbopen { display: block; margin: 10px 0 0; background: none; border: 0; padding: 0; font: inherit; font-size: var(--t-sm); font-weight: 600; color: var(--accent); cursor: pointer; text-align: left }
.hbopen::after { content: " ›" }

/* The plate: what proposes, what carries it, what decides. Boxes of real text rather than an SVG —
   labels in a 720-wide drawing land at about 6px on a 390px phone, half the floor this sheet sets. */
.hbplate { display: flex; align-items: stretch; gap: .8rem; flex-wrap: wrap; margin-bottom: .7rem }
.hbbox { flex: 1 1 14rem; background: var(--surface); border: 1px solid var(--rule-2); border-radius: var(--r); padding: .9rem 1rem; display: flex; flex-direction: column; gap: .3rem }
.hbbox b { font-family: var(--display); font-size: var(--t-md); font-weight: 600 }
.hbbox span { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5 }
.hbar { align-self: center; color: var(--ink-3); font-size: var(--t-lg) }
/* On a phone the plate reads downwards. Without the column the boxes wrap AROUND the arrows and come
   out at three different widths — measured at 390px: 263, 263, 294. */
@media (max-width: 720px) { .hbplate { flex-direction: column; align-items: stretch } .hbar { transform: rotate(90deg) } }
.hbnote { font-size: var(--t-sm); color: var(--ink-2); margin: 0 0 1.6rem; max-width: 46rem; line-height: 1.55 }

.hbchapters { display: flex; flex-direction: column; gap: .5rem }
.hbch { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); overflow: hidden }
/* The chevron is the only affordance a closed chapter has: without it the list reads as twelve
   cards nobody can open. Its own column, so a two-line lead does not push it off the corner. */
.hbch > summary { cursor: pointer; padding: .9rem 1.1rem; display: grid; grid-template-columns: 1fr 1.2rem; grid-template-rows: auto auto; gap: .2rem .6rem; list-style: none }
.hbch > summary::-webkit-details-marker { display: none }
.hbch > summary::after { content: "›"; grid-column: 2; grid-row: 1 / span 2; align-self: center; justify-self: end; color: var(--ink-3); font-size: var(--t-lg); transition: transform .12s ease }
.hbch[open] > summary::after { transform: rotate(90deg) }
@media (prefers-reduced-motion: reduce) { .hbch > summary::after { transition: none } }
.hbch > summary b { font-family: var(--display); font-size: var(--t-md); font-weight: 600 }
.hbch > summary span { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5 }
.hbch[open] > summary { border-bottom: 1px solid var(--rule) }
.hbbody { padding: 1.1rem; display: flex; flex-direction: column; gap: 1rem }
/* The declared facts, as chips above the three blocks. Not decoration and not a status: `alone` is
   the one that changes what Sjaak has to watch, so it is the only one that carries a tone. */
.hbfacts { display: flex; flex-wrap: wrap; gap: .4rem }
.hbf { font-size: var(--t-micro); padding: .25rem .6rem; border-radius: 999px; background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--rule) }
.hbf.at { font-variant-numeric: tabular-nums }
.hbf.alone { background: var(--warn-soft); color: var(--warn); border-color: transparent }
.hbb { display: grid; grid-template-columns: 7rem 1fr; gap: .9rem }
@media (max-width: 720px) { .hbb { grid-template-columns: 1fr; gap: .3rem } }
.hbk { font-size: var(--t-micro); font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); padding-top: .15rem }
.hbb ul { margin: 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: .4rem }
.hbb li { font-size: var(--t-base); color: var(--ink-2); line-height: 1.55 }
/* "Jij" is the block the reader came for, so it is the one that carries ink rather than grey. */
.hbb-act li { color: var(--ink) }
.hbgo { color: var(--accent); align-self: flex-start }

.hbrh { font-family: var(--display); font-size: var(--t-lg); font-weight: 600; margin: 2rem 0 .8rem }
.hbrhythm { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem }
@media (max-width: 860px) { .hbrhythm { grid-template-columns: 1fr } }
.hbrc { background: var(--surface-2); border: 1px solid var(--rule); border-radius: var(--r); padding: 1rem }
.hbrc b { font-family: var(--display); font-size: var(--t-md); font-weight: 600 }
.hbrc ul { margin: .6rem 0 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: .4rem }
.hbrc li { font-size: var(--t-sm); color: var(--ink-2); line-height: 1.5 }

.hcards { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem }
@media (max-width: 720px) { .hcards { grid-template-columns: 1fr } }
.hcard { background: var(--surface-2); border: 1px solid var(--rule); border-radius: 10px; padding: 1rem }
.hcn { font-size: var(--t-sm); font-weight: 700; margin-bottom: .5rem }
.hcq { font-size: var(--t-sm); color: var(--ink-2); margin-bottom: .7rem }
.hcr { font-size: var(--t-micro); color: var(--ink-2); line-height: 1.9 }
.hcr span { color: var(--ink-3); display: inline-block; min-width: 3.6rem }
.hlinks { display: flex; flex-direction: column; gap: .45rem; font-size: var(--t-sm); color: var(--ink-2); margin-top: .9rem }

/* Settled decisions fold away — level 1 is for what needs attention (dss-steering §7 rule 9), but the
   log of what you decided, and whether you took the advice, is the record and must stay reachable. */
.settled-fold { border-top: 1px solid var(--rule); margin-top: .3rem }
.settled-fold > summary {
  list-style: none; cursor: pointer; padding: .6rem 0 .1rem;
  font-size: var(--t-sm); font-weight: 600; color: var(--ink-3);
  display: flex; align-items: center; gap: .45rem;
}
.settled-fold > summary::-webkit-details-marker { display: none }
.settled-fold > summary::before { content: "›"; display: inline-block; transition: transform .12s; font-size: var(--t-md) }
.settled-fold[open] > summary::before { transform: rotate(90deg) }
.settled-fold > summary:hover { color: var(--ink-2) }
.settled-fold > summary .n { font-family: var(--mono); font-size: var(--t-micro); font-variant-numeric: tabular-nums }
.settled-fold .ai:first-of-type { border-top: 1px solid var(--rule) }

/* ── the dossier register — a config table behind the admin button, not a fifth surface ── */
/* Its own width. The register block used to widen `.helppanel` itself, which silently stretched the
   help overlay too — one screen's layout decision leaking into another's. */
/* The register is a PAGE — it takes the stage, not a window over it. No panel, no scrim, no
   height cap: the table scrolls with the document like every other surface, so a long register reads
   like a long page instead of a small window with its own scrollbar. */
.regpage { display: block }
.regpage .rtw { max-height: none }
.rhead { display: flex; align-items: flex-start; gap: .8rem; flex-wrap: wrap }
.rhead .rht { flex: 1; min-width: 14rem }
.rhead h2 { font-family: var(--display); font-size: var(--t-xl); font-weight: 680; margin: .1rem 0 0; letter-spacing: -.015em }
.rhead h3 { font-family: var(--display); font-size: var(--t-lg); font-weight: 680; margin: 0 }
/* The way back, where a page's way back belongs: above its title, naming the surface you came from. */
.rback { background: none; border: none; padding: 0; cursor: pointer; font: inherit; font-size: var(--t-sm); font-weight: 550; color: var(--ink-3) }
.rback:hover { color: var(--accent) }
.rhead .rhs { font-size: var(--t-sm); color: var(--ink-3); margin: .2rem 0 0 }
.rbar { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; margin-top: 1rem }
.rbar .rn { margin-left: auto; font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); font-variant-numeric: tabular-nums }

.rtw { overflow: auto; margin-top: .8rem; border: 1px solid var(--rule); border-radius: 10px; flex: 1 1 auto; min-height: 0 }
.rtab { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--t-sm); min-width: 780px }
.rtab th {
  text-align: left; padding: .55rem .7rem; font-size: var(--t-micro); font-weight: 650; color: var(--ink-3);
  background: var(--surface-2); white-space: nowrap; border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 1;
}
.rtab td { padding: .7rem; border-bottom: 1px solid var(--rule); vertical-align: top; color: var(--ink-2) }
.rtab tbody tr:last-child td { border-bottom: none }
.rtab tbody tr:hover { background: var(--surface-2) }
.rtab .rid { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3) }
.rtab .rdom { font-family: var(--mono); font-size: var(--t-micro); line-height: 1.7 }
.rtab .rnone { color: var(--ink-3) }
.rtab .ract { text-align: right; white-space: nowrap }

/* The register follows the entity tab — with a way back to everything, because a dossier
   filed under the wrong entity must stay findable in the one screen that can correct it. */
.rscope { display: inline-flex; align-items: center; gap: .45rem; font-size: var(--t-sm); color: var(--ink-2); cursor: pointer }
.rscope input { accent-color: var(--accent-fill); cursor: pointer }
.rscopen { font-size: var(--t-micro); color: var(--ink-3) }

/* A contact is a person, not a name: role and side sit with it, address beside it. One person is one
   line where it fits — stacking the address under every name made a four-contact dossier 200px tall. */
.rc { display: flex; flex-wrap: wrap; align-items: baseline; gap: .1rem .55rem; padding: .12rem 0; line-height: 1.4 }
.rc + .rc { border-top: 1px dashed var(--rule); margin-top: .25rem; padding-top: .3rem }
.rc .rcn { display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap }
.rc .rcr { color: var(--ink-3); font-size: var(--t-micro) }
.rc .rcs { font-size: var(--t-micro); padding: .05rem .35rem; border-radius: 5px; background: var(--surface-2); border: 1px solid var(--rule); color: var(--ink-3) }
.rc .rcm { font-family: var(--mono); font-size: var(--t-micro); color: var(--ink-3); word-break: break-word }
/* Beyond three contacts the row height ran away with the table. The rest fold, they do not vanish. */
.rmore { border-top: 1px dashed var(--rule); margin-top: .3rem; padding-top: .3rem }
.rmore > summary { list-style: none; cursor: pointer; font-size: var(--t-micro); color: var(--accent); padding: .1rem 0; display: flex; align-items: center; gap: .3rem }
.rmore > summary::-webkit-details-marker { display: none }
.rmore > summary::before { content: "›"; display: inline-block; transition: transform .12s; font-size: var(--t-sm) }
.rmore[open] > summary::before { transform: rotate(90deg) }
.rmore[open] > summary { color: var(--ink-3); margin-bottom: .2rem }
.rmore .rc:first-of-type { border-top: none; margin-top: 0; padding-top: 0 }

/* ── contact rows in the editor ───────────────────────────────────────────────
 * Five columns with one header, not five placeholders repeated per row. The old grid at 480px gave
 * name, role and address ~85px each, so every value it holds was truncated on sight. */
.cfield .chead, .crow {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .95fr) minmax(0, 1.75fr) 7.5rem 1.85rem;
  gap: .45rem; align-items: center;
}
.cfield .chead { font-size: var(--t-micro); font-weight: 650; color: var(--ink-3); margin-bottom: -.2rem; padding: 0 .05rem }
.crow { margin-bottom: .4rem }
.crow input, .crow select { width: 100%; margin: 0 }
.crow .c-del {
  width: 1.85rem; height: 1.85rem; display: grid; place-items: center; padding: 0; line-height: 1;
  border: 1px solid transparent; border-radius: 7px; background: none; color: var(--ink-3); cursor: pointer; font-size: var(--t-sm);
}
.crow .c-del:hover { border-color: var(--crit); color: var(--crit) }
.crow .c-del:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px }
@media (max-width: 700px) {
  .cfield .chead { display: none }
  .crow { grid-template-columns: 1fr 1fr 1.85rem; row-gap: .3rem }
  .crow .c-mail { grid-column: 1 / 3 } .crow .c-side { grid-column: 1 / 3 }
  .crow .c-del { grid-row: 1; grid-column: 3 }
  /* One person is three rows here, so the rows need a line telling you where one person ends. */
  .crow + .crow { border-top: 1px dashed var(--rule); padding-top: .55rem; margin-top: .55rem }
}

/* ── the proposal inbox ─────────────────────────────────────────
   Built from the app's own tokens rather than fresh numbers: the first version
   invented 10px and 11px and the type floor caught it within the hour. The only
   deliberate emphasis is on the GROUND — the sentence he decides on — and on the
   before → after, because a diff you can see one side of is not a diff. */
.ibadge { position: absolute; top: -5px; right: -5px; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--crit-fill); color: var(--on-fill); font-size: var(--t-micro);
  line-height: 18px; text-align: center; font-weight: 650; }
#inbox-btn { position: relative; overflow: visible; }

.applied { display: flex; align-items: center; gap: .6rem; margin: 0 0 1rem; padding: .6rem .8rem;
  border-radius: var(--r-s); background: var(--surface-2); border: 1px solid var(--rule);
  font-size: var(--t-sm); color: var(--ink-2); }

/* The proposals, as the first thing on the intake surface rather than a page of their own. It keeps
   the changeset card (`.csx`) it always had; what it loses is the page chrome — a heading and a back
   button for a screen you are no longer standing on. */
.inbox { display: block; margin: 0 0 1.1rem }
.csx { border: 1px solid var(--rule); border-radius: var(--r-s); margin: 0 0 1.1rem; overflow: hidden;
  background: var(--surface); }
.csh { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .8rem 1rem; background: var(--surface-2); border-bottom: 1px solid var(--rule); }
.cst h3 { margin: 0; font-size: var(--t-md); }
.csm { margin: .15rem 0 0; font-size: var(--t-sm); color: var(--ink-3); }
.csa { display: flex; gap: .4rem; flex-wrap: wrap; }

/* Applying takes seconds — a commit and a push per accepted line — so the changeset says so while it
   runs. The lines fade but stay readable: he judged them a second ago and may still be reading them. */
.csx.busy .chgs { opacity: .55; }
.csbusy { display: flex; align-items: center; gap: .5rem; margin: 0; padding: .55rem 1rem;
  background: var(--accent-soft); color: var(--ink-2); font-size: var(--t-sm);
  border-bottom: 1px solid var(--rule); }
.spin { width: .8em; height: .8em; flex: none; border-radius: 50%; display: inline-block;
  margin-right: .45rem; vertical-align: -.05em;
  border: 2px solid currentColor; border-top-color: transparent; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg) } }
/* Reduced motion kills the animation globally (line 129), which would leave a static ring saying
   nothing. The text beside it carries the message on its own, so that is fine — but the ring must not
   read as a broken control, hence the dimming. */
@media (prefers-reduced-motion: reduce) { .spin { opacity: .5 } }

.chgs { list-style: none; margin: 0; padding: 0; }
.chg { padding: .8rem 1rem; border-bottom: 1px solid var(--rule); }
.chg:last-child { border-bottom: 0; }
.chg.gone { opacity: .6; }
.chgstale { font-size: var(--t-sm); color: var(--warn); margin-top: .3rem; }
.chgh { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.chgt { font-size: var(--t-base); }
.chgi { font-size: var(--t-micro); color: var(--ink-3); font-family: var(--mono, ui-monospace, monospace); }
.chgd { font-size: var(--t-sm); color: var(--ink-2); margin-top: .3rem; line-height: 1.7; }
.fld { color: var(--ink-3); }
.arrow { color: var(--ink-3); margin: 0 .15rem; }
.was { color: var(--ink-3); }
.chgg { font-size: var(--t-sm); color: var(--ink-2); margin-top: .45rem; line-height: 1.5; }
.gl { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3);
  margin-right: .35rem; }
.chgv { display: flex; align-items: center; gap: .5rem; margin-top: .6rem; flex-wrap: wrap; }
/* What a decision looks like once it is made. The segmented control alone could not carry this: it
   renders with Accept already selected (twelve lines you agree with cost one click, not
   twelve), so the click that confirms it changed nothing on screen. The word is the feedback; the
   colour is the glance. Measured against the row ground in frontend-floors.test.js. */
/* **A state must not look like a control.** This chip sat next to two buttons, at the same size, with
   the same 5px radius and the same outline — so "✓ Accept  ✕ Reject  Accepted" read as three options,
   and Sjaak asked what the third one did. Everywhere else in this app a fill means status and an
   outline means control (`.pill` vs `.btn`); the outline here is not a slip, it is the measured
   separation below, so the shape carries the difference instead: a full round nothing in this app is
   clickable, plus the leading dot the boardroom already uses to mean "this is a reading". */
.vs { font-size: .75rem; font-weight: 600; letter-spacing: .01em; padding: .1rem .5rem .1rem .42rem;
      border-radius: 999px; border: 1px solid transparent; cursor: default; }
/* No font-size here on purpose: the type floor cannot resolve an em, and a
   decorative glyph is exactly the kind of thing that would earn an exception and then be copied by
   something that is text. A bullet is small enough at the chip's own size. */
.vs::before { content: '•'; margin-right: .3rem; }
/* Separation by EDGE, not by fill — the scrim rule, generalised. A soft fill works in light and
   cannot work in dark: `--good-soft` sits at 1.06 against `--surface` there, so it would separate
   nothing. The border reaches 4.4:1 at worst across both themes, and the label then sits on the
   row's own ground where it clears the 4.5:1 ink floor (a `--good-soft` fill put it at 4.42). */
.vs-applied { color: var(--good); border-color: var(--good); }
.vs-rejected { color: var(--crit); border-color: var(--crit); }
/* The step that is left, said in words rather than implied by a blue button. */
.csp { font-size: .8125rem; color: var(--ink-3); margin: .15rem 0 0; }
.vseg { flex: none; }
.vr { flex: 1 1 220px; min-width: 12rem; padding: .3rem .55rem; font-size: var(--t-sm);
  border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); color: var(--ink); }

/* ── the Chief's desk ───────────────────────────────────────────
   A conversation, not a steering surface — so it borrows the register page's frame and adds only
   what a transcript needs. Every type size is a token: the 12px floor is measured
   (`test/frontend-floors.test.js`), and this screen is read on a phone. */
/* The composer must stay on screen: the log takes the space that is left, rather than claiming a
   fixed slice of the viewport and pushing the input below the fold (which is what 62vh did). */
/* The 10rem is the header plus this page's own heading — the tab strip is gone while a page has the
   stage, so it is no longer part of the sum. */
.chatpage { display: flex; flex-direction: column; gap: .9rem; max-height: calc(100vh - 10rem); }

.chatlog { display: flex; flex-direction: column; gap: .55rem; overflow-y: auto;
  flex: 1 1 auto; min-height: 8rem; padding: .2rem; }

.ct { display: flex; }
.ct.me { justify-content: flex-end; }
.ct .cb { max-width: min(46rem, 88%); padding: .55rem .8rem; border-radius: var(--r);
  font-size: var(--t-base); line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.ct.me .cb { background: var(--accent-soft); color: var(--ink); border-bottom-right-radius: var(--r-s); }
.ct.chief .cb { background: var(--surface-2); color: var(--ink); border-bottom-left-radius: var(--r-s); }

/* A pending turn says so in words. The box may take a minute — a screen that shows nothing during
   that minute is the failure this whole design is trying not to have. */
.ct.chief .cb.waiting { color: var(--ink-3); font-style: italic; }
.ct.chief .cb.failed { background: var(--crit-soft); color: var(--crit); }
.applied.failed { background: var(--crit-soft); color: var(--crit); }

.chatbar { display: flex; gap: .5rem; align-items: center; }
.chatbar input { flex: 1; padding: .55rem .75rem; font-size: var(--t-base);
  border: 1px solid var(--rule-2); border-radius: var(--r-s);
  background: var(--surface); color: var(--ink); }
.chatbar input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.chatbar input:disabled { color: var(--ink-3); background: var(--surface-2); }
.ct.chief .cb.failed .cbl { display: block; margin-bottom: .15rem; }

/* Finance · the three figures beside revenue (2026-09-16). */
.fin-figs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin: 0 0 20px; }
.fin-fig { background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); padding: 18px 20px; }
.fin-fig .lab { font-size: var(--t-sm); color: var(--ink-2); }
.fin-fig .n1 { font-size: var(--t-2xl); font-weight: 600; letter-spacing: -.02em; margin-top: 6px; }
.fin-fig .n1.crit { color: var(--crit); }
.fin-fig .n1 small { font-size: var(--t-sm); font-weight: 400; color: var(--ink-3); margin-left: 6px; }

/* Work · a department's controls, one dated line (2026-09-16). */
.controls { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 24px; margin: 0 0 16px; font-size: var(--t-sm); color: var(--ink-2); }
.controls .lab { font-weight: 600; color: var(--ink); }
.controls .ctl b { color: var(--ink); font-weight: 600; margin-left: 4px; }
.controls .ctl.warn b { color: var(--warn); }
.controls .ctl.crit b { color: var(--crit); }
.controls .when { color: var(--ink-3); margin-left: 6px; }

/* ══ v5 (2026-09-16) — one navigation down the left, calm cards on Papier ═══════════════════════════
   The layer that turns the four-tab header into the v5 design Sjaak approved: a Nacht sidebar with the
   screens in three groups, and every surface built from the same card. It sits last so it wins
   over the older rules above without rewriting them one by one. */
.shell { display: flex; min-height: 100vh }
.side {
  width: 232px; flex: none; position: sticky; top: 0; height: 100vh; overflow-y: auto;
  background: var(--nav-bg); color: var(--nav-ink-3);
  display: flex; flex-direction: column; gap: 4px; padding: 20px 14px;
}
.side .brand { padding: 4px 10px 18px; display: flex; flex-direction: column; gap: 2px }
.side .logo { font-family: var(--display); font-weight: 700; font-size: 20px; letter-spacing: -.02em; color: var(--nav-ink) }
.side .logo i { font-style: normal; color: var(--nav-accent) }
.side .brand .sub { font-size: var(--t-micro); color: var(--nav-meta); margin: 0 }
.side .surfaces { display: flex; flex-direction: column; gap: 2px; border: 0; margin: 0 }
.side .grp { font-size: var(--t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--nav-meta); padding: 16px 10px 6px }
.side .surf {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 10px; margin: 0; border: 0; border-radius: 8px; background: none;
  font-size: var(--t-sm); font-weight: 500; color: var(--nav-ink-2); cursor: pointer;
}
.side .surf:hover { background: var(--nav-raise); color: var(--nav-ink) }
.side .surf.on { background: var(--nav-rule); color: var(--nav-ink); border: 0 }
.side .surf .lb { flex: 1 }
.side .surf .n { font-family: var(--sans); font-size: var(--t-micro); color: var(--nav-ink-3); padding: 0 7px; border-radius: 999px; background: var(--nav-rule) }
.side .surf .n.hot { background: var(--nav-accent); color: var(--on-fill) }
.side .ic { width: 16px; height: 16px; flex: none; background: currentColor; -webkit-mask: var(--ic) center / contain no-repeat; mask: var(--ic) center / contain no-repeat }
.ic-board { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Crect x='2' y='2' width='5' height='5' rx='1.2'/%3E%3Crect x='9' y='2' width='5' height='5' rx='1.2'/%3E%3Crect x='2' y='9' width='5' height='5' rx='1.2'/%3E%3Crect x='9' y='9' width='5' height='5' rx='1.2'/%3E%3C/svg%3E") }
.ic-objectives { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Ccircle cx='8' cy='8' r='2.5'/%3E%3C/svg%3E") }
.ic-work { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Crect x='2' y='3' width='3.5' height='10' rx='1'/%3E%3Crect x='6.25' y='3' width='3.5' height='7' rx='1'/%3E%3Crect x='10.5' y='3' width='3.5' height='4' rx='1'/%3E%3C/svg%3E") }
.ic-hours { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Cpath d='M8 5v3l2 1.5'/%3E%3C/svg%3E") }
.ic-finance { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M2 12l4-4 3 2 5-6'/%3E%3C/svg%3E") }
.ic-inbox { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M2 9l2-6h8l2 6v4H2z'/%3E%3Cpath d='M2 9h3.5l1 1.5h3l1-1.5H14'/%3E%3C/svg%3E") }
.ic-chat { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z'/%3E%3C/svg%3E") }
.ic-register { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M3 2.5h7l3 3v8H3z'/%3E%3Cpath d='M5.5 8h5M5.5 10.5h5'/%3E%3C/svg%3E") }
.ic-pipeline { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M2 3h12l-4.5 5v5l-3-1.5V8z'/%3E%3C/svg%3E") }
.ic-monitor { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M1.5 8.5h3l1.5-4 3 7 1.5-3h4'/%3E%3C/svg%3E") }
.ic-calendar { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Crect x='2' y='3' width='12' height='11' rx='1.5'/%3E%3Cpath d='M2 6.5h12M5.5 1.5v3M10.5 1.5v3'/%3E%3C/svg%3E") }
.ic-handbook { --ic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5'%3E%3Cpath d='M2.5 3h4a2 2 0 0 1 1.5.7A2 2 0 0 1 9.5 3h4v9.5h-4a2 2 0 0 0-1.5.7 2 2 0 0 0-1.5-.7h-4z'/%3E%3Cpath d='M8 3.7v9.5'/%3E%3C/svg%3E") }
/* The deadline calendars page: its subscribe button is a link, and must not look like one. */
.calpage a.btn { text-decoration: none; display: inline-block }
.side .foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; padding-top: 14px; border-top: 1px solid var(--nav-rule) }
.side .seg { background: var(--nav-raise); border-color: var(--nav-rule); align-self: flex-start }
.side .seg button { color: var(--nav-ink-3) }
.side .seg button.on { background: var(--nav-rule); color: var(--nav-ink); box-shadow: none }
.side .tools { display: flex; align-items: center; gap: 6px }
.side .iconbtn { background: var(--nav-raise); border-color: var(--nav-rule); color: var(--nav-ink-2) }
.side .uchip { display: flex; align-items: center; gap: 10px; color: var(--nav-ink-3) }
.side .uchip .avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--nav-accent); color: var(--on-fill); display: grid; place-items: center; font-weight: 600; font-size: var(--t-micro); flex: none }
.side .uchip .uw { display: flex; flex-direction: column; min-width: 0 }
.side .uchip .who { color: var(--nav-ink) }
.side .uchip .role { background: none; padding: 0; color: var(--nav-meta) }
.side .uchip .out { margin-left: auto; border-color: var(--nav-rule); color: var(--nav-ink-2) }
.content { flex: 1; min-width: 0; padding: 40px clamp(20px, 4vw, 56px) 56px }
/* One width for every page, whatever element renders it (2026-09-17). */
#stage > * { max-width: 1240px; width: 100% }
/* ── the phone (2026-09-17): one bar with one button, the menu as a drawer ──────────────────────
   Below 820px the menu used to sit above the page — eleven rows before the first number. The bar is
   40px of chrome; everything else the menu holds stays in the drawer, so nothing has two homes. */
.topbar, .navscrim, .navclose { display: none }
@media (max-width: 820px) {
  .shell { flex-direction: column }
  .topbar { display: flex; align-items: center; gap: 12px; padding: 10px 16px; background: var(--nav-bg); color: var(--nav-ink); position: sticky; top: 0; z-index: 40 }
  .topbar .logo { font-family: var(--display); font-weight: 700; font-size: var(--t-md); letter-spacing: -.02em }
  .topbar .logo i { color: var(--accent); font-style: normal }
  .topbar .where { margin-left: auto; font-size: var(--t-sm); color: var(--nav-ink-3) }
  .topbar .navbtn { margin-left: 4px }
  .navbtn { position: relative; width: 44px; height: 44px; border-radius: 10px; border: 0; background: var(--nav-btn); color: var(--nav-ink); display: grid; place-items: center; cursor: pointer }
  .navbtn .ndot { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-fill) }
  .navscrim { display: block; position: fixed; inset: 0; z-index: 45; background: var(--nav-scrim) }
  .side .brand { flex-direction: row; align-items: center; padding: 2px 0 14px }
  .side .brand .sub { display: none }
  .navclose { order: -1; margin-right: auto; width: 40px; height: 40px; border-radius: 10px; border: 0; background: var(--nav-btn); color: var(--nav-ink); display: grid; place-items: center; cursor: pointer }
  .navscrim.hidden { display: none }
  /* The button sits top right, as the other DSS apps have it, so the drawer comes in from that side. */
  .side { position: fixed; top: 0; bottom: 0; right: 0; left: auto; width: min(300px, 86vw); height: 100vh; z-index: 50;
    transform: translateX(100%); transition: transform .18s ease; padding: 16px 18px }
  .side.open { transform: none }
  .side .foot { margin-top: auto }
  .content { padding: 20px 16px 40px }
}
@media (prefers-reduced-motion: reduce) { .side { transition: none } }

/* The card every surface is built from. */
.panel, .qcard, .fin-fig, .card { background: var(--surface); border: 0; border-radius: 18px; box-shadow: var(--sh-card) }
.panel, .qcard { padding: 24px }
.h2 { font-size: 34px; font-weight: 600; letter-spacing: -.03em }
.eyebrow { letter-spacing: .08em }
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-bottom: 20px }
.big { font-family: var(--display); font-size: 44px; font-weight: 600; letter-spacing: -.04em; line-height: 1.05; font-variant-numeric: tabular-nums }
.big small { font-family: var(--sans); font-size: var(--t-md); font-weight: 450; color: var(--ink-3); letter-spacing: 0; margin-left: 8px }
.big.warn { color: var(--warn) } .big.crit { color: var(--crit) } .big.none { color: var(--rule-2) }

/* Board */
.qcard { display: flex; flex-direction: column; gap: 12px }
.qh { display: flex; align-items: center; justify-content: space-between; gap: 12px }
.qh .l1h { margin: 0; font-size: var(--t-sm); font-weight: 500; color: var(--ink-2) }
.stag { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-micro); font-weight: 600; padding: 3px 10px; border-radius: 999px; white-space: nowrap }
.stag i { width: 6px; height: 6px; border-radius: 50% }
.stag.good { background: var(--good-soft); color: var(--good) } .stag.good i { background: var(--good-fill) }
.stag.warn { background: var(--warn-soft); color: var(--warn) } .stag.warn i { background: var(--warn-fill) }
.stag.crit { background: var(--crit-soft); color: var(--crit) } .stag.crit i { background: var(--crit-fill) }
.stag.idle { background: var(--surface-2); color: var(--ink-2) } .stag.idle i { background: var(--idle-fill) }
.qcard .trendrow, .qcard .trend-none { min-height: 26px }
.qcard .lines { border-top: 1px solid var(--rule); padding-top: 6px; margin-top: auto }
.kl { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 7px 0; font-size: var(--t-sm) }
.kl .k { color: var(--ink-2) }
.kl .v { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums }
.kl .v small { font-weight: 400; color: var(--ink-3); margin-left: 4px }
.kl .v.warn { color: var(--warn) } .kl .v.crit { color: var(--crit) }
.qcard .why summary, .panel .why summary { cursor: pointer; font-size: var(--t-micro); color: var(--ink-3) }
.qcard .why .ans { font-size: var(--t-micro); color: var(--ink-2); padding-top: 6px; line-height: 1.5 }
.qcard .why .src { display: block; color: var(--ink-3) }
.attention .ph, .qband .ph, .toinvoice .ph, .hlog .ph { display: flex; align-items: center; gap: 8px; margin-bottom: 8px }
.attention .ph h4, .qband .ph h4, .toinvoice .ph h4, .hlog .ph h4 { margin: 0; font-size: var(--t-sm); font-weight: 500; color: var(--ink-2) }
.attention .ph .act, .qband .ph .act { margin-left: auto }
.need { border-top: 1px solid var(--rule) }
.need summary { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; cursor: pointer; list-style: none; font-size: var(--t-base) }
.need summary::-webkit-details-marker { display: none }
.need[data-empty] summary { cursor: default }
.need .none { color: var(--ink-3); font-size: var(--t-sm) }
.badge { min-width: 28px; height: 26px; padding: 0 8px; border-radius: 999px; display: inline-grid; place-items: center; font-size: var(--t-sm); font-weight: 600; background: var(--surface-2); color: var(--ink-2) }
.badge.crit { background: var(--crit-soft); color: var(--crit) }
.need .ai, .need .exrow { padding: 8px 0 10px; border: 0 }
.need .exrow small { color: var(--ink-3) }
.riskline { border-top: 1px solid var(--rule); padding-top: 4px }
.qband .theme { font-family: var(--display); font-size: 22px; font-weight: 600; letter-spacing: -.02em; margin: 4px 0 12px }
.qband .theme .none { color: var(--ink-3); font-family: var(--sans); font-size: var(--t-sm); font-weight: 400 }
.qband { display: block; margin: 0 }
.attention { display: block; margin: 0 }
.qband .cn { display: block; margin: 0 0 12px; font-size: inherit; color: inherit }
.qband .cn .big { font-size: 40px }
.qband .origin { font-size: var(--t-micro); color: var(--ink-3); margin-top: 6px }
.steps { display: flex; gap: 6px; margin-top: 10px }
.steps span { flex: 1; height: 8px; border-radius: 4px; background: var(--rule) }
.steps span.on { background: var(--accent-fill) }
.qband .track { height: 8px; border-radius: 4px; background: var(--rule); margin-top: 10px; overflow: hidden }
.qband .track i { display: block; height: 100%; background: var(--accent-fill) }
.qband .prio { font-size: var(--t-sm); color: var(--ink-2); margin: 8px 0 }
.qband .prio.none { color: var(--ink-3) }
.oline { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 8px 0; border-top: 1px solid var(--rule); font-size: var(--t-sm) }
.oline .o { grid-row: 2; font-size: var(--t-micro); color: var(--ink-3) }
.oline .v { grid-row: 1 / span 2; grid-column: 2; align-self: center; font-weight: 600; font-variant-numeric: tabular-nums }
.qband .unplanned { color: var(--ink-2); font-size: var(--t-sm); padding: 12px 0 }
.origin { font-size: var(--t-micro); color: var(--ink-3) }

/* Hours */
.hfig .lab { font-size: var(--t-sm); font-weight: 500; color: var(--ink-2) }
.hfig .big { margin: 10px 0 6px }
.hfig .sub { font-size: var(--t-micro); color: var(--ink-3) }
.hempty { text-align: center; padding: 48px 24px }
.hempty h3 { font-family: var(--display); font-size: 22px; margin: 0 0 8px }
.hempty p { color: var(--ink-2); margin: 0 auto; max-width: 480px }
.toinvoice, .hlog { margin-bottom: 20px }
.htab { width: 100%; border-collapse: collapse; font-size: var(--t-sm) }
.htab th { text-align: left; font-size: var(--t-micro); font-weight: 500; color: var(--ink-3); padding: 0 8px 8px 0 }
.htab td { padding: 10px 8px 10px 0; border-top: 1px solid var(--rule) }
.htab .r { text-align: right; font-variant-numeric: tabular-nums }
.htab tr.int td { color: var(--ink-2) }
.htab .note { color: var(--ink-2) }
.hweek { border-top: 1px solid var(--rule) }
.hweek summary { display: flex; justify-content: space-between; padding: 10px 0; cursor: pointer; font-weight: 500 }
.tag.quote { background: var(--accent-soft); color: var(--accent) }
.tag.warn { background: var(--warn-soft); color: var(--warn) }

/* Work, Finance */
.fcast { background: var(--surface); border-radius: 14px; box-shadow: var(--sh-hair); border: 0 }
.fcast b { font-family: var(--display) }
.kard { border-radius: 12px }
.fin-fig { padding: 20px 24px }
.fin-fig .n1 { font-family: var(--display); font-size: 36px }
.oline .star { color: var(--accent-fill) }
.col.folded .ch { height: auto; min-height: 8rem }
.cols { align-items: flex-start }
.col { background: var(--surface-2); border: 0; border-radius: 14px }
.htab { table-layout: fixed }
.htab col.c-date { width: 7.5rem } .htab col.c-for { width: 32% } .htab col.c-days { width: 4.5rem } .htab col.c-inv { width: 11rem }
.fin-big { font-family: var(--display); font-size: 56px; font-weight: 600; letter-spacing: -.04em }
.fin-sub { font-size: var(--t-md); color: var(--ink-3) }
/* Narrow content (a laptop with the sidebar open): the question sits on its own line above its state,
   the number's label sits under the number, and the three cards stay three — aligned — until the
   window is too narrow for them, then stack. A 2 + 1 reflow breaks the row they are read as. */
.qh { flex-wrap: wrap; align-items: flex-start }
.qh .l1h { flex: 1 1 11rem }
.big small { display: block; margin: 6px 0 0; line-height: 1.3 }
.grid3 { grid-template-columns: repeat(3, minmax(0, 1fr)) }
.grid3 .panel, .grid3 .qcard { padding: 20px }
@media (max-width: 1000px) { .grid3 { grid-template-columns: minmax(0, 1fr) } }

/* Finance · four figures, the open items, and the revenue mix against plan (2026-09-16). */
.fin-figs { grid-template-columns: repeat(4, minmax(0, 1fr)) }
.fin-fig .n1 { display: block }
.fin-fig .sub { font-size: var(--t-micro); color: var(--ink-3); margin-top: 6px }
.fin-open { grid-template-columns: repeat(4, minmax(0, 1fr)) }
.fin-openh { grid-column: 1 / -1; font-size: var(--t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 4px 0 -8px }
@media (max-width: 1000px) { .fin-figs, .fin-open { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
.revmix .fintab th { font-size: var(--t-micro); font-weight: 500; color: var(--ink-3); text-align: left; padding: 4px 0 }
.revmix .fintab th.v, .revmix .fintab th.pct { text-align: right }
.revmix .fintab td.pct.good { color: var(--good) } .revmix .fintab td.pct.warn { color: var(--warn) } .revmix .fintab td.pct.crit { color: var(--crit) }

/* ── v5 page header, segmented switch, objective rows (2026-09-16) ─────────────────────────────── */
.phead { display: flex; align-items: flex-end; gap: 32px; flex-wrap: wrap; margin-bottom: 24px }
.phead .h2 { margin: 6px 0 0 }
.phead .stats { margin-left: auto; display: flex; gap: 36px; flex-wrap: wrap }
.phead .stats .k { font-size: var(--t-micro); color: var(--ink-3) }
.phead .stats .sv { font-family: var(--display); font-size: 28px; font-weight: 600; letter-spacing: -.03em; margin-top: 2px; font-variant-numeric: tabular-nums }
.phead .stats .sv .of { font-size: var(--t-sm); font-weight: 400; color: var(--ink-3); letter-spacing: 0 }
.phead .stats .kl { font-size: var(--t-micro); color: var(--ink-3); max-width: 14rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.seg2 { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-2); border-radius: 12px; margin-bottom: 20px; flex-wrap: wrap }
.seg2 button { font-size: var(--t-sm); font-weight: 500; padding: 7px 14px; border-radius: 9px; border: 0; background: none; color: var(--ink-2); cursor: pointer }
.seg2 button .n { font-size: var(--t-micro); color: var(--ink-3); margin-left: 4px }
/* Selected tab, all four tablists. The v5 pill did not read as selected on dark, and the reason is in
   the tokens: --surface (0.0122) is DARKER than the --surface-2 track (0.0182), so the selected tile
   sank instead of rising, at 1.10:1, and --sh-seg (12% black) adds nothing on a near-black ground.
   Light inverts that (0.99 over 0.86), which is why only dark looked broken.
   The accent is this stylesheet's own answer: `one accent: selected state + primary action`, measured
   against --accent-soft precisely because that is the ground every selected state lands on — the
   token comment names `.domsw button.on`, which the v5 refresh had flattened to surface + ink.
   So: accent on --accent-soft, restored, plus weight. Three channels (hue, weight, tile), none of
   them a luminance step that flips between themes (Sjaak chose this over a 1px edge, 2026-09-20;
   an accent edge was refused because :focus-visible already is one). */
.seg2 button.on, .domsw button.on, .bsw .btab.on { font-weight: 700; color: var(--accent); background: var(--accent-soft) }
.seg2 button.on .n, .domsw button.on .n, .bsw .btab.on .n { color: var(--accent) }
.seg2 button.on { box-shadow: var(--sh-seg) }
.ocard .ph { display: flex; align-items: center; gap: 12px; margin-bottom: 8px }
.ocard .ph h4 { margin: 0; font-family: var(--display); font-size: 22px; font-weight: 600; letter-spacing: -.02em; color: var(--ink) }
.ocard .ph .pill { margin-left: auto; background: var(--accent-soft); color: var(--accent) }
.orow { border-top: 1px solid var(--rule); padding: 14px 0 }
.orow .orh { display: flex; align-items: baseline; gap: 16px; width: 100%; background: none; border: 0; padding: 0; text-align: left; color: var(--ink); font-size: var(--t-base); cursor: pointer }
.orow .orh .t { flex: 1; min-width: 0 }
.orow .orh .v { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap }
.orow .orh .v .of { font-weight: 400; color: var(--ink-3) }
.orow .star { color: var(--accent-fill) }
.orow .track { height: 6px; border-radius: 3px; background: var(--rule); overflow: hidden; margin-top: 10px }
.orow .track i { display: block; height: 100%; background: var(--accent-fill); border-radius: 3px }
.orow .odetail { display: none; padding-top: 12px }
.orow.open .odetail { display: block }
.orow .odetail .meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; font-size: var(--t-micro); color: var(--ink-3) }
.orow .odetail .meta .oedit { margin-left: auto }
.orow .odetail .links { display: flex; flex-direction: column; gap: 4px; margin-top: 10px }
.orow .odetail .olink { display: flex; gap: 12px; background: var(--surface-2); border: 0; border-radius: 8px; padding: 8px 10px; text-align: left; color: var(--ink); font-size: var(--t-sm); cursor: pointer }
.orow .odetail .olink .lm { margin-left: auto; color: var(--ink-3); white-space: nowrap }
.orow .odetail .none { font-size: var(--t-micro); color: var(--ink-3); margin-top: 8px }
.qband .qmore { background: none; border: 0; padding: 8px 0 0; color: var(--accent); font-size: var(--t-sm); cursor: pointer; text-align: left }

/* Work in v5: the switches read as segmented controls, the columns as quiet lanes (2026-09-16). */
.domsw, .bsw { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 4px; background: var(--surface-2); border-radius: 12px; border: 0; margin: 0 12px 16px 0 }
.domsw button, .bsw .btab { font-size: var(--t-sm); font-weight: 500; padding: 7px 14px; border-radius: 9px; border: 0; background: none; color: var(--ink-2); cursor: pointer; text-transform: capitalize }
.domsw button .n, .bsw .btab .n { font-size: var(--t-micro); color: var(--ink-3); margin-left: 6px; background: none }
.domsw button.on, .bsw .btab.on { box-shadow: var(--sh-seg); border: 0 }
.phead .stats .sv.accent { color: var(--accent) } .phead .stats .sv.warn { color: var(--warn) } .phead .stats .sv.crit { color: var(--crit) }
.col { background: var(--surface-2); padding: 12px }
.cx { border: 0 }
.kard { background: var(--surface); border: 0; box-shadow: var(--sh-hair-2); padding: 12px 14px }
.controls { margin-bottom: 16px }

/* v5 on every page (2026-09-17): one head, cards for the content, no back buttons. */
.phead .pht { min-width: 14rem }
.phead .phs { font-size: var(--t-sm); color: var(--ink-3); margin: 6px 0 0; max-width: 40rem }
.phead .pha { margin-left: auto }
.phead .stats + .pha { margin-left: 0 }
.phead .stats .kl { display: block }
.phead.fin-head { align-items: flex-start }
.csx { background: var(--surface); border: 0; border-radius: 18px; box-shadow: var(--sh-card); margin: 0 0 20px }
.csx .csh { padding: 20px 24px; border-bottom: 1px solid var(--rule); background: transparent }
.csx .csh h3 { font-family: var(--display); font-size: 20px; font-weight: 600; letter-spacing: -.02em }
.csx .chg { padding: 16px 24px }
.inbox > .empty { border: 0; background: var(--surface); border-radius: 18px; padding: 48px 24px; text-align: center; box-shadow: var(--sh-card) }
.chatpage .chatlog { background: var(--surface); border: 0; border-radius: 18px; padding: 20px; box-shadow: var(--sh-card) }
.chatpage .chatbar { background: var(--surface); border-radius: 16px; padding: 10px 12px; margin-top: 16px; box-shadow: var(--sh-card) }
.chatpage .chatbar input { border: 0; outline: none; background: transparent }
.regpage .rbar { margin: 0 0 12px }
.regpage .rtw { background: var(--surface); border: 0; border-radius: 18px; box-shadow: var(--sh-card) }
.regpage .rtab th { background: transparent }

/* Finance traffic lights (2026-09-17): quiet when fine; a rule on the left edge and a word when not. */
.fin-fig { position: relative; overflow: hidden }
.fin-fig.st-warn::before, .fin-fig.st-crit::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px }
.fin-fig.st-warn::before { background: var(--warn-fill) }
.fin-fig.st-crit::before { background: var(--crit-fill) }
.fin-fig .fh { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px }
.fin-fig .rule { font-size: var(--t-micro); color: var(--ink-3); margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--rule) }
.fin-health { margin: 10px 0 4px; font-size: var(--t-sm); color: var(--ink-2); display: flex; align-items: center; gap: 8px; flex-wrap: wrap }

/* Minimal pass (2026-09-17): explanations live in tooltips, not in small grey lines. */
.fin-fig .sub:empty { display: none }
.trendrow span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0) }
.why summary { list-style: none; display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; color: var(--ink-3); font-size: 14px }
.why summary::-webkit-details-marker { display: none }
.why summary:hover { background: var(--surface-2); color: var(--ink) }
.col .win:empty { display: none }
.kard .note.gr { -webkit-line-clamp: 1 }

/* One status language (2026-09-17). Green and "not measured" stay quiet: no fill, a dot and a word. */
.stag.good, .stag.idle { background: none; padding-left: 0; padding-right: 0; color: var(--ink-3) }
.stag.good i { background: var(--good-fill) }
.stag.idle i { background: transparent; border: 1.5px solid var(--idle-fill) }
.stag.done { background: var(--accent-soft); color: var(--accent) } .stag.done i { background: var(--accent); border-radius: 2px }
.track.pace { position: relative; overflow: visible; height: 6px; border-radius: 3px; background: var(--rule) }
.track.pace i { display: block; height: 100%; border-radius: 3px; background: var(--ink-3) }
.track.pace i.warn { background: var(--warn-fill) } .track.pace i.crit { background: var(--crit-fill) }
.track.pace b { position: absolute; top: -4px; width: 2px; height: 14px; border-radius: 1px; background: var(--ink) }
.orow .orh { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px }
.orow .track.pace { margin: 6px 0 2px }
.ocard .ph { display: flex; align-items: center; justify-content: space-between; gap: 12px }
.ocard .ocn { font-size: var(--t-sm); color: var(--ink-2); margin: 0 0 8px }
.qband .ph { justify-content: space-between }
.qband .cn .track.pace { margin-top: 12px }
/* Only a critical card carries an edge; anything else stays plain so the four that matter stand out. */
.kard.sev-crit { overflow: hidden }
.kard.sev-crit::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--crit-fill) }
.kard .note.due.crit { color: var(--crit); font-weight: 600 }
.qcard .qh .why { margin-left: auto }
.qcard .qh .why[open] { flex-basis: 100%; order: 3 }
/* The right edge does not jump between a page that scrolls and one that does not. */
html { scrollbar-gutter: stable }
/* The quarter card's head keeps its label on one line and lets the pill wrap under it. */
.qband .ph { flex-wrap: wrap; row-gap: 6px }
.qband .ph h4 { white-space: nowrap }

/* Walk-through fixes (2026-09-17). */
.big .u { font-family: var(--sans); font-size: var(--t-md); font-weight: 450; color: var(--ink-3); letter-spacing: 0; margin-left: 6px }
.qcard .qh .why { align-self: center }
.col .cx .ch .agg:empty { display: none }
.col .cx:has(.agg:empty) { margin-bottom: 0 }
.fin-open .fin-fig { grid-column: span 2 }
@media (max-width: 1000px) { .fin-open .fin-fig { grid-column: span 1 } }
.fin-fig .fh .lab { white-space: nowrap }
.revmix .fintab { width: 100%; border-collapse: collapse }
.revmix .fintab th { padding: 4px 0 6px 12px; white-space: nowrap }
.revmix .fintab th:first-child { padding-left: 0 }
.revmix .fintab td { padding: 8px 0 8px 12px }
.revmix .fintab td.lb { padding-left: 0 }
.revmix .fintab td.pct.good { color: inherit }
.chatpage .cb b { font-weight: 650 }
.regpage .rtab td, .regpage .rtab .rcm, .regpage .rdom, .regpage .rn { font-family: var(--sans) }
.regpage .rcm { overflow-wrap: normal; word-break: normal }
.regpage .rdom { white-space: nowrap }
/* The question takes its own line; its state and the info mark share the next one, centred. */
.qcard .qh { align-items: center }
.qcard .qh .l1h { flex-basis: 100% }
/* Numbers in the finance tables read in the page's face; the label column gets the room it needs. */
.fintab .v, .fintab .pct { font-family: var(--sans) }
.revmix .fintab td.lb { width: 42% }
.fintab .lb .lbw { display: flex; align-items: baseline; gap: 8px }
.fintab .lb .lbw i { flex: none; margin-right: 0 }
/* The info mark sits on the state's line, at its size; and a details panel opens on [open]. */
.qcard .qh .why { margin-top: 0 }
.qcard .qh .why > summary { font-size: 15px }
.why[open] .ans { display: block }

/* The monitor (2026-09-17): one verdict, one line per part; only what is off track carries an edge. */
.monverdict { display: flex; align-items: center; gap: 10px }
.monverdict .monchk { font-size: var(--t-sm); color: var(--ink-3) }
.monlist { padding: 8px 24px 16px }
.mong { font-size: var(--t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 18px 0 2px }
.monrow { position: relative; display: grid; grid-template-columns: 11rem 9.5rem minmax(0, 1fr) 5rem; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--rule); font-size: var(--t-sm) }
.monrow .mn { font-weight: 600 } .monrow .mt { color: var(--ink-2) } .monrow .ma { color: var(--ink-3); text-align: right; font-variant-numeric: tabular-nums }
.monrow.crit::before { content: ''; position: absolute; left: -24px; top: 8px; bottom: 8px; width: 4px; border-radius: 2px; background: var(--crit-fill) }
@media (max-width: 720px) { .monrow { grid-template-columns: 1fr auto } .monrow .mt { grid-column: 1 / -1 } .monrow .ma { text-align: left } }
/* Done and cancelled stand open with their latest few; the rest is one click away (2026-09-17). */
.termtog { background: none; border: 0; padding: 6px 4px 2px; color: var(--accent); font-size: var(--t-sm); cursor: pointer; text-align: left }
.termtog:hover { text-decoration: underline }
.attention .calm { color: var(--ink-3); font-size: var(--t-sm); margin: 8px 0 0 }

/* The card, read (2026-09-17): a page to read, in the app's own cards and type. */
.modal.cardview { align-items: flex-start; overflow-y: auto; padding: 40px 16px }
.cv { background: var(--surface); border-radius: 20px; box-shadow: var(--sh-dialog); width: min(640px, 100%); padding: 32px; display: flex; flex-direction: column; gap: 22px; box-sizing: border-box; margin: 0 auto }
.cvh { display: flex; align-items: flex-start; gap: 16px }
.cvh > div { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px }
.cvh .eyebrow { margin: 0 }
.cvh h2 { margin: 0; font-family: var(--display); font-size: 26px; line-height: 1.2; font-weight: 600; letter-spacing: -.02em; overflow-wrap: anywhere }
.cvpills { display: flex; gap: 8px; flex-wrap: wrap; align-items: center }
.cvcol { font-size: var(--t-micro); font-weight: 600; padding: 4px 10px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2) }
.cvx { flex: none; width: 44px; height: 44px; border-radius: 12px; border: 1px solid var(--rule); background: var(--surface); color: var(--ink-2); font-size: 16px; cursor: pointer }
.cvx:hover { color: var(--ink); border-color: var(--rule-2) }
.cvblock { display: flex; flex-direction: column; gap: 3px; padding: 14px 16px; border-radius: 14px; background: var(--surface-2) }
.cvblock .k { font-size: var(--t-micro); color: var(--ink-3) }
.cvblock b { font-size: var(--t-base); font-weight: 600 }
.cvblock.crit { background: var(--crit-soft) } .cvblock.crit b { color: var(--crit) }
.cvblock.warn { background: var(--warn-soft); flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap } .cvblock.warn b { color: var(--warn) }
.cvamount { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap }
.cvamount .big { font-size: 44px }
.cvamount span:last-child { color: var(--ink-3); font-size: var(--t-base) }
.cvfacts { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 16px }
@media (max-width: 560px) { .cvfacts { grid-template-columns: 1fr 1fr } }
.cvf { display: flex; flex-direction: column; gap: 4px; min-width: 0 }
.cvf .k { font-size: var(--t-micro); color: var(--ink-3) }
.cvf .v { font-size: var(--t-base); font-weight: 500; overflow-wrap: anywhere }
.cvf .v .crit { color: var(--crit) }
.cv section { display: flex; flex-direction: column; gap: 8px; border-top: 1px solid var(--rule); padding-top: 18px }
.cv section h3 { margin: 0; font-family: var(--sans); font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.cvp { margin: 0; font-size: var(--t-base); line-height: 1.6; color: var(--ink-2); white-space: pre-wrap; overflow-wrap: anywhere }
.cvp.clamp { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden }
.cvp a, .linkbtn { color: var(--accent) }
.linkbtn { background: none; border: 0; padding: 0; font: inherit; font-size: var(--t-sm); font-weight: 600; cursor: pointer; text-align: left }
/* The opportunity link (dss-virtual-office#110): the step and its deal open each other, like .cvobj. */
.cvblock.cvlink { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 12px; align-items: center; border: 0; font: inherit; color: var(--ink); text-align: left; cursor: pointer }
.cvblock.cvlink .k, .cvblock.cvlink b { grid-column: 1 }
.cvblock.cvlink .go { grid-column: 2; grid-row: 1 / span 2; font-size: var(--t-sm); font-weight: 600; color: var(--accent) }
.cvblock.cvlink:hover { background: var(--rule) }
.cvobj { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; align-items: center; padding: 12px 14px; border-radius: 12px; border: 0; background: var(--surface-2); color: var(--ink); font: inherit; text-align: left; cursor: pointer }
.cvobj:hover { background: var(--rule) }
.cvobj .t { font-weight: 600 } .cvobj .s { grid-row: 2; font-size: var(--t-micro); color: var(--ink-3) }
.cvobj .go { grid-row: 1 / span 2; grid-column: 2; font-size: var(--t-sm); font-weight: 600; color: var(--accent) }
.cvf-acts { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; border-top: 1px solid var(--rule); padding-top: 18px }
.cvf-acts .btn { min-height: 44px }
.cvf-acts .note { flex: 1; min-width: 12rem; text-align: right; font-size: var(--t-micro); color: var(--ink-3) }
.kard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
/* The objective the drill-down opened, and its contributing actions. */
.orow.focus { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 12px }
.orow .odetail .olh { font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin-top: 12px }
.orow .odetail .olink.crit { background: var(--crit-soft) }
.orow .odetail .olink.crit .lt { font-weight: 600 }
.orow .odetail .oall { margin-top: 6px }

/* The monitor, redesigned (2026-09-17): the answer, what to do, then quiet tiles. */
.mbadge { flex: none; border-radius: 50%; display: grid; place-items: center }
.mbadge.good { background: var(--good-soft); color: var(--good) }
.mbadge.warn { background: var(--warn-soft); color: var(--warn) }
.mbadge.crit { background: var(--crit-soft); color: var(--crit) }
.mbadge.idle { background: var(--surface-2); color: var(--ink-3) }
.mhero { display: flex; align-items: center; gap: 24px; background: var(--surface); border-radius: 20px; padding: 28px 32px; box-shadow: var(--sh-card); margin-bottom: 8px }
.mhero .mht { font-family: var(--display); font-size: 30px; font-weight: 600; letter-spacing: -.02em }
.mhero .mhs { font-size: var(--t-base); color: var(--ink-2); margin-top: 4px }
.mlabel { font-size: var(--t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin: 22px 0 10px }
.mcards { display: flex; flex-direction: column; gap: 12px }
.mcard { position: relative; overflow: hidden; display: flex; gap: 18px; align-items: flex-start; background: var(--surface); border-radius: 18px; padding: 22px 24px; box-shadow: var(--sh-card) }
.mcard::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px }
.mcard.warn::before { background: var(--warn-fill) } .mcard.crit::before { background: var(--crit-fill) }
.mcard.warn .mw b { color: var(--warn) } .mcard.crit .mw b { color: var(--crit) }
.mtxt { display: flex; flex-direction: column; gap: 4px; min-width: 0 }
.mcard .mt { font-size: 17px; font-weight: 600 }
.mcard .mw { font-size: var(--t-base); line-height: 1.55; color: var(--ink-2) }
.mitems summary { cursor: pointer; color: var(--accent); font-weight: 600; font-size: var(--t-sm); margin-top: 4px }
.mitems ul { margin: 8px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px }
.mitems li { display: flex; justify-content: space-between; gap: 12px; font-size: var(--t-sm); padding: 8px 10px; border-radius: 8px; background: var(--surface-2) }
.mitems .ma { color: var(--ink-3); white-space: nowrap }
.mtiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px }
@media (max-width: 1000px) { .mtiles { grid-template-columns: minmax(0, 1fr) } }
.mtile { display: flex; gap: 14px; align-items: flex-start; background: var(--surface); border-radius: 16px; padding: 18px 20px; box-shadow: var(--sh-card) }
.mtile .mg { font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.mtile .mt { font-size: var(--t-base); font-weight: 600 }
.mtile .mw { font-size: var(--t-sm); color: var(--ink-2) }
.mtile .mwhen { font-size: var(--t-micro); color: var(--ink-3) }
.kl .k .kd { display: block; font-size: var(--t-micro); color: var(--ink-3); margin-top: 2px }

/* The delivery window from the forge (2026-09-20): a stock and three flows, each in its own plot.
   The series hues are inline on the marks (they come from the data definition, not from a state), so
   only the frame is styled here. Grid and axis stay recessive: the data is the only thing with edge. */
.mflowhead { display: flex; align-items: baseline; justify-content: space-between; gap: 4px 12px; flex-wrap: wrap }
.mflowhead .mlabel { margin-bottom: 10px }
.mflowsrc { font-size: var(--t-sm); color: var(--ink-3) }
.mflow { background: var(--surface); border-radius: 18px; padding: 20px 24px 10px; box-shadow: var(--sh-card) }
.mflow + .mflow { margin-top: 14px }
.mflow.empty { color: var(--ink-2); font-size: var(--t-base); padding: 22px 24px; line-height: 1.55 }
.mfhead { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; flex-wrap: wrap }
.mfhead b { font-size: var(--t-md); font-weight: 600 }
.mfhead > span { font-size: var(--t-sm); color: var(--ink-3) }
.mflegend { display: flex; gap: 16px; flex-wrap: wrap; font-size: var(--t-sm); color: var(--ink-2); margin-top: 8px }
.mflegend span { display: flex; align-items: center; gap: 7px }
.mflegend i { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0 }
.mfsvg { width: 100%; height: auto; display: block; margin-top: 4px; overflow: visible }
.mfgrid line { stroke: var(--rule); stroke-width: 1 }
.mfax { font-family: var(--display); font-size: 12px; fill: var(--ink-3) }
.mfax.bold { font-weight: 600; fill: var(--ink-2) }
.mfarea { fill: var(--ink-3); fill-opacity: .10 }
.mfline { fill: none; stroke: var(--ink-3); stroke-width: 2; stroke-linejoin: round }
.mfzero { stroke: var(--ink-3); stroke-width: 1 }
.mfquiet { fill: var(--ink-3); fill-opacity: .5 }
.mfpr { fill: var(--idle-fill) }
.mftab { width: 100%; border-collapse: collapse; font-size: var(--t-sm); margin: 6px 0 12px }
.mftab th { font-weight: 600; color: var(--ink-3); text-align: right; padding: 7px 10px; border-bottom: 1px solid var(--rule) }
.mftab th:first-child { text-align: left; padding-left: 0 }
.mftab th:last-child, .mftab td:last-child { padding-right: 0 }
.mftab td { font-family: var(--display); text-align: right; color: var(--ink-2); padding: 6px 10px }
.mftab td.dt { font-family: var(--sans); text-align: left; color: var(--ink-3); padding-left: 0 }
.mftab td.op { font-weight: 600; color: var(--ink) }
.mftab td.nt { font-weight: 600; color: var(--ink) }
.mftab tr.today td { color: var(--ink-3); font-weight: 400 }
@media (max-width: 700px) { .mflegend { gap: 10px } .mflow { padding: 16px 16px 8px } }
/* Six columns in a 326px card: the padding goes, the header wraps, the figures stay. */
@media (max-width: 560px) { .mftab th, .mftab td { padding: 6px 4px } .mftab th { white-space: normal } }

/* ── Inbox, v5 (2026-09-17) ─────────────────────────────────────────────── */
.phsub { margin: 6px 0 0; font-size: var(--t-base); color: var(--ink-2) }
.inboxempty { margin-bottom: 0 }
.csx .csh { padding: 24px 28px 16px; border-bottom: 0; align-items: flex-start }
.csx .csh h3 { font-size: 22px }
.csx .csm { margin-top: 6px; color: var(--ink-3) }
.csx .csa { align-items: center; gap: 16px; flex-wrap: nowrap }
.csx .csa .linkbtn { color: var(--ink-2); font-weight: 500; white-space: nowrap }
.csx .csa .btn.primary { white-space: nowrap }
.csx .csp { font-size: inherit; color: inherit; margin: 0; font-weight: 600 }
.csx .chgs { padding: 0 28px 8px }
.csx .chg { display: flex; gap: 18px; align-items: flex-start; padding: 18px 0; border-top: 1px solid var(--rule); border-bottom: 0 }
.chgm { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px }
.chgh { align-items: center; gap: 10px }
.chgt { font-size: 16px; font-weight: 600 }
.chgw { font-size: var(--t-sm); color: var(--ink-3) }
.opchip { font-size: var(--t-micro); font-weight: 600; padding: 4px 10px; border-radius: 999px; white-space: nowrap }
.opchip.op-create { background: var(--good-soft); color: var(--good) }
.opchip.op-patch { background: var(--accent-soft); color: var(--accent) }
.opchip.op-retire { background: var(--warn-soft); color: var(--warn) }
.opchip.op-remove { background: var(--crit-soft); color: var(--crit) }
dl.chgd { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 6px 16px; margin: 0; font-size: var(--t-base); color: var(--ink); line-height: 1.5 }
dl.chgd dt { font-size: var(--t-sm); color: var(--ink-3); padding-top: 1px }
dl.chgd dd { margin: 0; overflow-wrap: anywhere }
dl.chgd .was { color: var(--ink-3) }
dl.chgd s.was { text-decoration: line-through }
dl.chgd .arrow { color: var(--ink-3); margin: 0 6px }
.chgg { margin: 0; font-size: var(--t-base); line-height: 1.5; color: var(--ink-2) }
.chgg b { color: var(--ink); font-weight: 600 }
.chg.no .chgh, .chg.no .chgw, .chg.no .chgd, .chg.no .chgg { opacity: .5 }
.chgr { display: flex; gap: 10px; align-items: center; margin-top: 4px }
.chgr span { font-size: var(--t-sm); font-weight: 600; color: var(--crit); white-space: nowrap }
.chgr .vr { flex: 1; min-width: 0; border: 1px solid var(--crit-soft); border-radius: 8px; padding: 8px 12px; font: inherit; font-size: var(--t-base); background: var(--surface); color: var(--ink) }
.csx .vseg { display: flex; gap: 6px; background: none; border: 0; padding: 0 }
.csx .vseg button { width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--rule); background: var(--surface); color: var(--ink-3); display: grid; place-items: center; padding: 0; cursor: pointer; box-shadow: none }
.csx .vseg button[data-v="applied"].on { background: var(--good); border-color: var(--good); color: var(--surface) }
.csx .vseg button[data-v="rejected"].on { background: var(--crit); border-color: var(--crit); color: var(--surface) }
.receipt { display: flex; align-items: center; gap: 16px; background: var(--surface); border-radius: 16px; padding: 18px 22px; margin-bottom: 20px; box-shadow: var(--sh-card) }
.receipt .rct { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px }
.receipt .rct b { font-size: var(--t-base) }
.receipt .rct span { font-size: var(--t-sm); color: var(--ink-2) }
@media (max-width: 720px) {
  .csx .csh { flex-direction: column }
  .csx .csh, .csx .chgs { padding-inline: 18px }
  dl.chgd { grid-template-columns: 1fr }
}

/* ── Register, v5 (2026-09-17) ──────────────────────────────────────────── */
.regpage .rbar { gap: 12px; margin: 0 0 18px; flex-wrap: wrap }
.rsearch { flex: 1 1 260px; display: flex }
.rsearch input { width: 100%; border: 1px solid var(--rule); border-radius: 10px; padding: 10px 14px; font: inherit; font-size: var(--t-base); background: var(--surface); color: var(--ink) }
.rseg button { padding: 6px 12px; font-size: var(--t-sm) }
.dgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px }
.dcard { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 6px; background: var(--surface); border-radius: 18px; padding: 20px 22px; box-shadow: var(--sh-card); min-width: 0 }
.dcard:hover { box-shadow: var(--sh-card-hover) }
.dcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
.dcard.hidden { display: none }
.dcard .dk { font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.dcard .dn { font-family: var(--display); font-size: 20px; font-weight: 600; letter-spacing: -.02em; color: var(--ink) }
.dcard .dd { font-size: var(--t-sm); color: var(--ink-2); overflow-wrap: anywhere }
.dcard .dp { display: flex; align-items: center; gap: 10px; margin-top: 8px; font-size: var(--t-sm); color: var(--ink-2) }
.dcard .dw { border-top: 1px solid var(--rule); padding-top: 12px; margin-top: 8px; font-size: var(--t-base); font-weight: 500; color: var(--ink) }
.dcard .dw .none, .dcard.closed .dw { color: var(--ink-3); font-weight: 400 }
.avs { display: flex; padding-left: 6px }
.avs .av, .dperson .av { width: 28px; height: 28px; margin-left: -3px; border: 2px solid var(--surface); background: var(--accent-soft); color: var(--accent); font-size: var(--t-micro); font-weight: 600 }
.avs .av.more { background: var(--surface-2); color: var(--ink-2) }
.dclosed { margin-top: 22px }
.dclosed > summary { cursor: pointer; font-size: var(--t-base); color: var(--ink-2); margin-bottom: 14px }
.dclosed > summary span { color: var(--ink-3) }
.regpage .rnone { color: var(--ink-3) }
.dossierview .cv { width: min(680px, 100%) }
.dossierview .cvh .btn { align-self: center }
.dwrow { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 0; border-top: 1px solid var(--rule) }
.dwrow:hover .wt { color: var(--accent) }
.dwrow .wk { width: 56px; flex: none; font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.dwrow .wt { flex: 1; min-width: 0; font-size: var(--t-base); font-weight: 500 }
.dwrow .wr { font-size: var(--t-sm); color: var(--ink-2); min-width: 64px; text-align: right }
.dwrow .go { color: var(--ink-3) }
.dperson { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--rule) }
.dperson .av { width: 34px; height: 34px; margin: 0; border: 0; font-size: var(--t-micro) }
.dperson .pn { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: var(--t-base) }
.dperson .pn small { font-size: var(--t-sm); color: var(--ink-3) }
.dperson .pm { font-size: var(--t-sm); text-align: right; overflow-wrap: anywhere }
.dperson .pm a { color: var(--accent) }
.tagint { font-size: var(--t-micro); font-weight: 600; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2) }
.dvall { margin-top: 8px }
@media (max-width: 560px) { .dperson { flex-wrap: wrap } .dperson .pm { width: 100%; text-align: left; padding-left: 46px } }

/* A refusal on the line it is about (2026-09-17). */
.refusal { margin: 4px 0 0; padding: 10px 14px; border-radius: 10px; background: var(--crit-soft); color: var(--crit); font-size: var(--t-base); line-height: 1.5 }
.refusal b { font-weight: 600; margin-right: 4px }
.refusal small { display: block; margin-top: 4px; font-size: var(--t-micro); color: var(--ink-2); overflow-wrap: anywhere }
.refusal.cs { margin: 0 28px 12px }

/* ── Opportunities, v5 (2026-09-17) ─────────────────────────────────────── */
.pipepage .phead .stats .sv .stag { display: flex; width: max-content; margin-top: 6px; font-family: var(--sans); letter-spacing: 0 }
.pipecols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; align-items: start }
.pcol { background: var(--surface-2); border-radius: 18px; padding: 14px; display: flex; flex-direction: column; gap: 10px; min-width: 0 }
.pcol > header { display: flex; align-items: baseline; gap: 8px; padding: 2px 4px }
.pcol > header b { font-size: var(--t-base); font-weight: 600 }
.pcol > header .pp { font-size: var(--t-sm); color: var(--ink-3) }
.pcol > header .pn { margin-left: auto; font-size: var(--t-sm); color: var(--ink-2); white-space: nowrap }
.pempty { margin: 0; padding: 6px 4px; font-size: var(--t-sm); color: var(--ink-3) }
.kard.deal { all: unset; box-sizing: border-box; cursor: pointer; position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 8px; background: var(--surface); border-radius: 14px; padding: 16px 18px; box-shadow: var(--sh-card) }
.kard.deal:hover { box-shadow: var(--sh-card-hover) }
.kard.deal:focus-visible, .kard.crow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
.kard.deal.late::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--crit-fill) }
.kard.deal .dt { font-size: var(--t-base); font-weight: 600; line-height: 1.35; color: var(--ink) }
.kard.deal .da { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap }
.kard.deal .da b { font-family: var(--display); font-size: 22px; font-weight: 600; letter-spacing: -.02em; color: var(--ink) }
.kard.deal .da small { font-size: var(--t-sm); color: var(--ink-3) }
.kard.deal .ds { display: flex; gap: 8px; align-items: flex-start; font-size: var(--t-sm); color: var(--ink); border-top: 1px solid var(--rule); padding-top: 8px; line-height: 1.45 }
.kard.deal .ds svg { flex: none; margin-top: 2px }
.kard.deal .ds.crit { color: var(--crit); font-weight: 500 }
.kard.deal .ds.warn { color: var(--warn); font-weight: 500 }
.kard.deal .dm { font-size: var(--t-micro); color: var(--ink-3) }
.kard.deal .dm .dc.warn { color: var(--warn) } .kard.deal .dm .dc.crit { color: var(--crit) }
.kard.deal .dm .quote { background: none; padding: 0; color: var(--ink-3) }
.pclosed { margin-top: 22px; background: var(--surface); border-radius: 18px; padding: 18px 24px 8px; box-shadow: var(--sh-card) }
.pclosed > header { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-bottom: 10px }
.pclosed > header b { font-family: var(--display); font-size: 18px; font-weight: 600 }
.pclosed > header span { font-size: var(--t-sm); color: var(--ink-2) }
.pclosed > header .pall { margin-left: auto }
.kard.crow { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px 0; border-top: 1px solid var(--rule); font-size: var(--t-base) }
.kard.crow.hidden { display: none }
.kard.crow:hover .ct { color: var(--accent) }
.crow .cchip { flex: none; width: 84px; text-align: center; font-size: var(--t-micro); font-weight: 600; padding: 3px 0; border-radius: 999px; background: var(--surface-2); color: var(--ink-2) }
.crow .cchip.won { background: var(--good-soft); color: var(--good) }
.crow .ct { flex: 1; min-width: 0; font-weight: 500 }
.crow .cx { flex: 0 1 240px; min-width: 0; font-size: var(--t-sm); color: var(--ink-2) }
.crow .ca { width: 80px; text-align: right; font-weight: 600 }
.crow .ca.lost { color: var(--ink-3) }
.crow .cx .lr { color: var(--ink-2) } .crow .cx .lr.warn { color: var(--warn); font-weight: 600 }
@media (max-width: 900px) { .pipecols { grid-template-columns: 1fr 1fr !important } }
@media (max-width: 560px) { .pipecols { grid-template-columns: 1fr !important } .crow .cx { display: none } }

/* ── Chat, v5 (2026-09-17) ──────────────────────────────────────────────── */
.chatpage .chatlog { background: none; box-shadow: none; padding: 4px 2px; gap: 16px }
.chatpage .ct { gap: 12px; align-items: flex-start }
.chatpage .ct .cb { white-space: normal; max-width: min(46rem, 78%); padding: 14px 18px; font-size: var(--t-base); line-height: 1.55 }
.chatpage .ct.me .cb { border-radius: 16px 16px 4px 16px; padding: 12px 16px }
.chatpage .ct.chief .cb { background: var(--surface); border-radius: 4px 16px 16px 16px; box-shadow: var(--sh-card) }
.chatpage .ct.chief .cb.failed { background: var(--crit-soft) }
.chatpage .cb p { margin: 0 0 8px } .chatpage .cb p:last-child { margin-bottom: 0 }
.chatpage .cb ul { margin: 0 0 10px; padding-left: 20px; display: flex; flex-direction: column; gap: 4px } .chatpage .cb ul:last-child { margin-bottom: 0 }
.cav { flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--ink); color: var(--surface); display: grid; place-items: center; font-size: var(--t-micro); font-weight: 600 }
.chatpage .chatbar { padding: 8px 8px 8px 18px; gap: 10px }
.chatpage .chatbar input { font-size: var(--t-base); padding: 10px 0 }
.chatpage .chatbar .send { width: 44px; height: 44px; border-radius: 12px; border: 0; background: var(--accent-fill); color: var(--surface); display: grid; place-items: center; cursor: pointer; flex: none }
.chatpage .chatbar .send:disabled { opacity: .5; cursor: default }
.chatnote { margin: 0; text-align: center; font-size: var(--t-sm); color: var(--ink-3) }

/* ── Agenda, v5 (2026-09-17) ────────────────────────────────────────────── */
.calcards { display: flex; flex-direction: column; gap: 14px }
.calcard { display: flex; align-items: center; gap: 18px; background: var(--surface); border-radius: 18px; padding: 22px 24px; box-shadow: var(--sh-card) }
.calico { flex: none; width: 48px; height: 48px; border-radius: 14px; background: var(--accent-soft); color: var(--accent); display: grid; place-items: center }
.caltxt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px }
.caltxt b { font-size: var(--t-md) }
.caltxt span { font-size: var(--t-sm); color: var(--ink-2) }
.calcopy { color: var(--ink-2); font-weight: 500 }
.calmore { position: relative }
.calmore > summary { list-style: none; width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--rule); display: grid; place-items: center; cursor: pointer; color: var(--ink-2); font-size: var(--t-md) }
.calmore > summary::-webkit-details-marker { display: none }
.calmenu { position: absolute; right: 0; top: 46px; background: var(--surface); border-radius: 12px; padding: 10px 14px; box-shadow: var(--sh-menu); white-space: nowrap; z-index: 5 }
.calmenu .danger { color: var(--crit) }
.calhow { margin-top: 18px }
.calhow > summary { cursor: pointer; color: var(--accent); font-size: var(--t-sm); font-weight: 600 }
.calhow p { margin: 8px 0 0; max-width: 68ch; font-size: var(--t-sm); color: var(--ink-2); line-height: 1.55 }
@media (max-width: 720px) { .calcard { flex-wrap: wrap } .caltxt { flex-basis: calc(100% - 66px) } }

/* ── Uren, v5 (2026-09-17) ──────────────────────────────────────────────── */
.hours .hempty { text-align: left; padding: 28px 32px }
.hours .hempty .mhs { max-width: 60ch }
.hours .toinvoice { position: relative; overflow: hidden; background: var(--surface); border-radius: 18px; padding: 20px 24px 14px 29px; margin-bottom: 20px; box-shadow: var(--sh-card) }
.hours .toinvoice::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; background: var(--warn-fill) }
.hours .tih { display: block; font-size: var(--t-md); margin-bottom: 6px }
.hours .tir { display: flex; align-items: baseline; gap: 16px; padding: 6px 0; font-size: var(--t-base); color: var(--ink-2) }
.hours .tir > span:first-child { flex: 1; min-width: 0 }
.hours .tid { font-weight: 600; color: var(--ink) }
.hours .hlog { background: var(--surface); border-radius: 18px; padding: 6px 24px 14px; box-shadow: var(--sh-card) }
.hours .hweek > summary { display: flex; align-items: baseline; padding: 14px 0 6px; cursor: pointer; font-size: var(--t-base); font-weight: 600; list-style: none }
.hours .hweek > summary::-webkit-details-marker { display: none }
.hours .hweek > summary::before { content: '›'; display: inline-block; width: 16px; color: var(--ink-3); transition: transform .12s }
.hours .hweek[open] > summary::before { transform: rotate(90deg) }
.hours .hweek > summary .n { margin-left: auto; font-weight: 400; color: var(--ink-2) }
.hours .hrow { display: grid; grid-template-columns: 110px minmax(0, 1fr) 60px 150px; gap: 14px; align-items: center; padding: 11px 0; border-top: 1px solid var(--rule); font-size: var(--t-base) }
.hours .hrow .hd { color: var(--ink-2) }
.hours .hrow .hw b { font-weight: 500 }
.hours .hrow .hw span { color: var(--ink-3) }
.hours .hrow .hn { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums }
.hours .hrow.int .hw b { color: var(--ink-2) }
.hst { justify-self: end; font-size: var(--t-micro); font-weight: 600; padding: 3px 10px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2); white-space: nowrap }
.hst.warn { background: var(--warn-soft); color: var(--warn) }
.hst.quiet { background: none; color: var(--ink-3); font-weight: 500 }
@media (max-width: 720px) { .hours .hrow { grid-template-columns: 80px minmax(0, 1fr) 40px } .hours .hrow .hst { grid-column: 2 / -1; justify-self: start } }

/* ── Acties, v5 (2026-09-17) ─────────────────────────────────────────────── */
/* The department switch counts in the body face, not the code face. */
.domsw button .n, .bsw .btab .n { font-family: var(--sans) }
.domsw button.on .n, .bsw .btab.on .n { color: var(--accent) }
/* One wide column, the rest narrow on the right: an action board never scrolls sideways. */
.actgrid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 14px; align-items: start }
.actgrid.solo { grid-template-columns: minmax(0, 1fr) }
.actside { display: flex; flex-direction: column; gap: 14px; min-width: 0 }
.acol { background: var(--surface-2); border-radius: 18px; padding: 14px; display: flex; flex-direction: column; gap: 10px; min-width: 0 }
.acol.drop, .aclosed.drop { box-shadow: inset 0 0 0 2px var(--accent) }
.acol > header { display: flex; align-items: baseline; gap: 8px; padding: 2px 4px }
.acol > header b { font-size: var(--t-base); font-weight: 600 }
.acol > header .an, .acol > header .wip { margin-left: auto; font-size: var(--t-sm); color: var(--ink-2); white-space: nowrap; background: none; padding: 0; font-family: var(--sans) }
.acol > header .wip.over { color: var(--crit); font-weight: 600 }
.acol > header .add { background: none; border: 0; color: var(--ink-3); font-size: var(--t-md); line-height: 1; cursor: pointer; padding: 0 2px }
.acol > header .add:hover { color: var(--accent) }
.acards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; align-items: start }
.agrp { grid-column: 1 / -1; margin-top: 4px; font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.aempty { margin: 0; padding: 6px 4px; font-size: var(--t-sm); color: var(--ink-3) }
.afree { margin: 0; padding: 4px; font-size: var(--t-sm); color: var(--ink-3) }
.afree.over { color: var(--crit); font-weight: 600 }
.acol .amore { align-self: flex-start; padding: 4px; color: var(--accent) }
.kard.act { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 8px; min-width: 0; background: var(--surface); border: 0; border-radius: 12px; padding: 14px 16px; box-shadow: var(--sh-card) }
.kard.act:hover { border: 0; box-shadow: var(--sh-card-hover) }
.kard.act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
.kard.act.sev-crit::before, .kard.act.sev-warn::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--crit-fill) }
.kard.act.sev-warn::before { background: var(--warn-fill) }
.kard.act .at { font-size: var(--t-base); font-weight: 600; line-height: 1.4; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden }
.kard.act .aw { font-size: var(--t-sm); font-weight: 500; color: var(--crit) }
.kard.act .aw small { font-size: var(--t-micro); font-weight: 400; color: var(--ink-3) }
.kard.act .am { display: flex; flex-wrap: nowrap; gap: 10px; align-items: baseline; min-width: 0; margin-top: 0; font-size: var(--t-sm) }
.kard.act .ad { flex: none; white-space: nowrap; color: var(--ink-2) }
.kard.act .ad.soon { color: var(--crit); font-weight: 600 }
.kard.act .ao { display: block; flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--t-sm); align-self: baseline; color: var(--ink-3) }
/* What finished, below the board — the Opportunities closed list in the action board's words. */
.aclosed { margin-top: 22px; background: var(--surface); border-radius: 18px; padding: 18px 24px 8px; box-shadow: var(--sh-card) }
.aclosed > header { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-bottom: 10px }
.aclosed > header b { font-family: var(--display); font-size: 18px; font-weight: 600 }
.aclosed > header .asum { font-size: var(--t-sm); color: var(--ink-2) }
.aclosed > header .aall { margin-left: auto; color: var(--accent) }
.aclosed .kard.crow { position: static; background: none; border-radius: 0; box-shadow: none; border-top: 1px solid var(--rule) }
.aclosed .crow .cchip { width: 92px }
.aclosed .crow .cchip.done { background: var(--good-soft); color: var(--good) }
.aclosed .crow .cchip.cancelled { background: var(--surface-2); color: var(--ink-2) }
.aclosed .crow .cd { flex: none; font-size: var(--t-sm); color: var(--ink-3); white-space: nowrap }
.aold { margin: 0; padding: 10px 0; border-top: 1px solid var(--rule); font-size: var(--t-sm); color: var(--ink-3) }
@media (max-width: 900px) { .actgrid { grid-template-columns: minmax(0, 1fr) } }
@media (max-width: 700px) { .acards { grid-template-columns: minmax(0, 1fr) } }

/* ── Board panels: one column style for every board (the PO, 2026-09-17, layout A) ─────────────
   A column is a white panel with a real heading and its count as a label; the column being worked
   is the focus panel (blue edge and dot), one per page. Acties and Opportunities share this. */
.actgrid, .actgrid.solo { display: flex; flex-direction: column; gap: 16px; align-items: stretch }
.acol, .pcol { background: var(--surface); border-radius: 20px; padding: 22px 24px; gap: 14px; box-shadow: var(--sh-card) }
.acol > header, .pcol > header { align-items: center; gap: 12px; padding: 0 }
.acol > header b, .pcol > header b { font-family: var(--display); font-size: 22px; font-weight: 600; letter-spacing: -.02em }
.acol > header .an, .acol > header .wip, .pcol > header .pn { margin-left: 0; font-size: var(--t-sm); font-weight: 600; padding: 3px 10px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2) }
.acol > header .afree { margin-left: auto; padding: 0; font-size: var(--t-sm); color: var(--ink-2) }
.acol > header .add { margin-left: auto }
.acol > header .afree + .add { margin-left: 8px }
.acol.focus { border-top: 4px solid var(--accent-fill) }
.acol.focus > header .wip { background: var(--accent-soft); color: var(--accent) }
.acol.focus > header .wip.over { background: var(--crit-soft); color: var(--crit) }
.adot { width: 10px; height: 10px; border-radius: 50%; background: var(--accent-fill); box-shadow: 0 0 0 4px var(--accent-soft); flex: none }
.acol .acards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px }
.aslot { border: 1.5px dashed var(--accent-soft); border-radius: 12px; min-height: 86px; display: grid; place-items: center; font-size: var(--t-sm); color: var(--accent) }
.acol .aempty, .pcol .pempty { border: 1.5px dashed var(--rule); border-radius: 12px; padding: 18px; text-align: center }
.pipecols { gap: 16px }
.pcol > header { flex-wrap: wrap; row-gap: 6px }
.pcol > header .pp { font-size: var(--t-sm); color: var(--ink-3) }
.pcol > header .pn { margin-left: auto }
.pbar { height: 4px; border-radius: 2px; background: var(--surface-2); overflow: hidden }
.pbar i { display: block; height: 100%; background: var(--accent-fill); opacity: .6 }
.pcol .kard.deal { box-shadow: 0 0 0 1px var(--rule), var(--sh-soft) }
.acol .kard.act { box-shadow: 0 0 0 1px var(--rule), var(--sh-soft) }
@media (max-width: 1100px) { .acol .acards { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
@media (max-width: 700px) { .acol .acards { grid-template-columns: minmax(0, 1fr) } }

/* Chat flows with the page (2026-09-17): no scroll box inside the page, the composer sticks to the
   bottom of the window, so the transcript reads like the other pages and the input never leaves view. */
.chatpage { max-height: none }
.chatpage .chatlog { overflow: visible; min-height: 0 }
.chatpage .chatbar { position: sticky; bottom: 34px; z-index: 3; margin-top: 8px; box-shadow: 0 -16px 0 0 var(--bg), var(--sh-card) }
.chatpage .chatlog { scroll-margin-bottom: 120px }
.chatpage .ct { scroll-margin-bottom: 120px }
.chatpage .chatnote { position: sticky; bottom: 0; padding: 8px 0 12px; background: var(--bg) }

/* UX round (2026-09-17): the blocked line reads at the floor size, counts use the body face, and a
   term the Chief quotes reads as a term, not as raw backticks. */
.need .exrow small { font-size: var(--t-micro) }
.need .exrow small b { font-size: inherit }
.panel .ph .n { font-family: var(--sans) }
.chatpage .cb code { font-family: var(--mono); font-size: var(--t-sm); background: var(--surface-2); padding: 1px 5px; border-radius: 5px }

/* ── Acties: Alle and search (2026-09-18) ─────────────────────────────── */
.actbar { display: flex; gap: 12px; align-items: center; margin-bottom: 1.1rem; flex-wrap: wrap }
.actbar .domsw { margin-bottom: 0 }
.actsearch { flex: 1 1 240px; display: flex }
.actsearch input { width: 100%; border: 1px solid var(--rule); border-radius: 12px; padding: 10px 14px; font: inherit; font-size: var(--t-base); background: var(--surface); color: var(--ink) }
.actsearch input:focus { outline: none; border-color: var(--accent) }
.kard.act .adept { font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.actresults { background: var(--surface); border-radius: 20px; padding: 18px 24px 10px; box-shadow: var(--sh-card) }
.actresults > header { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-bottom: 8px }
.actresults > header b { font-family: var(--display); font-size: 20px; font-weight: 600 }
.actresults > header span { font-size: var(--t-sm); color: var(--ink-2) }
.kard.srow { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 14px; width: 100%; padding: 13px 0; border-top: 1px solid var(--rule); font-size: var(--t-base) }
.kard.srow:hover b { color: var(--accent) }
.kard.srow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
.srow .sd { width: 92px; flex: none; font-size: var(--t-micro); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3) }
.srow .st { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px }
.srow .st b { font-weight: 600 }
.srow .st small { font-size: var(--t-sm); color: var(--ink-3); overflow: hidden; white-space: nowrap; text-overflow: ellipsis }
.srow .sc { flex: none; font-size: var(--t-micro); font-weight: 600; padding: 3px 10px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2) }
.srow .sdue { width: 80px; flex: none; text-align: right; color: var(--ink-2); font-size: var(--t-sm) }
.srow .go { color: var(--ink-3) }
.actresults mark { background: var(--warn-soft); color: inherit; border-radius: 3px; padding: 0 2px }
@media (max-width: 700px) { .srow .sd, .srow .sdue { display: none } }
