/* IBM Plex Sans for the interface: a working-tool typeface with humanist detail, rather than
   one of the neutral grotesques every new product ships with. Geist Mono stays for account
   numbers, IBANs and wallet addresses, where a slashed zero matters more than family. */
@font-face { font-family: "Plex"; src: url("/fonts/plex/ibm-plex-sans-latin-wght-normal.woff2") format("woff2-variations"); font-weight: 100 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Plex"; src: url("/fonts/plex/ibm-plex-sans-latin-wght-italic.woff2") format("woff2-variations"); font-weight: 100 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/fonts/geist-mono/GeistMono-Variable.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }

/* ==========================================================================
   Design tokens. Every colour, size, space, radius and shadow in the app
   references one of these (anti-ai-design rules, .claude/skills/anti-ai-design).
   Brand: "canopy to forest floor" (see COLOUR.md for the measured contrast).
     Midnight    #0C2E3D  text, headings, chrome, and the footer floor
     Mint        #A1BCB2  the canopy band, and footer body text
     Pale green  #CDE4B5  cards inside the canopy
     Sage        #90C689  the features band
     Forest      #1C6A3E  the deep band, and the success tone
     Olive       #6AB36A  marks on dark bands, and footer headings
     Lime        #9AD64C  sharp marks on dark bands
     Chartreuse  #BDE63D  badge FILLS, never a mark on sage
     Grass       #2D7D3A  the call to action, with white on it
   Six of the briefed text pairings measured below 4.5:1; COLOUR.md lists each
   one and the colour from the same family that replaced it.
   ========================================================================== */
:root {
  color-scheme: light;

  /* Colour */
  --color-primary: #0c2e3d;      /* Midnight */
  --color-secondary: #f3f8ee;    /* lightest canopy tint: surfaces, and ink on the chrome */
  --color-mint: #a1bcb2;         /* canopy band, footer body text */
  --color-pale: #cde4b5;         /* cards inside the canopy */
  --color-sage: #90c689;         /* features band */
  --color-fern: #4e8e52;         /* fills and borders -- NOT text on sage (2.00) */
  --color-forest: #1c6a3e;       /* the deep band */
  --color-olive: #6ab36a;        /* marks on dark bands, footer headings (5.61) */
  --color-lime: #9ad64c;         /* sharp marks on dark bands (3.80 on forest) */
  --color-chartreuse: #bde63d;   /* badge FILLS with midnight on them (9.87) */
  --color-secondary-25: #ffffff; /* cards, lifted above the page */
  --color-secondary-50: #f3f8ee; /* the page itself */
  --color-secondary-100: #e9f1df;
  --color-secondary-200: #dceccb; /* bands and sunken blocks */
  --color-accent: #2d7d3a;       /* Grass, one step deeper than the briefed #359244 so that
                                    white clears 4.5 on it (5.11 against 3.93) */
  --color-accent-ink: #ffffff;   /* white on grass: 5.11 */
  --color-accent-text: #276c32;  /* grass as text on the page: 5.94 */
  --color-highlight: #bde63d;    /* Chartreuse */
  --color-highlight-ink: #3f5a0a; /* chartreuse as text on the page */
  /* Neutrals are tinted toward the midnight/canopy family, never a flat cold grey. */
  --color-neutral-0: #ffffff;
  --color-neutral-50: #f3f8ee;
  --color-neutral-100: #e9f1df;
  --color-neutral-200: #d8e4d3;
  --color-neutral-300: #b4c9b8;
  --color-neutral-400: #7a9490;  /* large text and icons: 3.01 */
  --color-neutral-500: #4d6b70;  /* muted body text: 5.33 */
  --color-neutral-700: #244b58;  /* secondary text: 8.76 */
  --color-neutral-900: #0c2e3d;  /* body text: 13.21 */
  --color-white: #ffffff; /* fixed: does not change with the theme */
  --color-black: #000000;
  --color-success: #1c6a3e;
  --color-warning: #8a5a08;
  --color-error: #b02a1e;
  --color-info: #0c5a73;

  /* Type: 12 / 14 / 16 / 20 / 24 / 32. The display size is for marketing hero headings only. */
  --text-xs: 12px;
  --text-sm: 14px;
  --text-base: 16px;
  --text-lg: 20px;
  --text-xl: 24px;
  --text-2xl: 32px;
  --text-display: clamp(40px, 4.4vw, 56px);
  --leading-body: 1.5;
  --leading-heading: 1.25;
  --weight-body: 400;
  --weight-medium: 500;
  --weight-heading: 600;

  /* Space: 4px grid (half step only for hairline gaps between data marks) */
  --space-half: 2px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  --space-12: 48px;
  --space-16: 64px;
  --space-20: 80px;
  --space-24: 96px;
  --space-32: 128px;

  /* Shape and depth: two radii, two shadow levels */
  --r-xs: 4px; /* data marks and flags only */
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 8px;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
  --border: 1px solid var(--color-neutral-200);
  --border-input: 1px solid var(--color-neutral-300);
  --focus-color: var(--color-accent);
  --control-sm: 32px;
  --control-md: 40px;
  --control-lg: 48px;

  /* Semantic aliases used by the components */
  --brand: var(--color-primary);
  --sand: var(--color-secondary);
  --mint: var(--color-mint);
  --lime: var(--color-lime);
  --amber: var(--color-accent);
  --bg: var(--color-secondary-50);
  --surface: var(--color-secondary-25);
  --surface-2: var(--color-secondary-100);
  --sunken: var(--color-secondary-200);
  --ink: var(--color-neutral-900);
  --ink-2: var(--color-neutral-700);
  --muted: var(--color-neutral-500);
  --faint: var(--color-neutral-400);
  --line: var(--color-neutral-200);
  --line-strong: var(--color-neutral-300);
  --primary: var(--color-primary);
  --primary-hover: color-mix(in srgb, var(--color-primary) 90%, #000);
  --primary-ink: var(--color-secondary-50);
  --accent: var(--color-success);
  --accent-strong: color-mix(in srgb, var(--color-success) 90%, #000);
  --accent-soft: color-mix(in srgb, var(--color-success) 11%, transparent);
  --cta: var(--color-accent);
  --cta-edge: var(--color-accent);
  --cta-hover: color-mix(in srgb, var(--color-accent) 90%, #000);
  --cta-ink: var(--color-accent-ink);
  --cta-text: var(--color-accent-text);
  --good: var(--color-success);  --good-soft: color-mix(in srgb, var(--color-success) 11%, transparent);
  --warn: var(--color-warning);  --warn-soft: color-mix(in srgb, var(--color-highlight) 60%, transparent);
  --bad: var(--color-error);     --bad-soft: color-mix(in srgb, var(--color-error) 9%, transparent);
  --info: var(--color-info);     --info-soft: color-mix(in srgb, var(--color-info) 10%, transparent);
  --ring: 0 0 0 1px var(--line);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --font: "Plex", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Consolas, monospace;
  --z-sticky: 10;
  --z-drawer: 30;
  /* Brand chrome (sidebar, site header and footer): dark teal with off-white text. */
  --chrome: var(--color-primary);
  --chrome-2: color-mix(in srgb, var(--color-primary) 86%, #fff);
  --chrome-ink: var(--color-secondary-50);
  --chrome-muted: color-mix(in srgb, var(--color-secondary) 82%, transparent);
}

/* Dark theme: the same token structure, muted values, no neon accents. */
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --color-neutral-0: #061b24;
    --color-neutral-50: #0c2e3d;
    --color-neutral-100: #123a4b;
    --color-neutral-200: #1b4a5c;
    --color-neutral-300: #2b5f6e;
    --color-neutral-400: #7fa39e;  /* large text and icons */
    --color-neutral-500: #a1bcb2;  /* muted: the mint, 7.02 on the midnight */
    --color-neutral-700: #cde4b5;  /* secondary text: the pale green */
    --color-neutral-900: #f3f8ee;  /* the canopy tint becomes the ink: 13.21 */
    --color-success: #6ab36a;
    --color-warning: #f0c35c;
    --color-error: #ee8074;
    --color-info: #8fc7dc;
    --color-mint: #a1bcb2;
    --color-highlight: #9ad64c;
    --color-highlight-ink: #9ad64c;
    /* The lime is the ink in the dark, so the tint behind it stays nearly black. */
    --warn-soft: color-mix(in srgb, var(--color-warning) 16%, transparent);
    --color-accent: #54b03f;       /* Leaf: the flow's own final-CTA green */
    --color-accent-ink: #0c2e3d;   /* midnight on leaf: 5.20, not white (2.74) */
    --color-accent-text: #9ad64c;  /* lime as text on the midnight: 8.21 */
    --bg: #061b24;
    --surface: #0c2e3d;
    --surface-2: #123a4b;
    --sunken: #04141b;
    --primary: var(--color-secondary);
    --primary-hover: color-mix(in srgb, var(--color-secondary) 90%, #000);
    --primary-ink: var(--color-primary);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
    --chrome: #04141b;
    --chrome-2: #123a4b;
  }
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { margin: 0; }
body { background: var(--bg); color: var(--ink); font: var(--weight-body) var(--text-sm)/var(--leading-body) var(--font); font-feature-settings: "cv02", "cv03", "cv04"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; transition: text-decoration-color 150ms ease, color 150ms ease; }
a:hover { text-decoration-color: currentColor; }
h1, h2, h3, h4 { margin: 0; line-height: var(--leading-heading); font-weight: var(--weight-heading); text-wrap: balance; }
h1 { font-size: var(--text-xl); letter-spacing: -0.025em; }
h2 { font-size: var(--text-base); letter-spacing: -0.012em; }
h3 { font-size: var(--text-sm); letter-spacing: -0.005em; }
p { margin: 0 0 var(--space-2); text-wrap: pretty; }
code { font-family: var(--mono); font-size: var(--text-xs); }
.icon { flex: none; vertical-align: -0.2em; }
.muted { color: var(--muted); }
.small { font-size: var(--text-xs); }
.mono { font-family: var(--mono); font-size: var(--text-xs); letter-spacing: -0.01em; }
.num { font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.01em; }
.right { text-align: right; }
.pos { color: var(--good); }
.neg { color: var(--bad); }
.nowrap { white-space: nowrap; }
.pre { white-space: pre-line; }
.stack > * + * { margin-top: var(--space-6); }
.stack > input[type=hidden] + * { margin-top: 0; }
.row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: 12px; top: -48px; z-index: 100; background: var(--cta); color: var(--cta-ink); padding: var(--space-2) var(--space-4); border-radius: var(--r-md); text-decoration: none; transition: transform 200ms var(--ease-out); }
.skip-link:focus { transform: translateY(60px); }
::selection { background: var(--accent-soft); }
:focus-visible { outline: 2px solid var(--focus-color); outline-offset: var(--space-half); }

/* ---------- Brand ---------- */
.brand { display: inline-flex; align-items: center; gap: var(--space-3); color: var(--ink); text-decoration: none; font-weight: 600; letter-spacing: -0.015em; line-height: 1.15; }
.brand-mark { width: 28px; height: 28px; border-radius: var(--r-md); background: var(--brand); color: var(--sand); display: grid; place-items: center; flex: none; }
.brand-mark svg { width: 16px; height: 16px; }
/* The CC Recovery logo: traced from the supplied artwork and recoloured to the palette
   (public/img/brand). logo-on-dark sits on the midnight chrome; logo-on-light on the page. */
.brand-logo { display: block; height: 36px; width: auto; max-width: 100%; }
.brand picture { display: block; }
/* The PWA install button stays out of sight until the browser offers an install (app.js). */
[data-install][hidden] { display: none; }
.brand small { display: block; font-weight: 450; color: var(--muted); font-size: var(--text-xs); letter-spacing: 0; margin-top: var(--space-half); }

/* ---------- Staff shell (sidebar) ---------- */
.shell { display: grid; grid-template-columns: 248px minmax(0, 1fr); min-height: 100dvh; }
.sidebar { background: var(--chrome); color: var(--chrome-ink); padding: var(--space-4) var(--space-3); position: sticky; top: 0; height: 100dvh; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-1); }
.sidebar .brand { padding: var(--space-1) var(--space-2) var(--space-4); color: var(--chrome-ink); }
.sidebar .brand small { color: var(--chrome-muted); }
.sidebar .brand-mark { background: var(--cta); color: var(--cta-ink); }
.nav { display: flex; flex-direction: column; gap: var(--space-half); }
.nav a { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--r-md); color: var(--chrome-muted); font-weight: 500; text-decoration: none; transition: background-color 150ms ease, color 150ms ease; }
.nav a .icon { color: var(--chrome-muted); transition: color 150ms ease; }
.nav a.active { background: var(--chrome-2); color: var(--chrome-ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-secondary) 8%, transparent); }
.nav a.active .icon { color: var(--cta); }
.nav .count { margin-left: auto; min-width: 20px; text-align: center; background: var(--cta); color: var(--cta-ink); font-size: var(--text-xs); font-weight: 600; border-radius: var(--r-sm); padding: 0 var(--space-2); font-variant-numeric: tabular-nums; }
.nav-label { font-size: var(--text-xs); font-weight: 500; color: var(--chrome-muted); padding: var(--space-4) var(--space-3) var(--space-2); }
.sidebar-foot { margin-top: auto; padding-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-half); }
.me { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3) var(--space-3); }
.avatar { width: 30px; height: 30px; border-radius: var(--r-md); background: var(--sand); box-shadow: var(--ring); color: var(--brand); display: grid; place-items: center; font-weight: 600; font-size: var(--text-xs); flex: none; letter-spacing: 0.02em; }
.me-name { font-weight: 550; font-size: var(--text-sm); line-height: 1.25; }
.me-role { font-size: var(--text-xs); color: var(--muted); }
.sidebar .me-role { color: var(--chrome-muted); }
.linkbtn { background: none; border: 0; padding: var(--space-2) var(--space-3); font: inherit; color: inherit; display: flex; align-items: center; gap: var(--space-3); width: 100%; border-radius: var(--r-md); cursor: pointer; font-weight: 500; transition: background-color 150ms ease, color 150ms ease; }
.linkbtn .icon { opacity: 0.7; }
.sidebar .linkbtn { color: var(--chrome-muted); }
@media (hover: hover) and (pointer: fine) {
  .linkbtn:hover { background: color-mix(in srgb, var(--color-neutral-500) 10%, transparent); color: var(--ink); }
  .nav a:not(.active):hover, .sidebar .linkbtn:hover { background: color-mix(in srgb, var(--color-secondary) 7%, transparent); color: var(--chrome-ink); }
  .nav a:not(.active):hover .icon { color: var(--chrome-ink); }
}

.main { min-width: 0; display: flex; flex-direction: column; }
.topbar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) clamp(var(--space-6), 3vw, var(--space-12)); position: sticky; top: 0; z-index: var(--z-sticky); background: var(--bg); }
.topbar .search { flex: 1; max-width: 440px; position: relative; }
.topbar .search .icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--faint); }
.topbar .search input { padding-left: var(--space-8); background: var(--surface); }
.topbar .search kbd { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); font: 500 var(--text-xs) var(--mono); color: var(--faint); padding: var(--space-half) var(--space-2); border-radius: var(--r-sm); box-shadow: var(--ring); }
.topbar-spacer { flex: 1; }
.topbar-toggle-only { display: none; }
.menu-toggle { display: none; background: none; border: 0; padding: var(--space-2); margin-left: calc(-1 * var(--space-2)); color: var(--ink); cursor: pointer; border-radius: var(--r-md); }
.content { padding: var(--space-3) clamp(var(--space-6), 3vw, var(--space-12)) var(--space-16); width: 100%; }

/* ---------- Client shell (top navigation) ---------- */
.account-menu { position: relative; }
.account-menu summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1); border-radius: var(--r-md); }
.account-menu summary::-webkit-details-marker { display: none; }
.account-menu .menu { color: var(--ink); position: absolute; right: 0; top: calc(100% + 6px); min-width: 220px; background: var(--surface); border-radius: var(--r-md); box-shadow: var(--shadow-md); padding: var(--space-2); transform-origin: top right; transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out); }
@starting-style { .account-menu[open] .menu { opacity: 0; transform: scale(0.97) translateY(-2px); } }
.account-menu .menu-head { padding: var(--space-2) var(--space-3) var(--space-3); box-shadow: var(--shadow-sm); margin-bottom: var(--space-1); }
.account-menu .menu a, .account-menu .menu .linkbtn { display: flex; gap: var(--space-3); align-items: center; padding: var(--space-2) var(--space-3); border-radius: var(--r-md); text-decoration: none; color: var(--ink-2); font-weight: 500; }
@media (hover: hover) and (pointer: fine) { .account-menu .menu a:hover { background: var(--surface-2); color: var(--ink); } }

/* ---------- Language menu (partials/lang-switch.ejs) ---------- */
.lang-menu summary { height: 36px; padding: 0 var(--space-3); gap: var(--space-2); color: inherit; font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; transition: background-color 150ms ease, color 150ms ease; }
.lang-menu summary .icon { opacity: 0.85; }
.lang-menu .menu { min-width: 184px; z-index: 50; }
.lang-menu .menu a { justify-content: space-between; }
.lang-menu .menu a[aria-current] { color: var(--ink); background: var(--surface-2); }
.lang-menu .menu a .icon { color: var(--brand); }
.lang-bar summary { color: color-mix(in srgb, var(--color-secondary) 82%, transparent); }
.lang-bar[open] summary { color: var(--sand); background: color-mix(in srgb, var(--color-secondary) 10%, transparent); }
.lang-page summary { color: var(--ink-2); box-shadow: var(--ring); }
.lang-sidebar summary { height: auto; padding: var(--space-2) var(--space-3); gap: var(--space-3); color: var(--chrome-muted); font-size: inherit; font-weight: 500; letter-spacing: 0; }
.lang-sidebar summary .icon { opacity: 1; }
.lang-sidebar .menu { top: auto; bottom: calc(100% + 6px); left: 0; right: auto; transform-origin: bottom left; }
@starting-style { .lang-sidebar[open] .menu { opacity: 0; transform: scale(0.97) translateY(2px); } }
@media (hover: hover) and (pointer: fine) {
  .lang-bar summary:hover { color: var(--sand); background: color-mix(in srgb, var(--color-secondary) 8%, transparent); }
  .lang-page summary:hover { color: var(--ink); background: var(--surface-2); }
  .lang-sidebar summary:hover { color: var(--chrome-ink); background: color-mix(in srgb, var(--color-secondary) 7%, transparent); }
}
.auth-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.lang-menu .lang-name { display: inline-flex; align-items: center; gap: var(--space-3); }

/* ---------- Flags (src/flags.js) ---------- */
/* A hairline ring keeps white-edged flags (Japan, Poland...) visible on light surfaces. */
.flag { display: inline-block; flex: none; vertical-align: -0.125em; border-radius: var(--r-xs); box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-neutral-900) 12%, transparent); object-fit: cover; }
.with-flag { display: inline-flex; align-items: center; gap: var(--space-2); }
/* Wallet brand marks: evidence in the intake, never a payment destination. */
.wallet-mark { display: inline-flex; vertical-align: middle; }
.wallet-mark svg { width: 18px; height: 18px; display: block; border-radius: var(--r-xs); }
.wallet-mark:empty { display: none; }
.select-with-mark { position: relative; }
.select-with-mark .wallet-mark { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); pointer-events: none; }
.select-with-mark:has(.wallet-mark:not(:empty)) select { padding-left: var(--space-12); }

.select-with-flag { position: relative; }
.select-with-flag .flag { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); pointer-events: none; }
.select-with-flag select { padding-left: var(--space-12); }
.select-with-flag .flag[hidden] { display: none; }
.select-with-flag:not(:has(.flag:not([hidden]))) select { padding-left: var(--space-3); }

/* ---------- Page header ---------- */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin: var(--space-3) 0 var(--space-6); }
.page-head .sub { color: var(--muted); margin-top: var(--space-2); max-width: 70ch; }
.crumb { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--muted); font-size: var(--text-sm); margin-top: var(--space-2); text-decoration: none; font-weight: 500; }
.crumb:hover { color: var(--ink); }
.crumb + .page-head { margin-top: var(--space-2); }
.title-row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* ---------- Surfaces ---------- */
.card { background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); min-width: 0; }
.card-pad { padding: var(--space-6); }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-6); flex-wrap: wrap; }
.card-head + * { box-shadow: var(--shadow-sm); }
.card-head h2 { font-size: var(--text-base); }
.card-head a { font-size: var(--text-sm); color: var(--muted); font-weight: 500; }
.card-body { padding: var(--space-6); }
.card-foot { padding: var(--space-3) var(--space-6); box-shadow: var(--shadow-sm); }
.grid { display: grid; gap: var(--space-6); }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-main { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); align-items: start; }
.align-start { align-items: start; }

.metric { padding: var(--space-4) var(--space-6); display: flex; flex-direction: column; }
.metric-label { color: var(--muted); font-size: var(--text-sm); font-weight: 500; display: flex; align-items: center; gap: var(--space-2); }
.metric-value { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.03em; margin-top: var(--space-2); font-variant-numeric: tabular-nums; line-height: 1.15; }
.metric-value.lg { font-size: var(--text-2xl); }
.metric-sub { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-1); }
.metric.accent .metric-value { color: var(--accent); }
.metric-multi .metric-value + .metric-value { font-size: var(--text-base); margin-top: var(--space-1); color: var(--ink-2); }

/* Statement-style recovery overview */
.overview { overflow: hidden; }
.overview-top { padding: var(--space-6) var(--space-8) var(--space-2); display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-8); align-items: end; }
.overview-top .figure-label { font-size: var(--text-sm); color: var(--muted); font-weight: 500; }
.overview-top .figure { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.025em; margin-top: var(--space-1); font-variant-numeric: tabular-nums; }
.overview-top .figure.hero { font-size: var(--text-2xl); letter-spacing: -0.04em; line-height: 1.05; color: var(--accent); }
.overview-progress { padding: var(--space-4) var(--space-8) var(--space-6); }
.overview-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); background: var(--surface-2); box-shadow: inset 0 1px 0 var(--line); }
.overview-meta > div { padding: var(--space-4) var(--space-8); }
.overview-meta > div + div { box-shadow: inset 1px 0 0 var(--line), inset 0 1px 0 var(--line); }
.overview-meta .value { margin-top: var(--space-1); font-weight: 550; }

.progress { height: 8px; background: var(--sunken); border-radius: var(--r-md); overflow: hidden; box-shadow: inset 0 0 0 1px var(--line); }
.progress > span { display: block; height: 100%; background: var(--accent); border-radius: var(--r-md); transform-origin: left center; }
.progress.sm { height: 5px; }
.progress-row { display: flex; align-items: center; gap: var(--space-4); }
.progress-row .progress { flex: 1; }
.progress-pct { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 44px; text-align: right; }
@media (prefers-reduced-motion: no-preference) {
  .progress > span { animation: fill 900ms var(--ease-out) 120ms both; }
  @keyframes fill { from { transform: scaleX(0.02); } }
}

/* ---------- Status labels ---------- */
.badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: var(--space-1) var(--space-2); border-radius: var(--r-sm); font-size: var(--text-xs); font-weight: 550; white-space: nowrap; line-height: 1.5; }
.tone-neutral { background: var(--sunken); color: var(--ink-2); }
.tone-info { background: var(--info-soft); color: var(--info); }
.tone-good { background: var(--good-soft); color: var(--good); }
.tone-warn { background: var(--warn-soft); color: var(--warn); }
.tone-bad { background: var(--bad-soft); color: var(--bad); }
.tone-accent { background: var(--accent-soft); color: var(--accent); }

/* Rich picker (app.js setUpPickers).
   The native <select> stays in the DOM holding the value and is hidden only once JS has built
   the replacement -- so with JS off, or before it runs, the real control is what you get. */
.picker { position: relative; }
.js .picker-native { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); border: 0; }
.picker-button { display: flex; align-items: center; gap: var(--space-2); width: 100%; height: var(--control-md); padding: 0 var(--space-3); background: var(--surface); border: var(--border-input); border-radius: var(--r-sm); font: inherit; color: var(--ink); text-align: left; cursor: pointer; transition: border-color 150ms ease; }
.picker-button:hover { border-color: var(--muted); }
.picker-button:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 1px; }
.picker-button::after { content: ""; margin-left: auto; width: 8px; height: 8px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: translateY(-2px) rotate(45deg); flex: none; }
.picker-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-mark { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 16px; flex: none; }
.picker-mark svg, .picker-mark img { width: 100%; height: 100%; object-fit: contain; border-radius: 2px; }

.picker-pop { position: absolute; z-index: 60; top: calc(100% + 4px); left: 0; right: 0; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md); box-shadow: var(--shadow-md, 0 4px 12px rgba(0,0,0,0.1)); overflow: hidden; }
.picker-search { width: 100%; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: var(--space-2) var(--space-3); font: inherit; background: transparent; color: var(--ink); }
.picker-search:focus { outline: none; border-bottom-color: var(--focus-color); }
.picker-list { list-style: none; margin: 0; padding: var(--space-1); max-height: 260px; overflow-y: auto; }
.picker-list li { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); border-radius: var(--r-sm); cursor: pointer; font-size: var(--text-sm); }
.picker-list li.is-active { background: var(--surface-2); }
.picker-list li[aria-selected="true"] { font-weight: 600; }
.picker-list li[aria-selected="true"]::after { content: ""; margin-left: auto; width: 5px; height: 9px; border-right: 2px solid var(--brand); border-bottom: 2px solid var(--brand); transform: rotate(45deg); flex: none; }

/* Case status chips (partials/case-status.ejs).

   Seven states, and colour alone cannot carry seven reliably -- dark hues converge, and under
   deuteranopia violet and blue are all but identical. So form does half the work and every chip
   also carries its own glyph and its full label:

     solid fill   the three states a case moves through under our hands
     outline      partial recovery (part of the way) and closed (done with)
     light fill   opened, which is a case nobody has picked up yet

   Solid fills are checked for 4.5:1 against their own label and 3:1 against the surface; the
   worst-separated pair is ~12 ΔE in both modes. Dark mode uses lighter fills with dark text
   rather than flipping, because deep fills disappear into a dark surface. */
.cstat { font-weight: 600; padding-inline: var(--space-2); border: 1px solid transparent; }
.cstat .icon { opacity: 0.9; flex: none; }

.cstat-opened { background: var(--sunken); color: var(--ink-2); border-color: var(--line); }
.cstat-under_review           { background: #2d5a7a; color: #fff; }
.cstat-documentation_required { background: #8f5208; color: #fff; }
.cstat-in_progress            { background: #6b3fa0; color: #fff; }
.cstat-completed              { background: #1c6b43; color: #fff; }
/* Not filled in, because the recovery is not: the outline is the point, not decoration. */
.cstat-partial_recovery { background: transparent; color: #1c6b43; border-color: #1c6b43; }
.cstat-closed { background: transparent; color: var(--muted); border-color: var(--line-strong); }

@media (prefers-color-scheme: dark) {
  .cstat-under_review           { background: #8fb8d6; color: #07130c; }
  .cstat-documentation_required { background: #e0a35c; color: #07130c; }
  .cstat-in_progress            { background: #d39ad4; color: #07130c; }
  .cstat-completed              { background: #72c395; color: #07130c; }
  .cstat-partial_recovery { color: #72c395; border-color: #72c395; }
}
}
.tag { display: inline-block; padding: var(--space-half) var(--space-2); border-radius: var(--r-sm); background: var(--surface-2); box-shadow: var(--ring); color: var(--ink-2); font-size: var(--text-xs); font-weight: 500; white-space: nowrap; }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; font-size: var(--text-xs); font-weight: 500; color: var(--muted); padding: var(--space-3) var(--space-4); white-space: nowrap; box-shadow: inset 0 -1px 0 var(--line); }
.table td { padding: var(--space-3) var(--space-4); box-shadow: inset 0 -1px 0 var(--line); vertical-align: middle; }
.table tbody tr:last-child td { box-shadow: none; }
.table th:first-child, .table td:first-child { padding-left: var(--space-6); }
.table th:last-child, .table td:last-child { padding-right: var(--space-6); }
.table tbody tr { transition: background-color 120ms ease; }
@media (hover: hover) and (pointer: fine) { .table tbody tr:hover td { background: color-mix(in srgb, var(--surface-2) 60%, transparent); } }
.table .primary-cell { font-weight: 550; color: var(--ink); text-decoration: none; }
.table a.primary-cell:hover { text-decoration: underline; }
.table tfoot td { font-weight: 600; box-shadow: inset 0 1px 0 var(--line-strong); background: var(--surface-2); }
.card > .table-wrap:last-child tfoot tr:last-child td:first-child { border-bottom-left-radius: var(--r-lg); }
.card > .table-wrap:last-child tfoot tr:last-child td:last-child { border-bottom-right-radius: var(--r-lg); }
.cell-sub { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-half); }
/* ---------- Payout accounts ---------- */
/* One row per bank account: mark, the bank and masked number, who it is in the name of, status. */
.account-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.account-row { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--r-md); box-shadow: var(--ring); }
.account-row form { margin-left: auto; }
.acct-mark { flex: none; display: grid; place-items: center; width: var(--space-8); height: var(--space-8); border-radius: var(--r-md); background: var(--surface-2); color: var(--ink-2); }
.acct-body { min-width: 0; flex: 1; display: grid; gap: var(--space-half); }
.acct-name { font-weight: 600; color: var(--ink); }
.acct-sub { font-size: var(--text-xs); color: var(--muted); overflow-wrap: anywhere; }
.acct-reason { color: var(--bad); }
.acct-kv { margin-top: var(--space-2); font-size: var(--text-sm); }
.account-list.staff .account-row { align-items: flex-start; }

/* Choosing the account to be paid into: the whole row is the target, not just the radio. */
.account-pick { border: 0; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.account-pick legend { font-size: var(--text-sm); font-weight: 500; color: var(--ink-2); padding: 0 0 var(--space-2); }
.account-option { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border-radius: var(--r-md); box-shadow: var(--ring); cursor: pointer; transition: box-shadow 150ms var(--ease-out); }
.account-option:has(input:checked) { box-shadow: inset 0 0 0 2px var(--accent); }
.account-option input { flex: none; }
.account-option .badge { margin-left: auto; }

.payout-limits { margin: 0; display: grid; gap: var(--space-1); padding: var(--space-3) var(--space-4); border-radius: var(--r-md); background: var(--surface-2); }
.payout-limits > div { display: flex; justify-content: space-between; gap: var(--space-4); font-size: var(--text-sm); }
.payout-limits dt { color: var(--ink-2); }
.payout-limits dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }

.add-account > summary { list-style: none; display: inline-flex; width: auto; }
.add-account > summary::-webkit-details-marker { display: none; }
.add-account[open] > summary { display: none; }

@media (max-width: 560px) {
  .account-row { flex-wrap: wrap; }
  .account-row form { margin-left: calc(var(--space-8) + var(--space-3)); }
}

/* ---------- Payment progress ---------- */
/* Steps sit on one line joined by a bar that fills as each is reached. The line into a step is
   coloured once the payment has got there, so the bar stops at the step it is waiting on. */
.lifecycle { display: grid; gap: var(--space-4); padding: var(--space-4); margin-bottom: var(--space-6); border-radius: var(--r-md); box-shadow: var(--ring); }
.lc-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.lc-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.lc-step { position: relative; display: grid; justify-items: center; align-content: start; gap: var(--space-2); padding: 0 var(--space-1); text-align: center; }
.lc-step + .lc-step::before { content: ""; position: absolute; top: calc(var(--space-8) / 2 - 1px); right: 50%; width: 100%; height: 2px; background: var(--line); }
.lc-steps .lc-step.is-done::before, .lc-steps .lc-step.is-current::before { background: var(--accent); }
.lc-steps .lc-step.is-failed::before { background: var(--bad); }

.lc-icon { position: relative; z-index: 1; display: grid; place-items: center; width: var(--space-8); height: var(--space-8); border-radius: 50%; background: var(--surface-2); color: var(--muted); }
.is-done .lc-icon { background: var(--accent); color: var(--color-white); }
.is-current .lc-icon { background: var(--surface); color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }
.is-failed .lc-icon { background: var(--bad); color: var(--color-white); }

.lc-text { display: grid; gap: var(--space-half); min-width: 0; }
.lc-label { font-size: var(--text-xs); font-weight: 600; color: var(--ink); line-height: 1.25; }
.is-pending .lc-label { color: var(--muted); font-weight: 500; }
.lc-time { font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.is-current .lc-time { color: var(--accent); font-weight: 550; }
.is-failed .lc-time { color: var(--bad); font-weight: 550; }
.lc-ref { font-size: var(--text-xs); color: var(--faint); }
.lc-time time { display: grid; }
.lc-clock { color: var(--faint); }

/* On a phone the steps stack, and the bar runs down the left instead of across. */
@media (max-width: 560px) {
  .lc-steps { grid-auto-flow: row; gap: var(--space-4); }
  .lc-step { grid-template-columns: var(--space-8) minmax(0, 1fr); justify-items: start; align-items: center; text-align: left; gap: var(--space-3); padding: 0; }
  .lc-step + .lc-step::before { top: auto; bottom: 50%; right: auto; left: calc(var(--space-8) / 2 - 1px); width: 2px; height: calc(100% + var(--space-4)); }
}

/* ---------- Payment detail ---------- */
/* gross -> charges -> net, then the route the money took. Read like a bank statement line. */
.pay-desc { margin: 0 0 var(--space-4); color: var(--ink-2); }
.pay { display: grid; gap: var(--space-6); }
.pay-amounts { display: grid; gap: var(--space-4); }
.pay-label { font-size: var(--text-xs); color: var(--muted); font-weight: 500; }
.pay-figure { font-size: var(--text-2xl); font-weight: 600; letter-spacing: -0.035em; line-height: 1.1; font-variant-numeric: tabular-nums; margin-top: var(--space-1); }
.pay-breakdown { margin: 0; display: grid; gap: var(--space-2); padding: var(--space-4); border-radius: var(--r-md); background: var(--surface-2); }
.pay-breakdown > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); }
.pay-breakdown dt { font-size: var(--text-sm); color: var(--ink-2); }
.pay-breakdown dd { margin: 0; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.pay-breakdown .pay-total { padding-top: var(--space-2); box-shadow: inset 0 1px 0 var(--line); font-weight: 600; }
.pay-breakdown .pay-total dt, .pay-breakdown .pay-total dd { color: var(--ink); font-weight: 600; }

.pay-route { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; padding: var(--space-4); border-radius: var(--r-md); box-shadow: var(--ring); }
.pay-end { min-width: 0; flex: 1; }
.pay-party { font-weight: 550; color: var(--ink); margin-top: var(--space-1); overflow-wrap: anywhere; }
.pay-arrow { flex: none; color: var(--muted); display: grid; place-items: center; }
.pay-facts { margin: 0; }
.pay-note { margin: 0; }

@media (max-width: 560px) {
  .pay-route { gap: var(--space-2); }
  .pay-arrow { transform: rotate(90deg); }
}

/* Form section heading inside the fields grid. */
.form-section { font-size: var(--text-sm); color: var(--ink-2); margin: var(--space-2) 0 0; padding-top: var(--space-4); box-shadow: inset 0 1px 0 var(--line); }

/* ---------- Record page ---------- */
/* Title, one primary action, then the facts. Everything secondary is one size down. */
.record-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin: var(--space-2) 0 var(--space-4); }
.record-id h1 { font-size: var(--text-xl); line-height: 1.25; }
.record-id .sub { color: var(--muted); margin-top: var(--space-1); }
.record-menu > summary { gap: var(--space-2); padding: var(--space-2) var(--space-3); border-radius: var(--r-md); font-size: var(--text-sm); font-weight: 550; color: var(--ink-2); background: var(--surface); box-shadow: var(--shadow-sm); }
.record-menu .menu { min-width: 200px; }

/* The facts band. Read across, not down: no hero figure on a worklist record. */
.highlights { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-8); align-items: flex-start; padding: var(--space-4) var(--space-6); margin-bottom: var(--space-4); background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-sm); }
.highlights .hl { min-width: 0; }
.highlights .hl.grow { flex: 1; min-width: 160px; }
.highlights dt { font-size: var(--text-xs); color: var(--muted); font-weight: 500; white-space: nowrap; }
.highlights dd { margin: var(--space-1) 0 0; font-size: var(--text-sm); font-weight: 550; color: var(--ink); }
.highlights .hl.num dd { font-variant-numeric: tabular-nums; }
.highlights .hl.grow dd { padding-top: var(--space-2); }
.highlights a { color: var(--ink); }

/* ---------- Activity ---------- */
.activity-compose { display: flex; gap: var(--space-2); padding: var(--space-3) var(--space-6); box-shadow: inset 0 -1px 0 var(--line); }
.activity-compose input { flex: 1; min-width: 0; height: var(--control-sm); font-size: var(--text-sm); }
.activity { list-style: none; margin: 0; padding: var(--space-2) var(--space-6) var(--space-4); }
.act { display: flex; gap: var(--space-3); padding: var(--space-3) 0; }
.act + .act { box-shadow: inset 0 1px 0 var(--line); }
.act-icon { flex: none; display: grid; place-items: center; width: var(--space-6); height: var(--space-6); margin-top: var(--space-half); border-radius: 50%; background: var(--surface-2); color: var(--muted); }
.act-ledger .act-icon { color: var(--accent); }
.act-milestone .act-icon { background: var(--accent); color: var(--color-white); }
.act-body { min-width: 0; flex: 1; }
.act-line { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.act-title { font-weight: 550; color: var(--ink); text-decoration: none; }
a.act-title:hover { text-decoration: underline; }
.act-line .num { margin-left: auto; font-variant-numeric: tabular-nums; }
.act-sub, .act-meta { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-half); }
.act-quote { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.list.compact li { padding-top: var(--space-2); padding-bottom: var(--space-2); }

@media (max-width: 720px) {
  .highlights { gap: var(--space-3) var(--space-6); padding: var(--space-4); }
  .activity { padding-left: var(--space-4); padding-right: var(--space-4); }
  .activity-compose { padding-left: var(--space-4); padding-right: var(--space-4); flex-wrap: wrap; }
}

/* ---------- List view ---------- */
/* A dense, sortable table under its own object header, in the shape of a CRM list view. */
.lv-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin: var(--space-3) 0 var(--space-4); }
.lv-id { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.lv-icon { flex: none; display: grid; place-items: center; width: var(--space-8); height: var(--space-8); border-radius: var(--r-md); background: var(--primary); color: var(--primary-ink); }
.lv-id h1 { font-size: var(--text-xl); line-height: 1.25; }
.lv-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-top: var(--space-half); font-size: var(--text-xs); color: var(--muted); }
.lv-meta > * + *::before { content: '·'; margin-right: var(--space-2); }
.lv-toolbar { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; padding: var(--space-3) var(--space-4); box-shadow: inset 0 -1px 0 var(--line); }
.lv-toolbar .f { min-width: 140px; }
.lv-toolbar label { display: block; font-size: var(--text-xs); margin-bottom: var(--space-1); color: var(--muted); font-weight: 500; }
.lv-toolbar select, .lv-toolbar input { height: var(--control-sm); font-size: var(--text-sm); }
.lv-search { flex: 1; min-width: 200px; max-width: 360px; }
.lv-search .wrap { position: relative; }
.lv-search .icon { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
/* Beats input[type=search], which sets the padding shorthand further down the file. */
.lv-toolbar .lv-search input { padding-left: var(--space-8); }

.table.lv { font-size: var(--text-sm); }
.table.lv td { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.table.lv tbody tr:hover { background: var(--surface-2); }
.table.lv th.is-sortable { padding: 0; }
.table.lv th.is-sortable a { display: flex; align-items: center; gap: var(--space-1); padding: var(--space-3) var(--space-4); color: inherit; text-decoration: none; }
.table.lv th.is-sortable a:hover { color: var(--ink); background: var(--surface-2); }
.table.lv th.is-sortable .icon { flex: none; opacity: 0.4; }
.table.lv th.is-sorted a { color: var(--ink); font-weight: 600; }
.table.lv th.is-sorted .icon { opacity: 1; color: var(--accent); }
.table.lv th.right a { justify-content: flex-end; }
.table.lv th.is-sortable:last-child a { padding-right: var(--space-6); }
.table.lv th.lv-n, .table.lv td.lv-n { width: var(--space-8); padding-left: var(--space-4); padding-right: 0; text-align: right; color: var(--faint); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.table.lv td.lv-act { text-align: right; white-space: nowrap; }
/* Keeps rows one line tall. The full text is in the title and on the record's own page. */
.table.lv td.clip { max-width: 28ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A clipped sub-line inside a cell, for a long note that must not widen the table. */
.table.lv td .cell-sub.clip { display: block; max-width: 32ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.table .mono, .table .num { white-space: nowrap; }

.empty { padding: var(--space-12) var(--space-6); text-align: center; color: var(--muted); display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.empty .icon { color: var(--faint); margin-bottom: var(--space-1); }
.empty h2 { color: var(--ink); }
.empty p { max-width: 44ch; margin: 0 auto var(--space-2); }

/* ---------- Buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); height: var(--control-md); padding: 0 var(--space-4); border-radius: var(--r-md); border: var(--border-input); background: var(--surface); box-shadow: none; color: var(--ink); font: inherit; font-weight: var(--weight-medium); cursor: pointer; white-space: nowrap; text-decoration: none; transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease, transform 160ms var(--ease-out); }
.btn:active { transform: scale(0.97); }
/* Primary actions are solid fills; secondary (.btn) is outlined; ghost has no chrome. */
.btn-primary { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.btn-accent { background: var(--accent); border-color: var(--accent); color: var(--color-neutral-0); }
/* The yellow is only 1.10:1 against the page, so the button has no edge of its own. The dark
   teal border is what makes it findable; it is not decoration. */
.btn-cta { background: var(--cta); border-color: var(--cta-edge); color: var(--cta-ink); }
.btn-danger { color: var(--bad); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
/* The shadow is load-bearing: this button sits on a pale photograph, where white on plaster
   is only 1.46:1 and the edge would otherwise disappear. */
.btn-light { background: var(--color-white); border-color: var(--color-white); color: #0c2e3d; box-shadow: 0 2px 10px rgba(6, 27, 36, 0.26); }
@media (hover: hover) { .btn-light:hover { background: #e9f1df; border-color: #e9f1df; } }
.btn-sm { height: var(--control-sm); padding: 0 var(--space-3); font-size: var(--text-xs); }
.btn-lg { height: var(--control-lg); padding: 0 var(--space-6); font-size: var(--text-base); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
/* Hover darkens the same colour by 10%; it never switches to a different colour. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: color-mix(in srgb, var(--surface) 90%, var(--color-black)); }
  .btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
  .btn-accent:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
  .btn-cta:hover { background: var(--cta-hover); border-color: var(--cta-hover); }
  .btn-danger:hover { background: color-mix(in srgb, var(--surface) 90%, var(--color-black)); }
  .btn-ghost:hover { background: color-mix(in srgb, currentColor 10%, transparent); color: var(--ink); }
}
@media (prefers-color-scheme: dark) { .btn-accent { color: var(--bg); } }

/* ---------- Forms ---------- */
label { display: block; font-weight: 550; font-size: var(--text-sm); margin-bottom: var(--space-2); color: var(--ink-2); }
.hint { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-2); font-weight: 400; }
input[type=text], input[type=email], input[type=password], input[type=date], input[type=search], input[type=tel], input:not([type]), select, textarea {
  width: 100%; height: var(--control-md); padding: 0 var(--space-3); border: var(--border-input); border-radius: var(--r-sm); font: inherit; color: var(--ink); background: var(--surface); box-shadow: none; transition: border-color 150ms ease;
}
textarea { height: auto; min-height: var(--space-24); padding: var(--space-3); resize: vertical; line-height: var(--leading-body); }
select { appearance: none; padding-right: var(--space-8); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%239ca3af'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right var(--space-3) center; background-size: var(--text-sm); }
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus, select:focus, textarea:focus { border-color: var(--primary); outline: 2px solid var(--focus-color); outline-offset: var(--space-half); }
input:user-invalid, textarea:user-invalid { border-color: var(--bad); }
input[type=file] { font: inherit; font-size: var(--text-sm); max-width: 100%; color: var(--muted); }
input[type=file]::file-selector-button { font: inherit; font-weight: 550; margin-right: var(--space-3); border: 0; border-radius: var(--r-md); padding: var(--space-2) var(--space-3); background: var(--surface-2); color: var(--ink); box-shadow: var(--shadow-sm); cursor: pointer; }
input[type=checkbox], input[type=radio] { accent-color: var(--accent); width: 16px; height: 16px; }
.field { margin-bottom: var(--space-4); }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--space-4); }
.fields .full { grid-column: 1 / -1; }
.check { display: flex; align-items: flex-start; gap: var(--space-2); font-weight: 500; color: var(--ink); }
.check input { margin-top: var(--space-1); }
.money-input input { font-variant-numeric: tabular-nums; }
.form-actions { display: flex; gap: var(--space-2); justify-content: flex-end; padding-top: var(--space-2); flex-wrap: wrap; }
.fieldset { border: 0; padding: 0; margin: 0 0 var(--space-8); }
.fieldset legend { font-weight: 600; font-size: var(--text-base); padding: 0; margin-bottom: var(--space-4); letter-spacing: -0.01em; }
.fieldset + .fieldset { padding-top: var(--space-6); box-shadow: var(--shadow-sm); }
.filters { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: flex-end; padding: var(--space-4) var(--space-6); }
.filters + * { box-shadow: var(--shadow-sm); }
.filters .f { min-width: 150px; }
.filters .f-grow { flex: 1; min-width: 210px; }
.filters label { font-size: var(--text-xs); margin-bottom: var(--space-1); color: var(--muted); font-weight: 500; }
.segmented { display: inline-flex; padding: var(--space-1); gap: var(--space-1); background: var(--sunken); border-radius: calc(var(--r-md) + var(--r-xs)); }
.segmented label { margin: 0; padding: var(--space-2) var(--space-3); cursor: pointer; font-weight: 550; display: flex; gap: var(--space-2); align-items: center; border-radius: var(--r-md); color: var(--muted); transition: background-color 150ms ease, color 150ms ease; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented label:has(input:checked) { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.segmented label:has(input:disabled) { opacity: 0.45; cursor: not-allowed; }
.segmented label:has(input:focus-visible) { outline: 2px solid var(--focus-color); outline-offset: var(--space-half); }

/* ---------- Feedback ---------- */
.flash { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) var(--space-4); border-radius: var(--r-md); margin-bottom: var(--space-4); font-weight: 500; transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out); }
@starting-style { .flash { opacity: 0; transform: translateY(-4px); } }
.flash-success { color: var(--good); }
.flash-success:not(.toast) { background: none; padding: 0; border-radius: 0; font-weight: 550; }
.flash-error { background: var(--bad-soft); color: var(--bad); }
.flash-warn { background: var(--warn-soft); color: var(--warn); }
.flash-info { background: var(--info-soft); color: var(--info); }

/* Typed reveal (app.js typeOut). The caret only exists while it is typing, so nothing blinks
   at a finished sentence. */
.signed-out { margin: 0 0 var(--space-4); color: var(--good); font-weight: 550; }
/* The two copies share one grid cell: the hidden one sets the height, the typed one is read. */
[data-typed].is-typing, [data-typed]:has(.typed-ghost) { display: grid; }
.typed-ghost, .typed-text { grid-area: 1 / 1; white-space: pre-wrap; }
.typed-ghost { visibility: hidden; }
.is-typing .typed-text::after { content: ""; display: inline-block; width: 1px; height: 1em; margin-left: 1px; vertical-align: -0.12em; background: currentColor; animation: caret 900ms steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }

/* ---------- Feedback: toasts, busy buttons, progress line (app.js) ---------- */

/* The deck sits above everything and out of the way of the sidebar. Toasts carry the same
   .flash classes as the banner they were promoted from, so a message looks the same either way. */
.toast-deck { position: fixed; z-index: 90; right: var(--space-4); bottom: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); width: min(360px, calc(100vw - var(--space-8))); pointer-events: none; }
.toast { pointer-events: auto; margin: 0; padding-right: var(--space-8); position: relative; box-shadow: var(--shadow-md); border: 1px solid var(--line); background-color: var(--surface); opacity: 0; transform: translateY(8px); transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out); }
/* No green card: the tone is carried by the tick and the ink. */
.toast.flash-error   { background-color: var(--bad-soft); }
.toast.flash-info    { background-color: var(--info-soft); }
.toast.is-in { opacity: 1; transform: translateY(0); }
.toast.is-leaving { opacity: 0; transform: translateY(8px); }
.toast-close { position: absolute; top: 4px; right: 4px; width: 28px; height: 28px; display: grid; place-items: center; border: 0; background: transparent; color: inherit; font-size: 20px; line-height: 1; border-radius: var(--r-sm); cursor: pointer; opacity: 0.6; }
.toast-close:hover { opacity: 1; background: color-mix(in srgb, currentColor 10%, transparent); }
.toast-close:focus-visible { outline: 2px solid var(--focus-color); outline-offset: -2px; opacity: 1; }
@media (max-width: 640px) { .toast-deck { right: var(--space-3); left: var(--space-3); bottom: var(--space-3); width: auto; } }

/* The pressed button keeps its width while it reports, so the row does not jump. */
.btn.is-busy { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-busy::after { content: ""; position: absolute; inset: 0; margin: auto; width: 15px; height: 15px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; color: var(--ink); animation: spin 700ms linear infinite; }
.btn-primary.is-busy::after, .btn-accent.is-busy::after, .btn-danger.is-busy::after { color: #fff; }
.btn.is-busy[data-busy-label] { color: inherit !important; }
.btn.is-busy[data-busy-label]::after { display: none; }
@keyframes spin { to { transform: rotate(360deg); } }
/* A form mid-submit stops accepting more input, without disabling anything: a disabled submit
   button sends no value, and several forms here carry their answer in the button. */
.is-submitting { cursor: progress; }
.is-submitting input, .is-submitting select, .is-submitting textarea { pointer-events: none; }

/* A slow page says so. It only appears once the wait is long enough to notice. */
.nav-bar { position: fixed; z-index: 100; top: 0; left: 0; height: 2px; width: 0; background: var(--accent); opacity: 0; transition: opacity 120ms linear; }
.nav-bar.is-on { opacity: 1; }
.nav-bar.is-slow { width: 85%; transition: width 6s cubic-bezier(0.1, 0.8, 0.2, 1), opacity 120ms linear; }

@media (prefers-reduced-motion: reduce) {
  .toast, .nav-bar { transition: none; }
  .btn.is-busy::after { animation-duration: 2s; }
}
.notice { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) var(--space-4); border-radius: var(--r-md); background: var(--info-soft); color: var(--info); font-size: var(--text-sm); }
.notice.warn { background: var(--warn-soft); color: var(--warn); }
.notice .icon { margin-top: var(--space-half); }
.notice a { color: inherit; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: var(--space-1); margin-bottom: var(--space-6); overflow-x: auto; scrollbar-width: none; box-shadow: inset 0 -1px 0 var(--line); }
.tabs a { padding: var(--space-3) var(--space-3); color: var(--muted); font-weight: 550; text-decoration: none; white-space: nowrap; display: inline-flex; gap: var(--space-2); align-items: center; box-shadow: inset 0 -2px 0 transparent; transition: color 150ms ease, box-shadow 200ms var(--ease-out); }
.tabs a:hover { color: var(--ink); }
.tabs a.active { color: var(--ink); box-shadow: inset 0 -2px 0 var(--cta); }
/* Inside a card the tabs wrap rather than scroll, so long translated labels stay visible. */
.card > .tabs { flex-wrap: wrap; overflow: visible; margin-bottom: 0; padding: var(--space-1) var(--space-4) 0; }
.tabs .count { background: var(--sunken); color: var(--muted); border-radius: var(--r-sm); padding: 0 var(--space-2); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }

/* ---------- Key/value ---------- */
.kv { display: grid; grid-template-columns: 136px minmax(0, 1fr); gap: var(--space-3) var(--space-4); margin: 0; }
.kv dt { color: var(--muted); font-size: var(--text-sm); }
.kv dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }

/* ---------- Timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 var(--space-6) var(--space-8); }
.timeline li::before { content: ""; position: absolute; left: 7px; top: 20px; bottom: 2px; width: 2px; border-radius: var(--r-xs); background: var(--line); }
.timeline li:last-child { padding-bottom: 0; }
.timeline li:last-child::before { display: none; }
.timeline li.done::before { background: color-mix(in srgb, var(--accent) 35%, transparent); }
.timeline .dot { position: absolute; left: 0; top: 3px; width: 16px; height: 16px; border-radius: 50%; box-shadow: inset 0 0 0 2px var(--line-strong); background: var(--surface); display: grid; place-items: center; }
.timeline li.done .dot { background: var(--accent); box-shadow: none; color: var(--surface); }
.timeline li.done .dot::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--surface); }
.timeline li.next .dot { box-shadow: inset 0 0 0 2px var(--cta); }
.timeline .t-title { font-weight: 550; }
.timeline li:not(.done) .t-title { color: var(--ink-2); }
.timeline .t-date { color: var(--muted); font-size: var(--text-xs); margin-top: var(--space-half); }
.timeline .t-desc { color: var(--ink-2); font-size: var(--text-sm); margin-top: var(--space-1); }

/* ---------- Messages ---------- */
.thread { display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-6); max-height: 60dvh; min-height: 280px; overflow-y: auto; background: var(--surface-2); border-radius: var(--r-lg) var(--r-lg) 0 0; }
.bubble { max-width: min(76%, 62ch); padding: var(--space-3) var(--space-4); border-radius: var(--r-md) var(--r-md) var(--r-md) var(--r-sm); background: var(--surface); box-shadow: var(--shadow-sm); }
.bubble.mine { align-self: flex-end; background: var(--primary); color: var(--primary-ink); border-radius: var(--r-md) var(--r-md) var(--r-sm) var(--r-md); box-shadow: none; }
.bubble .who { font-size: var(--text-xs); font-weight: 600; opacity: 0.75; margin-bottom: var(--space-1); }
.bubble .when { font-size: var(--text-xs); opacity: 0.6; margin-top: var(--space-1); }
.composer { display: flex; gap: var(--space-3); padding: var(--space-4) var(--space-4); align-items: flex-end; box-shadow: var(--shadow-sm); }
.composer textarea { min-height: 42px; height: 42px; }
.composer .btn { height: 42px; }

/* ---------- Lists ---------- */
.list { list-style: none; margin: 0; padding: 0; }
.list > li { padding: var(--space-4) var(--space-6); display: flex; gap: var(--space-4); align-items: center; box-shadow: inset 0 -1px 0 var(--line); }
.list > li:last-child { box-shadow: none; }
.list .grow { flex: 1; min-width: 0; }
.list .title { font-weight: 550; color: var(--ink); text-decoration: none; }
.list a.title:hover { text-decoration: underline; }
.list .unread { background: color-mix(in srgb, var(--info-soft) 60%, transparent); }
.list .unread .title::after { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--info); margin-left: var(--space-2); vertical-align: middle; }
.file-icon { width: 36px; height: 36px; border-radius: var(--r-md); background: var(--surface-2); box-shadow: var(--ring); color: var(--ink-2); display: grid; place-items: center; flex: none; }
.truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bars { display: flex; flex-direction: column; gap: var(--space-3); }
.bar-row { display: grid; grid-template-columns: 180px minmax(0, 1fr) 48px; gap: var(--space-4); align-items: center; }
.bar-track { height: 6px; border-radius: var(--r-md); overflow: hidden; }
.bar-track span { display: block; height: 100%; min-width: 2px; background: var(--ink-2); border-radius: var(--r-md); opacity: 0.85; }

/* ---------- Auth ---------- */
.auth { min-height: 100dvh; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
.auth-main { display: flex; flex-direction: column; padding: var(--space-8) var(--space-12); }
.auth-main .auth-body { flex: 1; display: grid; place-items: center; }
.auth-card { width: 100%; max-width: 360px; }
.auth-card h1 { font-size: var(--text-2xl); letter-spacing: -0.035em; margin-bottom: var(--space-2); }
.auth-side { margin: var(--space-3) var(--space-3) var(--space-3) 0; border-radius: var(--r-md); background: var(--brand) url('/static/img/gen/login-wall.jpg') center / cover no-repeat; color: var(--sand); padding: var(--space-12); display: flex; flex-direction: column; justify-content: flex-end; position: relative; overflow: hidden; }
.auth-side::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary) 15%, transparent) 30%, color-mix(in srgb, var(--color-primary) 88%, transparent) 100%); pointer-events: none; }
.auth-side > * { position: relative; }
.auth-side h2 { font-size: var(--text-2xl); letter-spacing: -0.035em; font-weight: 600; max-width: 18ch; line-height: 1.15; color: inherit; }
.auth-side p { opacity: 0.72; max-width: 40ch; margin-top: var(--space-3); }
.auth-figure { margin-bottom: auto; width: 100%; height: auto; max-width: 520px; border-radius: var(--r-md); box-shadow: var(--shadow-sm); }

.demo { margin-top: var(--space-8); font-size: var(--text-xs); color: var(--muted); padding: var(--space-4); border-radius: var(--r-md); background: var(--surface-2); line-height: 1.7; }
.demo code { color: var(--ink-2); }

.error-page { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-6); }
.error-page .inner { max-width: 420px; }
.error-page .code { font: 600 var(--text-sm) var(--mono); color: var(--muted); }
.error-page h1 { font-size: var(--text-2xl); margin: var(--space-3) 0 var(--space-3); letter-spacing: -0.035em; }

/* ---------- Responsive ---------- */
@media (max-width: 1100px) {
  .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-main { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: fixed; inset: 0 auto 0 0; width: 272px; z-index: var(--z-drawer); transform: translateX(-100%); transition: transform 320ms var(--ease-drawer); box-shadow: var(--shadow-md); }
  body.nav-open .sidebar { transform: none; }
  body.nav-open::after { content: ""; position: fixed; inset: 0; background: color-mix(in srgb, var(--color-black) 40%, transparent); z-index: calc(var(--z-drawer) - 1); }
  .menu-toggle { display: inline-grid; }
  .topbar-toggle-only { display: flex; }
  .topbar { padding: var(--space-3) var(--space-4); }
  .topbar .search kbd { display: none; }
  .content { padding: var(--space-2) var(--space-4) var(--space-12); }
  .g2, .g3 { grid-template-columns: minmax(0, 1fr); }
  .fields { grid-template-columns: minmax(0, 1fr); }
  .overview-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); padding: var(--space-6) var(--space-6) var(--space-1); gap: var(--space-4); }
  .overview-top > :first-child { grid-column: 1 / -1; }
  .overview-top .figure.hero { font-size: var(--text-2xl); }
  .overview-progress { padding: var(--space-4) var(--space-6) var(--space-6); }
  .overview-meta > div { padding: var(--space-4) var(--space-6); }
  .auth { grid-template-columns: minmax(0, 1fr); }
  .auth-side { display: none; }
  .auth-main { padding: var(--space-6) var(--space-4); }
  .bar-row { grid-template-columns: 120px minmax(0, 1fr) 40px; }
  .kv { grid-template-columns: 112px minmax(0, 1fr); }
  .bubble { max-width: 90%; }
  .page-head { margin-bottom: var(--space-6); }
}
@media (max-width: 560px) {
  .g4 { grid-template-columns: minmax(0, 1fr); }
  .overview-meta { grid-template-columns: minmax(0, 1fr); }
  .overview-meta > div + div { box-shadow: inset 0 1px 0 var(--line); }
  h1 { font-size: var(--text-xl); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
@media print {
  .sidebar, .topbar, .form-actions, .btn { display: none !important; }
  .shell { display: block; }
  body { background: var(--color-white); }
}

/* Help card with photo (client portal) */
.help-card { overflow: hidden; }
.help-card img { display: block; width: 100%; height: 150px; object-fit: cover; }
.help-card .card-pad { padding-top: var(--space-4); }

/* ---------- Dashboard charts (src/charts.js) ---------- */
/* Categorical slots in fixed order, validated for CVD separation on each surface (light and dark). */
:root {
  --c1: #1c7a4c; --c2: #2a78d6; --c3: #e67e22; --c4: #d55181; --c5: #7b5fc9; --c6: #1aa0a8;
  --spark-line: #5f9e7d;
  --chart-track: color-mix(in srgb, var(--color-sage) 40%, #fff);
  --heat-1: #e3efe7; --heat-2: #c4dfcd; --heat-3: #92c4a5; --heat-4: #4f9a70; --heat-5: #1c6b43;
}
@media (prefers-color-scheme: dark) {
  :root {
    --c1: #178a63; --c2: #3f86dc; --c3: #d9741f; --c4: #d5568a; --c5: #8a76dc; --c6: #2a9ab0;
    --spark-line: #4f9b74;
    --chart-track: color-mix(in srgb, var(--color-olive) 26%, #061b24);
    --heat-1: #12301f; --heat-2: #17432b; --heat-3: #1d5c3a; --heat-4: #2a7a50; --heat-5: #3f9c69;
  }
}
.g-charts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-charts .span-2 { grid-column: span 2; }
.g-charts .span-3 { grid-column: 1 / -1; }
.chart-card { display: flex; flex-direction: column; min-width: 0; }
.chart-body { padding: var(--space-4) var(--space-4) var(--space-4); flex: 1; }
.chart { margin: 0; position: relative; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; font-family: var(--font); }
.chart svg.is-compact { display: none; }
@media (max-width: 720px) {
  .chart svg.is-wide { display: none; }
  .chart svg.is-compact { display: block; }
}
.chart .grid { stroke: var(--line); stroke-width: 1; }
.chart .grid.zero { stroke: var(--line-strong); }
.chart .axis { fill: var(--muted); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.chart .value-label { fill: var(--ink-2); font-size: var(--text-xs); font-weight: 600; font-variant-numeric: tabular-nums; }
.chart .bar { transition: opacity 160ms var(--ease-out); }
.chart .line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .area { opacity: 0.16; }
.chart .dot { stroke: var(--surface); stroke-width: 2; }
.chart .goal { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 4 4; }
.chart .goal-label { fill: var(--ink-2); font-size: var(--text-xs); font-weight: 600; }
.chart .xhair { stroke: var(--line-strong); stroke-width: 1; opacity: 0; pointer-events: none; }
.chart .hit { fill: transparent; }
@media (hover: hover) {
  .chart svg:has(.hit:hover) .bar { opacity: 0.55; }
  .chart .hit:hover { fill: var(--line); }
}
/* Stat tile trend: one series, no axes. The line is a de-emphasised step of the series hue and
   the current period is full strength, so the eye lands on "now". */
/* Breakdown by currency: ranked meters, one hue. Not a pie, because amounts in different
   currencies have no common whole to be slices of. */
.metric.accent .rpie-fill { fill: var(--accent); }

.spark-figure { margin: var(--space-4) 0 0; }
/* The tiles no longer hold comparable amounts of content -- two carry a currency breakdown --
   so the trend follows the content rather than being pinned to the foot. Pinning it left a
   void mid-card on the short tiles, which reads worse than a ragged bottom edge. */
.metric .spark-figure { padding-top: var(--space-2); }
.spark { display: block; width: 100%; height: auto; overflow: visible; }
.spark-line { fill: none; stroke: var(--spark-line); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.spark-now { fill: var(--c1); stroke: var(--surface); stroke-width: 2; }
.metric.accent .spark-now { fill: var(--accent); }
.spark .hit { fill: transparent; }
@media (hover: hover) { .spark .hit:hover { fill: var(--line); } }
.metric-trend-note { font-size: var(--text-xs); color: var(--muted); margin-top: var(--space-2); }
.metric-multi .metric-value.is-other { font-size: var(--text-base); color: var(--muted); }

.chart-key { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); font-size: var(--text-xs); color: var(--ink-2); }
.chart-key li { display: inline-flex; align-items: center; gap: var(--space-2); }
.sw { width: 10px; height: 10px; border-radius: var(--r-xs); flex: none; display: inline-block; }
.sw.is-dashed { height: 0; width: 14px; border-top: 2px dashed var(--muted); border-radius: 0; }

/* Pie of one whole split into parts. Each wedge is stroked in the card colour, which is what
   separates adjacent hues -- the closest pair is ΔE 4.3 under tritanopia, so the gap and the
   legend carry identity, not the colour alone. */
.pie { margin: 0; display: grid; gap: var(--space-2); justify-items: center; }
.pie svg { display: block; width: 112px; height: auto; }
.pie-wedges { stroke: var(--surface); stroke-width: 2; }
.pie-slice { transition: opacity 160ms var(--ease-out); outline: none; }
.pie-pct { fill: #fff; font-size: 9px; font-weight: 600; font-variant-numeric: tabular-nums; pointer-events: none; }
@media (hover: hover) { .pie:hover .pie-slice { opacity: 0.55; } .pie .pie-slice:hover { opacity: 1; } }
.pie .pie-slice:focus-visible { stroke: var(--focus-color); stroke-width: 2.5; }
/* Tighter than the full-card legend: no dividers, small gaps, and a value that truncates
   rather than pushing the percentage out of the tile. */
.pie .pie-legend { width: 100%; font-size: var(--text-xs); max-height: none; overflow: visible; }
.pie .pie-legend li { grid-template-columns: 10px auto minmax(0, 1fr) auto; gap: var(--space-2); padding: 1px 0; border-bottom: 0; }
.pie .pie-legend .lg-label { font-weight: 600; color: var(--ink-2); }
.pie .pie-legend .lg-value { text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pie .pie-legend .lg-pct { min-width: 4ch; }
.pie > figcaption { font-size: var(--text-xs); color: var(--muted); text-align: center; }

/* One ratio per row, each its own whole: five currencies recovering against their own reported
   totals are five independent pies, never slices of one. */
/* A wallet address is long and unbreakable, so it is allowed to wrap mid-string rather than
   overflow the card. Staff read it back a chunk at a time when verifying. */
.acct-address { overflow-wrap: anywhere; word-break: break-all; line-height: 1.5; }

.rpies { margin: 0; display: grid; gap: var(--space-3); }
.rpies ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
.rpie { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); margin: 0 calc(-1 * var(--space-2)); border-radius: var(--r-sm); cursor: default; }
@media (hover: hover) { .rpie:hover { background: var(--surface-2); } }
.rpie:focus-visible { outline: 2px solid var(--focus-color); outline-offset: 0; }
.rpie svg { display: block; width: 24px; height: 24px; }
.rpie-track { fill: var(--chart-track); }
.rpie-fill { fill: var(--c1); }
.rpie .pie-wedges { stroke: var(--surface); stroke-width: 1.5; }
.rpie-text { display: flex; align-items: baseline; gap: var(--space-2); min-width: 0; }
.rpie-label { font-size: var(--text-xs); font-weight: 600; color: var(--ink-2); }
.rpie-amount { font-size: var(--text-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rpie-pct { font-size: var(--text-sm); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.rpies > figcaption { font-size: var(--text-xs); color: var(--muted); }

.donut { margin: 0; display: grid; gap: var(--space-4); }
.donut-ring { width: min(100%, 176px); justify-self: center; }
.donut-ring { position: relative; }
.donut-ring svg { display: block; width: 100%; height: auto; }
.donut-track { fill: none; stroke: var(--chart-track); stroke-width: 22; }
.donut .arc { fill: none; stroke-width: 22; transition: stroke-width 160ms var(--ease-out); }
@media (hover: hover) { .donut .arc:hover { stroke-width: 26; } }
.donut-center { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; pointer-events: none; }
.donut-center strong { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.donut-center span { font-size: var(--text-xs); color: var(--muted); }
.chart-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); font-size: var(--text-sm); max-height: 200px; overflow-y: auto; }
.chart-legend li { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto auto; gap: var(--space-3); align-items: center; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.chart-legend li:last-child { border-bottom: 0; }
.lg-label { min-width: 0; }
.lg-value { color: var(--muted); font-variant-numeric: tabular-nums; }
.lg-pct { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 4.5ch; text-align: right; }

.kpi-body { padding: var(--space-6) var(--space-6) var(--space-2); text-align: center; flex: 1; display: grid; align-content: center; justify-items: center; }
.kpi-value { font-size: var(--text-2xl); font-weight: 600; letter-spacing: -0.045em; line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-period { margin-top: var(--space-2); font-weight: 600; color: var(--ink-2); font-size: var(--text-sm); }
.kpi-delta { margin-top: var(--space-2); display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); flex-wrap: wrap; justify-content: center; }
.kpi-delta.up strong, .kpi-delta.up .icon { color: var(--good); }
.kpi-delta.down strong, .kpi-delta.down .icon { color: var(--bad); }
.kpi-goal { padding: var(--space-4) var(--space-6) var(--space-6); display: grid; gap: var(--space-3); border-top: 1px solid var(--line); }
.kpi-goal a { color: var(--muted); }

.goal-bar { position: relative; padding-top: var(--space-6); }
.gb-marker { position: absolute; top: 0; transform: translateX(-50%); font-size: var(--text-xs); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.gb-marker::after { content: ""; position: absolute; left: 50%; top: 17px; margin-left: calc(-1 * var(--space-1)); border: 5px solid transparent; border-top-color: var(--c1); }
.gb-track { height: 28px; border-radius: var(--r-sm); background: color-mix(in srgb, var(--c1) 26%, var(--surface)); overflow: hidden; }
.gb-track span { display: block; height: 100%; background: var(--c1); }
.gb-scale { display: flex; justify-content: space-between; margin-top: var(--space-2); font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }

.chart-filters { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.chart-filters .chip-btn { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); border-radius: var(--r-sm); font-size: var(--text-sm); font-weight: 500; color: var(--ink-2); background: var(--surface); box-shadow: var(--shadow-sm); text-decoration: none; }
.chart-filters .chip-btn[aria-pressed="true"] { background: var(--primary); color: var(--primary-ink); }

.table.pivot { font-size: var(--text-sm); }
.table.pivot th, .table.pivot td { padding: var(--space-2) var(--space-3); }
.table.pivot th:first-child, .table.pivot td:first-child { padding-left: var(--space-4); }
.table.pivot th:last-child, .table.pivot td:last-child { padding-right: var(--space-4); }
.pivot td.num, .pivot th.right { width: 13%; white-space: nowrap; text-align: right; }
.pivot .heat-1 { background: var(--heat-1); }
.pivot .heat-2 { background: var(--heat-2); }
.pivot .heat-3 { background: var(--heat-3); }
.pivot .heat-4 { background: var(--heat-4); color: var(--color-white); }
.pivot .heat-5 { background: var(--heat-5); color: var(--color-white); }

.chart-tip { position: fixed; z-index: 50; pointer-events: none; padding: var(--space-2) var(--space-3); border-radius: var(--r-md); background: var(--ink); color: var(--surface); font-size: var(--text-xs); line-height: 1.5; white-space: pre-line; font-variant-numeric: tabular-nums; box-shadow: var(--shadow-md); opacity: 0; transform: translateY(4px); transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out); max-width: 260px; }
.chart-tip.is-on { opacity: 1; transform: none; }
.chart-tip::first-line { font-weight: 600; }

@media (max-width: 1100px) {
  .g-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-charts .span-2 { grid-column: 1 / -1; }
}
@media (max-width: 720px) {
  .g-charts { grid-template-columns: minmax(0, 1fr); }
  .kpi-value { font-size: var(--text-2xl); }
}
@media (prefers-reduced-motion: reduce) {
  .chart .bar, .donut .arc, .pie-slice, .chart-tip { transition: none; }
}

/* Staff sign-in: same layout as the client page, marked clearly as the staff entrance. */
.auth-badge { display: inline-flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); padding: var(--space-1) var(--space-3); border-radius: var(--r-sm); font-size: var(--text-xs); font-weight: 600; color: var(--primary-ink); background: var(--primary); }
.auth-staff .auth-side { background-image: none; }

/* ---------- Reports: colour-coded sections ---------- */
.report-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: calc(-1 * var(--space-1)) 0 var(--space-6); position: sticky; top: 0; z-index: 5; padding: var(--space-2) 0; background: var(--bg); }
.report-tabs a { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4); border-radius: var(--r-sm); background: var(--surface); box-shadow: var(--shadow-sm); color: var(--ink-2); font-size: var(--text-sm); font-weight: 500; text-decoration: none; transition: box-shadow 160ms var(--ease-out); }
.report-tabs a:hover { box-shadow: var(--shadow-sm), inset 0 0 0 1.5px var(--accent); }
.report-tabs .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); }
.report { gap: var(--space-12); }
.report-section { scroll-margin-top: var(--space-16); }
.report-section > .grid + .grid, .report-section > .card + .card { margin-top: var(--space-6); }
.report-section .g-charts { align-items: stretch; }
.report-head { display: flex; align-items: flex-start; gap: var(--space-4); margin-bottom: var(--space-4); }
.report-head h2 { font-size: var(--text-lg); letter-spacing: -0.02em; }
.report-head p { color: var(--muted); font-size: var(--text-sm); margin-top: var(--space-1); }
.report-section .card { box-shadow: var(--shadow-sm), inset 0 3px 0 var(--accent); }
.report-section .card-head h3 { font-size: var(--text-base); }
.kpi-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border-top: 1px solid var(--line); }
.kpi-facts div { padding: var(--space-3) var(--space-4); }
.kpi-facts div + div { border-left: 1px solid var(--line); }
.kpi-facts dt { font-size: var(--text-xs); color: var(--muted); }
.kpi-facts dd { margin: var(--space-1) 0 0; font-size: var(--text-base); font-weight: 600; font-variant-numeric: tabular-nums; }

.hbars ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
.hbars li { display: grid; grid-template-columns: minmax(110px, 22%) minmax(0, 1fr) minmax(70px, auto); align-items: center; gap: var(--space-4); padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.hbars li:last-child { border-bottom: 0; }
.hb-label { font-size: var(--text-sm); font-weight: 500; min-width: 0; }
.hb-label small { display: block; color: var(--muted); font-weight: 400; font-size: var(--text-xs); }
.hb-track { display: flex; gap: var(--space-1); height: 18px; }
.hb-seg { display: block; height: 100%; min-width: 3px; transition: opacity 160ms var(--ease-out); }
.hb-seg:first-child { border-radius: var(--r-xs) 0 0 var(--r-xs); }
.hb-seg:last-child { border-radius: 0 var(--r-xs) var(--r-xs) 0; }
.hb-seg:only-child { border-radius: var(--r-xs); }
@media (hover: hover) { .hbars ul:has(.hb-seg:hover) .hb-seg:not(:hover) { opacity: 0.55; } }
.hb-value { font-size: var(--text-sm); font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 720px) {
  .hbars li { grid-template-columns: minmax(0, 1fr) auto; }
  .hb-track { grid-column: 1 / -1; order: 3; }
  .kpi-facts { grid-template-columns: minmax(0, 1fr); }
  .kpi-facts div + div { border-left: 0; border-top: 1px solid var(--line); }
}

/* ---------- Utilities ---------- */
/* Token-based helpers that replace inline styles. They win over component rules, as the inline styles did. */
.mt-0 { margin-top: 0 !important; } .mt-1 { margin-top: var(--space-1) !important; } .mt-2 { margin-top: var(--space-2) !important; } .mt-3 { margin-top: var(--space-3) !important; } .mt-4 { margin-top: var(--space-4) !important; } .mt-6 { margin-top: var(--space-6) !important; } .mt-8 { margin-top: var(--space-8) !important; } .mt-12 { margin-top: var(--space-12) !important; } .mt-16 { margin-top: var(--space-16) !important; }
.mb-0 { margin-bottom: 0 !important; } .mb-1 { margin-bottom: var(--space-1) !important; } .mb-2 { margin-bottom: var(--space-2) !important; } .mb-3 { margin-bottom: var(--space-3) !important; } .mb-4 { margin-bottom: var(--space-4) !important; } .mb-6 { margin-bottom: var(--space-6) !important; } .mb-8 { margin-bottom: var(--space-8) !important; } .mb-12 { margin-bottom: var(--space-12) !important; } .mb-16 { margin-bottom: var(--space-16) !important; }
.gap-1 { gap: var(--space-1) !important; } .gap-2 { gap: var(--space-2) !important; } .gap-3 { gap: var(--space-3) !important; } .gap-4 { gap: var(--space-4) !important; }
.px-2 { padding-inline: var(--space-2) !important; } .py-1 { padding-block: var(--space-1) !important; } .mx-auto { margin-inline: auto !important; }
.text-center { text-align: center !important; } .text-lg { font-size: var(--text-lg) !important; } .text-ink { color: var(--ink) !important; } .text-sand { color: var(--sand) !important; }
.strike { text-decoration: line-through; } .clip { overflow: hidden; } .ellipsis { text-overflow: ellipsis; } .block { display: block; }
.on-cta { background: var(--cta) !important; color: var(--cta-ink) !important; }
.badge-on-dark { background: color-mix(in srgb, var(--sand) 14%, transparent); color: var(--sand); }
.bg-c1 { background: var(--c1); } .bg-c2 { background: var(--c2); } .bg-c3 { background: var(--c3); } .bg-c4 { background: var(--c4); } .bg-c5 { background: var(--c5); } .bg-c6 { background: var(--c6); }

/* ---------- Client stage tracker (the five stages in constants.js CLIENT_STAGES) ---------- */
.stages .stage-track { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2); }
.stage-track li { position: relative; display: grid; justify-items: center; gap: var(--space-2); text-align: center; padding-top: var(--space-1); }
/* The rail runs behind the markers, through their centres. */
.stage-track li::before, .stage-track li::after { content: ""; position: absolute; top: calc(var(--space-1) + var(--space-3)); transform: translateY(-50%); height: 2px; background: var(--line-strong); }
.stage-track li::before { left: 0; right: 50%; }
.stage-track li::after { left: 50%; right: calc(-1 * var(--space-2)); }
.stage-track li:first-child::before, .stage-track li:last-child::after { display: none; }
.stage-track .done::before, .stage-track .done::after, .stage-track .now::before { background: var(--accent); }
.stage-mark { position: relative; z-index: 1; display: grid; place-items: center; width: var(--space-6); height: var(--space-6); border-radius: 50%; background: var(--surface); box-shadow: inset 0 0 0 2px var(--line-strong); color: var(--muted); }
.stage-track .done .stage-mark { background: var(--accent); color: var(--color-white); box-shadow: none; }
.stage-track .now .stage-mark { box-shadow: inset 0 0 0 2px var(--accent); }
.stage-track .now .stage-mark::after { content: ""; width: var(--space-2); height: var(--space-2); border-radius: 50%; background: var(--accent); }
.stage-label { font-size: var(--text-xs); color: var(--muted); }
.stage-track .done .stage-label { color: var(--ink-2); }
.stage-track .now .stage-label { color: var(--ink); font-weight: var(--weight-heading); }
.stage-blurb { margin: var(--space-6) 0 0; color: var(--ink-2); max-width: 70ch; }
@media (max-width: 720px) {
  .stages .stage-track { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .stage-track li { grid-template-columns: var(--space-6) minmax(0, 1fr); justify-items: start; text-align: left; align-items: center; gap: var(--space-3); padding: var(--space-1) 0; }
  .stage-track li::before, .stage-track li::after { top: auto; left: calc(var(--space-6) / 2); right: auto; width: 2px; height: auto; transform: translateX(-50%); }
  .stage-track li::before { top: 0; bottom: 50%; }
  .stage-track li::after { top: 50%; bottom: 0; }
}

/* ---------- Intake wizard ---------- */
.wizard-steps ol { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-2); }
.wizard-steps li { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3); border-radius: var(--r-md); background: var(--surface); color: var(--muted); font-size: var(--text-xs); }
.wizard-steps li a { display: flex; align-items: center; gap: var(--space-2); color: inherit; text-decoration: none; }
.wizard-steps .wz-num { flex: none; display: grid; place-items: center; width: var(--space-6); height: var(--space-6); border-radius: 50%; background: var(--surface-2); color: var(--muted); font-weight: var(--weight-heading); }
.wizard-steps .done { color: var(--ink-2); }
.wizard-steps .done .wz-num { background: var(--accent); color: var(--color-white); }
.wizard-steps .now { color: var(--ink); font-weight: var(--weight-heading); box-shadow: inset 0 0 0 2px var(--accent); }
.wizard-steps .now .wz-num { background: var(--accent); color: var(--color-white); }
.row-set { border: 0; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.row-set legend { font-weight: var(--weight-heading); color: var(--ink); padding: 0 0 var(--space-3); }
.row-set + .row-set { margin-top: var(--space-8); }
.intake .card, .intake .wizard-steps { max-width: 88ch; }
.evidence-row { display: grid; gap: var(--space-4); padding: var(--space-4); border-radius: var(--r-md); background: var(--surface-2); }
.er-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.er-num { font-size: var(--text-xs); font-weight: var(--weight-heading); color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.04em; }
.check-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-2); }
.check { display: flex; align-items: center; gap: var(--space-2); font-weight: var(--weight-body); margin: 0; }
.label-like { display: block; font-weight: var(--weight-medium); font-size: var(--text-sm); margin-bottom: var(--space-2); color: var(--ink-2); }
.field-error { color: var(--bad); font-size: var(--text-xs); margin: var(--space-1) 0 0; }
.intake-actions { padding-top: var(--space-2); }
.truncate { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wz-count { display: none; }
@media (max-width: 720px) {
  .wizard-steps ol { grid-template-columns: minmax(0, 1fr); }
  .wizard-steps li:not(.now):not(.done) { display: none; }
  .wz-count { display: block; margin: var(--space-2) 0 0; font-size: var(--text-xs); color: var(--muted); }
}
