/* NEXUS Client Delivery — visual identity matches is-cannabis.com
   (Space Grotesk, navy + gold). Redesigned 12.09.2026 for the client
   portal's ergonomics/consistency pass: a single typeface (was Space
   Grotesk + Open Sans), one shared spacing scale, moderate/consistent
   corner radii, and a light, sober surface everywhere -- including the
   nav rail, previously a full-height dark-navy block. Brief: "calme,
   précis, lisible" and no large dark surfaces, no decorative gradients,
   shadows kept to near-nothing. These are SHARED tokens (client, admin,
   regulator and agent portals all load this one file) -- refining them
   here is a deliberate one-system choice, not scope creep: the same
   tokens now read calmer everywhere, and no admin-specific selector
   (.data-table, .tabs, .pipeline-item, .editable-value) was restructured,
   only the shared color/type/radius/shadow tokens they already inherit.
   Login page keeps its dark "brand hero" register on purpose -- it's a
   single full-screen moment, not a working surface, and out of this
   pass's scope. Same class names/IDs; dashboard.js/admin-client.js own
   the markup, this file only owns presentation. */

@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap');

:root {
  /* Dark surface -- reserved for the login page and toast only now
     (12.09.2026: the sidebar moved to the light surface below -- a
     full-height dark rail read as exactly the "grand aplat sombre" the
     brief asks to avoid). */
  --navy-950: #060d19;
  --navy-900: #08101f;
  --navy-850: #0d1829;
  --navy-800: #121e33;
  --navy-700: #1e2d42;
  --navy-border: #2a3d56;
  --text-hi: #edf0f7;
  --text-muted: #b0c0d4;
  --text-dim: #7c8ba3;

  /* Light surface -- everything else, including the nav rail as of
     12.09.2026. --paper carries a faint warm tint (not neutral grey) so
     it reads as "chosen," per the brief's "fond général clair légèrement
     teinté." */
  --paper: #f7f6f2;
  --surface: #ffffff;
  --border: #e3e1da;
  --border-strong: #d3d0c6;
  --ink: #14181f;
  --ink-muted: #5c6470;
  --ink-dim: #6e7480;    /* WCAG AA fix (05.09.2026): #929aa6 measured 2.84:1 on white, failing even the 3:1 large-text floor -- this labels/eyebrows/step-meta color is real body-adjacent text, not decorative, and needs the 4.5:1 normal-text threshold. #6e7480 measures ~4.7:1. */

  /* Brand accent -- the ONE accent colour in the system (verified live
     against is-cannabis.com: #e8a830 gold button fill, #08101f
     text-on-gold). Every other colour on the page is either a neutral
     (ink/paper/border) or a semantic state colour (success/danger),
     never a second decorative accent. */
  --gold: #e8a830;
  --gold-hover: #cf9426;
  --gold-text-on: #08101f;
  --gold-ink: #96650f;    /* WCAG AA fix (05.09.2026): #a97315 measured 4.08:1 on white -- just under the 4.5:1 normal-text floor (badge-gold text, ghost-button labels, link hovers are all normal-weight/size, not "large text" under WCAG's 18.66px-bold threshold). #96650f measures ~5.0:1. The fill --gold is unaffected -- button backgrounds pass easily since the dark navy text sits on top of it, not white. */
  --gold-tint: rgba(232, 168, 48, 0.12);

  --danger: #c2412e;
  --danger-tint: rgba(194, 65, 46, 0.09);
  --success: #1f7a56;
  --success-tint: rgba(31, 122, 86, 0.10);
  --info: #3d6a94;         /* "Needs verification" / neutral-informational state -- distinct from success/danger/gold so a verification flag never reads as a sale-probability colour. */
  --info-tint: rgba(61, 106, 148, 0.09);

  --neutral-tile: #eef0f3;   /* badge base / roadmap-node idle fill -- named so dark mode can override it, was hardcoded before 05.09.2026 */
  --hover-wash: #fdf8ee;     /* btn-secondary hover -- same reason */

  /* One typeface, few weights (12.09.2026: was a Space Grotesk/Open Sans
     pairing) -- Space Grotesk reads fine at body sizes and is the one
     already verified against the live ISC brand, so consolidating onto
     it (instead of introducing a generic body face) keeps the brand
     anchor while meeting "une seule famille typographique." --font-body
     is kept as an alias so nothing else in this file has to change. */
  --font-display: 'Space Grotesk', sans-serif;
  --font-body: 'Space Grotesk', sans-serif;

  /* Spacing scale (12.09.2026) -- shared rhythm for the client portal's
     new/updated components (hero, roadmap, cards, panel). Existing
     hand-placed pixel values elsewhere in this file are left as-is. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;

  /* Radius scale -- moderate, and identical for components of the same
     kind: -sm for controls/badges/chips, (existing --radius) for
     buttons/inputs, --radius-lg for cards/panels/hero. Badges moved off
     a full 999px pill onto --radius-sm as part of this pass. */
  --radius-sm: 6px;
  --radius: 8px;
  --radius-lg: 12px;
  --shadow-card: 0 1px 2px rgba(20, 24, 31, 0.04), 0 1px 4px rgba(20, 24, 31, 0.03);   /* 12.09.2026: a flat border-only card read as an unfinished wireframe at production scale -- this whisper of shadow ("ombres très discrètes", not absent) is what actually reads as a considered, lifted surface in a professional product. */
  --shadow-modal: 0 2px 8px rgba(20, 24, 31, 0.06), 0 12px 28px rgba(20, 24, 31, 0.10);   /* softened 12.09.2026 -- "ombres très discrètes" */
  --shadow-panel: -4px 0 24px rgba(20, 24, 31, 0.08);
  --shadow-dark-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.28);
}

/* Dark mode -- user-toggled (see theme.js), persisted per-browser via
   localStorage, applied as data-theme on <html>. Values drawn from the
   Linear-inspired direction validated in the design canvas: hairline
   borders instead of shadows for depth, no heavy drop shadow, the base
   --gold read directly as text (no light-mode darkening needed --
   that adjustment existed only to fix contrast against WHITE). Sidebar
   and login are unaffected -- they're already dark-navy always, not
   wired to this toggle. */
:root[data-theme="dark"] {
  --paper: #08101f;
  --surface: #0d1829;
  --border: rgba(237, 240, 247, 0.09);
  --border-strong: rgba(237, 240, 247, 0.18);
  --ink: #edf0f7;
  --ink-muted: #b0c0d4;
  --ink-dim: #8b95a8;

  --gold-hover: #f0bb52;
  --gold-ink: #e8a830;
  --gold-tint: rgba(232, 168, 48, 0.15);

  --danger: #e2604f;
  --danger-tint: rgba(226, 96, 79, 0.16);
  --success: #4fae8a;
  --success-tint: rgba(79, 174, 138, 0.16);
  --info: #6f9dc7;    /* WCAG AA fix (12.09.2026): the light-mode #3d6a94 measures ~3.2:1 on the dark surface, under the 4.5:1 normal-text floor -- #6f9dc7 measures ~6.2:1. Same pattern as the existing danger/success dark-mode overrides above. */
  --info-tint: rgba(111, 157, 199, 0.16);

  --neutral-tile: #121e33;
  --hover-wash: #16233a;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 6px rgba(0, 0, 0, 0.2);
  --shadow-modal: 0 12px 32px rgba(0, 0, 0, 0.5), 0 32px 64px rgba(0, 0, 0, 0.45);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;   /* 12.09.2026: was 15px -- brief asks for a comfortable 16px body */
  line-height: 1.6;
  min-height: 100vh;
}

a { color: inherit; text-decoration: none; }

*:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 0.5em;
  text-wrap: balance;
}

h1 { font-size: 26px; letter-spacing: -0.01em; }
h2 { font-size: 19px; }
h3 { font-size: 13px; letter-spacing: 0.03em; text-transform: uppercase; color: var(--ink-dim); font-weight: 600; }

p { margin: 0 0 1em; color: var(--ink-muted); max-width: 68ch; }   /* line-length cap (12.09.2026) so long factual summaries stay readable */

button, .btn {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  border-radius: var(--radius);
  padding: 12px 20px;
  min-height: 44px;   /* 12.09.2026: comfortable tap target floor */
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
button:active, .btn:active { transform: translateY(1px); }
button:disabled, .btn:disabled { cursor: not-allowed; }

.btn-primary {
  background: var(--gold);
  color: var(--gold-text-on);
}
.btn-primary:hover { background: var(--gold-hover); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--border-strong);
}
.btn-secondary:hover { border-color: var(--gold); background: var(--hover-wash); }

.btn-ghost {
  background: transparent;
  color: var(--gold-ink);
  padding: 6px 10px;
  min-height: 36px;   /* inline text-style action, not a primary control -- still keyboard-reachable, just not held to the 44px floor */
}
.btn-ghost:hover { color: var(--gold-hover); }

/* Icon-only control (panel/modal close, mobile nav toggle) -- square,
   44x44 minimum, single icon centred. Shares the icon sprite (see
   dashboard.html's #icon-sprite) so every icon in the app comes from
   one drawn set. */
.btn-icon {
  width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--ink-dim);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-icon:hover { background: var(--paper); color: var(--ink); }
.icon { width: 18px; height: 18px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.icon-sm { width: 14px; height: 14px; }

input, textarea, select {
  font-family: var(--font-body);
  font-size: 14px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--ink);
  padding: 10px 12px;
  width: 100%;
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-tint);
}
label {
  display: block;
  font-size: 13px;
  color: var(--ink-muted);
  margin-bottom: 6px;
  font-family: var(--font-display);
}
.field { margin-bottom: 16px; }

/* ── Login page (kept on the dark/gold "hero" register — first brand
   impression, matches is-cannabis.com's own hero band) ──────────── */

.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 20% 20%, rgba(232, 168, 48, 0.08), transparent 42%),
    radial-gradient(circle at 82% 78%, rgba(232, 168, 48, 0.05), transparent 38%),
    var(--navy-900);
  padding: 24px;
}

.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--navy-850);
  border: 1px solid var(--navy-border);
  border-radius: var(--radius-lg);
  padding: 40px 36px;
  box-shadow: var(--shadow-dark-card);
}

.login-logo {
  display: block;
  width: 56px;
  height: 56px;
  margin: 0 auto 20px;
}

.login-card h1 {
  text-align: center;
  font-size: 22px;
  margin-bottom: 4px;
  color: var(--text-hi);
}

.login-sub {
  text-align: center;
  font-size: 13px;
  margin-bottom: 28px;
  color: var(--text-muted);
}

.login-card label { color: var(--text-muted); }
.login-card input { background: var(--navy-800); border-color: var(--navy-border); color: var(--text-hi); }
.login-card input:focus { box-shadow: 0 0 0 3px rgba(232, 168, 48, 0.15); }

.error-banner {
  background: rgba(226, 96, 79, 0.14);
  border: 1px solid rgba(226, 96, 79, 0.4);
  color: #f3a99c;
  font-size: 13px;
  padding: 10px 14px;
  border-radius: var(--radius);
  margin-bottom: 16px;
  display: none;
}
.error-banner.visible { display: block; }

/* ── Dashboard shell ────────────────────────────────────────────── */

.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

/* Nav rail (12.09.2026: moved off a full-height dark-navy block onto the
   same light surface as the rest of the app -- a persistent dark panel
   read as exactly the "grand aplat sombre" the brief asks to avoid).
   Shared across all four portals (client/admin/regulator/agent); the
   gold accent on the active item is the one place colour still marks
   state here, matching the "une seule couleur d'accent" rule. */
.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
}

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 8px var(--space-6);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}
.sidebar-logo img { width: 28px; height: 28px; }
.sidebar-logo span {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.03em;
  color: var(--ink);
}

.nav-item {
  /* 12.09.2026: markup moved from <div onclick> to a real <button> for
     full keyboard navigation -- this resets the native button chrome
     back to plain nav-row styling. */
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 12px;
  min-height: 44px;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  color: var(--ink-muted);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  margin-bottom: 2px;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.nav-item:hover { background: var(--paper); color: var(--ink); }
.nav-item.active { background: var(--gold-tint); color: var(--gold-ink); font-weight: 600; box-shadow: inset 3px 0 0 var(--gold); }

.sidebar-footer {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.sidebar-footer .client-name {
  font-size: 13px;
  color: var(--ink-dim);
  margin-bottom: 10px;
  overflow-wrap: break-word;
}

.main {
  padding: var(--space-8) var(--space-8);
  max-width: 980px;
  overflow-x: auto;
  background: var(--paper);   /* 12.09.2026: dropped the decorative radial-gradient wash */
}
/* Client portal only (dashboard.html carries "main main-client").
   12.09.2026 correction: 720px flush against the sidebar left the rest
   of any real monitor (a bare 720 of 1920px) as a lopsided void on the
   right -- exactly the "ne prend pas tout l'écran" complaint. Widened to
   a still-readable-but-substantial 960px and CENTRED in the remaining
   grid track (margin:auto) so the extra room reads as considered page
   margins at any width, not an accident. Admin/regulator/agent keep the
   shared .main's own flush-left 980px (or admin's 1180px via
   .main-admin) -- unchanged. */
.main-client { width: 100%; max-width: 960px; margin: 0 auto; }   /* width: a page with little content (the Dashboard) must not shrink-wrap it */

.page-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-6);
}

/* Section title row (12.09.2026) -- a bold, full-weight heading with a
   hairline rule underneath, for a page-level section (e.g. "Roadmap")
   that sits outside any card. Reads as a confident, considered section
   break rather than the small uppercase eyebrow labels used for
   in-card meta (.stat-label, .task-column-label, etc). */
.section-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-strong);
}
.section-title-row h2 { margin: 0; }

/* Flat, hairline-divided stat row (05.09.2026, Linear-inspired direction
   -- replaced the earlier individually-boxed "Bento" tiles: one row,
   dividers between values, no per-item border/background/radius). Used
   in the client roadmap header and admin's Company Details / Live
   Objective overview -- same classes, so this one change covers both. */
.stat-grid {
  display: flex;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  margin-top: 16px;
}
.stat-tile {
  flex: 1;
  min-width: 130px;
  padding: 14px 20px;
  border-right: 1px solid var(--border);
}
.stat-tile:last-child { border-right: none; }
.stat-label {
  display: block;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 4px;
}
.stat-value {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  font-family: var(--font-display);
  overflow-wrap: break-word;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 4px 10px;
  border-radius: var(--radius-sm);   /* 12.09.2026: was a full 999px pill -- moderate radius, matching every other component's corners */
  background: var(--neutral-tile);
  color: var(--ink-muted);
}
.badge[hidden] { display: none; }   /* the class's display would otherwise beat the hidden attribute (a count badge with nothing to count) */
.badge-gold { background: var(--gold-tint); color: var(--gold-ink); }
.badge-success { background: var(--success-tint); color: var(--success); }
.badge-danger { background: var(--danger-tint); color: var(--danger); }
.badge-info { background: var(--info-tint); color: var(--info); }

/* Quiet, text-only status voice (12.09.2026) -- for signals that
   describe the CLIENT's own state (shortlisted, priority) or a
   verification level, never ISC's qualification of an opportunity. Kept
   visually lighter than .badge on purpose: a coloured pill for
   "Confidence" reads like a sales-probability score, which the brief
   explicitly asks to avoid -- confidence and verification level show as
   quiet labelled text with an icon instead. */
.quiet-flag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-dim);
}
.quiet-flag .icon { color: var(--ink-dim); }
.quiet-flag--accent { color: var(--gold-ink); }
.quiet-flag--accent .icon { color: var(--gold-ink); }
.quiet-flag--info { color: var(--info); }
.quiet-flag--info .icon { color: var(--info); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 24px;
  margin-bottom: 16px;
  box-shadow: var(--shadow-card);
}
.card-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.card h3.card-name {
  text-transform: none;
  font-size: 16px;
  color: var(--ink);
  letter-spacing: normal;
  margin: 0;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: var(--ink-dim);
}

.spinner {
  width: 24px;
  height: 24px;
  border: 2px solid var(--border);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  margin: 40px auto;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Objective hero (12.09.2026 redesign): back onto the light surface --
   the dark-navy band (06.09.2026) was exactly the kind of "grand aplat
   sombre" this brief asks to avoid, and its decorative radial-gradient
   flourish is gone too. Definition now comes from the border, like every
   other card. */
.objective-hero {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-7) var(--space-6);
  margin-bottom: var(--space-7);
}
.objective-hero-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.hero-eyebrow {
  /* 12.09.2026: gold moved to ink-dim -- a plain section label isn't a
     status or an action, so it shouldn't compete with the real gold
     accents (the Active badge, Next Milestone, buttons) for attention.
     Gold now reads as "this matters" precisely because it isn't spent
     on decoration. */
  display: block;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink-dim);
  margin-bottom: 6px;
}
.objective-hero h1 { color: var(--ink); margin-bottom: 0; }
.objective-hero .hero-desc {
  color: var(--ink-muted);
  font-size: 15px;
  max-width: 62ch;
  margin: 10px 0 var(--space-6);
}
/* Bento stat tiles (12.09.2026 v2, client hero only) -- separate cards
   with their own border/radius/shadow and a gap between them, replacing
   the shared hairline-divided row. Direct feedback against a reference
   (a real-estate ops dashboard): its icon tiles are individually boxed,
   not one row with internal dividers -- and gold is reserved there for
   a true minority accent (it appears twice on the whole screen), with
   black/ink carrying the graphic weight everywhere else. So the icon
   chip here goes monochrome (ink on a flat neutral tile, no gold tint)
   -- gold stays reserved for real actions (buttons, active nav, the
   Next Milestone callout) rather than decorating every icon. */
.objective-hero .stat-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  border: none;
  margin-top: 0;
}
.objective-hero .stat-tile {
  flex: 1;
  min-width: 130px;
  padding: var(--space-4) var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.stat-tile-icon {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--neutral-tile);
  border-radius: var(--radius-sm);
  color: var(--ink);
  margin-bottom: var(--space-3);
}
.stat-tile-icon .icon { width: 15px; height: 15px; }
.objective-hero .stat-value { font-size: 18px; }

/* Next Milestone callout (12.09.2026) -- pulled out of the generic
   stat-grid into its own row so it visibly outweighs everything else in
   the hero, per the brief: "Le prochain jalon doit attirer davantage
   l'attention que le compteur d'étapes." Icon + label + the milestone
   text itself, set larger than any stat-value in the row below. */
.next-milestone {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: var(--space-4) var(--space-5);
  background: var(--gold-tint);
  border-radius: var(--radius);
  margin-bottom: var(--space-5);
}
.next-milestone .icon { color: var(--gold-ink); margin-top: 2px; flex-shrink: 0; }
.next-milestone-body { min-width: 0; }
.next-milestone-label {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 2px;
}
.next-milestone-text { font-size: 16px; font-weight: 600; color: var(--ink); }

/* Action-needed callout (12.09.2026) -- "Mets en évidence une demande au
   client lorsqu'elle existe." Sits right under the hero, above the
   roadmap, in the one other place colour is allowed to carry meaning
   (a request pending on the client vs. the sober no-action state). */
.action-needed {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-6);
}
.action-needed--pending {
  background: var(--surface);
  border: 1px solid var(--gold);
  box-shadow: inset 3px 0 0 var(--gold);
}
.action-needed--pending .icon { color: var(--gold-ink); }
.action-needed--none {
  background: transparent;
  border: 1px dashed var(--border-strong);
  color: var(--ink-dim);
}
.action-needed--none .icon { color: var(--ink-dim); }
.action-needed-label {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;   /* 26.09.2026: sentence case, like every other label of the portal now */
  color: var(--gold-ink);
  margin-bottom: 2px;
}
.action-needed--none .action-needed-label { color: var(--ink-dim); }
.action-needed-text { font-size: 15px; font-weight: 500; color: var(--ink); }
.action-needed--none .action-needed-text { font-weight: 400; color: var(--ink-dim); }

/* Roadmap progress summary -- deliberately quiet (12.09.2026: reduced
   from a bold bar+label row) so it never outweighs Next Milestone above.
   A plain count of completed steps, never framed as a probability. */
.roadmap-progress { display: flex; align-items: center; gap: 10px; margin-bottom: var(--space-4); }
.roadmap-progress-bar { width: 64px; height: 3px; border-radius: 2px; background: var(--border); overflow: hidden; flex-shrink: 0; }
.roadmap-progress-fill { height: 100%; background: var(--border-strong); border-radius: 2px; transition: width 0.3s ease; }
.roadmap-progress-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-dim);
  white-space: nowrap;
}

/* Roadmap (Objective Steps) -- Linear-inspired flat row list (05.09.2026):
   one bordered panel, hairline dividers between rows, no connecting
   timeline line, small inline status indicator instead of a large
   circular node. Replaced the earlier connected-node timeline, which
   read as a generic "stepper" pattern rather than a considered list. */
.roadmap-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.roadmap { list-style: none; padding: 0; margin: 0; }
.roadmap-step {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.roadmap-step:last-child { border-bottom: none; }
/* The step actually being worked gets a subtle full-row tint -- "you
   are here" should be unmissable at a glance down the list. */
.roadmap-step.is-active { background: var(--gold-tint); }

.roadmap-node {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--neutral-tile);
  border: 1.5px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10.5px;
  color: var(--ink-dim);
  flex-shrink: 0;
  margin-top: 1px;
}
.roadmap-node.active {
  background: transparent;
  border-color: var(--gold);
  font-size: 0;   /* hides the sequence-number text node -- the open ring + inner dot (::before) is the whole "active" indicator, showing both would look cluttered */
}
.roadmap-node.active::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
}
.roadmap-node.done {
  background: var(--success);
  border-color: var(--success);
  color: #fff;
}
.roadmap-content { flex: 1; min-width: 0; }

/* Editorial roadmap steps (06.09.2026 redesign): a large ghost sequence
   numeral anchors each row instead of the small circular node, and the
   active step gets a solid gold rail down its left edge rather than
   just a background tint -- a more considered, less generic "stepper"
   feel. Scoped to .roadmap-step--editorial (client roadmap only, for
   now) so admin's existing .roadmap-node markup/rendering is
   untouched -- deliberately not a shared default. */
.roadmap-step--editorial {
  position: relative;
  padding: 18px 20px 18px 68px;
}
.roadmap-step--editorial::before {
  content: attr(data-seq);
  position: absolute;
  left: 20px;
  top: 15px;
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 700;
  line-height: 1;
  color: var(--border-strong);
}
.roadmap-step--editorial.is-done::before { color: var(--success); opacity: 0.6; }
.roadmap-step--editorial.is-active {
  background: var(--gold-tint);
  box-shadow: inset 4px 0 0 var(--gold);
}
.roadmap-step--editorial.is-active::before { color: var(--gold); opacity: 1; }

/* Accordion (05.09.2026): only the In Progress step's details show by
   default -- every other step collapses to title + type + status, and
   any row can be clicked open. Reduces a 13-step list to something
   actually scannable instead of showing every advisory record and task
   list at once. A real <button> (not a div with onclick) so it's
   reachable and activatable by keyboard, not just mouse/touch. */
.roadmap-step-header {
  display: block;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.roadmap-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.roadmap-chevron {
  display: inline-block;
  font-size: 11px;
  color: var(--ink-dim);
  margin-right: 6px;
  transition: transform 0.15s ease;
  flex-shrink: 0;
}
.roadmap-step.is-expanded .roadmap-chevron { transform: rotate(90deg); }
.roadmap-details { display: none; margin-top: 12px; }
.roadmap-step.is-expanded .roadmap-details { display: block; }

.step-title { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--ink); }
.step-meta { font-size: 12px; color: var(--ink-dim); margin-top: 3px; }
.blocking-line { color: var(--danger); font-weight: 600; }

/* Outcome / Established / Ruled Out — a labelled advisory record block,
   rendered only when at least one is populated (see dashboard.js's
   renderAdvisoryBlock()). Admin edits these via the step form instead
   of a read-only block -- see admin-client.js's editStep(). */
.advisory-block {
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--border);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.advisory-row label {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
  display: block;
  margin-bottom: 2px;
}
.advisory-row p { font-size: 13px; color: var(--ink); margin: 0; white-space: pre-wrap; }

/* Who does a step and how we will know it is done (26.09.2026): plain definition rows, quieter than the gold advisory record. */
.step-plan { margin: 10px 0 0; display: flex; flex-direction: column; gap: 6px; }
.step-plan > div { display: grid; grid-template-columns: 84px 1fr; gap: 10px; align-items: baseline; }
.step-plan dt { font-size: 12px; font-weight: 600; color: var(--ink-dim); }
.step-plan dd { margin: 0; font-size: 13px; color: var(--ink); }

/* "What success looks like" in the hero (26.09.2026): the client reads what the objective is measured by before confirming it. */
.success-criteria { margin: 0 0 var(--space-5); max-width: 62ch; }
.success-criteria-label { font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-dim); margin-bottom: 4px; }
.success-criteria p { margin: 0; font-size: 14px; color: var(--ink); white-space: pre-wrap; }
/* Confirm or suggest a change (26.09.2026, dashboard.js renderFeedbackBlock for a step, objective-summary.js renderObjectiveReview for the objective):
   both answers are real buttons; ISC's replies stack underneath, newest first. The step row is restyled with the objective components below. */
.btn-sm { padding: 6px 12px; min-height: 36px; font-size: 13px; }
.fb-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.fb-confirmed { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--success); }
.fb-stale { font-size: 13px; color: var(--ink-muted); }
.fb-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.fb-item { padding: 10px 12px; background: var(--paper); border: 1px solid var(--border); border-radius: var(--radius); }
.fb-item-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fb-item-date { font-size: 12px; color: var(--ink-dim); }
.fb-item-text, .fb-item-reply { margin: 6px 0 0; font-size: 13px; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.fb-item-reply { padding-left: 10px; border-left: 3px solid var(--gold); }
.field-hint { margin-top: 4px; font-size: 12px; color: var(--ink-dim); text-align: right; }
.field-note { margin: 4px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-muted); }

.reg-portal-status { font-size: 13px; color: var(--ink-dim); margin-bottom: 8px; }
/* Fixed colors, not theme tokens (28.09.2026 fix): --surface-2 does not exist in this file, so this always
   fell back to a light grey background while its text inherited --ink -- near-white on near-white in dark
   mode, unreadable. A one-off "copy this now" reveal reads fine as a plain warm callout in either theme. */
.reg-portal-new { margin-top: 10px; padding: 10px 12px; border-radius: 6px; background: #fff8e1; border: 1px solid #f0c96b; color: #3a2f00; font-size: 13px; }
.reg-portal-new code { font-size: 14px; user-select: all; color: #3a2f00; }

/* The Agreement tab (26.09.2026, agreement.js): a document to read, then a signing card. The reading column is kept narrow and airy: it is a contract. */
.nav-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); margin-left: auto; flex-shrink: 0; }
.nav-dot[hidden] { display: none; }
.agreement-links { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-top: 4px; }
.agreement-links code { font-size: 12px; }
.sign-card { border: 1px solid var(--gold); box-shadow: inset 3px 0 0 var(--gold); }
.agreement-card { padding: var(--space-6) var(--space-6); }
.agreement-doc { max-width: 70ch; margin: 0 auto; font-size: 15px; line-height: 1.7; color: var(--ink); }
.agreement-doc h3 { text-transform: none; letter-spacing: 0; font-size: 15px; font-weight: 600; color: var(--ink); margin: 26px 0 8px; }
.agreement-doc section:first-child h3 { margin-top: 0; }
.agreement-doc p { margin: 0 0 10px; overflow-wrap: anywhere; }
.agreement-doc ul { margin: 0 0 10px; padding-left: 22px; }
.agreement-doc li { margin-bottom: 4px; overflow-wrap: anywhere; }
.agreement-doc dl { margin: 0 0 10px; }
.agreement-doc dt { font-size: 12px; font-weight: 600; color: var(--ink-dim); margin-top: 10px; }
.agreement-doc dd { margin: 2px 0 0; overflow-wrap: anywhere; }
.sig-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 16px 0 28px; }
.sig-block { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; }
.sig-block--empty { background: transparent; border-style: dashed; }
.sig-block-label { font-family: var(--font-display); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-dim); margin-bottom: 6px; }
.sig-block-name { font-size: 20px; font-style: italic; color: var(--ink); margin-bottom: 4px; overflow-wrap: anywhere; }
.sig-block-note { font-size: 12px; line-height: 1.55; color: var(--ink-muted); overflow-wrap: anywhere; }
.agreement-history { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.agreement-history li { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; }
@media (max-width: 640px) { .sig-grid { grid-template-columns: 1fr; } .agreement-card { padding: var(--space-4); } }

/* Step Tasks — the three-sided checklist ("ISC" / "Your" / "External
   Dependencies") nested under a roadmap step, splitting who owns getting
   the step validated from what neither side controls (12.09.2026: added
   the third column so a ministerial decision or vendor selection is
   never displayed as if it were an ISC- or client-owned task). */
.task-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
/* Grid items default to min-width:auto, which refuses to shrink below
   the min-content size of their contents -- with a long unbroken badge
   label inside, that silently starved the sibling .task-item-text down
   to near-zero width and forced it into one-character-per-line wrapping
   (found via the 12.09.2026 visual QA pass). min-width:0 lets each
   column actually shrink to its grid track and wrap text normally. */
.task-columns > div { min-width: 0; }
@media (max-width: 760px) { .task-columns { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .task-columns { grid-template-columns: 1fr; } }
.task-column-label {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin-bottom: 8px;
}
.task-list { list-style: none; margin: 0 0 8px; padding: 0; }
.task-list-blocking { padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px dashed var(--border-strong); }
.task-item {
  display: flex;
  flex-wrap: wrap;   /* 12.09.2026 fix: without this, a flex-basis:0% text item racing an auto-sized badge for space in a narrow (~170px) column collapses to 0 width and word-break turns every character onto its own line -- found in the visual QA pass. Wrapping lets the badge drop to its own line instead of fighting the text for the same one. */
  align-items: flex-start;
  gap: 8px;
  padding: 5px 0;
  font-size: 13px;
  color: var(--ink-muted);
}
/* Client-facing task rows (dashboard.js): checkbox + text share one
   label so the whole row is the tap target, not just the 16px box --
   a bare checkbox is well under the 44px touch-target floor. Admin's
   equivalent (admin-client.js) keeps a bare checkbox: its text has its
   own separate click-to-edit action, so merging them into one label
   would make clicking the text also toggle completion. */
.task-item-label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  flex: 1;
  cursor: pointer;
  padding: 3px 0;
  margin: -3px 0;
}
.task-item input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin-top: 1px;
  flex-shrink: 0;
  cursor: pointer;
  accent-color: var(--gold);
}
.task-item.done { color: var(--ink-dim); text-decoration: line-through; }
/* flex: 1 1 auto, not the flex:1 (1 1 0%) shorthand (12.09.2026 fix):
   with a 0% basis, the flex-wrap "does this fit on one line" check
   treats the text's contribution as zero and only weighs the badge's
   natural width against the row -- so on a wide-enough column (mobile's
   260px) the badge alone "fit", the browser never wrapped to a second
   line, and all the actual text got squeezed into a sliver. Restoring
   flex-basis:auto makes that fit-check use the text's real (long)
   natural width, so it reliably wraps to its own line at any column
   width instead of only when the badge alone overflows. overflow-wrap
   (not word-break/anywhere, which factors into min-content sizing and
   caused the same collapse a different way) only breaks a word that
   would truly overflow even then. */
.task-item-text { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
.task-empty { font-size: 12px; color: var(--ink-dim); font-style: italic; }
.task-add-row { display: flex; gap: 6px; margin-top: 4px; }
.task-add-row input { flex: 1; font-size: 13px; padding: 6px 10px; }
.task-add-row button { padding: 6px 12px; font-size: 12px; }

/* External Dependencies column (12.09.2026) — read-only status pill
   instead of a checkbox: nobody on either side of this portal performs
   the action an external task describes, so there is nothing to "check
   off". justify-content:space-between pushes the pill to the row's end
   since .task-item-text already takes flex:1. */
.task-item--readonly { justify-content: space-between; }

/* Opportunities — My Shortlist block ───────────────────────────────── */
.shortlist-list { list-style: none; margin: 0; padding: 0; }
.shortlist-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.shortlist-row:last-child { border-bottom: none; }
.shortlist-row-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shortlist-row-title { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--ink); }
.shortlist-row.is-top .shortlist-row-title { color: var(--gold-ink); }
.shortlist-row-actions { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }

/* Opportunity cards — priority/proposal flags sit between the summary
   text and the action row, quieter than a badge since they describe the
   client's own state rather than ISC's qualification of the opportunity. */
.opp-card-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.opp-priority-flag {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: var(--gold-ink);
  margin: -4px 0 8px;
}
.opp-priority-flag--muted { color: var(--ink-dim); }
.opp-proposal-flag {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-dim);
  margin: -4px 0 8px;
}

/* Opportunity detail modal — five required sections (Why it matters /
   What is confirmed / What still needs verification / Sources & last
   verification date / Recommended next step), plus the Propose-as-next-
   objective action block. detail-note is the honest-absence voice used
   throughout ("not yet recorded") rather than a fabricated placeholder. */
.detail-section { margin-bottom: 18px; }
.detail-section label {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
  display: block;
  margin-bottom: 4px;
}
.detail-section p { font-size: 14px; color: var(--ink); margin: 0; white-space: pre-wrap; }
.detail-note { font-size: 13px; color: var(--ink-dim); margin: 4px 0 0; }
.detail-section--action {
  padding-top: 14px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
}
.modal.modal--wide { max-width: 640px; }

/* Opportunity detail panel (12.09.2026) -- a docked side panel on
   desktop, a full-screen adapted view on mobile, per the brief: "Ouvre
   les détails dans un panneau latéral sur desktop et une vue adaptée sur
   mobile." Distinct component from .modal (used for the smaller Propose
   form) -- static containers in dashboard.html (#panel-overlay/#panel)
   rather than self-created, so open/close can manage focus and
   aria-hidden predictably. Because this overlays the page rather than
   navigating, the Opportunities list's scroll position is preserved
   automatically underneath it -- closing returns the client exactly
   where they were. */
.panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 31, 0.32);
  z-index: 210;   /* 12.09.2026 fix: above the mobile hamburger button's z-index:200 -- it was sitting over the panel's own header on mobile, clipping the opportunity's title (found in the mobile visual QA pass) */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}
.panel-overlay.visible { opacity: 1; pointer-events: auto; }
.panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  max-width: 480px;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-panel);
  padding: var(--space-6) var(--space-6) var(--space-5);
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 0.2s ease;
}
.panel-overlay.visible .panel { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .panel { transition: none; }
  .panel-overlay { transition: none; }
}
@media (max-width: 760px) {
  .panel { max-width: none; }
}
.panel-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: var(--space-5);
}
.panel-header h2 { margin-bottom: 0; }

textarea { min-height: 70px; resize: vertical; }

.comment-list { margin: 12px 0; }
.comment {
  font-size: 13px;
  padding: 8px 0;
  border-top: 1px solid var(--border);
  color: var(--ink-muted);
}
.comment .meta { font-size: 11px; color: var(--ink-dim); margin-bottom: 2px; }

/* Toast (12.09.2026): moved off the dark-navy register onto the same
   light surface as the rest of the working app -- a small confirmation
   shouldn't be the one moment that flashes a different visual language.
   A left accent bar carries the state (gold=confirmation, danger=error)
   so it's never colour-only. */
.toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  left: 24px;
  margin: 0 auto;
  max-width: 360px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  box-shadow: inset 3px 0 0 var(--gold);
  color: var(--ink);
  padding: 14px 18px;
  border-radius: var(--radius);
  font-size: 14px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
  z-index: 300;
}
.toast.visible { opacity: 1; transform: translateY(0); }
.toast.error { box-shadow: inset 3px 0 0 var(--danger); }
@media (min-width: 480px) { .toast { left: auto; } }
@media (prefers-reduced-motion: reduce) { .toast { transition: none; } }

/* "Connect as" banner (27.09.2026): a super admin viewing the client or regulator portal exactly as
   that account would see it (admin_routes.py's /api/admin/connect-as/*). Always on top, always the
   full width of the viewport, so it can never be mistaken for part of the page underneath it. */
.impersonation-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 10px 16px;
  background: var(--gold-tint);
  color: var(--gold-ink);
  border-bottom: 1px solid var(--gold);
  font-size: 14px;
  text-align: center;
}
.impersonation-banner .btn { padding: 4px 12px; font-size: 13px; }

/* Mobile nav -- CSS-only off-canvas drawer (checkbox hack, no JS): a
   hidden checkbox toggled by a visible label acting as the hamburger
   button; the sidebar and a dimming backdrop are later siblings of
   that checkbox, shown via :checked ~ selectors. Markup:
   <input type="checkbox" id="nav-toggle" class="nav-toggle-checkbox">
   <label for="nav-toggle" class="nav-toggle-btn">&#9776;</label>
   <nav class="sidebar">...</nav>
   <label for="nav-toggle" class="nav-backdrop"></label>
   -- all as direct children of .app-shell, checkbox first. Tapping the
   backdrop toggles the same checkbox back off (any label targeting it
   does), closing the drawer. Inert on desktop (button/backdrop hidden,
   sidebar unaffected) until the max-width: 760px query below. */
/* display:none would pull the checkbox out of the tab order entirely --
   a keyboard/screen-reader user could never reach it at all, since the
   <label> that visually acts as the button isn't natively focusable
   either. Visually hidden but still focusable (the standard
   "sr-only"-style technique) keeps Tab + Space working; the focus
   ring is drawn on the visible label via the sibling combinator below,
   since the real input itself is invisible. */
.nav-toggle-checkbox {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.nav-toggle-btn { display: none; }
.nav-backdrop { display: none; }

@media (max-width: 760px) {
  .app-shell { grid-template-columns: 1fr; }
  .nav-toggle-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 200;
    width: 44px;
    height: 44px;
    border-radius: var(--radius);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    color: var(--ink);
    cursor: pointer;
    box-shadow: var(--shadow-modal);
  }
  .nav-toggle-checkbox:focus-visible ~ .nav-toggle-btn {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
  }
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 260px;
    z-index: 190;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
  }
  .nav-toggle-checkbox:checked ~ .sidebar { transform: translateX(0); }
  .nav-toggle-checkbox:checked ~ .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(6, 13, 25, 0.55);
    z-index: 180;
  }
  .main { padding: 76px 20px 20px; }
  .field-row { grid-template-columns: 1fr; }
  .modal { padding: 22px 18px 18px; }
  .modal-overlay { padding: 24px 12px; }
}

/* ── Admin portal ───────────────────────────────────────────────── */

.main-admin { max-width: 1180px; }

.breadcrumb {
  font-size: 13px;
  color: var(--ink-dim);
  margin-bottom: 6px;
}
.breadcrumb a:hover { color: var(--gold-ink); }

.data-table-wrap { overflow-x: auto; }
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.data-table th {
  text-align: left;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-dim);
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}
.data-table td {
  padding: 12px;
  border-bottom: 1px solid var(--border);
  color: var(--ink-muted);
  vertical-align: top;
}
.data-table tbody tr { cursor: default; }
.data-table tbody tr.clickable { cursor: pointer; }
.data-table tbody tr.clickable:hover { background: var(--paper); }
.data-table td.name-cell { color: var(--ink); font-weight: 600; font-family: var(--font-display); }

.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border-strong);
  margin-bottom: 24px;
  overflow-x: auto;
}
.tab {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-dim);
  padding: 10px 16px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
  flex-shrink: 0;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--gold-ink); border-bottom-color: var(--gold); }

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 20, 28, 0.5);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 48px 24px;
  overflow-y: auto;
  z-index: 220;   /* 12.09.2026: above the mobile hamburger button and the panel, so the Propose form always reads on top of an open detail panel */
}
.modal-overlay:not(.visible) { display: none; }
.modal {
  width: 100%;
  max-width: 520px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px 28px 24px;
  box-shadow: var(--shadow-modal);
}
.modal-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 18px;
}
.modal-close {
  background: none;
  border: none;
  color: var(--ink-dim);
  font-size: 20px;
  cursor: pointer;
  padding: 0 4px;
}
.modal-close:hover { color: var(--ink); }
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}
.checkbox-row input { width: auto; accent-color: var(--gold); }
.checkbox-row label { margin-bottom: 0; }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.editable-value {
  cursor: pointer;
  border-bottom: 1px dashed var(--border-strong);
  padding-bottom: 1px;
}
.editable-value:hover { border-bottom-color: var(--gold); }

.pipeline-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.pipeline-item:last-child { border-bottom: none; }
.pipeline-item-body { flex: 1; min-width: 0; }
.pipeline-item-title { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--ink); }
.pipeline-item-meta { font-size: 12px; color: var(--ink-dim); margin-top: 4px; }

/* Respect a system-level reduced-motion preference -- the drawer slide,
   spinner spin and color transitions are all cosmetic, never load-bearing
   for understanding state, so they're safe to cut entirely. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ── Jurisdictions map (13.09.2026) ─────────────────────────────────────────── */

.jur-legend { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 14px; }
.jur-legend-item { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-muted); }
.jur-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.jur-dot-active { background: var(--success); }
.jur-dot-watchlist { background: var(--gold); }
.jur-dot-universe { background: var(--border-strong); }
.jur-dot-none { background: var(--paper); border: 1px solid var(--border-strong); }

.jur-map-wrap { position: relative; }
.jur-map-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 4px;
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.jur-map-svg { width: 100%; height: auto; display: block; cursor: grab; }
.jur-map-svg:active { cursor: grabbing; }
.jur-country { stroke: var(--surface); stroke-width: 0.5; vector-effect: non-scaling-stroke; cursor: pointer; transition: opacity 0.1s; }
.jur-country:hover { opacity: 0.75; }

.jur-map-controls { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; gap: 4px; z-index: 2; }
.jur-map-controls button {
  width: 30px; height: 30px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--ink); font-size: 16px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.jur-map-controls button:hover { background: var(--paper); }
.jur-map-controls button.jur-zoom-reset { font-size: 11px; }
.jur-map-hint {
  position: absolute; bottom: 10px; left: 12px; font-size: 11.5px; color: var(--ink-dim);
  background: var(--surface); padding: 3px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  pointer-events: none; z-index: 2;
}

.jur-search { max-width: 260px; }
.jur-iso { color: var(--ink-dim); font-size: 12px; margin-left: 6px; }

.jur-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 20px;
  font-size: 14px;
  color: var(--ink);
}
.jur-detail-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-dim); margin-bottom: 4px; }

/* ── Filter pills (Client Actions + Jurisdictions & Regulators, 13.09.2026) ──── */

.filter-pills { display: flex; gap: 6px; flex-wrap: wrap; }
.filter-pill {
  font: inherit; font-size: 13px; font-weight: 500; color: var(--ink-dim);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 6px 12px; cursor: pointer;
}
.filter-pill:hover { border-color: var(--gold); color: var(--ink); }
.filter-pill.active { background: var(--gold-tint); color: var(--gold-ink); border-color: var(--gold); font-weight: 600; }

/* ── Client Actions work queue (13.09.2026) ──────────────────────────────────── */

.action-group { margin: 10px 0; }
.action-group-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-dim); margin-bottom: 6px; }
.action-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 14px; }
.action-item input[type="checkbox"] { accent-color: var(--gold); width: auto; }
.card-footer-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }

/* ── Regulator interlocutor cards (Jurisdictions & Regulators, 13.09.2026) ───── */

.regulator-card { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 14px 16px; margin-bottom: 10px; }
.regulator-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.regulator-history { white-space: pre-wrap; font-size: 12.5px; color: var(--ink-dim); margin-top: 8px; max-height: 120px; overflow-y: auto; }


/* ── Power Map (admin, 19.09.2026) ───────────────────────────────────────────
   The globe is always a dark "space" card, in light and dark theme alike (same
   look as the sales-page globe); everything around it follows the theme. */
.pm-summary { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: -8px 0 16px; font-size: 13px; color: var(--ink-muted); }
.pm-summary strong { color: var(--ink); font-size: 15px; }
.pm-layout { display: grid; grid-template-columns: minmax(280px, 340px) minmax(0, 1fr); gap: 18px; align-items: start; }
.pm-list { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); max-height: 78vh; display: flex; flex-direction: column; }
.pm-list-tools { padding: 12px; border-bottom: 1px solid var(--border); display: grid; gap: 8px; }
.pm-list-body { overflow-y: auto; padding: 4px 0 8px; }
.pm-jur { padding: 8px 14px 4px; }
.pm-jur-head { display: flex; align-items: center; justify-content: flex-start; gap: 8px; width: 100%; background: none; border: 0; padding: 4px 0; cursor: pointer; text-align: left; font: inherit; color: var(--ink); }
.pm-jur-head:hover strong { color: var(--gold-ink); }
.pm-jur-head strong { font-size: 14px; }
.pm-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 10px; border: 2px solid var(--ink-dim); background: transparent; }
.pm-dot.s1 { background: #c8901a; border-color: #c8901a; }
.pm-dot.s2 { background: var(--gold); border-color: var(--gold); }
.pm-dot.s3 { background: #4fae8a; border-color: #4fae8a; }
.pm-chip { font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; padding: 1px 6px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--ink-muted); }
.pm-chip.oecs { border-color: #60a5fa; color: var(--info); }
.pm-chip.caricom { border-color: var(--gold); color: var(--gold-ink); }
.pm-reg { display: flex; justify-content: space-between; gap: 8px; width: 100%; background: none; border: 0; border-radius: var(--radius-sm); padding: 5px 8px 5px 20px; cursor: pointer; text-align: left; font: inherit; color: var(--ink-muted); font-size: 13px; }
.pm-reg > span:first-child { min-width: 0; }
.pm-reg > span:last-child { flex: 0 0 auto; white-space: nowrap; }
.pm-reg:hover { background: var(--gold-tint); color: var(--ink); }
.pm-gap { padding: 2px 8px 6px 20px; font-size: 12px; color: var(--ink-dim); }
.pm-globe-wrap { position: relative; background: radial-gradient(ellipse at 50% 40%, #0e1c33 0%, #08101f 62%, #050a14 100%); border-radius: var(--radius-lg); border: 1px solid #1e2d42; overflow: hidden; box-shadow: var(--shadow-dark-card); }
.pm-globe-wrap canvas { display: block; width: 100%; height: min(74vh, 720px); min-height: 460px; cursor: grab; touch-action: none; }
.pm-globe-wrap canvas.dragging { cursor: grabbing; }
.pm-layers { position: absolute; top: 12px; left: 12px; display: grid; gap: 4px; background: rgba(8, 16, 31, .78); border: 1px solid #1e2d42; border-radius: var(--radius); padding: 10px 12px; font-size: 12px; color: #b0c0d4; backdrop-filter: blur(4px); }
.pm-layers label { display: flex; align-items: center; gap: 8px; cursor: pointer; margin: 0; white-space: nowrap; color: #b0c0d4; }
.pm-layers input[type="checkbox"] { width: auto; flex: 0 0 auto; padding: 0; margin: 0; accent-color: var(--gold); }
.pm-swatch { width: 18px; height: 3px; border-radius: 2px; display: inline-block; }
.pm-globe-tools { position: absolute; top: 12px; right: 12px; display: flex; gap: 6px; }
.pm-globe-tools button { background: rgba(8, 16, 31, .78); color: #edf0f7; border: 1px solid #1e2d42; border-radius: var(--radius-sm); padding: 6px 10px; font: 600 12px var(--font-body); cursor: pointer; }
.pm-globe-tools button:hover { border-color: var(--gold); color: var(--gold); }
.pm-legend { position: absolute; left: 12px; bottom: 10px; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11px; color: #8fa0b8; max-width: 70%; }
.pm-legend span { display: inline-flex; align-items: center; gap: 6px; }
.pm-tip { position: absolute; pointer-events: none; background: rgba(8, 16, 31, .95); border: 1px solid rgba(232, 168, 48, .4); border-radius: var(--radius-sm); padding: 8px 10px; font-size: 12px; color: #edf0f7; max-width: 240px; opacity: 0; transition: opacity .1s; z-index: 3; }
.pm-tip.on { opacity: 1; }
.pm-tip b { display: block; margin-bottom: 2px; }
.pm-tip span { color: #9badc3; }
.pm-note { margin-top: 10px; font-size: 12px; color: var(--ink-dim); }
.pm-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(500px, 100vw); background: var(--surface); border-left: 1px solid var(--border-strong); box-shadow: var(--shadow-panel); z-index: 205; overflow-y: auto; transform: translateX(105%); transition: transform .22s ease; padding: 22px 22px 40px; }
.pm-drawer.open { transform: none; }
.pm-drawer h2 { margin: 0 0 4px; font-size: 20px; padding-right: 34px; overflow-wrap: anywhere; }
.pm-drawer h4 { margin: 20px 0 8px; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); }
.pm-drawer-close { position: absolute; top: 14px; right: 16px; background: none; border: 0; font-size: 26px; line-height: 1; cursor: pointer; color: var(--ink-muted); }
.pm-kv { display: grid; grid-template-columns: 140px 1fr; gap: 6px 12px; font-size: 13px; }
.pm-kv dt { color: var(--ink-dim); }
.pm-kv dd { margin: 0; overflow-wrap: anywhere; }
.pm-link { border-left: 3px solid var(--border-strong); padding: 6px 10px; margin-bottom: 6px; font-size: 13px; background: var(--paper); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.pm-link.objective { border-color: var(--gold); }
.pm-link.interest { border-color: #60a5fa; }
.pm-link.potential { border-color: #4fae8a; }
.pm-link.blocked { border-color: var(--ink-dim); opacity: .8; }
.pm-topic-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 12px; }
.pm-need { border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; margin-bottom: 8px; background: var(--paper); }
.pm-need-top { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start; }
.pm-tabs { display: flex; gap: 6px; margin: 14px 0 4px; }
.pm-tabs button { background: none; border: 1px solid var(--border-strong); border-radius: 999px; padding: 4px 12px; font: 600 12px var(--font-body); color: var(--ink-muted); cursor: pointer; }
.pm-tabs button.active { background: var(--gold-tint); border-color: var(--gold); color: var(--gold-ink); }
@media (max-width: 1000px) { .pm-layout { grid-template-columns: 1fr; } .pm-list { max-height: 44vh; } .pm-topic-grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .pm-drawer { transition: none; } }

/* ── Regulator roadmap (19.09.2026) ─────────────────────────────────────────── */
.rm-head { display: grid; gap: 10px; }
.rm-checkpoints { display: flex; flex-wrap: wrap; gap: 6px; }
.rm-cp { font-size: 12px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--ink-dim); }
.rm-cp.done { background: var(--success-tint); border-color: transparent; color: var(--success); }
.rm-summary { font-size: 14px; color: var(--ink-muted); }
.rm-need { border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; margin: 10px 0; background: var(--paper); }
.rm-need.pending { border-color: var(--gold); background: var(--gold-tint); }
.rm-need-top { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.rm-need h4 { margin: 0; font-size: 15px; }
.rm-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.rm-based { font-size: 12px; color: var(--ink-dim); margin-top: 4px; }
.rm-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.rm-status { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--ink-muted); }
.rm-status select { width: auto; min-width: 12rem; padding-top: 6px; padding-bottom: 6px; font-size: 13px; }
.rm-respond { margin-top: 10px; display: grid; gap: 8px; }
.rm-phase-empty { font-size: 13px; color: var(--ink-dim); }

/* ── Regulators directory (19.09.2026) ─────────────────────────────────── */
.rd-intro { margin: 14px 0 12px; color: var(--ink-muted); font-size: 14px; max-width: 70ch; }
.rd-toolbar { margin-top: 14px; display: grid; justify-content: stretch; gap: 10px; }
.rd-actions { display: flex; gap: 10px; align-items: center; }
.rd-actions .jur-search { flex: 1; max-width: none; }
.rd-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.rd-table th.sortable:hover { color: var(--ink); }
.rd-table th.sorted { color: var(--gold-ink); }
.rd-table th.sorted::after { content: " ↕"; font-size: 11px; opacity: .6; }
.rd-table td { vertical-align: top; }
.rd-table td .step-meta { font-weight: 400; font-family: var(--font-body); }
.rd-table td .pm-chip { margin-left: 4px; }

/* ── Admin Dashboard (19.09.2026) ──────────────────────────────────────────
   Tokens only, so dark mode follows. The attention list is ONE surface with
   three quiet groups (a stripe says the tone, the group title says it in words);
   the tiles are for scanning, not reading. The one distinctive piece is the
   perimeter strip inside the Power Map tile. */
.ad-head-meta { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-dim); }
.ad-head-meta .btn { min-height: 36px; padding: 6px 14px; }
.ad-week { margin: -8px 0 14px; }

.ad-attention { padding: 0; overflow: hidden; margin-bottom: 20px; }
.ad-group + .ad-group { border-top: 1px solid var(--border); }
.ad-group-title { margin: 0; padding: 14px 24px 6px; font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-dim); }
.ad-list { list-style: none; margin: 0; padding: 0 0 8px; }
.ad-none { margin: 0; padding: 4px 24px 16px; font-size: 14px; color: var(--ink-muted); }

.ad-row {
  --tone: var(--gold);
  display: grid; grid-template-columns: 2.4rem minmax(0, 1fr) 16px; align-items: center; gap: 14px;
  width: 100%; min-height: 0; padding: 10px 22px 10px 21px;
  border: 0; border-radius: 0; background: transparent; color: var(--ink); text-align: left; font-weight: 400;
  box-shadow: inset 3px 0 0 var(--tone);
}
.ad-row[data-tone="watch"] { --tone: var(--info); }
.ad-row[data-tone="news"] { --tone: var(--success); }
.ad-row:hover { background: var(--hover-wash); }
.ad-row:focus-visible, .ad-tile-link:focus-visible, .ad-chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.ad-row:focus-visible { outline-offset: -2px; }
.ad-count { font-size: 20px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.ad-row-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ad-row-text strong { font-size: 14.5px; font-weight: 600; }
.ad-row-text span { font-size: 13px; color: var(--ink-muted); }
.ad-chevron { color: var(--ink-dim); flex: 0 0 16px; }
.ad-row:hover .ad-chevron { color: var(--gold-ink); }

/* ── Admin Today panel (29.09.2026) ─────────────────────────────────────────
   The first card on the dashboard: what to do, in order. Urgency is said three ways (group title, stripe,
   button weight), so colour is never the only signal. Tokens only: dark mode follows. */
.td { padding: 0; overflow: hidden; margin-bottom: 20px; }
.td-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; padding: 18px 24px 14px; border-bottom: 1px solid var(--border); }
.td-head h2 { margin: 0; font-size: 22px; letter-spacing: -0.01em; text-transform: none; color: var(--ink); }
.td-date { font-size: 14px; color: var(--ink-muted); }
.td-summary { margin-left: auto; font-size: 14px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.td-summary b { color: var(--ink); font-size: 16px; }
.td-empty { margin: 0; padding: 22px 24px; max-width: none; font-size: 14.5px; color: var(--ink-muted); }
.td-empty strong { color: var(--ink); }

.td-group + .td-group { border-top: 1px solid var(--border); }
.td-group-head { display: flex; align-items: baseline; gap: 10px; margin: 0; padding: 14px 24px 6px; font-size: 13px; font-weight: 600; color: var(--ink-dim); text-transform: none; letter-spacing: 0; list-style: none; }
.td-group-head::-webkit-details-marker { display: none; }
summary.td-group-head { cursor: pointer; }
summary.td-group-head:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
summary.td-group-head::before { content: ""; width: 6px; height: 6px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); align-self: center; transition: transform .15s ease; }
details[open] > summary.td-group-head::before { transform: rotate(45deg); }
.td-group-title { color: var(--ink); font-size: 14px; white-space: nowrap; }
.td-group-hint { font-weight: 400; }
.td-group-n { margin-left: auto; font-variant-numeric: tabular-nums; }
.td-list { list-style: none; margin: 0; padding: 0 0 8px; }

.td-row {
  --tone: var(--gold);
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) auto; align-items: center; gap: 4px 16px;
  padding: 11px 22px 11px 21px; box-shadow: inset 3px 0 0 var(--tone);
}
.td-row[data-urgency="now"] { --tone: var(--danger); }
.td-row[data-urgency="week"] { --tone: var(--info); }
.td-row:hover { background: var(--hover-wash); }
.td-verb { justify-self: start; padding: 2px 9px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); font-size: 12.5px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.td-row[data-urgency="now"] .td-verb { border-color: var(--danger); color: var(--danger); background: var(--danger-tint); }
.td-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.td-text strong { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.td-text span { font-size: 13px; color: var(--ink-muted); max-width: 70ch; }
.td-cta { min-height: 36px; padding: 6px 14px; font-size: 13px; text-decoration: none; white-space: nowrap; }
.td-row[data-urgency="later"] { --tone: var(--ink-dim); }
.td-side { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.td-text .td-rel { font-size: 12.5px; font-weight: 600; color: var(--ink-dim); }
.td-done { min-height: 36px; padding: 6px 14px; font-size: 13px; white-space: nowrap; }

/* The few tasks that matter now are cards, the rest wait under "more" (12 Oct 2026). Same stripe and tone tokens as the compact rows. */
.td-focus + .td-focus, .td-focus + .td-more, .td-more + .td-hidden { border-top: 1px solid var(--border); }
.td-row--focus { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; align-items: start; padding: 14px 22px 14px 21px; }
.td-card-top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.td-card-title { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.4; color: var(--ink); max-width: 68ch; }
.td-card-why { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--ink-muted); max-width: 70ch; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.td-row--focus .td-rel { font-size: 12.5px; font-weight: 600; color: var(--ink-dim); }
.td-card-actions { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 4px; }
.td-more > summary.td-more-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 14px 24px; cursor: pointer; list-style: none; font-size: 13px; color: var(--ink-dim); }
.td-more > summary.td-more-head::-webkit-details-marker { display: none; }
.td-more > summary.td-more-head::before { content: ""; width: 6px; height: 6px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); align-self: center; transition: transform .15s ease; }
.td-more[open] > summary.td-more-head::before { transform: rotate(45deg); }
.td-more > summary.td-more-head:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.td-hidden { margin: 0; padding: 12px 24px; font-size: 13px; color: var(--ink-muted); }
.td-unhide { border: 0; background: none; padding: 0; font: inherit; font-weight: 600; color: var(--gold-ink); cursor: pointer; text-decoration: underline; }

/* What Claude prepared: open, read, approve (12 Oct 2026) */
.pr-panel { background: var(--gold-tint); }
.pr-panel .td-row--focus { background: var(--surface); margin: 0 14px 10px; border: 1px solid var(--border); border-radius: var(--radius); box-shadow: none; }
.pr-modal-why { margin: 0 0 12px; font-size: 14px; line-height: 1.5; color: var(--ink-muted); }
.pr-modal-why:empty { display: none; }
.pr-error { margin: 8px 0 0; font-size: 13.5px; color: var(--danger); }
.pr-error:empty { display: none; }
.pr-note { white-space: pre-wrap; font-size: 14.5px; line-height: 1.6; max-height: 55vh; overflow: auto; padding: 4px 2px; }
.pr-links { margin: 10px 0 0; padding-left: 18px; font-size: 13.5px; }
.pr-changes { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.pr-changes th, .pr-changes td { padding: 7px 10px 7px 0; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
.pr-changes thead th { font-size: 12px; color: var(--ink-muted); }
.pr-before { color: var(--ink-muted); }

/* ISC's own tasks (10 Oct 2026): "Add a task" opens under the title of the panel */
.td-add { flex-basis: 100%; }
.td-add > summary { display: inline-block; cursor: pointer; font-size: 13.5px; font-weight: 600; color: var(--gold-ink); border-radius: 4px; }
.td-add > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.td-add-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px 14px; align-items: end; padding: 12px 0 6px; }
.td-add-form label { display: grid; gap: 4px; font-size: 12.5px; font-weight: 600; color: var(--ink-muted); }
.td-add-wide { grid-column: span 2; }
.td-add-msg { grid-column: 1 / -1; font-size: 13px; color: var(--danger); }
.td-add-msg:empty { display: none; }

@media (max-width: 720px) {
  .td-head { padding: 16px 16px 12px; }
  .td-summary { margin-left: 0; flex-basis: 100%; }
  .td-group-head { padding: 12px 16px 4px; flex-wrap: wrap; }
  .td-group-hint { flex-basis: 100%; order: 3; }
  .td-row { grid-template-columns: minmax(0, 1fr); padding: 12px 16px 12px 15px; gap: 8px; }
  .td-row--focus { padding: 12px 16px 12px 15px; }
  .pr-panel .td-row--focus { margin: 0 10px 10px; }
  .td-cta { justify-self: start; }
  .td-side { justify-content: flex-start; }
  .td-add-wide { grid-column: auto; }
}

.ad-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.ad-tile { display: flex; flex-direction: column; gap: 12px; min-width: 0; padding: 18px 22px 20px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.ad-tile--wide { grid-column: 1 / -1; }
.ad-tile h3 { margin: 0; font-size: 15px; letter-spacing: 0; text-transform: none; color: var(--ink); }
.ad-tile-link { min-height: 0; padding: 0; gap: 4px; justify-content: flex-start; background: none; border: 0; border-radius: 4px; font: inherit; color: inherit; }
.ad-tile-link:hover { color: var(--gold-ink); }
.ad-tile-link .ad-chevron { color: var(--ink-dim); }
.ad-figure { margin: 0; font-size: 14px; color: var(--ink-muted); max-width: none; }
.ad-figure strong { font-size: 28px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); font-variant-numeric: tabular-nums; margin-right: 4px; }
.ad-figure span { display: block; font-size: 13px; color: var(--ink-dim); margin-top: 2px; }
.ad-quiet { margin: 0; font-size: 13px; color: var(--ink-dim); }
.ad-sub { margin: 4px 0 -4px; font-size: 13px; font-weight: 600; color: var(--ink-dim); }

.ad-facts, .cd-facts { display: grid; margin: 0; }
.ad-facts > div, .cd-facts > div { display: flex; justify-content: space-between; gap: 14px; padding: 7px 0; border-top: 1px solid var(--border); font-size: 13.5px; }
.ad-facts dt, .cd-facts dt { color: var(--ink-muted); }
.ad-facts dd, .cd-facts dd { margin: 0; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.ad-facts dd.is-hot { color: var(--gold-ink); }
.ad-facts dd.is-bad { color: var(--danger); }

/* one bar split into parts + its legend (the legend carries the numbers) */
.c-success { --c: var(--success); } .c-gold { --c: var(--gold); } .c-info { --c: var(--info); }
.c-danger { --c: var(--danger); } .c-neutral { --c: var(--border-strong); }
.ad-bar { display: flex; gap: 2px; height: 8px; border-radius: 4px; overflow: hidden; background: var(--neutral-tile); }
.ad-bar > i { display: block; min-width: 4px; background: var(--c); }
.ad-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; list-style: none; margin: 0; padding: 0; font-size: 12.5px; color: var(--ink-muted); }
.ad-legend li { display: inline-flex; align-items: center; gap: 6px; }
.ad-legend b { color: var(--ink); font-variant-numeric: tabular-nums; }
.ad-swatch { display: inline-block; width: 9px; height: 9px; border-radius: 2px; background: var(--c); }

/* stage columns: one scale (zero baseline), the count above each column */
.ad-stages { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; align-items: end; }
.ad-col { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px; }
.ad-col i { display: block; width: 100%; max-width: 34px; border-radius: 3px 3px 0 0; background: var(--gold); }
.ad-col.is-zero i { background: var(--border-strong); }
.ad-col-n { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
.ad-col-l { font-size: 11.5px; color: var(--ink-dim); border-top: 1px solid var(--border-strong); width: 100%; text-align: center; padding-top: 3px; }

/* the perimeter strip: one chip per jurisdiction, coloured like its Power Map dot */
.ad-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ad-chip { min-height: 0; padding: 4px 10px 4px 9px; gap: 7px; font-size: 12px; font-weight: 600; letter-spacing: 0.04em; border-radius: var(--radius-sm); background: var(--paper); border: 1px solid var(--border-strong); color: var(--ink); }
.ad-chip[data-strength="0"] { border-style: dashed; color: var(--ink-dim); }
.ad-chip:hover { border-color: var(--gold); background: var(--hover-wash); }
.ad-legend .pm-dot { flex: 0 0 10px; }

/* ISC-led objectives */
.ad-slots { display: flex; gap: 6px; }
.ad-slot { width: 30px; height: 10px; border-radius: 3px; border: 1.5px solid var(--border-strong); }
.ad-slot.is-used { background: var(--success); border-color: var(--success); }
.ad-objs { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.ad-objs li { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 14px; }
.ad-obj-name { min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.ad-progress-head { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; color: var(--ink-muted); margin-bottom: -6px; }
.ad-progress-head b { color: var(--ink); font-variant-numeric: tabular-nums; }
.ad-progress { height: 8px; border-radius: 4px; background: var(--neutral-tile); overflow: hidden; }
.ad-progress > i { display: block; height: 100%; background: var(--c); border-radius: 4px; min-width: 3px; }
.spinner--small { width: 18px; height: 18px; }

@media (max-width: 760px) {
  .ad-grid { grid-template-columns: 1fr; }
  .ad-row { padding-left: 16px; padding-right: 16px; gap: 10px; grid-template-columns: 2rem minmax(0, 1fr) 16px; }
  .ad-group-title { padding-left: 19px; padding-right: 19px; }
  .ad-none { padding-left: 19px; padding-right: 19px; }
  .ad-head-meta #ad-asof { display: none; }
}

/* ── Client Dashboard (19.09.2026) ─────────────────────────────────────────
   Built from the client portal's own pieces (card, badge, next-milestone,
   action-needed, quiet-flag). The progress bar is deliberately quiet, like
   .roadmap-progress: a plain count of steps, never a probability. */
.cd-tile { display: flex; flex-direction: column; gap: 14px; }
.cd-tile[hidden] { display: none; }
.cd-tile > .card-title-row { margin-bottom: 0; }
.cd-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 16px; }
.cd-grid > .card { margin-bottom: 0; }
.cd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.cd-name { margin: 0; font-size: 22px; letter-spacing: -0.01em; }
.cd-outcome { margin: 0; font-size: 15px; }
.cd-tile .next-milestone { margin: 0; }
.cd-progress { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-muted); }
.cd-progress-bar { flex: 1; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.cd-progress-bar > i { display: block; height: 100%; min-width: 3px; border-radius: 3px; background: var(--ink-muted); }
.cd-now { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--paper); }
.cd-now-label { display: block; font-size: 12px; font-weight: 600; color: var(--ink-dim); margin-bottom: 2px; }
.cd-now-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.cd-now-meta { display: flex; align-items: center; gap: 10px; }
.cd-now-meta .step-meta { margin: 0; }
.cd-figure { margin: 0; font-size: 14px; color: var(--ink-muted); max-width: none; }
.cd-figure strong { font-size: 28px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); font-variant-numeric: tabular-nums; margin-right: 4px; }
.cd-list { list-style: none; margin: 0; padding: 0; }
.cd-list li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 14px; }
.cd-list-name { min-width: 0; overflow-wrap: anywhere; font-weight: 600; color: var(--ink); }
.cd-more { margin: -6px 0 0; font-size: 13px; color: var(--ink-dim); }
.cd-actions { margin-top: auto; padding-top: 2px; }
.cd-empty { padding: 24px 10px; }

/* ── Opportunity quality checklist (19.09.2026) ────────────────────────────── */
.q-title { margin: 12px 0 4px; font-size: 13px; font-weight: 600; color: var(--danger); }
.q-problems { margin: 0 0 12px; padding: 0 0 0 18px; font-size: 13px; color: var(--ink-muted); }
.q-problems li { margin: 3px 0; }

/* ══ Live Objective at a glance, the review, and the Agreement (26.09.2026) ═══════════════════════════════
   Same language as the regulator portal: a card with a title and one line of context, a muted label above the value, a hairline
   between rows, one pill for a state. Sentence case, numbers before words. Gold stays for what needs the client: the next move,
   the button that signs. Everything is read from the objective and the agreement; nothing here is scored. */

.btn-lg { padding: 12px 22px; min-height: 46px; font-size: 15px; }
.action-needed-buttons { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

.lo { padding: var(--space-6) var(--space-7); margin-bottom: var(--space-4); }
.lo-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.lo-head h1 { margin: 0; }
.lo-outcome { margin: var(--space-3) 0 var(--space-5); max-width: 62ch; font-size: 18px; line-height: 1.5; color: var(--ink); }
.lo .next-milestone { margin-bottom: 0; }
.lo .next-milestone-label { font-size: 12px; letter-spacing: 0; text-transform: none; }
.lo-glance { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1px; margin: var(--space-5) 0 0; background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.lo-cell { display: grid; gap: 6px; align-content: start; padding: 14px 16px; background: var(--surface); }
.lo-cell dt { font-size: 13px; color: var(--ink-muted); }
.lo-cell dd { margin: 0; display: grid; gap: 8px; font-size: 15px; }
.lo-cell.is-you { background: color-mix(in srgb, var(--gold) 12%, var(--surface)); }
.lo-figure { font-size: 26px; line-height: 1.1; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.lo-step { font-size: 15px; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.lo-cell-note { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; line-height: 1.45; color: var(--ink-muted); }
.lo-cell-date { font-size: 13px; color: var(--ink-muted); }
.lo-bar { display: block; width: 100%; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.lo-bar > i { display: block; height: 100%; min-width: 3px; border-radius: 3px; background: var(--success); }
.lo-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5) var(--space-7); margin-top: var(--space-6); }
.lo-label { margin: 0 0 4px; font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-muted); }
.lo-text { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
@media (max-width: 760px) { .lo { padding: var(--space-5) var(--space-4); } .lo-cols { grid-template-columns: 1fr; } .lo-outcome { font-size: 16px; } }

.lo-title { margin: 0; font-size: 16px; line-height: 1.35; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink); }
.lo-sub { margin: 2px 0 0; max-width: 64ch; font-size: 13px; line-height: 1.5; color: var(--ink-muted); }
.lo-review { margin-bottom: var(--space-6); }
.lo-review-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3) var(--space-5); }
.lo-review-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--space-4); }
.lo-review .fb-list { margin-top: var(--space-4); }

/* The review of one step: a bordered row inside the step, with both answers as real buttons. */
.fb { margin-top: 16px; padding: 12px 14px; background: var(--paper); border: 1px solid var(--border); border-radius: var(--radius); }
.fb-label { margin-right: 4px; font-size: 13px; font-weight: 600; color: var(--ink-muted); }

/* Agreement */
.ag-head { padding: var(--space-6) var(--space-7); margin-bottom: var(--space-4); }
.ag-head-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.ag-head h1 { margin: 0; }
.ag-intro { margin: var(--space-3) 0 0; max-width: 64ch; font-size: 15px; line-height: 1.55; color: var(--ink-muted); }
.ag-track { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: var(--space-5) 0 0; padding: 0; list-style: none; }
.ag-track li { display: grid; grid-template-columns: 22px minmax(0, 1fr); column-gap: 10px; row-gap: 1px; align-items: center; padding: 10px 12px; background: var(--paper); border: 1px solid var(--border); border-radius: var(--radius); }
.ag-track-mark { grid-row: 1 / span 2; display: grid; place-items: center; width: 22px; height: 22px; border: 2px solid var(--border-strong); border-radius: 50%; color: var(--success); }
.ag-track-mark .icon { width: 12px; height: 12px; }
.ag-track li[data-state="done"] .ag-track-mark { border-color: var(--success); background: var(--success-tint); }
.ag-track li[data-state="now"] { border-color: var(--gold); background: var(--gold-tint); }
.ag-track li[data-state="now"] .ag-track-mark { border-color: var(--gold); }
.ag-track-name { font-size: 14px; font-weight: 600; }
.ag-track-note { font-size: 12px; color: var(--ink-muted); }
.ag-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin-top: var(--space-5); }
@media (max-width: 640px) { .ag-head { padding: var(--space-5) var(--space-4); } .ag-track { grid-template-columns: 1fr; } }

.ag-contents { padding: var(--space-5) var(--space-6); }
.ag-contents-title { margin: 0 0 var(--space-3); font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ink-muted); }
.ag-contents ol { margin: 0; padding: 0; list-style: none; columns: 2; column-gap: var(--space-6); }
.ag-contents li { break-inside: avoid; }
.ag-jump { display: block; width: 100%; min-height: 0; padding: 5px 0; border: 0; background: none; font: inherit; font-size: 14px; text-align: left; color: var(--ink); cursor: pointer; }
.ag-jump:hover { color: var(--gold-ink); }
.ag-jump.is-key { font-weight: 600; }
.ag-jump-tag { margin-left: 8px; vertical-align: middle; }
@media (max-width: 640px) { .ag-contents ol { columns: 1; } }

.agreement-doc section.is-key { margin: 26px -16px 0; padding: 14px 16px 6px; background: var(--gold-tint); border-radius: var(--radius); }
.agreement-doc section.is-key h3 { margin-top: 0; }
.agr-key-badge { margin-left: 10px; vertical-align: middle; }
.agreement-doc section { scroll-margin-top: var(--space-5); }

.sign-bar { position: sticky; bottom: var(--space-4); z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin: var(--space-4) 0; padding: 12px 16px; background: var(--surface); border: 1px solid var(--gold); border-radius: var(--radius-lg); box-shadow: var(--shadow-modal); font-size: 14px; }
@media (max-width: 640px) { .sign-bar { flex-direction: column; align-items: stretch; text-align: left; } }
.sign-card { scroll-margin-top: var(--space-5); }
.ag-statements { display: grid; gap: 10px; margin: var(--space-4) 0 0; }
.ag-inline-link { min-height: 0; padding: 0; border: 0; background: none; font: inherit; font-weight: 600; color: var(--gold-ink); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }

/* A callout with actions (the proposal, the agreement): on a phone the actions drop under the text instead of squeezing it. */
@media (max-width: 640px) {
  .action-needed { flex-wrap: wrap; }
  .action-needed > div:not(.action-needed-buttons) { flex: 1 1 200px; min-width: 0; }
  .action-needed > .btn, .action-needed-buttons { flex: 1 1 100%; }
  .action-needed-buttons .btn { flex: 1 1 auto; }
}

/* Your membership (Lot 2, 14 Oct 2026): the card at the top of the client's Agreement tab. */
.membership-card { margin-bottom: 20px; }
.mem-note { margin: 10px 0 0; font-size: 13px; color: var(--ink-dim); overflow-wrap: anywhere; }
.mem-next { margin: 10px 0 0; font-size: 14px; }
.mem-h { margin: 18px 0 0; font-size: 14px; }
.mem-deals { margin: 8px 0 0; padding-left: 18px; display: grid; gap: 10px; font-size: 13px; }
