﻿/* ─────────────────────────────────────────────────────────────────────────
   Courts Admin — design system (from Claude Design "Courts Admin.html").
   Warm-stone / Inter base; orange = app primary; one owned color per
   integration (JTI red, Tyler purple, OC blue). Layout/typography rules are
   scoped under `.cx`, but the --cx-* TOKENS live on :root: they are the app's
   shared shade vocabulary (settings shell, portal, modals — which render
   OUTSIDE any .cx ancestor via ModalHost) and all resolve through the
   bit tokens anyway.
   ───────────────────────────────────────────────────────────────────────── */
:root, .cx {
  /* BRAND IDENTITY 2026-09-25 (brand-identity-token-plan.md): Open Sans for text, tables
     and forms; Montserrat for titles (800, uppercase), buttons (800), nav and labels
     (600/700). Fonts are self-hosted (wwwroot/fonts). */
  --cx-font: var(--id-font-text);
  --cx-mono: var(--id-font-mono);

  /* ── THE LABEL VOICE (D46, owner ruling, permanent): every caps label —
     field labels, table headers, KV labels — binds to these tokens, app-wide,
     current AND future surfaces. Figtree 600 / .09em / 10.5px in the subtle
     tier; body text stays Inter — the two-face split is deliberate. Fallback
     position on record: same form at 11px if 10.5 proves too small in live
     use. Consume via the .cx-cap utility below or the tokens directly. ── */
  --cx-label-font: var(--id-font-display); /* identity: Figtree -> Montserrat */
  --cx-label-weight: var(--id-label-weight);
  /* FAMILIARITY ROUND 2026-09-24: 10.5px → 13px (the old build's table heads were
     13.5/600). Tracking eases with the size so the caps don't spread. */
  --cx-label-track: var(--id-label-track);
  --cx-label-size: 12px;
  /* OWNER RULING 2026-08-19 (final, after living with ink phase 2A): the subtle
     tier is RIGHT for true captions — labels naming a value beside them (KV rows,
     column heads, band captions, editor micro-caps). But a STANDALONE SECTION
     TITLE ("Parties in this case") is not a caption and stays EXACTLY as it was
     before the ink round: 11px / 600 / .085em / uppercase / --cx-slate, Inter.
     Rejected takes, do not resurrect: titles on the subtle caps voice; all
     captions muted; block-head titles (13/700 sentence); muted-ink titles.
     Flow to the design agent in the next ink correction round. */
  /* ROUND 2: captions and column heads move to the second ink (#404040, 10.4:1).
     They are scanned on every screen; the caption voice recedes by size, caps and
     face, not by lightness. Supersedes the "subtle tier for true captions" ruling above. */
  /* identity: mid grey #5C6470 (6.0:1) - the owner's "descriptions and labels" tier */
  --cx-label-color: var(--cx-subtle);

  /* ── THE INK & LABEL SYSTEM, I1 (ink-kit.jsx, rulings I1–I9; adoption state in
     docs/ink-adoption-plan.md): ONE SCALE, FIVE SIZES, FOR CONTENT. Adding a size
     means editing this block — that is the point. Controls keep their own ladder
     (13.5 button / 13 input / 12.5 small + label); the ink scale does not reach
     inside a control. ── */
  /* FAMILIARITY ROUND 2026-09-24 (filer feedback + measured drift: Review body had
     fallen to 12–13px). FLOORS, app-wide: body ≥15, secondary ≥13. Nothing that is
     read may be set below --cx-size-cap. Review raises body to 16 / meta 14 on its
     own scope (.rvw) — a read-every-filing screen gets the old build's 16px.
     Was: 21 / 15 / 13 / 12 / 10.5. */
  /* 2026-09-28: tuned down toward the owner's proposal (its body text is 9–12px, ours was
     12–15px); landed between the two, a little closer to the proposal. Root stays 16px.
     Page titles keep their size: the proposal's are larger than ours. */
  --cx-size-title: var(--id-size-title);
  --cx-size-head: var(--id-size-head);
  --cx-size-lead: var(--id-size-lead);   /* row titles, card labels, feed items */
  --cx-size-body: var(--id-size-body);
  --cx-size-meta: var(--id-size-meta);
  --cx-size-cap: var(--id-size-cap);
  /* big figures (dashboard counts, chart totals, stat strips) */
  --cx-size-figure: var(--id-size-figure);
  --cx-size-figure-md: var(--id-size-figure-md);
  --cx-size-figure-sm: var(--id-size-figure-sm);
  --cx-size-figure-xs: var(--id-size-figure-xs);
  --cx-lh-title: 1.2;
  --cx-lh-head: 1.3;
  --cx-lh-body: 1.5;
  --cx-lh-meta: 1.45;

  /* ── INK I10 · the SECTION-TITLE voice (owner ruling, ratified by the design's
     correction round 1). A second caps voice, separated from the caption voice
     by RANK: a title stands alone and owns the region beneath it; a caption
     names the thing beside it. 11px is spoken for — the caption voice's 11px
     fallback position is withdrawn. No variation: not color, not size, not
     weight, not track. ── */
  --cx-title-font: var(--id-font-display);
  /* FAMILIARITY ROUND: 11px → 13px, and ink instead of slate. Surfaces whose sections
     are READ top to bottom (Review, detail pages) use the sentence-case head voice
     (--cx-size-head / 700 / --cx-text, primary-colour icon) instead — see .cx-sechead. */
  --cx-title-size: 12.5px;
  --cx-title-weight: 700;
  --cx-title-track: .06em;
  --cx-title-color: var(--cx-text);

  /* -- IDENTITY - THE HEADING VOICE. Page titles (h1 / PageIntro), panel heads (h2 /
     PanelCard), section heads, card and empty-state titles. Owner ruling 2026-09-25:
     EVERY title is uppercase, including a title slot that carries data. Sizes come
     from the scale above and do not change. -- */
  --cx-heading-font: var(--id-font-display);
  --cx-heading-weight: var(--id-heading-weight);
  --cx-heading-transform: var(--id-heading-case);
  --cx-heading-track: var(--id-heading-track);
  --cx-heading-lh: var(--id-heading-lh);
  /* buttons and big figures (values in tokens.css) */
  --cx-btn-font: var(--app-btn-font, var(--cx-font));
  --cx-btn-weight: var(--app-btn-weight, 600);
  --cx-btn-transform: var(--app-btn-transform, none);
  --cx-btn-track: var(--app-btn-track, 0);
  --cx-data-font: var(--app-data-font, var(--cx-font));
  --cx-data-weight: var(--app-data-weight, 700);
  --cx-data-track: var(--app-data-track, -.02em);
  /* the section kicker: a 21px primary rule + tracked uppercase label (SectionKicker) */
  --cx-kicker-font: var(--cx-label-font);
  --cx-kicker-weight: var(--id-kicker-weight);
  --cx-kicker-track: var(--id-kicker-track);
  --cx-kicker-rule: var(--id-kicker-rule);
  /* the 3px primary rule across the top of the app header (shell round) */
  --cx-header-rule: 3px solid var(--cx-accent);

  /* ── WARM REBASE (D45, 2026-08-12, owner-decided, design-agent ratified):
     the cool era ends. The neutral chrome tokens below are pinned to the
     design's warm-stone literals; they no longer derive from the cool bit
     neutrals (zinc fg-ter #71717A, brd-sec #d9d9d9), which must not influence
     any cx token. Semantic hues (pri/green/red/amber/blue) still resolve
     through the app/tenant tokens. Supersedes the 2026-07-21 COLOR
     UNIFICATION note for neutrals. ── */
  /* IDENTITY 2026-09-25: the warm-stone era ends - the owner's cool neutral set.
     bg #F7F8FA (app background) - border #E6E8EC - white cards. */
  --cx-bg: var(--id-bg);
  --cx-bg-deep: var(--id-bg-deep);
  /* table headers: readable (muted, not subtle) labels on the panel-alt band.
     NOTE: a deeper bg was tried and reverted — neutral tints land imperceptibly
     close to the page bg. If more separation is wanted later, it needs a
     different treatment (a darker band or a bordered/ink header), not a tint. */
  --cx-thead-bg: var(--cx-panel-alt);
  --cx-thead-fg: var(--cx-subtle);
  --cx-panel: var(--id-panel);
  /* ROUND 3: panel-alt was #fafaf9 — 1.5% off white, invisible as a band. Now stone-100,
     the old portal's #F5F5F5 family: visibly a band on white, still quiet. RULE: a band
     always meets content with a hairline (--cx-border) on its open edge; tint alone never
     separates. Every text tier on it still clears its floor (grey #5a5a5a → 6.4:1). */
  --cx-panel-alt: var(--id-bg); /* identity: the owner's light grey; the hairline rule still applies */
  /* the two radii (tokens.css): control 6px, surface 10px */
  --cx-r-control: var(--app-radius-control, 6px);
  --cx-r-surface: var(--app-radius-surface, 10px);
  /* card/panel/divider hairline — D45 warm stone literals (previously zinc
     brd-sec mixes; the 2026-07 "step darker" 72% tune is superseded by the
     warm rebase — the stone-200 hairline carries the same firmness warm). */
  --cx-border: var(--id-border); /* identity: border grey */
  --cx-border-soft: var(--id-border-soft);
  /* input edges: one deliberate step darker than --cx-border (which is tuned as a
     hairline for cards/dividers and reads too faint as a field boundary on white).
     2026-07 control-skin redesign: the slimmer 32px control carries no resting
     shadow, so the border alone must draw the edge. Mixed from the WARM fg-sec
     (stone) — NOT the cool fg-ter (zinc): the design values (#b9b3ab resting,
     #8f8880 hover, #a8a29e placeholder) are stone, and zinc-mixed edges read
     cold/washed against the warm panels. Focus stays --cx-pri, error --cx-red. */
  /* 2026-07 border iteration (final, user-chosen): #ccc — the original app's
     border tone, neutral and calm. It can afford to be this light because the
     INNER BOTTOM EDGE (18% ink inset, below) carries the grounding contrast.
     Hover = a tad darker. Do not re-derive these from theme text tokens. */
  /* identity: one step darker than the hairline, DERIVED (~#cbced2 resting, ~#b5b9be
     hover), so a border-token change moves field edges with it. */
  --cx-input-border: color-mix(in srgb, var(--cx-border) 88%, var(--cx-text));
  --cx-input-border-strong: color-mix(in srgb, var(--cx-border) 76%, var(--cx-text));
  --cx-input-bw: 1px;
  /* softened 18% → 11% (user: 18% read as a thicker bottom border, not grounding) */
  --cx-input-edge: inset 0 -1px 0 color-mix(in srgb, var(--cx-text, #1c1917) 11%, transparent);
  /* placeholder/ghost text inside controls — its own token so the decorative
     --cx-faint tier (chevrons, dots) stays untouched. INK SYSTEM I3: a
     placeholder is READ, so it sits at the subtle tier (was 52% ≈ faint,
     ~2.5:1 — below the floor the tokens exist to hold). */
  /* FAMILIARITY ROUND: pinned. The mix resolved against Bit's #5A5A5A, not the
     #57534e fallback, and landed on #7B7B7B (4.2:1). #767676 = 4.54:1 on white. */
  --cx-placeholder: var(--id-ink-3); /* identity: mid grey, 6.0:1 */
  /* disabled control surface (≈ redesign #f4f3f1 / #e3e0dc — D45: mixed from
     warm stone at the same perceived lightness as the old zinc mixes) */
  --cx-disabled-bg: color-mix(in srgb, var(--bit-clr-fg-sec, #57534e) 8%, #fff);
  --cx-disabled-border: color-mix(in srgb, var(--bit-clr-fg-sec, #57534e) 22%, #fff);
  /* option-row fills for popovers/menus — D45 warm literals: hover pinned by
     the ruling, active = the redesign's own warm value (was zinc mixes) */
  --cx-row-hover: var(--id-row-hover);
  --cx-row-active: var(--id-bg-deep);
  /* File-KIND hint hues (uploader family). The hue names the FILE, not the app:
     Word blue / Excel green are the products' own brand values, deliberately
     outside the app palette so they can never read as state. The bare --up-kind
     trio is the indigo fallback for kinds with no brand of their own (XML).
     Excel green sits well away from the success green (deeper, cooler) and is
     NEVER used to report an outcome. Roles: -doc = slot expects a Word file;
     -xls = expects a spreadsheet. Each trio = glyph/chip fg, chip soft bg, chip border. */
  --up-kind-doc: #2b579a;
  --up-kind-doc-bg: #eef2fa;
  --up-kind-doc-bd: #d4e0f2;
  --up-kind-xls: #217346;
  --up-kind-xls-bg: #ecf6f0;
  --up-kind-xls-bd: #cbe5d8;
  --up-kind: #5566a8;
  --up-kind-bg: #f3f5fb;
  --up-kind-bd: #dfe4f3;
  /* ── INK TIERS — ROUND 2 (2026-09-24). Authoritative copy: Portal Design System.html.
     Measured complaint: the app reads grey — 53–77% of on-screen text sat under 10:1.
     Three readable steps and ONE grey. The second ink sits just above the 10:1 line on
     purpose: labels, column heads and secondary columns are scanned on every screen, so
     they read as ink; hierarchy between the two inks comes from size and weight, not
     lightness. Grey is reserved for text that is genuinely secondary.
     Ratios on white / on --cx-bg:
       text    #1a1a1a  17.4 / 15.8   values, names, headings, body
       muted   #404040  10.4 /  9.4   labels, column heads, secondary columns, quiet actions
       subtle  #5a5a5a   6.9 /  6.3   meta only: times, counts, hints, provenance
       faint   (below)   decoration only, never text
     Round 1 had muted #5a5a5a / subtle #6b6b6b: each tier moves one step darker, and
     #6b6b6b retires. Floors: primary ≥7:1, secondary ≥4.5:1 on every surface. ── */
  /* IDENTITY 2026-09-25 (owner's table): black / dark grey / mid grey / brand grey.
       text    #0E1116  19.0:1  titles and primary text
       muted   #2B313D  12.6:1  secondary text
       subtle  #5C6470   6.0:1  descriptions and labels
       faint   #7F7F7F   4.0:1  decoration only (the owner's brand grey) */
  --cx-text: var(--id-ink);
  --cx-muted: var(--id-ink-2);
  --cx-subtle: var(--id-ink-3);
  /* faint = decorative/ghost ONLY (chevrons, dots, empty "—") — below the floor on
     purpose. If a faint element turns out to carry information, promote it to subtle. */
  --cx-faint: var(--id-ink-4);
  /* ── ACCENT — ROUND 2. The tenant's brand does STRUCTURE, never meaning: status never
     depends on it, because a tenant may be orange #F97316 or crimson #b3153a. One tenant
     input (--bit-clr-pri, set by ThemeService); every step below derives from it in
     tokens.css (--app-accent-*), each with one job and a floor the design system page
     verifies live for every tenant:
       accent         brand as given   strokes, bars, section icons, rail line, focus
       accent-strong  75% + black      FILLS carrying white: primary action, rail dots,
                                       current step, avatar — white on it ≥4.5:1
       accent-text    65% + black      accent-coloured text and links on white ≥4.5:1
       accent-soft    8% on white      active nav, selected tab, current step ground
       accent-border  30% on white     hairline of an accent-soft surface
     A tenant whose brand misses a floor pins the step: --tenant-accent-strong. ── */
  --cx-pri: var(--bit-clr-pri, var(--id-brand));
  --cx-accent: var(--app-accent, var(--cx-pri));
  --cx-accent-strong: var(--app-accent-strong);
  --cx-accent-strong-hover: var(--app-accent-strong-hover);
  --cx-on-accent: var(--app-on-accent, #fff);
  --cx-accent-text: var(--app-accent-text);
  --cx-accent-soft: var(--app-accent-soft);
  --cx-accent-border: var(--app-accent-border);
  /* legacy names — kept so the 51 consuming stylesheets keep working; new code uses accent-* */
  --cx-pri-strong: var(--cx-accent-strong-hover);
  --cx-pri-text: var(--cx-accent-text);
  --cx-pri-soft: var(--cx-accent-soft);
  --cx-pri-border: var(--cx-accent-border);
  /* focus/error rings for the 2px control focus treatment (translucent so they
     read over any bg; ≈ redesign rgba(pri,.28) / rgba(red,.14)) */
  --cx-pri-ring: color-mix(in srgb, var(--bit-clr-pri, #F85918) 28%, transparent);
  --cx-red-ring: color-mix(in srgb, var(--cx-red-dot, #dc2626) 14%, transparent);
  /* ── STATUS TONE SYSTEM (owner ruling 2026-08-12, source: FSX_TONES bank) ──
     Each tone is a full ensemble: text fg on soft bg with border (every fg/bg
     pair ≥7:1) plus a vivid -dot SIGNAL tier (≥3:1 on white) for status dots.
     The legacy family name stays and IS the text/fg tier, so every existing
     `color: var(--cx-amber)` usage app-wide is readable by construction.
     These literals RETIRE the old var(--bit-clr-wrn/suc/err, …) derivations —
     the tone system no longer inherits component-library defaults (the Bit
     library keeps its own internals untouched). Amber/green/red double as
     warning/success/error semantics. */
  --cx-green: var(--id-green);
  --cx-green-soft: var(--id-green-soft);
  --cx-green-border: var(--id-green-border);
  --cx-green-dot: var(--id-green-dot);
  --cx-red: var(--id-red);
  --cx-red-soft: var(--id-red-soft);
  --cx-red-border: var(--id-red-border);
  --cx-red-dot: var(--id-red-dot);
  --cx-amber: var(--id-amber);
  --cx-amber-soft: var(--id-amber-soft);
  --cx-amber-border: var(--id-amber-border);
  --cx-amber-dot: var(--id-amber-dot); /* owner 2026-08-12: brightened golden from the design's #c07807 (owner pick; 2.5:1 on white — a redundant signal beside readable text, and the owner's explicit call) */
  --cx-slate: var(--id-slate);  --cx-slate-soft: var(--id-slate-soft);  --cx-slate-border: var(--id-slate-border);  --cx-slate-dot: var(--id-slate-dot);
  /* blue joined the tone system 2026-08-12 — no longer derived from the
     secondary (--bit-clr-sec); the secondary itself is untouched. */
  --cx-blue: var(--id-blue);
  --cx-blue-soft: var(--id-blue-soft);
  --cx-blue-border: var(--id-blue-border);
  --cx-blue-dot: var(--id-blue-dot);
  /* ── control metrics (2026-07 form-control skin) — the ONE size vocabulary for
     the `.form-input` anatomy (app.css FORMS block) and Select's popover. Kept as
     custom properties so a compact density variant can re-scope them later. ── */
  /* FAMILIARITY ROUND: controls follow the body floor — text typed into a field is
     read like body text. Was 34 / 13 / 30 / 13. */
  --cx-ctl-h: 36px;      /* control height */
  --cx-ctl-r: var(--id-radius-control);       /* control radius */
  --cx-ctl-px: 10px;     /* control horizontal padding */
  --cx-ctl-fs: var(--id-size-control);   /* control font size (was 15px; tuned with the size scale) */
  --cx-ring-w: 2px;      /* focus/error ring width */
  --cx-opt-h: 34px;      /* option row min-height */
  --cx-opt-px: 10px;     /* option row horizontal padding */
  --cx-opt-fs: 15px;     /* option row font size */

  --cx-shadow-card: var(--id-shadow-card);
  --cx-shadow-raise: var(--id-shadow-raise);
  --cx-shadow-pop: var(--id-shadow-pop);
  /* the primary button's hover glow (identity) */
  --cx-shadow-glow: 0 4px 14px color-mix(in srgb, var(--cx-accent) 32%, transparent);

  /* per-integration tokens — set on a scope via .cx-int-{jti|tyler|oc}

/* element-level base styles stay scoped to .cx — :root only carries the tokens */
.cx {
  font-family: var(--cx-font);
  color: var(--cx-text);
} */
}
.cx-int-jti   { --int-color:#dc2626; --int-soft:#fef2f2; --int-border:#fbcfcf; }
.cx-int-tyler { --int-color:#7c3aed; --int-soft:#f5f3ff; --int-border:#ddd6fe; }
.cx-int-oc    { --int-color:#2563eb; --int-soft:#eff6ff; --int-border:#bfdbfe; }

.cx *, .cx *::before, .cx *::after { box-sizing: border-box; }
.cx .mono { font-family: var(--cx-mono); }

/* D46 shared label-voice utility — THE one class for caps labels app-wide
   (field labels, table headers, KV labels). New surfaces use this instead of
   hand-writing the recipe. Unscoped on purpose: labels render inside portals/
   modals outside any .cx ancestor, same as the tokens themselves. */
/* the section-title voice (I10) — see the --cx-title-* tokens */
.cx-sectitle {
  font-family: var(--cx-title-font);
  font-size: var(--cx-title-size);
  font-weight: var(--cx-title-weight);
  letter-spacing: var(--cx-title-track);
  text-transform: uppercase;
  color: var(--cx-title-color);
  line-height: 1.3;
}

.cx-cap {
  font-family: var(--cx-label-font);
  font-size: var(--cx-label-size);
  font-weight: var(--cx-label-weight);
  letter-spacing: var(--cx-label-track);
  text-transform: uppercase;
  color: var(--cx-label-color);
  line-height: 1;
}

/* ── INK SYSTEM label forms (ink-tokens.css; taxonomy in ink-spec.jsx INK_TAX).
   The citable classes for phases 2–4: section/column caption variants, record
   label + value, qualifier, count, note, and the content sizes. Deliberately
   ABSENT here: the one chip anatomy (.cx-chip) and in-table status (.cx-status)
   — both names are already taken by admin-page classes with different
   anatomies; they reconcile in the settings/admin adoption round (phase 4).
   See docs/ink-adoption-plan.md. ── */
.cx-cap-row { display: flex; align-items: baseline; gap: 7px; }
th.cx-cap, .cx-cap.col { text-align: left; white-space: nowrap; }
th.cx-cap.num, .cx-cap.col.num { text-align: right; }
.cx-cap.sticky { position: sticky; top: 0; z-index: 1; background: var(--cx-panel, #fff); }
/* the only sanctioned variation on the caps voice is COLOR (I2) */
.cx-cap.on-tone { color: currentColor; }

/* record label (read-only fact) + its value — INK_TAX 3 */
.cx-kv { display: flex; align-items: baseline; gap: 12px; padding: 6px 0; }
.cx-kv > .cx-cap { flex: 0 0 auto; }
.cx-kv > .lead { flex: 1; min-width: 8px; border-bottom: 1px dotted var(--cx-border-soft, #f0efed); }
.cx-val { font-size: var(--cx-size-body); line-height: var(--cx-lh-body); font-weight: 600; color: var(--cx-text); }

/* inline qualifier — a fact in words, no chrome — INK_TAX 5 */
.cx-qual { font-size: var(--cx-size-meta); line-height: var(--cx-lh-meta); color: var(--cx-muted); }

/* count — mono, muted, tabular. I7: a count of 1 is not a count — the caller
   renders nothing at 1. Amounts are sans + tabular (I5), never mono. */
.cx-count { font-family: var(--cx-mono); font-size: var(--cx-size-meta); color: var(--cx-muted); font-variant-numeric: tabular-nums; }
.cx-amount { font-size: var(--cx-size-body); color: var(--cx-text); font-variant-numeric: tabular-nums; }

/* margin note / hint / provenance — INK_TAX 8 */
.cx-note { font-size: var(--cx-size-meta); line-height: var(--cx-lh-meta); color: var(--cx-subtle); text-wrap: pretty; }

/* content sizes, for the surfaces that need a class */
.cx-title { font-size: var(--cx-size-title); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
.cx-head { font-size: var(--cx-size-head); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
/* FAMILIARITY ROUND — the READ-SURFACE section head: sentence case, head size, ink,
   with the icon in the primary colour. Colour is structural here (it marks where a
   section starts), the way the old build's orange headings and step rail were. */
.cx-sechead { display: flex; align-items: center; gap: 9px; font-size: var(--cx-size-head); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
.cx-sechead > svg, .cx-sechead > .ic { color: var(--cx-accent); flex-shrink: 0; }
/* block heads organize in muted; titles own ink; caps labels recede (D47) */
.cx-blockhead { font-size: var(--cx-size-body); line-height: var(--cx-lh-body); font-weight: 700; color: var(--cx-muted); }
.cx-body { font-size: var(--cx-size-body); line-height: var(--cx-lh-body); color: var(--cx-text); }
.cx-meta { font-size: var(--cx-size-meta); line-height: var(--cx-lh-meta); color: var(--cx-muted); }

/* ── animations ── */
@keyframes cx-spin { to { transform: rotate(360deg); } }
@keyframes cx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cx-pop  { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
.cx-spin { animation: cx-spin .9s linear infinite; }

/* ── layout: top tab strip + view ── */
.cx-tabs-head { background: #fff; border-bottom: 1px solid var(--cx-border); padding-top: 14px; }
.cx-tabs-title { padding: 0 32px 12px; font-size: 18px; font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
.cx-tabs { display: flex; gap: 4px; padding: 0 32px; }
.cx-tab { display: inline-flex; align-items: center; gap: 7px; height: 46px; padding: 0 14px; font: 600 14px/1 var(--cx-label-font);
  color: var(--cx-muted); text-decoration: none; border: none; background: transparent; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; }
.cx-tab:hover { color: var(--cx-text); }
.cx-tab.on { color: var(--cx-text); font-weight: 600; border-bottom-color: var(--cx-pri); }
.cx-tab.on svg { color: var(--cx-pri); }
.cx-tab-badge { font-size: var(--cx-size-meta, 12px); font-weight: 700; color: var(--cx-red); background: var(--cx-red-soft); border: 1px solid var(--cx-red-border);
  border-radius: 999px; padding: 0 6px; height: 17px; display: inline-flex; align-items: center; }
.cx-wrap { padding: 26px 32px 64px; margin: 0 auto; }
/* page-level tab strip (court detail facets) — same look, hosted in a header band */
.cx-ptabs { display: flex; gap: 2px; margin-top: 4px; }

/* ── page intro ── */
.cx-intro { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 20px; flex-wrap: wrap; }
.cx-intro h1 { margin: 0; font-size: var(--cx-size-title); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); text-wrap: balance; }
.cx-intro p { margin: 6px 0 0; font-size: var(--cx-size-body); color: var(--cx-muted); line-height: 1.5; max-width: 680px; }
.cx-intro-eyebrow { margin-bottom: 10px; }
.cx-intro-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }

/* ── cards ── */
.cx-card { background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-r-surface); box-shadow: var(--cx-shadow-card); }
.cx-card.dashed { border-style: dashed; }
.cx-card-hover { transition: border-color .14s, box-shadow .14s, transform .14s; }
.cx-card-hover:hover { border-color: #d6d3d1; box-shadow: var(--cx-shadow-raise); }
.cx-panel { background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-r-surface); overflow: hidden; box-shadow: var(--cx-shadow-card); }
.cx-panel-head { display: flex; align-items: center; gap: 11px; padding: 15px 20px; border-bottom: 1px solid var(--cx-border-soft); flex-wrap: wrap; }
.cx-panel-head .ico { color: var(--cx-muted); display: inline-flex; }
.cx-panel-head h2 { margin: 0; font-size: var(--cx-size-head); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
.cx-panel-head .sub { font-size: var(--cx-size-meta, 12px); color: var(--cx-muted); margin-top: 2px; }
.cx-panel-head .grow { min-width: 0; flex: 1 1 220px; }
.cx-panel-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* ── grid rows / tables ── */
.cx-row { transition: background .12s; }
.cx-row:hover { background: var(--cx-panel-alt); }
.cx-thead { background: var(--cx-panel-alt); font-family: var(--cx-label-font); font-size: var(--cx-label-size); font-weight: var(--cx-label-weight); letter-spacing: var(--cx-label-track); text-transform: uppercase; color: var(--cx-thead-fg, var(--cx-label-color)); } /* ink I2: table-band caption on the caption voice — was 700/.5px */

/* ── avatar ── */
.cx-avatar { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: #fff; font-weight: 700; letter-spacing: .3px;
  background: var(--int-color); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.cx-avatar.group { background: var(--cx-text); }

/* ── badges & pills ── */
.cx-int-badge { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px 2px 7px; border-radius: 6px; font-size: var(--cx-size-meta, 12px); font-weight: 600;
  letter-spacing: .2px; white-space: nowrap; background: var(--int-soft); color: var(--int-color); border: 1px solid var(--int-border); }
.cx-int-badge .dot { width: 6px; height: 6px; border-radius: 999px; background: var(--int-color); flex-shrink: 0; }
/* ink phase 4: the .cx-status env pill (a second caps voice) is RETIRED — dead CSS
   since StatusPill.razor moved to BitPill (sentence case). The name is now free; the
   one chip anatomy owns badges (I6). */
.cx-sync { display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px; border-radius: 6px; font-size: var(--cx-size-meta, 12px); font-weight: 600; white-space: nowrap; }
.cx-sync.ok      { color: var(--cx-green); background: var(--cx-green-soft); border: 1px solid var(--cx-green-border); }
.cx-sync.partial { color: var(--cx-amber); background: var(--cx-amber-soft); border: 1px solid var(--cx-amber-border); }
.cx-sync.failed  { color: var(--cx-red);   background: var(--cx-red-soft);   border: 1px solid var(--cx-red-border); }
.cx-sync.never   { color: var(--cx-slate); background: var(--cx-slate-soft); border: 1px solid var(--cx-slate-border); }

/* ── segmented control ── */
.cx-seg { display: inline-flex; background: var(--cx-bg-deep); border: 1px solid var(--cx-border); border-radius: 10px; padding: 3px; gap: 2px; }
.cx-seg button { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 12px; font: 600 12.5px/1 var(--cx-font); border: none;
  border-radius: 7px; background: transparent; color: var(--cx-muted); cursor: pointer; white-space: nowrap; }
.cx-seg.sm button { height: 30px; }
.cx-seg button.on { background: #fff; color: var(--cx-text); box-shadow: var(--cx-shadow-card); }
.cx-seg button .dot { width: 6px; height: 6px; border-radius: 999px; }
/* INK SYSTEM I3 — a tab count is READ: was faint 11px (below the floor) on
   every Segmented in the app. Now subtle mono at meta size; muted when active. */
.cx-seg button .cnt { font-family: var(--cx-mono); font-size: var(--cx-size-meta, 12px); color: var(--cx-subtle); font-variant-numeric: tabular-nums; }
.cx-seg button.on .cnt { color: var(--cx-muted); }

/* ── search input — rides the shared --cx-ctl-* control metrics ── */
.cx-search { position: relative; height: var(--cx-ctl-h); max-width: 100%; }
.cx-search svg { position: absolute; left: var(--cx-ctl-px); top: calc((var(--cx-ctl-h) - 15px) / 2); color: var(--cx-subtle); pointer-events: none; }
.cx-search input { width: 100%; height: var(--cx-ctl-h); padding: 0 var(--cx-ctl-px) 0 calc(var(--cx-ctl-px) + 21px); background: #fff; border: 1px solid var(--cx-input-border); border-radius: var(--cx-ctl-r);
  font: var(--cx-ctl-fs) var(--cx-font); color: var(--cx-text); outline: none; }
.cx-search input:hover:not(:focus) { border-color: var(--cx-input-border-strong); }
.cx-input:focus, .cx-search input:focus { border-color: var(--cx-pri); box-shadow: 0 0 0 var(--cx-ring-w) var(--cx-pri-ring); }

/* ── empty state ── */
.cx-empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 48px 28px; gap: 4px; }
.cx-empty .glyph { width: 48px; height: 48px; border-radius: 12px; background: var(--cx-panel-alt); border: 1px solid var(--cx-border);
  display: inline-flex; align-items: center; justify-content: center; color: var(--cx-subtle); margin-bottom: 8px; }
.cx-empty .t { font-size: var(--cx-size-head); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); }
.cx-empty .d { font-size: var(--cx-size-body); color: var(--cx-muted); max-width: 360px; }

/* ── court card (grid) ── */
.cx-court-card { text-align: left; cursor: pointer; background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-r-surface);
  display: flex; flex-direction: column; gap: 13px; box-shadow: var(--cx-shadow-card); font: inherit; width: 100%; }
.cx-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
.cx-grid.dense { gap: 12px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* ── chips (sync queue) ── */
.cx-chip { display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 9px; max-width: 280px; font-size: var(--cx-size-meta, 12px); font-weight: 600; }
.cx-chip.pending { background: var(--cx-slate-soft); border: 1px solid var(--cx-slate-border); color: var(--cx-slate); }
.cx-chip.running { background: var(--cx-blue-soft);  border: 1px solid var(--cx-blue-border);  color: var(--cx-blue); }
.cx-chip.done    { background: var(--cx-green-soft); border: 1px solid var(--cx-green-border); color: var(--cx-green); }
.cx-chip.failed  { background: var(--cx-red-soft);   border: 1px solid var(--cx-red-border);   color: var(--cx-red); }
.cx-chip span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── progress bar ── */
.cx-progress { height: 7px; background: var(--cx-bg-deep); border-radius: 999px; overflow: hidden; }
.cx-progress > i { display: block; height: 100%; transition: width .4s ease; }

/* ── modal ── */
/* the page behind an open dialog does not scroll */
body:has(.cx-modal-scrim) { overflow: hidden; }
.cx-modal-scrim { position: fixed; inset: 0; background: rgba(28,25,23,.46); display: flex; align-items: center; justify-content: center; z-index: 100; animation: cx-fade .12s ease; }
/* Dialogs opened from code (sign in again, a failed replace) can open while a wizard editor's
   overlay (z-index 400) is up; they must sit above it or the filer can't reach them. */
.cx-modal-host > .cx-modal-scrim { z-index: 500; }
/* a bare card's content brings its own header and sets few sizes: give it the dialog text base */
.cx-modal.bare { font-family: var(--cx-font); font-size: var(--cx-size-lead); }
.cx-modal { max-width: 92vw; max-height: 92vh; overflow-y: auto; background: #fff; border-radius: var(--cx-r-surface); box-shadow: var(--cx-shadow-pop); animation: cx-pop .14s ease; }

/* ── misc text ── */
.cx-faint { color: var(--cx-faint); } .cx-subtle { color: var(--cx-subtle); } .cx-muted { color: var(--cx-muted); }
.cx-danger-btn:hover { color: var(--cx-red) !important; border-color: var(--cx-red-border) !important; background: var(--cx-red-soft) !important; }
.cx-menu-item { transition: background .1s; }
.cx-menu-item:hover { background: var(--cx-panel-alt) !important; }

/* ── data overflow menu item ── */
.cx-data-item { display: flex; width: 100%; align-items: center; gap: 10px; padding: 9px 12px; border: none; border-radius: 8px;
  background: transparent; color: var(--cx-text); font: var(--cx-size-body) var(--cx-font); cursor: pointer; }
.cx-data-item > span { flex: 1; text-align: left; }
.cx-data-item b { font-weight: 500; display: block; }
.cx-data-item i { font-size: var(--cx-size-meta); color: var(--cx-subtle); font-style: normal; }

/* ── clear-filters ghost ── */
.cx-clear { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 11px; border: 1px solid transparent; border-radius: 8px;
  background: transparent; color: var(--cx-muted); font: 500 12.5px var(--cx-font); cursor: pointer; }
.cx-clear:hover { background: var(--cx-panel-alt); }

/* ── groups: member rows ── */
.cx-mem-grid { display: grid; grid-template-columns: 170px minmax(0,1fr) 74px 156px 84px; gap: 14px; }
.cx-mem-input { height: 36px; padding: 0 11px; border: 1px solid var(--cx-border); border-radius: 8px; font: 13px var(--cx-font);
  color: var(--cx-text); background: #fff; width: 100%; box-sizing: border-box; outline: none; }
.cx-cat-cell { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; font-size: 12px; font-weight: 600; border-radius: 8px; cursor: pointer; }
.cx-cat-cell.full { background: #fff; color: var(--cx-muted); border: 1px solid var(--cx-border); font-weight: 500; }
.cx-cat-cell.partial { background: var(--cx-amber-soft); color: var(--cx-amber); border: 1px solid var(--cx-amber-border); }
.cx-cat-cell.excluded { background: var(--cx-slate-soft); color: var(--cx-subtle); border: 1px dashed var(--cx-slate-border); cursor: help; }
.cx-icon-btn { width: 34px; height: 34px; padding: 0; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  border: 1px solid var(--cx-border); border-radius: 8px; background: #fff; color: var(--cx-muted); cursor: pointer; }

/* ═════════════════════════════════════════════════════════════════════════
   COMPONENT VOICES — ROUND 2 (2026-09-24). The anatomy every screen shares, bound to
   the tokens above. Portal Design System.html renders these exact classes; a Razor
   component either uses the class or binds the same tokens. Anything that looks like
   one of these and doesn't is drift.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── actions: one primary per view ── */
.cx-action { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: var(--cx-ctl-h); padding: 0 16px; border-radius: var(--cx-ctl-r);
  font: var(--cx-btn-weight) var(--cx-ctl-fs)/1 var(--cx-btn-font); text-transform: var(--cx-btn-transform); letter-spacing: var(--cx-btn-track); border: 1px solid transparent; cursor: pointer; white-space: nowrap; text-decoration: none; transition: background .12s, border-color .12s, color .12s; }
.cx-action.primary { background: var(--cx-accent-strong); border-color: var(--cx-accent-strong); color: var(--cx-on-accent); }
.cx-action.primary:hover { background: var(--cx-accent-strong-hover); border-color: var(--cx-accent-strong-hover); box-shadow: var(--cx-shadow-glow); }
.cx-action.secondary { background: var(--cx-panel); border-color: var(--cx-border); color: var(--cx-text); }
.cx-action.secondary:hover { border-color: var(--cx-text); }
.cx-action.quiet { background: transparent; color: var(--cx-muted); padding: 0 10px; }
.cx-action.quiet:hover { color: var(--cx-text); background: var(--cx-bg-deep); }
.cx-action.danger-quiet { background: transparent; color: var(--cx-red); padding: 0 10px; }
.cx-action:focus-visible { outline: none; box-shadow: 0 0 0 var(--cx-ring-w) var(--cx-pri-ring); }
.cx-action svg { width: 16px; height: 16px; flex-shrink: 0; }
/* "add" affordance: the accent names what can be added; text stays at accent-text */
.cx-add { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px; border-radius: var(--cx-ctl-r); border: 1px solid var(--cx-accent-border);
  background: var(--cx-panel); color: var(--cx-accent-text); font: 600 var(--cx-size-meta)/1 var(--cx-font); cursor: pointer; }
.cx-add:hover { background: var(--cx-accent-soft); }
.cx-add svg { color: var(--cx-accent); width: 15px; height: 15px; }

/* ── status pill: semantic tone, ALWAYS icon + word, never the accent ── */
.cx-pill { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 9px 0 8px; border-radius: 6px; border: 0; font: 600 var(--cx-size-cap)/1 var(--cx-label-font); white-space: nowrap; } /* identity: the proposal badge - soft fill, r6, no border */
.cx-pill svg { width: 14px; height: 14px; flex-shrink: 0; }
.cx-pill.draft    { color: var(--cx-slate); background: var(--cx-slate-soft); border-color: var(--cx-slate-border); }
.cx-pill.pending  { color: var(--cx-amber); background: var(--cx-amber-soft); border-color: var(--cx-amber-border); }
.cx-pill.accepted { color: var(--cx-green); background: var(--cx-green-soft); border-color: var(--cx-green-border); }
.cx-pill.rejected { color: var(--cx-red);   background: var(--cx-red-soft);   border-color: var(--cx-red-border); }
.cx-pill.partial  { color: var(--cx-blue);  background: var(--cx-blue-soft);  border-color: var(--cx-blue-border); }

/* ── label / value pair: one short label, one value ── */
.cx-kvp { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cx-kvp > .k { font-size: var(--cx-size-meta); color: var(--cx-muted); line-height: 1.35; }
.cx-kvp > .v { font-size: var(--cx-size-body); font-weight: 500; color: var(--cx-text); line-height: var(--cx-lh-body); overflow-wrap: anywhere; }
.cx-kvp > .v.mono { font-family: var(--cx-mono); font-weight: 400; }

/* ── wizard step strip (desktop): progress is STRUCTURE, so it is accent, not green ── */
.cx-strip { display: flex; background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-r-surface); overflow: hidden; }
.cx-strip > .s { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 9px; padding: 12px 14px; font: 500 var(--cx-size-meta)/1.2 var(--cx-font); color: var(--cx-muted);
  border-right: 1px solid var(--cx-border-soft); border-bottom: 3px solid transparent; background: none; text-align: left; }
.cx-strip > .s:last-child { border-right: none; }
.cx-strip > .s .n { width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px;
  border: 1.5px solid var(--cx-input-border-strong); color: var(--cx-muted); background: var(--cx-panel); }
.cx-strip > .s .n svg { width: 13px; height: 13px; }
.cx-strip > .s.done { color: var(--cx-text); border-bottom-color: var(--cx-accent); }
.cx-strip > .s.done .n { background: var(--cx-accent-strong); border-color: var(--cx-accent-strong); color: var(--cx-on-accent); }
.cx-strip > .s.cur { color: var(--cx-text); font-weight: 700; background: var(--cx-accent-soft); border-bottom-color: var(--cx-accent); }
.cx-strip > .s.cur .n { background: var(--cx-panel); border: 2px solid var(--cx-accent-strong); color: var(--cx-accent-text); }
.cx-strip > .s.err .n { background: var(--cx-red-soft); border-color: var(--cx-red); color: var(--cx-red); }

/* ── step rail (narrow containers, confirm pages): dots on a line ── */
.cx-rail { display: flex; align-items: flex-start; }
.cx-rail > .s { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 8px; position: relative; font: 500 var(--cx-size-meta)/1.2 var(--cx-font); color: var(--cx-text); text-align: center; }
.cx-rail > .s::before { content: ""; position: absolute; top: 14px; left: -50%; right: 50%; height: 2px; background: var(--cx-accent); }
.cx-rail > .s:first-child::before { display: none; }
.cx-rail > .s.todo::before { background: var(--cx-border); }
.cx-rail > .s .d { position: relative; z-index: 1; width: 30px; height: 30px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--cx-accent-strong); color: var(--cx-on-accent); font-weight: 700; font-size: 12px; }
.cx-rail > .s .d svg { width: 14px; height: 14px; }
.cx-rail > .s.cur { font-weight: 700; }
.cx-rail > .s.cur .d { background: var(--cx-panel); border: 2px solid var(--cx-accent-strong); color: var(--cx-accent-text); }
.cx-rail > .s.todo { color: var(--cx-muted); }
.cx-rail > .s.todo .d { background: var(--cx-panel); border: 1.5px solid var(--cx-input-border-strong); color: var(--cx-muted); }

/* ── side-nav item ── */
.cx-navitem { display: flex; align-items: center; gap: 10px; height: 38px; padding: 0 12px; border-radius: 8px; font: 500 var(--cx-size-body)/1 var(--cx-font); color: var(--cx-text); text-decoration: none; position: relative; }
.cx-navitem svg { width: 17px; height: 17px; color: var(--cx-muted); flex-shrink: 0; }
.cx-navitem:hover { background: var(--cx-bg-deep); }
.cx-navitem.on { background: var(--cx-accent-soft); color: var(--cx-accent-text); font-weight: 700; box-shadow: inset 3px 0 0 var(--cx-accent); } /* identity: soft fill + inset primary bar */
.cx-navitem.on svg { color: var(--cx-accent); }
.cx-navitem.on::before { content: ""; position: absolute; left: -10px; top: 7px; bottom: 7px; width: 3px; border-radius: 0 3px 3px 0; background: var(--cx-accent); }

/* ── status tab (a list's status filter with its counts) ── */
/* One row, equal shares: a status set never breaks 5 + 1. In narrow containers the
   padding and count shrink and labels ellipsise. Hairlines are
   per-tab shadows, so no empty cell can show a grey ground. */
.cx-stattabs { container: stattabs / inline-size; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); background: var(--cx-panel); border: 1px solid var(--cx-border); border-radius: var(--cx-r-surface); overflow: hidden; }
.cx-stattab { min-width: 0; background: var(--cx-panel); box-shadow: 1px 0 0 var(--cx-border-soft), 0 1px 0 var(--cx-border-soft); display: flex; flex-direction: column; gap: 6px; padding: 12px 16px 11px; border: none;
  border-bottom: 3px solid transparent; cursor: pointer; text-align: left; font-family: var(--cx-font); }
.cx-stattab .l { display: flex; align-items: center; gap: 7px; font-size: var(--cx-size-meta); font-weight: 600; color: var(--cx-muted); }
.cx-stattab .l svg { width: 15px; height: 15px; flex-shrink: 0; }
.cx-stattab .c { font-size: var(--cx-size-title); font-weight: 700; line-height: 1; color: var(--cx-text); font-variant-numeric: tabular-nums; letter-spacing: -.3px; }
.cx-stattab .l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@container stattabs (max-width: 720px) {
  .cx-stattab { padding: 10px 10px 9px; gap: 4px; }
  .cx-stattab .c { font-size: var(--cx-size-head); }
}
.cx-stattab:hover { background: var(--cx-panel-alt); }
.cx-stattab.on { background: var(--cx-accent-soft); border-bottom-color: var(--cx-accent); }
.cx-stattab.on .l { color: var(--cx-text); }
.cx-stattab .t-draft { color: var(--cx-slate-dot); } .cx-stattab .t-pending { color: var(--cx-amber); } .cx-stattab .t-accepted { color: var(--cx-green-dot); }
.cx-stattab .t-rejected { color: var(--cx-red-dot); } .cx-stattab .t-partial { color: var(--cx-blue-dot); } .cx-stattab .t-all { color: var(--cx-accent); }

/* =========================================================================
   IDENTITY VOICES (2026-09-25)
   ========================================================================= */
/* page title - the one class PageIntro and every page h1 binds */
.cx-h1 { margin: 0; font-size: var(--cx-size-title); font-family: var(--cx-heading-font); font-weight: var(--cx-heading-weight); text-transform: var(--cx-heading-transform); letter-spacing: var(--cx-heading-track); line-height: var(--cx-heading-lh); color: var(--cx-text); text-wrap: balance; }
/* section kicker - 21px primary rule + tracked uppercase label (SectionKicker component) */
.cx-kicker { display: inline-flex; align-items: center; gap: 10px; font-family: var(--cx-kicker-font); font-size: var(--cx-size-cap); font-weight: var(--cx-kicker-weight);
  letter-spacing: var(--cx-kicker-track); text-transform: uppercase; color: var(--cx-accent-text); line-height: 1; white-space: nowrap; }
.cx-kicker::before { content: ""; width: var(--cx-kicker-rule); height: 2px; background: var(--cx-accent); flex-shrink: 0; }
/* app header - the 3px primary rule across the top */
.cx-appbar { border-top: var(--cx-header-rule); }
/* big figures - dashboard cards, fee totals */
.cx-figure { font-family: var(--cx-data-font); font-weight: var(--cx-data-weight); letter-spacing: var(--cx-data-track); font-variant-numeric: tabular-nums; color: var(--cx-text); line-height: 1; }
