/* Aecos — design tokens + base styles. Cool off-white, deep ink, muted indigo. */

:root {
  /* density (overridden by .density-*) */
  --d-pad: 20px;
  --d-gap: 16px;
  --d-row: 44px;
  --d-card-pad: 22px;

  /* button radii — unified 2026-07-16. Text/action buttons are full pills;
     square icon-only buttons stay a consistent rounded-rect (a pill would turn
     them into circles). One token each → change the whole app's button shape in
     one place. */
  --radius-btn: 999px;
  --radius-btn-icon: 8px;
  --radius-menu: 10px;      /* dropdown / popover menu panels */
  --radius-card: 14px;      /* modal cards + elevated cards (matches native .modal-card) */

  /* CONTAINER radii — added 2026-08-02 (queue 65946e93). ⚠️ These are for
     surfaces that hold content: rows, inset callouts, bordered panels. They are
     NOT interchangeable with the button tokens above — a container must never
     take --radius-btn (999px), which would turn a row into a lozenge, and
     --radius-btn-icon exists so a square icon button can change shape WITHOUT
     dragging every panel with it (they happen to share 8px today; that is a
     coincidence the tokens exist to let you break).

     WHY THEY WERE ADDED. project-detail.jsx carried seven hardcoded
     borderRadius literals — 6, 8 and 10 — and the audit that flagged them
     concluded, correctly, that the buttons in that file were ALREADY tokenised
     and the drift was in containers, where NO TOKEN EXISTED TO REACH FOR. That
     absence is the root cause, so the answer is a token, not a lint rule. */
  --radius-sm: 6px;         /* compact list rows — a deadline/line item in a stack */
  --radius-md: 8px;         /* an inset callout or note sitting inside another surface */
  --radius-lg: 10px;        /* a standalone bordered panel or card-like row (matches .card) */

  /* CHAT COMPOSER GROWTH CAP — added 2026-08-03. Every auto-growing chat
     composer stops here and becomes a scroller; window.AECOS_autoSizeTextarea
     (command-bar.jsx) READS this off the element, so the JS never carries a
     second copy of the number. Consumers: .cmd-textarea (Aecos Intelligence —
     the reference composer) and .ppm-chat-input (project builder "Refine with
     Aecos"). 140px is ~6.7 rows at the chat's 13.5px/1.55 and ~7.2 rows at the
     builder's 12.5px/1.55 — deliberately one PIXEL cap rather than one ROW
     count, so the two composers end at the same place on screen. */
  --chat-composer-max-h: 140px;

  /* type */
  --f-sans: "Inter", "Söhne", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --f-serif: "Instrument Serif", "Source Serif Pro", "Iowan Old Style", Georgia, serif;
  --f-mono: "JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* light theme */
  --bg: #ffffff;
  --bg-elev: #ffffff;
  --bg-card: #ffffff;
  --bg-sunk: #f2f2f2;
  --bg-hover: #f4f4f5;
  --line: #e6e5df;
  --line-strong: #d6d5cd;
  --line-soft: #ecebe5;
  --ink: #15161a;
  --ink-2: #2a2c33;
  --ink-3: #4a4c55;
  --ink-4: #76787f;
  --ink-5: #a4a6ac;

  --indigo: oklch(48% 0.13 268);
  --indigo-soft: oklch(94% 0.025 268);
  --indigo-line: oklch(85% 0.05 268);
  --indigo-ink: oklch(35% 0.13 268);

  --ok: oklch(52% 0.10 155);
  --ok-soft: oklch(94% 0.04 155);
  --ok-line: oklch(82% 0.07 155);
  --warn: oklch(58% 0.13 60);
  --warn-soft: oklch(95% 0.05 70);
  --warn-line: oklch(85% 0.08 60);
  --bad: oklch(50% 0.16 28);
  --bad-soft: oklch(95% 0.04 28);
  --bad-line: oklch(85% 0.07 28);

  /* --info* is referenced (with an --indigo fallback) by badges/alerts/
     announcements but was never actually defined — aliased straight to the
     indigo family so those lookups resolve without a second blue palette. */
  --info: var(--indigo);
  --info-soft: var(--indigo-soft);
  --info-line: var(--indigo-line);
  --info-ink: var(--indigo-ink);

  /* Studio Review PDF-canvas surround — a neutral "mat" the page floats on,
     distinct from --bg-sunk so a future SR surface can use it independently. */
  --sr-canvas-bg: #e8edf3;

  /* ── Finance chart palette ─────────────────────────────────────────────────
     Canonical Robinhood-style token set for ALL finance charts — used by
     FinanceGraph, IncomeOverTime, the master portfolio chart, and the
     office-detail finance charts. These are CHART-ONLY colors: do NOT swap in
     --ok / --bad here (those remain the app's semantic green/red for buttons,
     status text, etc.). The pages minion applies these to chart components in
     Round 2; the chart renders --fin-projected as a dashed segment.
     ──────────────────────────────────────────────────────────────────────── */
  --fin-line:      #149441;                 /* primary line — deep grass-green (≥3:1 on white; #21CE56 was 2.1:1) */
  --fin-fill:      rgba(20, 148, 65, 0.12); /* translucent area fill under line */
  --fin-up:        #A9DEA9;                 /* pale-green "up" volume bar */
  --fin-down:      #F0A39C;                 /* salmon "down" volume bar (FILLS only — too pale for strokes on white) */
  --fin-down-line: #CE4437;                 /* outflow LINE/stroke — validated ≥3:1 + CVD ΔE 12.3 vs --fin-line on white */
  --fin-projected: rgba(20, 148, 65, 0.55); /* future/projected segment (dashed) */
  --fin-grid:      rgba(20, 22, 26, 0.06);  /* very faint gridline */
  --fin-axis:      var(--ink-5);            /* axis + label gray */
  --fin-line-neg:  #CE4437;                 /* red "down" line state (matched to --fin-down-line) */

  /* ── Legacy alias tokens ──────────────────────────────────────────────────
     Several JSX surfaces reference --good / --danger / --brand / --surface /
     --ink-1 — synonyms that were never defined, so the browser silently
     resolved them to nothing (colorless status text, transparent panel
     backgrounds). Aliased once here; var() chains resolve per-element at
     computed-value time, so [data-theme="mid"|"dark"] pick up their own
     --ok / --bad / --bg-card automatically. Use the canonical tokens
     (--ok / --bad / --indigo / --bg-card / --ink) in new code. */
  --good: var(--ok);
  --danger: var(--bad);
  --brand: var(--indigo);
  --surface: var(--bg-card);
  /* --surface-2 — one tint step above --surface (chip/tag/secondary fills).
     Matches the literal fallbacks in use (rgba(0,0,0,.03) / rgba(127,127,127,.08)
     ≈ --bg-hover in both themes); alias resolves per-theme automatically.
     NOTE: --bg-base is DELIBERATELY not defined — its two usage families
     conflict (.sr-dash-chip.active expects var(--bg); the SR demo intro
     overlays in studio-review.jsx expect always-dark #0f1117). Defining it
     as var(--bg) would white-out the demo intro in light theme. Migrate the
     demo-overlay sites off --bg-base first, then define it as var(--bg). */
  --surface-2: var(--bg-hover);
  /* --surface-1 / --surface-3 — SAME FAMILY, FOUND 2026-08-14 by the sweep in
     scripts/test_modal_visibility_contract.js. Both were read WITHOUT a fallback and
     neither existed, so `.imp-card` (styles.css:~1941 — the office → Finance →
     Banking "Other ways to bring transactions in" card) painted NO BACKGROUND
     AT ALL, and `.imp-ico` / `.imp-dupe` were transparent chips. Identical
     mechanism to the Stripe onboarding modal that shipped with no surface
     (9762faab): an undefined var() resolves to nothing and the browser says
     nothing about it.
     --surface-1 is the base card surface (a synonym of --surface, kept because
     the ".imp-*" block reaches for the numbered scale); --surface-3 is the step
     BELOW --surface-2 in elevation — the inset/sunken fill. */
  --surface-1: var(--bg-card);
  --surface-3: var(--bg-sunk);
  --ink-1: var(--ink);
  /* --mono — the font-family read by .lawyer-var-occ / .lawyer-var-from-val
     without a fallback. The real token has always been --f-mono; this name was
     never defined, so those two rules declared an invalid font-family and the
     "monospace" affordance silently did not exist. */
  --mono: var(--f-mono);
  /* Same family, found 2026-08-02: the landing STATUS page styles its
     incident levels with var(--amber) (6 sites, landing.jsx:2243-2467) and
     its healthy state with var(--success, var(--green)) — and NONE of those
     three names was ever defined, so "Minor service disruption", "Partial
     service outage" AND "Operational" all rendered colorless. Aliased rather
     than rewritten at the call sites so the whole family resolves per-theme.
     Use the canonical --warn / --ok in new code. */
  --amber:   var(--warn);
  --success: var(--ok);
  --green:   var(--ok);

  --shadow-sm: 0 1px 0 rgba(20,20,30,.04), 0 1px 2px rgba(20,20,30,.04);
  --shadow-md: 0 1px 0 rgba(20,20,30,.05), 0 6px 18px -8px rgba(20,20,30,.10);
  --shadow-lg: 0 24px 48px -16px rgba(20,20,30,.18);

  /* SCRIM — the dim behind an overlay that captures the next tap. Added
     2026-08-17 for the client portal's phone nav drawer, which is a token-only
     family and had NO token to reach for; the value is the one .modal-overlay
     has always hardcoded (rgba(0,0,0,0.35), styles.css ~14422). ⚠️ It is
     deliberately NOT re-declared per theme: a scrim is a DIM, not a colour, so
     an --ink-derived value would go WHITE in dark mode and stop reading as
     "behind". ⚠️ .modal-overlay is not repointed at this token here — that
     block is duplicated verbatim (last one wins) and belongs to the dialog
     layer, not to this change; adopting it there is its own edit. */
  --scrim: rgba(0,0,0,0.35);

  /* ── Motion tokens ──────────────────────────────────────────────────────────
     Use --duration-fast  for popovers, toggles, hover affordances (120ms)
     Use --duration-base  for modals, inline expands, default panels (180ms)
     Use --duration-slow  for sheet panels, page-level transitions (260ms)
     Easing:
       --ease-out     → exits / "settles into place"
       --ease-in-out  → default enter for most elements
       --ease-spring  → playful pop affordances (subtle overshoot)
     NEW code must use these tokens. Other minions adopt on first touch.
     ──────────────────────────────────────────────────────────────────────── */
  --duration-fast:  120ms;
  --duration-base:  180ms;
  --duration-slow:  260ms;
  --ease-out:       cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out:    cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring:    cubic-bezier(0.34, 1.56, 0.64, 1);
}

[data-theme="dark"] {
  --bg: #0e0f12;
  --bg-elev: #14161a;
  --bg-card: #161820;
  --bg-sunk: #0a0b0e;
  --bg-hover: #1c1e26;
  --line: #232631;
  --line-strong: #2e313d;
  --line-soft: #1a1c24;
  --ink: #ecedf0;
  --ink-2: #d0d2d9;
  --ink-3: #9da0ab;
  --ink-4: #6f717b;
  --ink-5: #4a4c55;

  --indigo: oklch(72% 0.14 268);
  --indigo-soft: oklch(28% 0.07 268);
  --indigo-line: oklch(38% 0.10 268);
  --indigo-ink: oklch(82% 0.10 268);

  --ok: oklch(72% 0.12 155);
  --ok-soft: oklch(26% 0.05 155);
  --ok-line: oklch(36% 0.07 155);
  --warn: oklch(78% 0.14 70);
  --warn-soft: oklch(28% 0.06 70);
  --warn-line: oklch(40% 0.10 60);
  --bad: oklch(72% 0.16 28);
  --bad-soft: oklch(28% 0.07 28);
  --bad-line: oklch(40% 0.10 28);

  --info: var(--indigo);
  --info-soft: var(--indigo-soft);
  --info-line: var(--indigo-line);
  --info-ink: var(--indigo-ink);

  /* Canvas mat — a hair lighter/cooler than --bg-sunk so it still reads as
     a distinct surface instead of pure black. */
  --sr-canvas-bg: #15171c;

  /* Finance chart palette — dark variant (see :root for usage notes) */
  --fin-line:      #21CE56;
  --fin-fill:      rgba(33, 206, 86, 0.14);
  --fin-up:        #6FB97C;
  --fin-down:      #D07A70;
  --fin-down-line: #D07A70;                 /* outflow LINE — validated ≥3:1 + CVD ΔE 20.5 vs --fin-line on #161820 */
  --fin-projected: rgba(33, 206, 86, 0.50);
  --fin-grid:      rgba(255, 255, 255, 0.06);
  --fin-axis:      var(--ink-5);
  --fin-line-neg:  #F0564B;

  --shadow-sm: 0 1px 0 rgba(0,0,0,.4);
  --shadow-md: 0 6px 18px -8px rgba(0,0,0,.6);
}

/* density */
.density-spacious { --d-pad: 28px; --d-gap: 22px; --d-row: 52px; --d-card-pad: 26px; }
.density-balanced { --d-pad: 20px; --d-gap: 16px; --d-row: 44px; --d-card-pad: 22px; }
.density-dense    { --d-pad: 14px; --d-gap: 10px; --d-row: 36px; --d-card-pad: 16px; }

/* base */
* { box-sizing: border-box; }
html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }
body { width: 100%; height: 100%; overflow: hidden; margin: 0; padding: 0; }
#root { width: 100%; height: 100%; display: flex; flex-direction: column; overflow: hidden; }
body {
  font-family: var(--f-sans);
  background: var(--bg);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01", "cv11";
  letter-spacing: -0.005em;
}
button { font: inherit; color: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
h1,h2,h3,h4 { margin: 0; font-weight: 500; letter-spacing: -0.02em; }

/* numerals in serif */
.numstat { display: inline-flex; align-items: baseline; gap: 2px; font-family: var(--f-sans); font-feature-settings: "lnum","tnum"; }
.numstat-lg .numstat-value { font-size: 32px; line-height: 1.05; letter-spacing: -0.02em; font-weight: 400; }
.numstat-md .numstat-value { font-size: 22px; line-height: 1.1; }
.numstat-sm .numstat-value { font-size: 16px; line-height: 1.2; }
.numstat-prefix, .numstat-suffix { color: var(--ink-3); font-size: 0.65em; font-family: var(--f-sans); }

/* eyebrow label */
.eyebrow {
  font-family: var(--f-sans);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-4);
  font-weight: 500;
}

/* ─── App shell ───────────────────────────────────────────────────────────── */
.app-root { display: flex; flex-direction: row; height: 100%; width: 100%; overflow: hidden; background: var(--bg); }
.app-right {
  flex: 1 1 auto; min-width: 0; max-width: 9999px;
  display: flex; flex-direction: column; overflow: hidden;
  container-type: inline-size;
  position: relative;
  transition: max-width 0.3s cubic-bezier(0.4,0,0.2,1), opacity 0.25s ease;
}
.app-chat-panel.cmd-expanded ~ .app-right {
  max-width: 0; opacity: 0; pointer-events: none;
}

/* legacy .app kept for safety */
.app { display: flex; flex-direction: row; min-height: 100vh; background: var(--bg); }

/* ⭐ THE PLATFORM'S "FLOATING NAV" IS THIS RULE — elevated card, 12px radius,
   8px inset margins, sticky. The CLIENT PORTAL WEARS THIS EXACT CLASS (plus
   .ext-sidebar for its handful of deltas) rather than owning a lookalike, so a
   restyle here reaches both surfaces and cannot drift. The portal's deltas —
   and the reason each one exists — live in the .ext-* block at the bottom of
   this file; grep `.ext-sidebar`. Do not fork this rule for the portal. */
.sidebar {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 12px;
  position: sticky; top: 0; height: calc(100% - 16px);
  display: flex; flex-direction: column;
  padding: 6px 8px 16px;
  width: 216px; flex-shrink: 0;
  z-index: 10;
  margin: 8px 0 8px 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.07);
  transition: width 0.25s cubic-bezier(0.4,0,0.2,1), padding 0.25s cubic-bezier(0.4,0,0.2,1),
              margin 0.25s cubic-bezier(0.4,0,0.2,1), opacity 0.2s ease, border 0.25s ease;
  overflow: hidden;
}
.sidebar .nav { flex: 0 0 auto; }
.sidebar .chat-ctx-sidebar { flex: 1; min-height: 0; }
.sidebar .sidebar-foot { margin-top: auto; flex-shrink: 0; }
/* Chat context slot — fills sidebar below nav items */
.chat-ctx-sidebar {
  flex: 1; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column;
  border-top: 1px solid var(--line);
  margin-top: 8px; padding-top: 8px;
}
.chat-ctx-sidebar .cmd-sidebar-content { flex: 1; min-height: 0; overflow-y: auto; }
.chat-ctx-sidebar .cmd-sidebar-tabs {
  flex-shrink: 0; border-bottom: none;
  display: flex; align-items: center;
  padding: 0 8px 4px; gap: 2px;
}
.chat-ctx-sidebar .cmd-sidebar-tab {
  flex: none; padding: 3px 8px; border-radius: var(--radius-btn); border-bottom: none;
  margin-bottom: 0; font-size: 11.5px; font-weight: 500; color: var(--ink-4);
  transition: background .1s, color .1s;
}
.chat-ctx-sidebar .cmd-sidebar-tab:hover { background: var(--bg-hover); color: var(--ink); }
.chat-ctx-sidebar .cmd-sidebar-tab.active { background: var(--bg-hover); color: var(--ink); }
.chat-ctx-sidebar .cmd-proj-sidebar-head { display: none; }
.sidebar.collapsed .chat-ctx-sidebar { display: none; }
.brand {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 4px 12px; margin-bottom: 4px;
  margin-top: 36px;
}
.brand-glyph {
  width: 24px; height: 24px;
  color: var(--ink); display: block; flex: 0 0 auto;
}
.brand-name { font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink); }
.crumb-home {
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--ink-3); cursor: pointer;
  border-radius: 4px;
  transition: color .12s;
}
.crumb-home:hover { color: var(--ink); }
.brand-tag { font-family: var(--f-sans); font-style: italic; color: var(--ink-3); font-size: 12.5px; line-height: 1.35; padding: 8px 8px 0; max-width: 18ch; }

.nav { display: flex; flex-direction: column; gap: 1px; flex: 0 0 auto; }
/* The brand used to provide top clearance for the fixed collapse/fullscreen
   controls; now that it's moved below the nav, the nav itself clears them. */
.sidebar .nav { margin-top: 38px; }
.sidebar.collapsed .nav { margin-top: 84px; }
/* Aecos Intelligence button — titles the chats/projects list + opens the chat. */
.nav-intel {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 8px; margin: 10px 2px 4px;
  width: calc(100% - 4px); text-align: left;
  background: none; border: 0; cursor: pointer; border-radius: var(--radius-btn);
  color: var(--ink); transition: color .12s, background .12s;
}
.nav-intel:hover, .nav-intel:focus-visible { color: var(--brand, #5e5ce6); background: var(--bg-hover); outline: none; }
.nav-intel:hover .nav-intel-glyph, .nav-intel:focus-visible .nav-intel-glyph { color: var(--brand, #5e5ce6); }
.nav-intel-glyph { width: 22px; height: 22px; flex: 0 0 auto; color: inherit; display: block; }
.nav-intel-name { font-size: 13.5px; font-weight: 550; letter-spacing: -0.01em; color: inherit; }
.sidebar.collapsed .nav-intel { justify-content: center; padding-left: 0; padding-right: 0; width: 100%; margin-left: 0; margin-right: 0; }
/* Chat panel header close button */
.cmd-head-close {
  background: none; border: 0; cursor: pointer; color: var(--ink-4);
  padding: 4px; border-radius: var(--radius-btn-icon); display: flex; align-items: center;
  transition: color .12s, background .12s; flex-shrink: 0;
}
.cmd-head-close:hover { color: var(--ink); background: var(--bg-hover); }
.nav-section { font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em; color: var(--ink-5); padding: 14px 8px 6px; font-weight: 500; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; border-radius: var(--radius-btn);
  color: var(--ink-4); font-size: 13px; font-weight: 450;
  background: none; border: 0; width: 100%; text-align: left;
  position: relative;
  transition: color .12s;
}
.nav-item:hover { color: var(--ink); }
.nav-item.active { color: var(--ink); }
.nav-item.active::before {
  content: ""; position: absolute; left: -8px; top: 7px; bottom: 7px; width: 2px;
  background: var(--indigo); border-radius: 0 2px 2px 0;
}
.nav-item .nav-icon { color: var(--ink-5); flex: 0 0 auto; transition: color .12s; }
.nav-item:hover .nav-icon { color: var(--ink-3); }
.nav-item.active .nav-icon { color: var(--indigo); }
/* Contextual rail (Time & Calendar sections replacing the Operate list). */
.nav-context-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-5); padding: 10px 10px 4px;
}
.nav-item-back { color: var(--ink-5); font-weight: 500; margin-bottom: 2px; }
.nav-item-back:hover { color: var(--ink-2); }
.nav-badge { margin-left: auto; font-size: 10.5px; color: var(--ink-4); font-feature-settings: "tnum"; }

.sidebar-foot {
  padding: 8px 0 0; margin-top: 8px;
  position: relative;
}
.avatar-btn {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: none; border: none; cursor: pointer; padding: 6px 8px;
  border-radius: var(--radius-btn-icon); text-align: left; transition: background .12s;
}
.avatar-btn:hover { background: var(--bg-hover); }
.avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--ink); color: var(--bg-elev); display: grid; place-items: center; font-size: 11px; font-weight: 500; flex: 0 0 auto; letter-spacing: 0; background-size: cover; background-position: center; background-repeat: no-repeat; }
.avatar.has-img { background-color: var(--bg-card); }
.avatar-info { flex: 1; min-width: 0; }
.avatar-name { font-size: 12.5px; font-weight: 500; line-height: 1.2; }
.avatar-role { font-size: 11px; color: var(--ink-4); line-height: 1.2; }
.avatar-chevron { color: var(--ink-4); flex: 0 0 auto; }

/* Profile drop-up */
.profile-dropup {
  position: absolute; bottom: calc(100% + 6px); left: 0; right: 0;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); box-shadow: var(--shadow-lg);
  padding: 5px; z-index: 200;
  animation: dropupIn .12s ease;
}
@keyframes dropupIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
.profile-dropup-section {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-5); font-weight: 500; padding: 6px 10px 3px;
}
.profile-dropup-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 7px 10px; border-radius: var(--radius-btn-icon);
  background: none; border: none; cursor: pointer; text-align: left;
  font-size: 13px; color: var(--ink-3); transition: background .1s, color .1s;
}
.profile-dropup-item:hover { background: var(--bg-hover); color: var(--ink); }
.profile-dropup-item.active { color: var(--indigo); }
.profile-dropup-divider { height: 1px; background: var(--line-soft); margin: 4px 0; }
.profile-dropup-signout { color: var(--ink-4); }
.profile-dropup-signout:hover { color: var(--red, #ef4444); }

/* Profile drop-up — Switch-account sub-section.
   Gated in JSX on AECOS_SCHEMA.hasMultiAccount, so these selectors are inert
   when the schema flag is off (the drop-up keeps its Sign-out-only shape). */
.profile-dropup-switch-toggle { gap: 9px; }
.profile-dropup-switch-label { flex: 1; min-width: 0; text-align: left; }
.profile-dropup-switch-chev { color: var(--ink-5); flex: 0 0 auto; }
.profile-dropup-switch-panel {
  display: flex; flex-direction: column; gap: 2px;
  margin: 2px 0 4px;
  max-height: 280px; overflow-y: auto;
}
.profile-dropup-acct-wrap { display: flex; flex-direction: column; }
.profile-dropup-acct {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 6px 8px; border-radius: 6px;
  background: none; border: none; cursor: pointer; text-align: left;
  color: var(--ink-2); transition: background .1s;
}
.profile-dropup-acct:hover,
.profile-dropup-acct.is-expanded { background: var(--bg-hover); }
.profile-dropup-acct.is-active { background: color-mix(in oklab, var(--indigo, #6366f1) 8%, transparent); cursor: default; }
.profile-dropup-acct.is-active:hover { background: color-mix(in oklab, var(--indigo, #6366f1) 10%, transparent); }
.profile-dropup-acct-meta {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px;
}
.profile-dropup-acct-name {
  font-size: 12.5px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-dropup-acct-email {
  font-size: 11px; color: var(--ink-4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.profile-dropup-acct-check { color: var(--indigo, #6366f1); flex: 0 0 auto; }
.profile-dropup-acct-status {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-5); flex: 0 0 auto;
}
.profile-dropup-acct-signin {
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px 8px 8px 41px;
}
.profile-dropup-acct-input {
  width: 100%; padding: 6px 8px;
  font-size: 12.5px; color: var(--ink);
  background: var(--bg-sunk); border: 1px solid var(--line);
  border-radius: 5px; outline: none;
}
.profile-dropup-acct-input:focus { border-color: var(--line-strong); }
.profile-dropup-acct-err {
  font-size: 11px; color: var(--bad, #dc2626);
}
.profile-dropup-acct-submit {
  align-self: flex-end; padding: 5px 10px;
  font-size: 11.5px; font-weight: 500;
  color: #fff; background: var(--ink);
  border: none; border-radius: 5px; cursor: pointer;
}
.profile-dropup-acct-submit:disabled { opacity: 0.5; cursor: default; }
.profile-dropup-acct-submit:not(:disabled):hover { opacity: 0.9; }
.profile-dropup-acct-cancel {
  padding: 5px 10px;
  font-size: 11.5px; color: var(--ink-3);
  background: none; border: none; cursor: pointer; border-radius: 5px;
}
.profile-dropup-acct-cancel:hover { background: var(--bg-hover); color: var(--ink); }
.profile-dropup-acct-add {
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px;
  border-top: 1px solid var(--line-soft); margin-top: 2px;
}
.profile-dropup-acct-add-row {
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
}
.profile-dropup-acct-add-btn {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 7px 10px; border-radius: var(--radius-btn-icon);
  background: none; border: none; cursor: pointer; text-align: left;
  font-size: 12.5px; color: var(--ink-3);
  border-top: 1px solid var(--line-soft); margin-top: 2px;
  transition: background .1s, color .1s;
}
.profile-dropup-acct-add-btn:hover { background: var(--bg-hover); color: var(--ink); }
.profile-dropup-acct-add-btn svg { color: currentColor; opacity: 0.85; flex: 0 0 auto; }

/* ─── Auth page ───────────────────────────────────────────────────────────── */
.auth-screen {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: var(--bg); padding: 24px; position: relative;
}
.auth-back-link {
  position: absolute; top: 24px; left: 24px;
  background: none; border: none; padding: 8px 12px; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--ink-3);
  border-radius: 6px;
  transition: color 0.15s, background-color 0.15s;
}
.auth-back-link:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 5%, transparent); }
.auth-card {
  width: 100%; max-width: 400px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 16px; padding: 40px 36px;
  box-shadow: var(--shadow-lg);
}
.auth-brand { display: flex; align-items: center; gap: 10px; margin-bottom: 28px; }
.auth-glyph { width: 32px; height: 32px; color: var(--ink); }
.auth-brand-name { font-size: 18px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.auth-title { font-size: 20px; font-weight: 600; color: var(--ink); margin-bottom: 24px; letter-spacing: -0.02em; }
.auth-form { display: flex; flex-direction: column; gap: 14px; }
.auth-field { display: flex; flex-direction: column; gap: 5px; }
.auth-field label { font-size: 12.5px; font-weight: 500; color: var(--ink-3); }
.auth-field input {
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-elev); font: inherit; font-size: 14px; color: var(--ink);
  outline: none; transition: border-color .15s;
}
.auth-field input:focus { border-color: var(--indigo); }
.auth-error { font-size: 12.5px; color: var(--red, #ef4444); padding: 8px 10px; background: color-mix(in srgb, var(--red, #ef4444) 8%, transparent); border-radius: 6px; }
.auth-submit { width: 100%; padding: 11px; margin-top: 4px; font-size: 14px; justify-content: center; }
.auth-switch { margin-top: 20px; font-size: 13px; color: var(--ink-4); text-align: center; }
.auth-switch button { background: none; border: none; cursor: pointer; color: var(--indigo); font: inherit; font-size: 13px; }
.auth-switch button:hover { text-decoration: underline; }
.auth-footnote { margin-top: 28px; font-size: 11.5px; color: var(--ink-5); text-align: center; line-height: 1.5; }
/* Sign-up consent disclosure (ToS + Privacy). Sits inside .auth-form as a
   flex child so the form's 14px gap spaces it from the password field above
   and the submit button below. */
.auth-consent { font-size: 11.5px; color: var(--ink-4); text-align: center; line-height: 1.55; }
.auth-consent a { color: var(--indigo); text-decoration: none; }
.auth-consent a:hover { text-decoration: underline; }
.auth-verify-icon { font-size: 36px; text-align: center; margin-bottom: 8px; }
.auth-verify-body { font-size: 13.5px; color: var(--ink-3); line-height: 1.6; text-align: center; }
.auth-inline-btn { background: none; border: none; cursor: pointer; color: var(--indigo); font: inherit; padding: 0; }
.auth-inline-btn:hover { text-decoration: underline; }

/* ─── App loading screen ──────────────────────────────────────────────────── */
.app-loading { display: flex; flex-direction: column; align-items: center; gap: 20px; }
.app-loading-logo {
  width: 56px; height: 56px; color: var(--ink);
  animation: logo-spin 3s linear infinite;
  opacity: 0.85;
}
@keyframes logo-spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Appearance toggle + popup */
.foot-row { display: flex; align-items: center; gap: 2px; }
.foot-row .avatar-btn { flex: 1; min-width: 0; }
.appearance-toggle {
  width: 28px; height: 28px; border-radius: var(--radius-btn); border: none;
  background: none; color: var(--ink-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto; transition: background .1s, color .1s;
}
.appearance-toggle:hover { background: var(--bg-hover); color: var(--ink); }
.appearance-popup {
  position: absolute; bottom: calc(100% + 6px); right: 0;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow-lg);
  padding: 4px; z-index: 200; min-width: 130px;
  animation: dropupIn .12s ease;
}
.appearance-popup-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-5);
  padding: 6px 10px 2px;
}
.appearance-opt {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 7px 10px; border-radius: 6px;
  background: none; border: none; cursor: pointer;
  font-size: 12.5px; color: var(--ink-2); transition: background .1s, color .1s;
}
.appearance-opt:hover { background: var(--bg-hover); color: var(--ink); }
.appearance-opt.active { color: var(--ink); font-weight: 500; }
.appearance-check { margin-left: auto; color: var(--indigo); }

/* Collapsed sidebar — fully hidden */
/* Collapsed = icon-only mini rail (not fully hidden): keep a narrow sidebar
   showing each nav item's icon; labels hide (JSX) + Tooltip surfaces them. */
.sidebar.collapsed {
  width: 60px;
  padding: 6px 6px 16px;
}
/* In the rail the top controls stack vertically (fullscreen top:8 + collapse
   toggle top:50, each 39px tall → toggle bottom ~89px). Push the logo + nav
   icons down so they begin clearly below both controls, with no overlap. */
.sidebar.collapsed .brand { justify-content: center; padding-left: 0; padding-right: 0; margin-top: 90px; }
.sidebar.collapsed .nav-item {
  justify-content: center; gap: 0;
  padding-left: 0; padding-right: 0;
}
.sidebar.collapsed .nav-item.active::before { left: -6px; }
.sidebar.collapsed .nav-badge { display: none; }
.sidebar.collapsed .avatar-btn { justify-content: center; padding-left: 0; padding-right: 0; width: 100%; }
/* Collapsed: the avatar sits inside a Tooltip wrapper, so flex:1 never reaches the
   button — center the foot-row (and stretch the wrapper) so the avatar lines up
   under the nav icons instead of hugging the left edge. */
.sidebar.collapsed .foot-row { justify-content: center; }
.sidebar.collapsed .foot-row > * { flex: 1; display: flex; justify-content: center; }

/* Sidebar collapse toggle */
.sidebar-collapse-btn {
  position: fixed; top: 8px; left: 20px; z-index: 200;
  background: none; border: none; cursor: pointer;
  padding: 12px 8px; border-radius: var(--radius-btn-icon);
  color: var(--ink-4);
  transition: background .12s, color .12s,
              top .25s cubic-bezier(0.4,0,0.2,1), left .25s cubic-bezier(0.4,0,0.2,1);
  display: flex; align-items: center; justify-content: center;
}
.sidebar-collapse-btn:hover { background: var(--bg-hover); color: var(--ink); }
/* Expanded nav: fullscreen sits just right of the collapse toggle (side by side). */
.sidebar-ctl-fullscreen { left: 52px; }
/* Collapsed icon rail: stack the two controls vertically inside the 60px rail,
   centered like the nav icons — fullscreen on top, collapse toggle below it. */
.sidebar-ctl-fullscreen.is-rail { top: 8px;  left: 22px; }
.sidebar-ctl-toggle.is-rail     { top: 50px; left: 22px; }

/* ─── AI chat panel — chat messages column ───────────────────────────────── */
.cmd-resize-handle {
  position: absolute; right: 0; top: 0; bottom: 0; width: 4px;
  cursor: col-resize; z-index: 10;
  transition: background .15s;
}
.cmd-resize-handle:hover { background: var(--indigo); opacity: 0.4; }
.app-chat-panel {
  position: relative;
  flex: 0 0 auto; width: 300px;
  display: flex; flex-direction: column;
  background: var(--bg);
  border-right: 1px solid var(--line);
  height: 100vh; position: sticky; top: 0;
  overflow: hidden;
  transition: flex-grow 0.3s cubic-bezier(0.4,0,0.2,1), width 0.32s cubic-bezier(0.4,0,0.2,1), opacity 0.22s ease;
}
.app-chat-panel.sr-hidden {
  width: 0 !important;
  opacity: 0;
  pointer-events: none;
  border-right: none;
  /* QA finding #8: a collapsed panel must not keep growing to fill the flex row.
     Without these, `.cmd-expanded { flex-grow: 1 }` wins and the width:0 panel still
     spans the whole app as an invisible slab. Neutralize the flex sizing too. */
  flex-grow: 0 !important;
  flex-basis: 0 !important;
  min-width: 0 !important;
}
.app-chat-panel.resizing {
  transition: none; user-select: none;
}
.app-chat-panel.cmd-expanded {
  flex-grow: 1;
  border-right: none;
}

/* ⭐ EXPANDED CHAT READS AS A CENTRED COLUMN, NOT FULL BLEED.
   `.chat-msg` is capped at 760px, but `.chat-msg.ai` is `align-self: flex-start`
   and `.chat-msg.user` is `align-self: flex-end` — so in a narrow docked panel
   they sit sensibly, while in the expanded panel (which grows to fill the
   window) the AI column pins to the far LEFT and the user's turns pin to the
   far RIGHT. Nothing shares an axis, and the eye reads it as full-bleed and
   lopsided rather than as a conversation.

   Centring the THREAD instead of the messages keeps the left/right bubble
   behaviour intact *inside* the column, which is what every chat UI that reads
   well does. `width: 100%` is required — a flex column child would otherwise
   shrink-to-fit and the auto margins would have nothing to distribute. */
.app-chat-panel.cmd-expanded .chat-thread {
  width: 100%;
  max-width: 820px;
  margin-inline: auto;
}
.app-chat-panel.cmd-expanded .chat-input {
  width: 100%;
  max-width: 820px;
  margin-inline: auto;
}
/* ⚠️ THE TWO RULES ABOVE NEVER MATCHED ANYTHING (found 2026-08-20). They were
   written against the ANALYST page's class names (.chat-thread / .chat-input),
   but the panel that carries .cmd-expanded is the Command Center chat, whose
   thread is .cmd-chat-scroll and whose composer is .cmd-chat-composer — so the
   shipped "centred column" fix silently applied to nothing and the expanded
   chat stayed full-bleed. The rules stay (harmless, and the comment above is
   the design rationale); these are the selectors that actually exist in that
   panel. Rows are centred rather than the scroll container so the scrollbar
   stays at the panel edge; the landing keeps its own 1040px cap
   (.cmd-general-landing-inner) and is deliberately not touched. */
.app-chat-panel.cmd-expanded .cmd-chat-scroll .cmd-chat-row,
.app-chat-panel.cmd-expanded .cmd-chat-scroll .cmd-proj-instructions {
  width: 100%;
  max-width: 820px;
  margin-inline: auto;
}
.app-chat-panel.cmd-expanded .cmd-chat-composer {
  /* calc keeps the composer's own 12px gutters when the panel is narrower
     than the cap (margin-inline:auto replaces the base rule's side margins) */
  width: calc(100% - 24px);
  max-width: 820px;
  margin-inline: auto;
}

/* Topbar buttons */
.topbar-nav-btn { color: var(--ink-4); }
.topbar-nav-btn:hover { color: var(--ink); }
.topbar-nav-toggle {
  background: none; border: none; cursor: pointer;
  padding: 4px; border-radius: 6px; margin-right: 8px;
  color: var(--ink-4); display: flex; align-items: center; justify-content: center;
  transition: background .12s, color .12s;
  flex-shrink: 0;
}
.topbar-nav-toggle:hover { background: var(--bg-hover); color: var(--ink); }

/* ─── Top header ──────────────────────────────────────────────────────────── */
.topbar {
  /* OVERLAY, not in-flow. The frost was invisible because the .page scroll
     container used to sit BELOW the in-flow bar — content clipped at the bar's
     bottom edge, so the backdrop-filter only ever blurred the flat app
     background (proven live: pageOverlapsTopbar=false, 50% --bg-card over
     --bg-sunk ≈ imperceptible). Absolute-positioning the bar over .page (which
     pads its content below via --topbar-clearance, set by AppShell) lets page
     content actually scroll BEHIND the glass, which is what makes blur read. */
  /* ⚠️ z-index 60, NOT 5 — APP CHROME MUST OUTRANK PAGE CONTENT.
     At 5 the bar tied with `.ts-cal-split-headrow` (also z-index 5, sticky), and
     on a tie DOM ORDER decides: the calendar header comes later, so it painted
     ON TOP. The visible symptom was the notifications popover appearing sliced —
     a teammate's calendar banner cut straight through the list, leaving
     "…tifications" and half a row showing (founder, 2026-08-05, Split view).
     ⚠️ THE POPOVER'S OWN `z-index: 400` COULD NOT HELP, and that is the part
     worth remembering: `.notif-popover` lives INSIDE this bar, and this bar's
     z-index creates a STACKING CONTEXT — so 400 only orders it against its
     siblings in here, and the whole context still enters the page at the bar's
     own z-index. A big number on a child is meaningless once an ancestor has
     boxed it in. Same class as the AecosSelect menu that opened behind a panel
     at z 390 and looked dead.
     60 clears the page's dropdown band (30/40/50) and stays well under
     `.ts-modal-overlay` (300) — verified live: a modal overlay still covers the
     bar. The absolute positioning and the glass are unchanged; content still
     scrolls behind it, which is the whole reason this bar is an overlay. */
  position: absolute; top: 8px; left: 0; right: 0; z-index: 60;
  /* The BOX (border + rounded shape) is always visible — at the top it's a clean
     see-through outline; the frosted glass fills in on scroll. Unlike the landing
     nav (which fully blends away at the top), this bar keeps its box up there. */
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 20px;
  margin: 0 8px; /* horizontal insets via margin so the nav-collapsed inline marginLeft:52 keeps working */
  display: flex; align-items: center;
  gap: 12px;
  min-width: 0;
  background: transparent;
  /* Do NOT transition background/backdrop-filter — Chrome gets STUCK on the
     first transition from `transparent` to a color-mix(var(--bg-card)) value
     (it never resolves → the frost silently never appears; that was the bug).
     Snap those instantly; transition only literal-valued box-shadow + margin. */
  transition: margin-left 0.25s cubic-bezier(0.4,0,0.2,1), box-shadow 0.18s linear;
}
/* Frosted-glass fill that fades IN on scroll, like the landing nav pill. The
   fill lives DIRECTLY on the .topbar element (toggled by the `is-scrolled` class
   that AppShell adds when the .page scroll container is scrolled) — NOT on a
   ::before with opacity:var(--np). That earlier pseudo approach was unfixably
   broken: an unregistered custom property (--np) inside a *transitioned*
   `opacity` on a pseudo-element computes to 0 in Chrome no matter what (proven
   live — even `opacity:1 !important` couldn't move it). A class-toggled
   background on the element is bulletproof. At the top only the box outline
   shows; once you scroll, the blur + ~85% --bg-card fill + shadow firm in. */
.topbar.is-scrolled {
  /* Real glass: keep the fill LIGHT (~30%) and let the heavy blur do the work —
     at 85% it read as a solid bar, 50% still felt heavy. The blur+saturate is
     what keeps content behind it legible, not opacity, so a lighter fill reads
     as more transparent glass without hurting readability. (Content genuinely
     passes behind the bar — see the overlay note on .topbar — so blur is visible.) */
  background: color-mix(in srgb, var(--bg-card) 30%, transparent);
  -webkit-backdrop-filter: blur(28px) saturate(180%);
  backdrop-filter: blur(28px) saturate(180%);
  border-color: var(--line-strong);
  box-shadow: 0 2px 12px rgba(0,0,0,0.10);
}
.topbar-titlebar {
  display: flex; align-items: baseline; gap: 10px;
  min-width: 0;
  flex: 0 1 auto;
}
.topbar-title {
  font-size: 14px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-date {
  font-size: 11.5px; color: var(--ink-5);
  white-space: nowrap;
}
.topbar-search {
  flex: 1; max-width: 420px;
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 7px; padding: 7px 10px; color: var(--ink-4); font-size: 13px;
}
.topbar-search:focus-within { border-color: var(--line-strong); }
.topbar-search input { flex: 1; border: 0; background: none; outline: none; color: var(--ink); font: inherit; }
.topbar-search kbd {
  font-family: var(--f-mono); font-size: 10.5px; padding: 2px 6px;
  border: 1px solid var(--line); border-radius: 4px; color: var(--ink-4);
  background: var(--bg-card);
}
.topbar-right { display: flex; align-items: center; gap: 14px; margin-left: auto; min-width: 0; }
.topbar-actions { display: flex; align-items: center; gap: 6px; }
.topbar-firm {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 4px 0;
  font: inherit; font-size: 12.5px; color: var(--ink-3);
  max-width: 240px; min-width: 0;
}
.topbar-firm span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-firm svg { color: var(--ink-4); flex: 0 0 auto; }
/* Firm letterhead logo in the top-right, shown bigger than the old building icon
   and to the RIGHT of the firm name (workspace personalization 2026-07-24). */
.topbar-firm-logo {
  height: 22px; width: auto; max-width: 130px;
  object-fit: contain; flex: 0 0 auto; display: block; border-radius: 4px;
}
.topbar-action-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 10px; border-radius: var(--radius-btn-icon);
  font-size: 12px; font-weight: 500; color: var(--ink-3);
  background: none; border: 0; cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
  transition: color .12s, background .12s;
}
.topbar-action-btn:hover { color: var(--ink); background: var(--bg-hover); }
.topbar-action-btn--primary { color: var(--indigo); }
.topbar-action-btn--primary:hover { background: color-mix(in oklab, var(--indigo) 8%, transparent); }
.icon-btn {
  width: 32px; height: 32px; border-radius: var(--radius-btn-icon); border: 1px solid transparent;
  background: none; color: var(--ink-3); display: grid; place-items: center;
  position: relative;
}
.icon-btn:hover { background: var(--bg-hover); color: var(--ink); }
.icon-btn .dot-notif { position: absolute; top: 7px; right: 7px; width: 6px; height: 6px; border-radius: 50%; background: var(--bad); }

/* ─── Page ────────────────────────────────────────────────────────────────── */
/* padding-top clears the OVERLAID .topbar (absolute over this scroller — see
   .topbar). --topbar-clearance = measured bar height + its 8px top offset, set
   by AppShell on .app-right (0 when the bar is hidden, e.g. SR sessions).
   NOT transitioned, so the var-valued padding is safe per the var-transition
   Chrome gotcha. */
.page { padding: 16px 28px 40px; padding-top: calc(var(--topbar-clearance, 62px) + 16px); width: 100%; margin: 0; flex: 1; min-height: 0; overflow: auto; scrollbar-gutter: stable; }
/* Full-height surfaces (Time & Calendar) own their spacing — the page shell
   goes flush so the inner layout can use every vertical pixel (calendar grid
   fills to the viewport bottom instead of floating inside page padding).
   BUT the topbar is an absolute OVERLAY (see .topbar) — the bare `padding: 0`
   shorthand also wiped the topbar clearance, sliding the ts-layout header row
   ("Ask Aecos to log time…", Calendars toggle, ⌘T/⌘L hints) up UNDER the
   transparent bar so the topbar title/date rendered on top of it. Keep the
   sides/bottom flush but restore padding-top to the published clearance
   (already includes the bar's 8px top offset; 0 when the bar is hidden). */
.page:has(> .ts-layout) { padding: 0; padding-top: var(--topbar-clearance, 62px); overflow: hidden; }
.page-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 24px; margin-bottom: 18px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.page-desc { font-size: 12.5px; color: var(--ink-4); padding: 10px 28px; }
/* Command Center: the page itself scrolls VERTICALLY only. The offices row keeps
   its own overflow-x:auto (the one section meant to scroll sideways); a stray
   wide gadget (e.g. the Gantt axis) must not make the whole page scroll sideways.
   Scoped via :has(> .page-desc) — .page-desc is unique to the Command Center. */
.page:has(> .page-desc) { overflow-x: hidden; }
/* Offices row is a 2-track GRID (row 1 = the office cards, row 2 = the cashflow
   graphs) flowing into per-office columns. Grid makes every card in row 1 the same
   height and every graph in row 2 start at the same Y — so the cashflow gadgets line
   up beneath the cards regardless of a taller card or a taller graph. The location is
   allowed to show in full (wraps if long, e.g. SF's timezone) — the grid keeps the
   cards equal height anyway, so wrapping no longer misaligns anything (and nothing is
   truncated). Cards stretch to equal height; graphs keep their natural height
   (align-self:start) so charts aren't distorted, only their tops align. */
.cc-office-grid > .office-card { align-self: stretch; scroll-snap-align: start; min-width: 0; }
.cc-office-grid > :not(.office-card) { align-self: start; min-width: 0; }
.page-title { font-size: 26px; font-family: var(--f-sans); font-weight: 450; letter-spacing: -0.025em; }
.page-sub { color: var(--ink-3); font-size: 13px; margin-top: 4px; max-width: 60ch; }
.page-head-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* Consistent vertical rhythm — every direct child of .page gets spacing below it */
.page > * { margin-bottom: 28px; }
.page > *:last-child { margin-bottom: 0; }

/* Bookkeeping: the in-page H1 moved to the topbar, so .page-head only carries the
   stat sub-line + actions. The global .page > * { margin-bottom:28px } over-rode
   .page-head's own 18px and stacked with its 12px padding-bottom + border, leaving
   a big empty band before the view tabs. Tighten it so content sits under the
   header like every other page. */
.bk-page > .page-head { margin-bottom: 10px; padding-bottom: 10px; }

/* ─── PageHeader ──────────────────────────────────────────────────────────
   Replaces the ad-hoc .page-head pattern with a structured primitive.
   .page-header + __crumbs + __main + __text + __eyebrow + __title + __subtitle
                + __actions + __tabs. Modifiers: --border (default on),
   --with-tabs (auto-applied when tabs prop present, suppresses extra margin).
   ----------------------------------------------------------------------- */
.page-header {
  display: flex; flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
  padding-bottom: 12px;
}
.page-header--border { border-bottom: 1px solid var(--line); }
.page-header--with-tabs.page-header--border {
  /* When tabs are present, the tab strip carries its own underline so we
     don't need the page-header border duplicating it. */
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 24px;
}

.page-header__crumbs {
  /* Breadcrumbs sit above title; tighter rhythm */
  margin-bottom: -4px;
}

.page-header__main {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between;
  gap: 12px 24px;
}

.page-header__text {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.page-header__eyebrow {
  font-size: 11px; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-5);
}
.page-header__title {
  font-size: 26px; font-family: var(--f-sans); font-weight: 450;
  letter-spacing: -0.025em; color: var(--ink);
  line-height: 1.15;
  margin: 0;
}
.page-header__subtitle {
  font-size: 13px; color: var(--ink-3);
  margin: 0; max-width: 60ch; line-height: 1.5;
}

.page-header__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  flex: 0 0 auto;
}

.page-header__tabs {
  /* Tab strip slot — small top margin so it sits cleanly below the title row */
  margin-top: 4px;
}
.page-header__tabs .tabs { margin-bottom: 0; } /* avoid double-margin from Tabs primitive */

@media (max-width: 640px) {
  .page-header__title { font-size: 22px; }
  .page-header__main { gap: 8px; }
  .page-header__actions { width: 100%; }
}

/* ─── Splitter ──────────────────────────────────────────────────────────────
   Draggable divider between two panes.
   .splitter + __pane (--first|--second) + __handle (--row|--column) + __handle-grip
   Direction: --row (side-by-side, vertical divider) / --column (stacked,
                                                                  horizontal divider)
   ────────────────────────────────────────────────────────────────────────── */
.splitter {
  display: flex;
  width: 100%;
  height: 100%;
  min-width: 0; min-height: 0;
  position: relative;
}
.splitter--row    { flex-direction: row; }
.splitter--column { flex-direction: column; }
.splitter--disabled .splitter__handle { cursor: not-allowed; opacity: 0.5; }

.splitter__pane {
  min-width: 0; min-height: 0;   /* required so panes can shrink below content size */
  overflow: auto;
}
.splitter__pane--second {
  flex: 1 1 0;
}

/* Handle — the draggable divider. 6px wide visual hit area with a subtle
   center grip; hover/active brightens for affordance. */
.splitter__handle {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  background: transparent;
  border: none;
  padding: 0;
  z-index: 1;
}
.splitter__handle--row    { width: 6px;  cursor: col-resize; height: auto; }
.splitter__handle--column { height: 6px; cursor: row-resize; width: auto; }

.splitter__handle:hover,
.splitter__handle:active,
.splitter__handle:focus-visible {
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
}
.splitter__handle:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--indigo) 35%, transparent);
}

/* Center grip — visual hint that the handle is draggable. Two parallel
   lines like a window-resize cursor mark. */
.splitter__handle-grip {
  display: block;
  background: var(--line-strong);
  border-radius: 1px;
  transition: background var(--duration-fast, 120ms) ease-out;
}
.splitter__handle--row    .splitter__handle-grip { width: 2px;  height: 24px; }
.splitter__handle--column .splitter__handle-grip { height: 2px; width: 24px; }

.splitter__handle:hover .splitter__handle-grip,
.splitter__handle:active .splitter__handle-grip {
  background: var(--indigo);
}

/* buttons */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: var(--radius-btn); font-size: 13px; font-weight: 500;
  background: var(--bg-card); color: var(--ink); border: 1px solid var(--line-strong);
  transition: background .12s, border-color .12s;
}
.btn:hover { background: var(--bg-hover); }
/* Keyboard focus ring — matches the app's indigo ring convention. Uses OUTLINE
   (not box-shadow) so it composes with .btn-primary's inset rim shadow instead
   of clobbering it. Generic disabled state — .btn-primary/.btn-danger keep
   their own more specific disabled treatments. */
.btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent);
  outline-offset: 2px;
}
.btn:disabled, .btn[disabled] { opacity: .55; cursor: not-allowed; }
/* ── Primary button: living brand-gradient (landing treatment) ─────────────
   Replaces the flat fill with the landing's brand palette — the same indigo→
   violet→periwinkle family as .aecos-sheen-text / the Enterprise .aecos-aurora
   band — brought alive by a slow aurora wash that drifts via TRANSFORM only
   (compositor work, never background-position, per the aurora playbook) plus a
   one-shot sheen sweep on hover (same technique as .fsd-sheen). Box model is
   UNCHANGED (padding/radius/font/1px border all still come from .btn) so no
   layout shifts anywhere. Scoped STRICTLY to .btn-primary — .btn, .btn-ghost,
   .btn-danger and secondary variants stay untouched.
   Gotcha honored ([[feedback-css-var-transition-stuck]]): nothing animated or
   transitioned here rides on a var()/color-mix() value — the gradients are
   literal oklch/rgba, motion is transform/opacity/box-shadow. */
/* Calm treatment (founder 2026-07-16, quieted 2026-08-20): a subtle perimeter
   rim-light; hover BRIGHTENS the fill and the rim — nothing moves, nothing
   glows. Founder directive 2026-08-20 ("get rid of the effect where the
   button bounces forward on hover… don't do drop shadow anywhere"): the
   translateY lift and the hover glow shadow were removed. The ONE convention
   for button hover product-wide is a quiet fill lift — var(--bg-hover) on
   neutral buttons, a brighter literal gradient here (a white fill would kill
   the primary's meaning). No transform, no added shadow, ever. */
.btn-primary {
  position: relative; isolation: isolate;
  background: linear-gradient(118deg,
    oklch(44% 0.15 264),
    oklch(50% 0.18 288),
    oklch(46% 0.14 254));
  color: #fff; border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), 0 1px 3px rgba(20, 20, 40, 0.14);
  transition: box-shadow .18s cubic-bezier(0.16, 1, 0.3, 1);
}
.btn-primary:hover {
  /* brighter literal gradient — background SNAPS (not transitioned); only
     the literal-valued box-shadow rim animates */
  background: linear-gradient(118deg,
    oklch(48% 0.16 264),
    oklch(54% 0.19 288),
    oklch(50% 0.15 254));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.26), 0 1px 3px rgba(20, 20, 40, 0.14);
}
.btn-primary:active { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18), 0 1px 3px rgba(20, 20, 40, 0.14); }
/* Disabled must READ disabled — freeze all life, muted static fill, no rim. */
.btn-primary:disabled,
.btn-primary[disabled],
.btn-primary[aria-disabled="true"] {
  background: oklch(56% 0.045 268);
  color: rgba(255, 255, 255, 0.8);
  opacity: 0.6; cursor: not-allowed;
  transform: none; box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .btn-primary { transition: none; }
}
.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-3); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--ink); }
.btn-sm { padding: 5px 9px; font-size: 12px; }
.btn-xs { padding: 3px 8px; font-size: 11.5px; }
/* .btn-danger is defined once, later in this file (soft --bad-soft fill,
   hover fills solid). A stale solid duplicate that lived here leaked its
   `:hover { opacity: .88 }` into that hover — removed 2026-07-16. */

.cmd-confirm-backdrop {
  position: fixed; inset: 0; z-index: 9998;
  background: rgba(0,0,0,0.22);
  display: flex; align-items: center; justify-content: center;
}
.cmd-confirm-dialog {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; padding: 20px 22px;
  min-width: 288px; max-width: 340px;
  box-shadow: 0 8px 32px -8px rgba(0,0,0,0.22);
}
.cmd-confirm-title { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 5px; }
.cmd-confirm-sub { font-size: 12.5px; color: var(--ink-4); margin-bottom: 18px; line-height: 1.5; }
.cmd-confirm-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* ─── Cards ───────────────────────────────────────────────────────────────── */
.card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-sm);
}
.card-padded { padding: var(--d-card-pad); }

.section-header {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  margin-bottom: 18px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft);
}
.section-title { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.section-meta { color: var(--ink-4); font-size: 12px; margin-top: 3px; }

/* ─── Metric card ─────────────────────────────────────────────────────────── */
.metric-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  padding: 16px 18px 14px; box-shadow: var(--shadow-sm); position: relative; overflow: hidden;
  container-type: inline-size; min-width: 0;
  transition: border-color var(--duration-fast, 120ms) var(--ease-out, ease-out),
              box-shadow var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
/* Metric cards render inside bare-chrome <button> wrappers (Command Center
   KPI gadgets) but had zero hover/focus affordance despite being clickable.
   Add a subtle lift on hover + an indigo focus ring on keyboard focus. */
button:hover > .metric-card {
  border-color: var(--indigo-line);
  box-shadow: var(--shadow-sm), 0 2px 8px color-mix(in srgb, var(--indigo) 10%, transparent);
}
button:focus-visible > .metric-card {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .metric-card { transition: none; }
}
.metric-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.13em; color: var(--ink-4); font-weight: 500; }
.metric-value-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; margin-top: 10px; min-width: 0; }
/* Value scales with the card's inline size so long currencies (e.g. $2,310,450)
   shrink to fit narrow tiles instead of clipping; wide tiles keep the full 32px.
   Scoped to .metric-card so other numstat-lg usages (and .hcc-frame's own
   later override) are untouched. overflow-wrap is the guaranteed no-clip
   backstop for absurd lengths. */
.metric-card .numstat { min-width: 0; max-width: 100%; }
.metric-card .numstat-value { min-width: 0; overflow-wrap: anywhere; }
.metric-card .numstat-lg .numstat-value { font-size: clamp(16px, 12.5cqi, 32px); }
.metric-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin-top: 8px; font-size: 12px; min-width: 0; }
.metric-foot-text { color: var(--ink-4); min-width: 0; overflow-wrap: anywhere; }
.metric-delta { display: inline-flex; align-items: center; gap: 3px; font-size: 11.5px; font-weight: 500; padding: 1px 6px 1px 4px; border-radius: 4px; font-feature-settings: "tnum"; }
.delta-ok   { color: var(--ok); background: var(--ok-soft); }
.delta-bad  { color: var(--bad); background: var(--bad-soft); }
.delta-warn { color: var(--warn); background: var(--warn-soft); }
.delta-neutral { color: var(--ink-3); background: var(--bg-sunk); }
.metric-accent { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.metric-accent-ok { background: var(--ok); }
.metric-accent-warn { background: var(--warn); }
.metric-accent-bad { background: var(--bad); }
.metric-accent-indigo { background: var(--indigo); }

/* Command Center KPI gadgets: each gadget is a <button> grid item that wraps
   a .metric-card. The grid stretches its buttons to a uniform row height
   (~136px) but .metric-card's own height is content-sized — leaving a visible
   gap below the shorter cards (Outstanding A/R, Avg utilization → 118px vs
   the 135-136px of the other four). Force the inner card to fill the wrapper
   so all six gadgets read as equal-height tiles. Scoped to button-wrapped
   children so other .grid-metrics usages (where .metric-card is a direct
   grid item) keep their natural content height. */
.grid-metrics > button > .metric-card { height: 100%; box-sizing: border-box; }

/* ─── Stat ──────────────────────────────────────────────────────────────────
   Compact KPI: big value + label + optional trend arrow + delta.
   .stat + __row + __value + __trend + __delta + __label
   Size modifiers: --sm / --md / --lg
   Trend tones: --success / --danger / --warning / --neutral
   ────────────────────────────────────────────────────────────────────────── */
.stat {
  display: flex; flex-direction: column;
  gap: 4px;
  font-family: var(--f-sans);
  font-feature-settings: "lnum","tnum";
}

.stat__row {
  display: flex; align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.stat__value {
  font-weight: 450;
  color: var(--ink);
  letter-spacing: -0.025em;
  line-height: 1.05;
}
.stat--sm .stat__value { font-size: 18px; }
.stat--md .stat__value { font-size: 24px; }
.stat--lg .stat__value { font-size: 32px; }

.stat__trend {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px 2px 5px;
  border-radius: 99px;
  font-size: 11.5px; font-weight: 500; line-height: 1.4;
  font-feature-settings: "tnum";
  white-space: nowrap;
  /* Tone vars set on the chip; arrow + text inherit currentColor */
  background: var(--tone-soft, var(--bg-sunk));
  color: var(--tone-fg, var(--ink-3));
}
.stat--sm .stat__trend { padding: 1px 6px 1px 4px; font-size: 10.5px; }
.stat__trend svg  { color: currentColor; flex: 0 0 auto; }
.stat__delta { line-height: 1.4; }

.stat__trend--success { --tone-fg: var(--ok);   --tone-soft: var(--ok-soft); }
.stat__trend--danger  { --tone-fg: var(--bad);  --tone-soft: var(--bad-soft); }
.stat__trend--warning { --tone-fg: var(--warn); --tone-soft: var(--warn-soft); }
.stat__trend--neutral { --tone-fg: var(--ink-3); --tone-soft: var(--bg-sunk); }

.stat__label {
  font-size: 12px; color: var(--ink-4);
  letter-spacing: 0;
  line-height: 1.4;
  margin-top: 2px;
}
.stat--sm .stat__label { font-size: 11px; }
.stat--lg .stat__label { font-size: 13px; }

/* Compare subtext — small muted phrase after the label, e.g. "vs last month".
   Lives inside .stat__label as an inline span so it wraps with the label
   naturally on narrow containers. */
.stat__compare {
  color: var(--ink-5);
  font-weight: 400;
}

/* Loading skeleton — replaces the value span with a shimmer rectangle while
   data fetches. Sized to roughly match the would-be value's footprint so
   the layout doesn't jump when real data arrives. */
.stat--loading .stat__value-skeleton {
  display: inline-block;
  background: var(--bg-sunk);
  background-image: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--ink) 6%, transparent) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: skeleton-shimmer 1.6s linear infinite;
  border-radius: 5px;
  min-height: 1em;
}
.stat--sm.stat--loading .stat__value-skeleton { width: 64px;  height: 18px; }
.stat--md.stat--loading .stat__value-skeleton { width: 92px;  height: 24px; }
.stat--lg.stat--loading .stat__value-skeleton { width: 120px; height: 32px; }

@media (prefers-reduced-motion: reduce) {
  .stat__value-skeleton {
    animation: none; background-image: none; opacity: 0.8;
  }
}

/* ─── KeyValueList ────────────────────────────────────────────────────────────
   Definition-list metadata display (label : value pairs).
   .kv-list + __item + __key + __value + __value-text + __copy
   Layouts:  --rows (label-above-value stack) / --grid (label-left side-by-side)
   Sizes:    --sm / --md
   Modifiers: --dividers / --label-default / --label-caps / --align-start|end
   ────────────────────────────────────────────────────────────────────────── */

.kv-list {
  margin: 0;
  padding: 0;
  font-family: inherit;
  display: flex; flex-direction: column;
  gap: 10px;
}
.kv-list--sm { gap: 8px; }
.kv-list--md { gap: 10px; }

.kv-list--dividers .kv-list__item {
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft);
}
.kv-list--dividers .kv-list__item:last-child {
  padding-bottom: 0;
  border-bottom: none;
}
.kv-list--sm.kv-list--dividers .kv-list__item { padding-bottom: 8px; }

/* Rows layout — label on top, value below (default).
   Used when values are long, multi-line, or contain rich content. */
.kv-list--rows .kv-list__item {
  display: flex; flex-direction: column;
  gap: 2px;
}

/* Grid layout — label on left, value on right (2-col side-by-side).
   Used for tight metadata cards with short values. */
.kv-list--grid .kv-list__item {
  display: grid;
  grid-template-columns: minmax(80px, 30%) 1fr;
  gap: 12px;
  align-items: baseline;
}
.kv-list--grid.kv-list--align-end .kv-list__value { justify-self: end; text-align: right; }
.kv-list--grid.kv-list--align-end .kv-list__value-text { justify-content: flex-end; }

/* Multiline value override — switches the row to column layout so the value
   can wrap on its own line under the label even in grid mode. */
.kv-list--grid .kv-list__item--multiline {
  grid-template-columns: 1fr;
}

/* Key (label) — small, muted. Caps variant adds uppercase + letter spacing. */
.kv-list__key {
  font-size: 12px; font-weight: 500; color: var(--ink-4);
  letter-spacing: -0.005em;
  line-height: 1.4;
  margin: 0;
  min-width: 0;
}
.kv-list--sm .kv-list__key { font-size: 11px; }

.kv-list--label-caps .kv-list__key {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-5);
}
.kv-list--sm.kv-list--label-caps .kv-list__key { font-size: 10px; }

/* Value — supports inline-flex layout for value-text + copy button stacking */
.kv-list__value {
  display: flex; align-items: center; gap: 6px;
  margin: 0; min-width: 0;
  font-size: 13px; color: var(--ink);
  line-height: 1.45;
}
.kv-list--sm .kv-list__value { font-size: 12.5px; }

.kv-list__value-text {
  display: inline-flex; align-items: center; gap: 6px;
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kv-list__value-text--multiline {
  display: block;
  white-space: normal;
  word-wrap: break-word;
}

/* Copy button — small, appears in the value cell when copyable=true.
   Uses opacity-0 + opacity-1-on-hover so the button is non-distracting
   when not interacting but discoverable on row hover. */
.kv-list__copy {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--ink-4);
  cursor: pointer;
  flex: 0 0 auto;
  opacity: 0;
  transition: opacity var(--duration-fast, 120ms) ease-out,
              background var(--duration-fast, 120ms) ease-out,
              color var(--duration-fast, 120ms) ease-out;
}
.kv-list__item:hover .kv-list__copy,
.kv-list__copy:focus-visible {
  opacity: 1;
}
.kv-list__copy:hover {
  background: var(--bg-hover);
  color: var(--ink);
}
.kv-list__copy:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* ─── Pills ───────────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; font-size: 11.5px; font-weight: 500; line-height: 1.5;
  border-radius: 100px; border: 1px solid transparent;
  font-feature-settings: "tnum";
}
.pill-sm { padding: 1.5px 7px; font-size: 11px; }
.pill-ok { background: var(--ok-soft); color: var(--ok); border-color: var(--ok-line); }
.pill-warn { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.pill-bad { background: var(--bad-soft); color: var(--bad); border-color: var(--bad-line); }
.pill-indigo { background: var(--indigo-soft); color: var(--indigo-ink); border-color: var(--indigo-line); }
.pill-neutral { background: var(--bg-sunk); color: var(--ink-3); border-color: var(--line); }
.pill-dot { width: 5px; height: 5px; border-radius: 50%; flex: 0 0 auto; }
.pill-dot-ok { background: var(--ok); }
.pill-dot-warn { background: var(--warn); }
.pill-dot-bad { background: var(--bad); }
.pill-dot-indigo { background: var(--indigo); }
.pill-dot-neutral { background: var(--ink-4); }

/* ─── Badge ──────────────────────────────────────────────────────────────────
   Inline pill: tone × variant × size axes.
   Tones map to theme tokens — info added alongside existing ok/warn/bad/indigo.
   Variants: solid (filled, white text) · outline (transparent + ring) · subtle (soft bg, default).
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; font-size: 11.5px; font-weight: 500; line-height: 1.4;
  border-radius: 100px; border: 1px solid transparent;
  white-space: nowrap; font-feature-settings: "tnum";
}
.badge--sm { padding: 1px 6px; font-size: 10.5px; gap: 3px; }
.badge--md { /* default sizing above */ }

/* Tone × variant matrix — uses CSS vars per tone for DRY.
   Each tone sets --tone-fg / --tone-bg / --tone-line / --tone-ink,
   then the variant rules consume those. */
.badge--neutral { --tone-fg: var(--ink-3); --tone-bg: var(--bg-sunk);     --tone-line: var(--line);        --tone-ink: var(--ink); }
.badge--success { --tone-fg: var(--ok);    --tone-bg: var(--ok-soft);    --tone-line: var(--ok-line);    --tone-ink: var(--ok); }
.badge--warning { --tone-fg: var(--warn);  --tone-bg: var(--warn-soft);  --tone-line: var(--warn-line);  --tone-ink: var(--warn); }
.badge--danger  { --tone-fg: var(--bad);   --tone-bg: var(--bad-soft);   --tone-line: var(--bad-line);   --tone-ink: var(--bad); }
.badge--info    { --tone-fg: var(--info);  --tone-bg: var(--info-soft);  --tone-line: var(--info-line);  --tone-ink: var(--info-ink, var(--info)); }
.badge--accent  { --tone-fg: var(--indigo);--tone-bg: var(--indigo-soft);--tone-line: var(--indigo-line);--tone-ink: var(--indigo-ink); }

/* Variant: subtle (default) — soft bg + tone fg + matching line */
.badge--subtle {
  background: var(--tone-bg);
  color: var(--tone-ink);
  border-color: var(--tone-line);
}
/* Variant: outline — transparent bg + ring + tone fg */
.badge--outline {
  background: transparent;
  color: var(--tone-fg);
  border-color: var(--tone-line);
}
/* Variant: solid — filled with tone-fg + white text. Neutral keeps ink. */
.badge--solid {
  background: var(--tone-fg);
  color: #fff;
  border-color: transparent;
}
.badge--neutral.badge--solid {
  background: var(--ink-3);
  color: var(--bg-card);
}

/* Tone alias: "error" ↔ "danger". The JS resolver maps `tone="error"` to
   class `badge--danger`, but if anything bypasses the resolver (e.g., a
   custom className prop), this rule keeps it working. */
.badge--error {
  --tone-fg: var(--bad); --tone-bg: var(--bad-soft);
  --tone-line: var(--bad-line); --tone-ink: var(--bad);
}

/* Leading status dot — colored circle inside the badge. Color inherits
   from the current tone via the --tone-fg var. */
.badge__dot {
  display: inline-block; flex: 0 0 auto;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--tone-fg, var(--ink-4));
  margin-right: 1px;
}
.badge--sm .badge__dot { width: 5px; height: 5px; }
/* On solid variant, the bg is the tone-fg color — dot would be invisible.
   Switch to white for visibility on solid badges. */
.badge--solid .badge__dot { background: #fff; }

/* ─── ColorSwatch ────────────────────────────────────────────────────────────
   Small colored circle for project colors / status indicators.
   .color-swatch + __dot + __label
   Size: --xs (8px) / --sm (12px) / --md (16px) / --lg (20px)
   Modifiers: --outlined / --clickable / --with-label
   ────────────────────────────────────────────────────────────────────────── */
.color-swatch {
  display: inline-flex; align-items: center;
  gap: 7px;
  vertical-align: middle;
  background: none; border: none; padding: 0;
  font: inherit; color: inherit;
  line-height: 1;
}
.color-swatch--with-label { gap: 7px; }

.color-swatch__dot {
  display: inline-block; flex: 0 0 auto;
  border-radius: 50%;
  /* Inner subtle border for contrast against light bg (white-on-white) without
     stomping the swatch color. Uses an inset shadow so it doesn't change the
     element's box size. */
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
.color-swatch--xs .color-swatch__dot { width: 8px;  height: 8px;  }
.color-swatch--sm .color-swatch__dot { width: 12px; height: 12px; }
.color-swatch--md .color-swatch__dot { width: 16px; height: 16px; }
.color-swatch--lg .color-swatch__dot { width: 20px; height: 20px; }

/* Outlined — adds a visible contrasting ring outside the swatch */
.color-swatch--outlined .color-swatch__dot {
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,0.08),
    0 0 0 2px var(--bg-card),
    0 0 0 3px var(--line);
}

.color-swatch__label {
  font-size: 12.5px; color: var(--ink-2);
  line-height: 1.4;
  white-space: nowrap;
}
.color-swatch--xs .color-swatch__label { font-size: 11.5px; gap: 5px; }
.color-swatch--lg .color-swatch__label { font-size: 13px; }

/* Clickable */
.color-swatch--clickable {
  cursor: pointer;
  border-radius: 6px;
  padding: 2px;
  margin: -2px;
  transition: background var(--duration-fast, 120ms) ease-out;
}
.color-swatch--clickable:hover  { background: var(--bg-hover); }
.color-swatch--clickable:focus-visible {
  outline: none;
  background: var(--bg-hover);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* ─── ColorPicker ────────────────────────────────────────────────────────────
   Palette of preset swatches + optional hex input field.
   .color-picker + __palette + __swatch + __check + __hex + __hex-input
   Size modifiers: --sm / --md
   ────────────────────────────────────────────────────────────────────────── */
.color-picker {
  display: flex; flex-direction: column;
  gap: 8px;
  width: 100%;
  min-width: 0;
}
.color-picker--disabled { opacity: 0.55; pointer-events: none; }

.color-picker__palette {
  display: flex; flex-wrap: wrap;
  gap: 6px;
}

.color-picker__swatch {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.08);   /* inner contrast border for white-on-white */
  padding: 0;
  cursor: pointer;
  background-clip: padding-box;
  transition: transform var(--duration-fast, 120ms) ease-out,
              box-shadow var(--duration-fast, 120ms) ease-out;
}
.color-picker--sm .color-picker__swatch { width: 18px; height: 18px; border-radius: 5px; }

.color-picker__swatch:hover {
  transform: scale(1.08);
}
.color-picker__swatch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg-card),
              0 0 0 4px color-mix(in srgb, var(--indigo) 30%, transparent);
}

/* Selected — outer ring in indigo so the selected color is unmistakable
   regardless of the swatch's own hue (which might be close to indigo). */
.color-picker__swatch--selected {
  box-shadow: 0 0 0 2px var(--bg-card),
              0 0 0 3px var(--indigo);
}
.color-picker__check {
  /* White check sits in the center; mix-blend-mode keeps it readable
     against light AND dark swatches without per-color rules. */
  color: #fff;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
  display: inline-flex;
}

/* Clear swatch (× option) — empty box with diagonal-line indicator */
.color-picker__swatch--clear {
  background:
    linear-gradient(to bottom right,
      transparent calc(50% - 1px),
      var(--bad) 50%,
      transparent calc(50% + 1px)),
    var(--bg-card);
  color: var(--ink-4);
}
.color-picker__swatch--clear svg { display: none; }
.color-picker__swatch--clear.color-picker__swatch--selected {
  box-shadow: 0 0 0 2px var(--bg-card),
              0 0 0 3px var(--ink-3);
}

/* Hex input row */
.color-picker__hex {
  display: inline-flex; align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg-card);
  width: 100px;
  transition: border-color 120ms;
}
.color-picker--sm .color-picker__hex { padding: 2px 6px; width: 88px; }
.color-picker__hex:hover { border-color: var(--line-strong); }
.color-picker__hex:focus-within {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.color-picker__hex-prefix {
  color: var(--ink-5);
  font: inherit; font-size: 12px;
  font-family: var(--f-mono, ui-monospace, Menlo, Consolas, monospace);
}
.color-picker__hex-input {
  flex: 1; min-width: 0;
  border: none; outline: none; background: transparent;
  font: inherit; font-size: 12px; color: var(--ink);
  font-family: var(--f-mono, ui-monospace, Menlo, Consolas, monospace);
  letter-spacing: 0.02em;
  text-transform: lowercase;
  padding: 0;
}
.color-picker__hex-input::placeholder { color: var(--ink-5); }

@media (prefers-reduced-motion: reduce) {
  .color-picker__swatch { transition: none; }
}

/* ─── Avatar + AvatarGroup ───────────────────────────────────────────────────
   New BEM-style size modifiers (avatar--xs/sm/md/lg/xl) + sub-elements
   (__initials, __img) layered on top of the existing legacy .avatar base
   (line 294) so the sidebar's bare <.avatar> keeps its 26×26. The legacy
   .avatar-sm (single hyphen) also stays untouched.
   -------------------------------------------------------------------------- */
.avatar--xs { width: 20px; height: 20px; font-size: 9px; }
.avatar--sm { width: 24px; height: 24px; font-size: 10.5px; }
.avatar--md { width: 32px; height: 32px; font-size: 12px; }
.avatar--lg { width: 40px; height: 40px; font-size: 14px; }
.avatar--xl { width: 56px; height: 56px; font-size: 18px; }

/* Avatar needs position:relative so the status dot can absolute-position over it.
   The existing legacy .avatar base doesn't set position, so add it here for the
   BEM-sized variants without disturbing the legacy bare-.avatar callers. */
.avatar--xs, .avatar--sm, .avatar--md, .avatar--lg, .avatar--xl { position: relative; }

/* Ring — colored border around the avatar (useful for "speaking" / "selected"
   / "active" states in presence UIs). Uses outline so it doesn't shift layout. */
.avatar--ring          { outline: 2px solid var(--indigo);  outline-offset: 1px; }
.avatar--ring-accent   { outline: 2px solid var(--indigo);  outline-offset: 1px; }
.avatar--ring-success  { outline: 2px solid var(--ok);      outline-offset: 1px; }
.avatar--ring-warning  { outline: 2px solid var(--warn);    outline-offset: 1px; }
.avatar--ring-danger   { outline: 2px solid var(--bad);     outline-offset: 1px; }

/* Status dot — bottom-right presence indicator. White ring lifts it off the
   avatar bg regardless of theme. Sizes scale with avatar size. */
.avatar__status {
  position: absolute; right: 0; bottom: 0;
  width: 30%; height: 30%;
  min-width: 8px; min-height: 8px;
  max-width: 14px; max-height: 14px;
  border-radius: 50%;
  background: var(--ink-4);
  box-shadow: 0 0 0 2px var(--bg-card);
  pointer-events: none;
}
/* Smaller dot ring at xs size (2px ring on a 6px dot eats too much) */
.avatar--xs .avatar__status { box-shadow: 0 0 0 1.5px var(--bg-card); }

.avatar__status--online  { background: var(--ok);   }
.avatar__status--away    { background: var(--warn); }
.avatar__status--busy    { background: var(--bad);  }
.avatar__status--offline { background: var(--ink-5); }

.avatar__initials {
  font-weight: 500; line-height: 1; letter-spacing: 0;
  user-select: none;
}
.avatar__img {
  width: 100%; height: 100%; object-fit: cover;
  display: block; border-radius: inherit;
  user-select: none;
}
.avatar--img { background: var(--bg-card); overflow: hidden; padding: 0; }

/* AvatarGroup — overlap stack + +N overflow chip */
.avatar-group {
  display: inline-flex; align-items: center;
  isolation: isolate; /* keep stacking contexts predictable */
}
.avatar-group__item {
  position: relative;
  outline: 2px solid var(--bg-card);
  outline-offset: -2px;
  border-radius: 50%;
  transition: transform var(--duration-fast, 120ms) var(--ease-out, ease-out),
              z-index   0s;
}
.avatar-group__item + .avatar-group__item { margin-left: -6px; }
.avatar-group--xs .avatar-group__item + .avatar-group__item { margin-left: -4px; }
.avatar-group--sm .avatar-group__item + .avatar-group__item { margin-left: -5px; }
.avatar-group--lg .avatar-group__item + .avatar-group__item { margin-left: -8px; }
.avatar-group--xl .avatar-group__item + .avatar-group__item { margin-left: -10px; }

/* Stacking: later siblings sit underneath so earlier (left-most) feels primary */
.avatar-group__item { z-index: 5; }
.avatar-group__item:nth-child(2) { z-index: 4; }
.avatar-group__item:nth-child(3) { z-index: 3; }
.avatar-group__item:nth-child(4) { z-index: 2; }
.avatar-group__item:nth-child(5) { z-index: 1; }

/* Interactive mode — hovered avatar lifts and pops to front so the user can
   read it cleanly even when partially covered by adjacent siblings. */
.avatar-group--interactive .avatar-group__item { cursor: pointer; }
.avatar-group--interactive .avatar-group__item:hover {
  z-index: 10;
  transform: translateY(-2px);
}

/* +N chip — same outline ring as siblings; subtle bg, lighter text */
.avatar-group__more {
  background: var(--bg-sunk);
  color: var(--ink-3);
  font-weight: 500;
  /* Override Avatar's default fill bg from the color-from-name palette */
  background-image: none !important;
}
/* Clickable variant — button reset + hover affordance */
.avatar-group__more--clickable {
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  transition: background var(--duration-fast, 120ms) ease-out,
              color      var(--duration-fast, 120ms) ease-out,
              transform  var(--duration-fast, 120ms) ease-out;
}
.avatar-group__more--clickable:hover {
  background: var(--bg-hover);
  color: var(--ink-2);
  transform: translateY(-1px);
}
.avatar-group__more--clickable:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 1px;
}

/* ─── Budget bar ──────────────────────────────────────────────────────────── */
.bbar { display: flex; align-items: center; gap: 8px; }
.bbar-track { flex: 1; height: 5px; background: var(--bg-sunk); border-radius: 3px; overflow: hidden; position: relative; min-width: 80px; }
.bbar-fill { height: 100%; border-radius: 3px; }
.bbar-ok { background: var(--ok); }
.bbar-warn { background: var(--warn); }
.bbar-bad { background: var(--bad); }
.bbar-over { position: absolute; top: 0; bottom: 0; left: 100%; transform: translateX(-50%); width: 0; background: repeating-linear-gradient(135deg, var(--bad), var(--bad) 3px, var(--bad-soft) 3px, var(--bad-soft) 6px); border-left: 1px solid var(--bad); }
.bbar-pct { font-family: var(--f-sans); font-size: 13px; min-width: 40px; text-align: right; font-feature-settings: "tnum"; color: var(--ink-2); }
.bbar-pct-bad { color: var(--bad); }
.bbar-pct-warn { color: var(--warn); }
.bbar-pct-ok { color: var(--ink-2); }

/* ─── Tables ──────────────────────────────────────────────────────────────── */
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl thead th {
  text-align: left; font-weight: 500; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.13em; color: var(--ink-4);
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  background: var(--bg-card);
}
.tbl tbody td {
  padding: 12px 14px; border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tbody tr.expandable { cursor: pointer; }
.tbl tbody tr.expandable:hover { background: var(--bg-hover); }
.tbl tbody tr.expanded { background: var(--bg-hover); }
/* Row-selection feedback (e.g. Bookkeeping "select N → post to ledger") — was
   toggled in markup with no matching rule, so multi-select gave zero visual
   confirmation of what was picked. */
.tbl tbody tr.is-selected { background: var(--indigo-soft); }
.tbl tbody tr.is-selected:hover { background: var(--indigo-soft); }
.tbl tbody tr.is-selected td { border-bottom-color: var(--indigo-line); }
.tbl-num { font-family: var(--f-sans); font-feature-settings: "tnum","lnum"; font-size: 14px; }
.tbl-mono { font-family: var(--f-mono); font-size: 12px; color: var(--ink-3); }
.tbl-link { font-weight: 500; color: var(--ink); cursor: pointer; transition: color 0.1s; }
.tbl-link:hover { color: #1d6fd8; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }
.tbl-link-btn { background: none; border: none; padding: 0; font-family: inherit; font-size: inherit; text-align: left; }
.tbl-sub  { color: var(--ink-4); font-size: 11.5px; margin-top: 1px; }

.row-detail td {
  background: var(--bg-elev); border-top: 1px solid var(--line) !important;
  padding: 18px 24px; font-size: 13px;
}

/* ─── Layout grids ────────────────────────────────────────────────────────── */
.grid-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--d-gap); }
.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; }
.stack { display: flex; flex-direction: column; gap: var(--d-gap); }
.row { display: flex; align-items: center; gap: 10px; }

/* ── Reorderable Command Center blocks ─────────────────────────────────── */
.dash-block { position: relative; border-radius: 12px; transition: box-shadow .15s ease, opacity .15s ease, outline-color .15s ease; outline: 1.5px solid transparent; outline-offset: 4px; }
/* ⭐ GADGET HOVER CONVENTION (founder 2026-08-20): "just thicken the already
   existing outline". A 0-blur ring in the border's own color makes the 1px
   border read as 2px WITHOUT changing the box size (a real border-width bump
   would shift layout). The ring SNAPS — no transition, its value is a var().
   Same treatment on the card surfaces below (phase/meeting/session/report/
   project/note cards): ring replaces the old hover drop shadows and indigo
   border swaps. */
.dash-block:hover > .card { box-shadow: 0 0 0 1px var(--line), var(--shadow-sm); }
/* Grip handle — hidden until the block is hovered, so it never clutters the
   default view. Sits top-right, clear of card content. */
.dash-block__grip {
  position: absolute; top: -6px; right: 6px; z-index: 5;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 22px; padding: 0;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card); color: var(--ink-4);
  cursor: grab; opacity: 0; transition: opacity .15s ease, color .15s ease, border-color .15s ease;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.dash-block:hover > .dash-block__grip { opacity: 1; }
.dash-block__grip:hover { color: var(--indigo); border-color: var(--indigo); }
.dash-block.is-armed > .dash-block__grip { cursor: grabbing; color: var(--indigo); border-color: var(--indigo); opacity: 1; }
.dash-block.is-armed { opacity: 0.55; box-shadow: 0 10px 30px rgba(0,0,0,0.14); }
.dash-block.is-over { outline-color: var(--indigo); }
@media (hover: none) { .dash-block__grip { opacity: 1; } }

/* Command Center "Gadgets" show/hide menu — toggle switch per row */
.cc-gadget-switch { position: relative; flex: 0 0 auto; width: 30px; height: 17px; border-radius: 999px; background: var(--line); transition: background .14s ease; }
.cc-gadget-switch.is-on { background: var(--indigo); }
.cc-gadget-switch__knob { position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.25); transition: transform .14s ease; }
.cc-gadget-switch.is-on .cc-gadget-switch__knob { transform: translateX(13px); }

/* Canvas-width responsive overrides (container queries on .app-right) */
@container (max-width: 800px) {
  .grid-2 { grid-template-columns: 1fr; }
  .report-pane { grid-template-columns: 1fr; }
  .settings-layout { grid-template-columns: 1fr; }
  .settings-grid { grid-template-columns: 1fr; }
  .office-grid { grid-template-columns: 1fr; }
}
@container (max-width: 600px) {
  .page { padding: 16px 16px 48px; padding-top: calc(var(--topbar-clearance, 62px) + 16px); }
}

/* ─── Office card ─────────────────────────────────────────────────────────── */
.office-card { padding: 0; overflow: hidden; }
.office-head { display: flex; align-items: flex-start; justify-content: space-between; padding: 18px 22px 14px; border-bottom: 1px solid var(--line-soft); }
.office-name { font-size: 17px; font-weight: 500; letter-spacing: -0.015em; }
.office-loc { color: var(--ink-4); font-size: 12px; font-family: var(--f-mono); margin-top: 2px; }
.office-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0; }
.office-stat { padding: 14px 22px; border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.office-stat:nth-child(2n) { border-right: 0; }
.office-stat:nth-last-child(-n+2) { border-bottom: 0; }
.office-stat-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.13em; color: var(--ink-4); font-weight: 500; }
.office-stat-value { margin-top: 6px; }

/* ─── Action queue / decision list ────────────────────────────────────────── */
.action-list { display: flex; flex-direction: column; }
.action-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 0; border-bottom: 1px solid var(--line-soft);
}
.action-item:last-child { border-bottom: 0; }
.action-bullet { width: 22px; height: 22px; border-radius: 50%; background: var(--indigo-soft); color: var(--indigo-ink); display: grid; place-items: center; flex: 0 0 auto; font-family: var(--f-sans); font-size: 12px; }
.action-body { flex: 1; }
.action-text { color: var(--ink); font-size: 13.5px; line-height: 1.45; }
.action-meta { display: flex; align-items: center; gap: 14px; margin-top: 6px; color: var(--ink-4); font-size: 11.5px; }

/* ─── Confidence ──────────────────────────────────────────────────────────── */
.confidence { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-3); }
.confidence-bars { display: inline-flex; gap: 2px; align-items: flex-end; height: 10px; }
.cb { width: 3px; background: var(--ink-5); border-radius: 1px; opacity: .5; }
.cb:nth-child(1) { height: 4px; }
.cb:nth-child(2) { height: 7px; }
.cb:nth-child(3) { height: 10px; }
.cb.on { background: var(--indigo); opacity: 1; }
.confidence-label { font-feature-settings: "tnum"; }

.sources { display: flex; flex-wrap: wrap; gap: 6px; }
.source-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--ink-3); padding: 2px 7px 2px 4px; border: 1px solid var(--line); border-radius: 100px; background: var(--bg-elev); }
/* A source that resolves to a real place is a LINK, and must look like one —
   the founder could not tell the clickable ones from the inert ones because they
   were styled identically (console task 9b672563). Colour is not the only
   signal: the cursor and the hover border change too. */
.source-tag--link { cursor: pointer; color: var(--ink-2); text-decoration: none; transition: border-color var(--duration-fast) var(--ease-in-out), color var(--duration-fast) var(--ease-in-out); }
.source-tag--link:hover { color: var(--ink-1); border-color: var(--line-strong); }
.source-tag--link:focus-visible { outline: 2px solid var(--indigo); outline-offset: 1px; }
/* Sources collapse behind a count so a long answer isn't buried under pills.
   The toggle is a real button: keyboard-reachable, with a focus ring, and it
   never becomes the only thing distinguishing "grounded" from "not". */
.sources--collapsible { display: block; }
.sources-toggle { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--ink-3); background: none; border: 0; padding: 2px 0; cursor: pointer; border-radius: var(--radius-btn, 999px); }
.sources-toggle:hover { color: var(--ink-1); }
.sources-toggle:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.sources--collapsible .sources { margin-top: 4px; }

/* ─── Tabs ────────────────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.tab { padding: 8px 12px; font-size: 13px; color: var(--ink-3); background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; font-weight: 500; }
.tab.active { color: var(--ink); border-color: var(--indigo); }
.tab:hover:not(.active) { color: var(--ink); }
.tab-count { color: var(--ink-5); font-size: 11.5px; margin-left: 6px; font-weight: 400; font-feature-settings: "tnum"; }

/* ─── Upload zone ─────────────────────────────────────────────────────────── */
.upload-zone {
  border: 1.5px dashed var(--line-strong);
  border-radius: 12px; padding: 38px;
  text-align: center; background: var(--bg-elev);
  position: relative; overflow: hidden;
  transition: border-color .15s, background .15s;
}
.upload-zone.over { border-color: var(--indigo); background: var(--indigo-soft); }
.upload-zone::before {
  content: ""; position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
  background-size: 32px 32px; opacity: .5; pointer-events: none;
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%);
}
.upload-icon {
  width: 44px; height: 44px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--line);
  display: grid; place-items: center; margin: 0 auto 14px; color: var(--ink-3);
  position: relative; z-index: 1;
}
.upload-title { font-size: 16px; font-weight: 500; position: relative; z-index: 1; }
.upload-sub { color: var(--ink-3); font-size: 12.5px; margin-top: 4px; position: relative; z-index: 1; }
.upload-cats { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 18px; position: relative; z-index: 1; }
.upload-cat { font-size: 11px; padding: 3px 9px; border: 1px solid var(--line); border-radius: 100px; color: var(--ink-3); background: var(--bg-card); }

/* classification animation row — scrolls horizontally if canvas is narrow */
.classify-table { overflow-x: auto; }
.classify-row { display: grid; grid-template-columns: 24px minmax(120px, 1fr) 110px 110px 130px 80px; gap: 14px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--line-soft); font-size: 13px; min-width: 540px; }
.classify-row:last-child { border-bottom: 0; }
.classify-name { display: flex; align-items: center; gap: 9px; min-width: 0; }
.classify-name strong { font-weight: 500; truncate: ellipsis; white-space: nowrap; overflow: hidden; }
/* ── "Other ways to bring transactions in" (office → Finance → Banking) ──────
   Was a raw <input type="file"> rendering the OS "Choose File / No file chosen"
   control, plus three same-weight buttons on one row. Restyled into two
   symmetric option rows with a real drop zone. */
.imp-card { border: 1px solid var(--line); border-radius: 12px; background: var(--surface-1); overflow: hidden; margin-bottom: 16px; }
.imp-head { display: flex; align-items: flex-start; gap: 11px; padding: 14px 16px; border-bottom: 1px solid var(--line-soft); }
.imp-badge { width: 30px; height: 30px; border-radius: 8px; flex: none; display: grid; place-items: center;
  background: color-mix(in srgb, var(--indigo) 12%, transparent); color: var(--indigo); }
.imp-row { display: flex; align-items: flex-start; gap: 11px; padding: 14px 16px; }
.imp-row + .imp-row { border-top: 1px solid var(--line-soft); }
.imp-ico { width: 30px; height: 30px; border-radius: 8px; flex: none; display: grid; place-items: center;
  background: var(--surface-3); color: var(--ink-3); }
.imp-body { flex: 1 1 auto; min-width: 0; }
.imp-title { font-size: 12.5px; font-weight: 600; }
.imp-sub { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; line-height: 1.45; }
.imp-act { flex: none; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* The drop zone doubles as the file picker: the whole thing is a <label>. */
.imp-drop { margin-top: 9px; display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 13px 14px; border: 1px dashed var(--line-strong); border-radius: 9px; cursor: pointer;
  font-size: 12.5px; color: var(--ink-3); background: var(--surface-2);
  transition: border-color .12s ease, color .12s ease, background .12s ease; text-align: center; }
.imp-drop:hover { border-color: var(--indigo); color: var(--ink-2); }
.imp-drop.is-over { border-color: var(--indigo); color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 8%, transparent); border-style: solid; }
.imp-drop.is-busy { opacity: .55; pointer-events: none; }
.imp-drop input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.imp-preview { margin-top: 10px; padding: 11px 12px; border: 1px solid var(--line-soft); border-radius: 9px; background: var(--surface-2); }
.imp-cols { font-size: 11.5px; color: var(--ink-4); margin-top: 4px; word-break: break-word; }
/* Duplicate cross-check, shown BEFORE the import is committed. The all-duplicate
   case is deliberately the loudest: importing a statement that is entirely
   already in the books does nothing, and a cheerful "12 rows read" next to an
   enabled Import button is what makes someone press it twice. */
.imp-dupe { margin-top: 9px; padding: 9px 11px; border-radius: 8px; font-size: 12px; line-height: 1.5;
  border: 1px solid var(--line-soft); background: var(--surface-3); color: var(--ink-3); }
.imp-dupe.is-clean { border-color: color-mix(in srgb, var(--ok) 40%, var(--line-soft));
  background: color-mix(in srgb, var(--ok) 8%, transparent); }
.imp-dupe.is-partial { border-color: color-mix(in srgb, var(--warn) 45%, var(--line-soft));
  background: color-mix(in srgb, var(--warn) 9%, transparent); }
.imp-dupe.is-all { border-color: color-mix(in srgb, var(--bad) 45%, var(--line-soft));
  background: color-mix(in srgb, var(--bad) 9%, transparent); }
.imp-dupe-head { font-weight: 600; color: var(--ink-2); display: flex; align-items: center; gap: 6px; }
.imp-dupe-note { margin-top: 3px; color: var(--ink-4); font-size: 11.5px; }
.imp-dupe-list { margin-top: 6px; font-size: 11.5px; color: var(--ink-4); }
.imp-dupe-line { display: flex; gap: 10px; font-variant-numeric: tabular-nums; }
.imp-dupe-line span:nth-child(2) { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* Which bank account a statement is being filed under. Sits above the duplicate
   cross-check because the account is the question that has to be answered
   FIRST — the duplicate counts depend on the answer. */
.imp-acct { margin-top: 9px; padding: 9px 11px; border-radius: 8px; font-size: 12px;
  line-height: 1.5; border: 1px solid var(--line-soft); background: var(--bg-card); }
.imp-acct-head { color: var(--ink-3); }
.imp-acct-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 7px; }
.imp-acct-row label { display: block; color: var(--ink-4); min-width: 220px; flex: 1 1 220px; }
.imp-acct-note { margin-top: 5px; color: var(--ink-4); font-size: 11.5px; }
@media (max-width: 640px) {
  .imp-row { flex-wrap: wrap; }
  .imp-act { width: 100%; justify-content: flex-start; }
}
/* Approve-button busy spinner. The action card had NO pending state: the click
   handler awaits a ~2s network call and only then flips to the result, so the
   first click looked dead and users clicked again (the in-flight guard silently
   swallowed the second). Reuses @keyframes spin below. */
.cmd-btn-spin { width: 11px; height: 11px; border-radius: 50%; border: 1.5px solid currentColor; border-top-color: transparent; animation: spin .7s linear infinite; display: inline-block; flex: none; }
.classify-spinner { width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid var(--line-strong); border-top-color: var(--indigo); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.classify-bar { height: 4px; background: var(--bg-sunk); border-radius: 2px; overflow: hidden; }
.classify-bar-fill { height: 100%; background: var(--indigo); transition: width .3s ease; }

/* ─── Reports preview ─────────────────────────────────────────────────────── */
.report-pane { display: grid; grid-template-columns: 240px 1fr; gap: var(--d-gap); }
.report-list { display: flex; flex-direction: column; gap: 2px; }
.report-list-item { padding: 10px 12px; border-radius: var(--radius-btn-icon); cursor: pointer; font-size: 13px; display: flex; align-items: center; gap: 9px; color: var(--ink-3); }
.report-list-item:hover { background: var(--bg-hover); color: var(--ink); }
.report-list-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.report-list-item.active { background: var(--bg-card); color: var(--ink); border: 1px solid var(--line); box-shadow: var(--shadow-sm); }
.report-list-item .label-sub { color: var(--ink-5); font-size: 11px; margin-left: auto; }

.report-preview {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-md); overflow: hidden;
}
.report-head {
  padding: 28px 32px 22px; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg-elev), var(--bg-card));
}
.report-eyebrow { color: var(--indigo); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.16em; font-weight: 500; }
.report-title { font-family: var(--f-sans); font-size: 26px; font-weight: 400; letter-spacing: -0.015em; margin-top: 6px; }
.report-meta { color: var(--ink-3); font-size: 12.5px; margin-top: 8px; display: flex; gap: 16px; flex-wrap: wrap; font-family: var(--f-mono); }
.report-body { padding: 28px 32px; }
.report-section { margin-bottom: 24px; }
.report-section h4 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.13em; color: var(--ink-4); margin-bottom: 10px; font-weight: 500; }
.report-section p { color: var(--ink-2); line-height: 1.65; max-width: 70ch; }
.report-section ul { margin: 6px 0 0; padding-left: 16px; color: var(--ink-2); line-height: 1.7; }

/* ─── Chat ────────────────────────────────────────────────────────────────── */
/* AnalystPage chat layout — the composer is sticky to the .page scroll
   container (the only ancestor with overflow:auto), so it stays visible at
   the viewport bottom even on first load when page-head + suggested chips
   push .chat below the fold. Dropping the fixed height on .chat AND the
   internal overflow on .chat-thread funnels everything to a single scroll
   surface (.page) — no nested-scroll trap. min-height keeps the area
   visually present when the thread is short. */
.chat { display: grid; grid-template-rows: 1fr auto; min-height: 360px; }
.chat-thread { padding: 12px 4px 16px; display: flex; flex-direction: column; gap: 24px; }
/* scroll-margin-bottom lifts scrollIntoView landings clear of the sticky
   composer (~88px tall + 8px breathing room). Without it, the last message
   tucks behind the composer when new replies arrive. */
.chat-msg { max-width: 760px; scroll-margin-bottom: 96px; }
.chat-msg.user { align-self: flex-end; background: var(--ink); color: var(--bg-card); padding: 12px 16px; border-radius: 12px 12px 4px 12px; }
.chat-msg.ai { align-self: flex-start; }
.ai-avatar { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; color: var(--ink-3); font-size: 12px; }
.ai-mark { width: 22px; height: 22px; border-radius: 50%; background: var(--indigo-soft); color: var(--indigo); display: grid; place-items: center; }
.ai-body { font-size: 14px; line-height: 1.65; color: var(--ink); }
.ai-body p { margin: 0 0 12px; }
.ai-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); }

.analyst-patch-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line-soft); }
.analyst-patch-label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); flex: 1; }

.chat-input {
  display: flex; align-items: flex-end; gap: 10px;
  padding: 14px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-card); box-shadow: var(--shadow-sm);
  /* Pin to the bottom of the .page scroll viewport so the composer is
     visible the moment AnalystPage opens, even before any scrolling.
     Once the user scrolls to the bottom of the thread, the composer
     un-pins and settles at its natural grid position. Solid background
     via --bg-card (auto-adapts light/dark) prevents thread content from
     showing through. z-index keeps it above any in-thread popovers. */
  position: sticky;
  bottom: 0;
  z-index: 5;
}
.chat-input textarea {
  flex: 1; border: 0; outline: 0; background: none; resize: none;
  font: inherit; color: var(--ink); min-height: 40px; max-height: 160px;
}
.chat-input textarea::placeholder { color: var(--ink-4); }

.suggested { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.suggested-chip { padding: 6px 11px; border: 1px solid var(--line); border-radius: var(--radius-btn); background: var(--bg-card); color: var(--ink-2); font-size: 12.5px; cursor: pointer; }
.suggested-chip:hover { border-color: var(--line-strong); background: var(--bg-hover); }
.suggested-chip:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* ─── Daily briefing card ─────────────────────────────────────────────────── */
.briefing-card { background: var(--indigo-soft); border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 25%, transparent)); border-radius: 10px; padding: 14px 16px; margin-bottom: 20px; transition: padding 120ms ease; }
.briefing-card.is-minimized { padding: 8px 16px; }
/* Bookkeeping-backlog callout on the Command Center — amber, actionable. */
.cc-review-callout { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  background: color-mix(in srgb, var(--warn, #d97706) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn, #d97706) 32%, transparent);
  border-radius: 10px; padding: 11px 14px; margin-bottom: 20px; color: var(--ink-1);
  transition: background 120ms ease, border-color 120ms ease; }
.cc-review-callout:hover { background: color-mix(in srgb, var(--warn, #d97706) 18%, transparent);
  border-color: color-mix(in srgb, var(--warn, #d97706) 45%, transparent); }
.cc-review-ic { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 28px; height: 28px; border-radius: 8px; color: var(--warn, #d97706);
  background: color-mix(in srgb, var(--warn, #d97706) 18%, transparent); }
.cc-review-txt { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.cc-review-txt strong { font-size: 13px; font-weight: 650; line-height: 1.3; }
.cc-review-sub { font-size: 12px; color: var(--ink-3); line-height: 1.3; }
/* Two-step-verification nudge — indigo variant of the review callout
   (a suggestion, not a warning) with an inline dismiss ✕. */
.cc-mfa-callout { background: color-mix(in srgb, var(--indigo) 8%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 26%, transparent); }
.cc-mfa-callout:hover { background: color-mix(in srgb, var(--indigo) 13%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 38%, transparent); }
.cc-mfa-ic { color: var(--indigo); background: color-mix(in srgb, var(--indigo) 14%, transparent); }
.cc-mfa-actions { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; }
/* ── Morning-brief action cards — "Today — N things" (inside .briefing-body).
   Compact, secondary to the prose; theme-aware via canonical tokens only.
   Done cards dim + strike and swap "Get me on it" for Undo. ──────────────── */
.cc-brief-actions { margin-top: 14px; padding-top: 12px; display: flex; flex-direction: column; gap: 6px;
  border-top: 1px solid color-mix(in srgb, var(--indigo) 18%, transparent); }
.cc-brief-actions-head { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: 2px; }
.cc-task-card { display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px; }
.cc-task-card.is-done { opacity: .68; }
.cc-task-check { flex: 0 0 auto; width: 18px; height: 18px; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--ink-4); border-radius: 6px; background: transparent; color: transparent; }
.cc-task-check:hover { border-color: var(--ink-2, var(--ink)); }
.cc-task-card.is-done .cc-task-check { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.cc-task-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cc-task-title { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-task-card.is-done .cc-task-title { text-decoration: line-through; color: var(--ink-4); }
.cc-task-entity { font-size: 12px; color: var(--ink-3); line-height: 1.3; width: fit-content; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: none; border: none; padding: 0; text-align: left; font-family: inherit; }
button.cc-task-entity { cursor: pointer; }
button.cc-task-entity:hover { color: var(--ink); text-decoration: underline; }
.cc-task-go { flex: 0 0 auto; cursor: pointer; font-size: 12px; font-weight: 600; line-height: 1;
  padding: 6px 12px; border-radius: var(--radius-btn); font-family: inherit;
  color: var(--indigo); background: color-mix(in srgb, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 28%, transparent); }
.cc-task-go:hover { background: color-mix(in srgb, var(--indigo) 16%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 40%, transparent); }
.cc-task-undo { flex: 0 0 auto; cursor: pointer; font-size: 12px; font-weight: 600; line-height: 1;
  padding: 6px 12px; border-radius: var(--radius-btn); font-family: inherit;
  color: var(--ink-3); background: transparent; border: 1px solid var(--line); }
.cc-task-undo:hover { color: var(--ink); border-color: var(--ink-4); }
.cc-mfa-cta { display: inline-flex; align-items: center; gap: 3px; font-size: 12px;
  font-weight: 600; color: var(--indigo); white-space: nowrap; }
.cc-callout-x { background: none; border: none; cursor: pointer; color: var(--ink-4);
  font-size: 12px; line-height: 1; padding: 5px 6px; border-radius: 6px; }
.cc-callout-x:hover { background: var(--bg-hover); color: var(--ink); }
/* Connect-your-email nudge — indigo variant (same family as the 2FA nudge). */
.cc-email-callout { background: color-mix(in srgb, var(--indigo) 8%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 26%, transparent); }
.cc-email-callout:hover { background: color-mix(in srgb, var(--indigo) 13%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 38%, transparent); }
.cc-email-callout .cc-mfa-cta { color: var(--indigo); }
.cc-email-ic { color: var(--indigo); background: color-mix(in srgb, var(--indigo) 14%, transparent); }
/* First-run welcome inside the briefing card — replaces the AI brief while
   the firm is a blank slate. */
.cc-welcome { display: flex; flex-direction: column; gap: 10px; }
.cc-welcome-title { font-size: 16px; font-weight: 650; color: var(--ink-1); letter-spacing: -0.01em; }
.cc-welcome-lede { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ink-2); max-width: 640px; }
.cc-welcome-steps { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; margin-top: 2px; }
.cc-welcome-step { display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px;
  color: var(--ink-1); transition: border-color 120ms ease, background 120ms ease; }
.cc-welcome-step:hover { border-color: color-mix(in srgb, var(--indigo) 45%, transparent); background: var(--bg-hover); }
.cc-welcome-step-num { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 22px; height: 22px; border-radius: 50%; font-size: 11px; font-weight: 650;
  color: var(--indigo); background: color-mix(in srgb, var(--indigo) 13%, transparent); }
.cc-welcome-step-txt { display: flex; flex-direction: column; gap: 0; flex: 1; min-width: 0; }
.cc-welcome-step-label { font-size: 12.5px; font-weight: 600; line-height: 1.35; }
.cc-welcome-step-hint { font-size: 11px; color: var(--ink-4); line-height: 1.35; }
.cc-welcome-foot { margin: 2px 0 0; font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.briefing-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.briefing-card.is-minimized .briefing-head { margin-bottom: 0; }
.briefing-label { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--indigo); }
.briefing-dismiss { background: none; border: none; cursor: pointer; color: var(--ink-4); padding: 2px; border-radius: var(--radius-btn-icon); display: grid; place-items: center; }
.briefing-dismiss:hover { background: var(--bg-hover); color: var(--ink); }
.briefing-body { font-size: 13px; line-height: 1.6; color: var(--ink-2); }
.briefing-body p { margin: 0 0 6px; }
.briefing-body ul { margin: 0 0 6px; padding-left: 18px; }
.briefing-body li { margin-bottom: 3px; }

/* ─── Settings ────────────────────────────────────────────────────────────── */
.settings-layout { display: grid; grid-template-columns: 190px 1fr; gap: var(--d-gap); }
.settings-side { display: flex; flex-direction: column; gap: 2px; }
.settings-side .report-list-item {
  padding: 8px 14px; border-radius: var(--radius-btn);
  white-space: nowrap; box-sizing: border-box;
  /* Reserve the active border in the RESTING state (transparent) so activating
     an item only RECOLORS it — no 1px box growth, no reflow, and no wrapping the
     longest label ("Intelligence report settings") to a second line on click. */
  border: 1px solid transparent;
}
.settings-side .report-list-item.active { border-color: var(--line); }
.setting-row { display: flex; align-items: center; justify-content: space-between; padding: 14px 0; border-bottom: 1px solid var(--line-soft); gap: 24px; }
.setting-row:last-child { border-bottom: 0; }
.setting-row .label { font-size: 13px; font-weight: 500; }
.setting-row .desc { font-size: 12px; color: var(--ink-4); margin-top: 2px; max-width: 50ch; }
.setting-toggle { width: 32px; height: 18px; border-radius: var(--radius-btn); background: var(--bg-sunk); border: 1px solid var(--line); position: relative; cursor: pointer; flex: 0 0 auto; }
.setting-toggle::after { content: ""; position: absolute; top: 1px; left: 1px; width: 14px; height: 14px; border-radius: 50%; background: var(--ink-3); transition: all .15s; }
.setting-toggle:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.setting-toggle.on { background: var(--indigo); border-color: var(--indigo); }
.setting-toggle.on::after { left: 15px; background: white; }

/* alert banner for security note */
.alert-banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 14px 16px; border-radius: 9px;
  background: var(--warn-soft); border: 1px solid var(--warn-line);
  color: var(--warn); font-size: 13px; line-height: 1.55;
}
.alert-banner strong { color: var(--ink); }

/* ─── Decision board ─────────────────────────────────────────────────────── */
.decision-card { padding: 16px 18px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-card); display: flex; flex-direction: column; gap: 10px; }
.decision-title { font-size: 14px; font-weight: 500; line-height: 1.4; }
.decision-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 11.5px; color: var(--ink-4); }
.decision-actions { display: flex; gap: 6px; margin-top: auto; padding-top: 8px; border-top: 1px solid var(--line-soft); }

/* utility */
.muted { color: var(--ink-4); }
.divider { height: 1px; background: var(--line); margin: 18px 0; }

/* small bar charts (for offices summary) */
.minibar { display: flex; align-items: center; gap: 10px; padding: 8px 0; }
.minibar-label { font-size: 12px; color: var(--ink-3); width: 110px; flex: 0 0 auto; }
.minibar-track { flex: 1; height: 10px; background: var(--bg-sunk); border-radius: 3px; overflow: hidden; }
.minibar-fill { height: 100%; border-radius: 3px; background: var(--indigo); }
.minibar-val { font-family: var(--f-sans); font-size: 14px; min-width: 80px; text-align: right; color: var(--ink-2); font-feature-settings: "tnum"; }

/* Tweak panel polish (works with copied tweaks-panel.jsx) */
.tweak-toggle { right: 18px !important; bottom: 18px !important; }

/* ─── Project Field (Monograph-style Gantt) ───────────────────────────── */
.pf { display: flex; flex-direction: column; }
.pf-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  padding: 20px 24px 16px; border-bottom: 1px solid var(--line-soft);
}
.pf-head-embedded { justify-content: flex-end; padding: 12px 16px; }
.pf-controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: flex-end; }
.seg { display: inline-flex; background: var(--bg-sunk); border-radius: var(--radius-btn); padding: 2px; }
.seg-btn {
  border: 0; background: none; padding: 4px 10px; font: inherit; font-size: 12px;
  color: var(--ink-3); border-radius: var(--radius-btn); cursor: pointer;
}
.seg-btn.on { background: var(--bg-card); color: var(--ink); box-shadow: var(--shadow-sm); }
.pf-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); cursor: pointer; }
.pf-toggle input { accent-color: var(--indigo); }
.pf-legend { display: flex; align-items: center; gap: 12px; font-size: 11px; color: var(--ink-4); font-family: var(--f-mono); }
.lg-item { display: inline-flex; align-items: center; gap: 5px; }
.lg-sw { width: 18px; height: 6px; border-radius: 2px; display: inline-block; }
.lg-phase { background: var(--indigo-soft); border: 1px solid var(--indigo-line); }
.lg-money { background: var(--indigo); }
.lg-over  { background: repeating-linear-gradient(135deg, var(--bad) 0 3px, var(--bad-soft) 3px 6px); }
.lg-diamond { display: inline-flex; align-items: center; gap: 5px; }
.diamond {
  width: 9px; height: 9px; transform: rotate(45deg);
  background: var(--bg-card); border: 1.5px solid var(--ink-3);
  display: inline-block;
}

/* Grid: sticky 280px sidebar + scrolling track */
.pf-grid { display: grid; grid-template-columns: 280px 1fr; }
.density-spacious .pf-grid { grid-template-columns: 320px 1fr; }
.density-dense .pf-grid    { grid-template-columns: 240px 1fr; }
.pf-side { border-right: 1px solid var(--line); background: var(--bg-card); }
.pf-track { overflow-x: auto; overflow-y: hidden; position: relative; background: var(--bg-elev); }

/* Side column rows */
.pf-side-head, .pf-axis {
  height: 48px; border-bottom: 1px solid var(--line); display: flex; align-items: center;
  padding: 0 16px; font-size: 11px; color: var(--ink-4);
  text-transform: uppercase; letter-spacing: 0.14em; font-weight: 500;
  background: var(--bg-elev);
}
.pf-axis { min-width: 1400px; }
/* Project-row height. ONE source of truth, because .pf-side-row (left labels)
   and .pf-row-summary (right gantt) are separate DOM subtrees that must stay
   1:1 — if these two numbers ever drift the whole field mis-registers. Both
   read this var; nothing else sets either height.
   Budget (money on): 3×16 title + 2+16 meta + 3+16 econ = 85, +1 slack = 86,
   + 8/8 padding = 102. The three line-heights are declared as LENGTHS on the
   rules below precisely so this arithmetic is stable — the meta line carries a
   14px .tbl-num fee span inside an 11px row, so an inherited unitless
   line-height would size it off the wrong font. Change any of those metrics and
   you must change these numbers with them.
   With the economics line off there is nothing to reserve for it, so the rows
   come back down — see .pf-grid.pf-money-off. */
.pf-grid { --pf-proj-lines-h: 86px; --pf-row-h: 102px; }
.pf-grid.pf-money-off { --pf-proj-lines-h: 67px; --pf-row-h: 83px; }

.pf-side-row {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 16px; height: var(--pf-row-h, 68px); box-sizing: border-box;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer; user-select: none;
  transition: background .12s;
  /* The height is load-bearing: these labels align 1:1 with the gantt rows on
     the right, so the row CANNOT grow to fit its content. Anything taller than
     the row therefore has to be clipped here, or it bleeds into the
     neighbouring rows. That is why the name clamps at three lines rather than
     wrapping freely — the reserve below is sized for exactly three. */
  overflow: hidden;
}
/* align-items is flex-start so the chevron and the risk pill sit on the FIRST
   line of the title instead of floating to the middle of a tall row. 2px puts
   the 12px chevron on the optical centre of a 16px line. */
.pf-side-row > :not(.pf-proj-lines) { margin-top: 2px; }
.pf-side-row:hover { background: var(--bg-hover); }
.pf-side-row.open { background: var(--bg-hover); }
/* THE FIX for "the titles are all shifted around" (reported 2026-08-02).
   This block used to be auto-height inside a centered row, so its height
   changed with its content — a project with an economics line centered three
   lines, one without centered two, and the title landed ~8px higher or lower
   in every row. Pinning the height makes the title's baseline identical in
   every row regardless of what does or doesn't render below it. */
.pf-proj-lines {
  flex: 1; min-width: 0;
  height: var(--pf-proj-lines-h, 52px);
  overflow: hidden;
}
/* Up to three lines, per the founder's request — a long name ("46 Tech Hub –
   Experience Centre") is now readable instead of ellipsised at one line. The
   clamp is what keeps a very long name inside the reserved height; the full
   name also stays in the title attribute. */
.pf-proj-name {
  font-size: 13.5px; font-weight: 500; letter-spacing: -0.005em; line-height: 16px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden; overflow-wrap: anywhere;
}
/* The meta line stays hugging its own title (it is that title's metadata — the
   fixed block height leaves the slack at the BOTTOM, not between the two). It
   is the title that has to sit at a constant y, and now does. */
.pf-proj-meta {
  display: flex; gap: 6px; align-items: center; font-size: 11px; color: var(--ink-4);
  /* 16px, not 15: this row's fee is a .tbl-num span at 14px, whose em box does
     not fit a 15px line box and would have its glyphs shaved by the
     overflow:hidden below. */
  margin-top: 2px; line-height: 16px;
  /* A long lead name must ellipsis, not wrap onto a second line. */
  white-space: nowrap; min-width: 0; overflow: hidden;
}
.pf-proj-meta > span { overflow: hidden; text-overflow: ellipsis; }

.pf-side-sub {
  display: flex; align-items: center;
  padding: 0 16px 0 28px; height: 24px; box-sizing: border-box;
  background: var(--bg-elev); border-bottom: 1px solid var(--line-soft);
}
.pf-side-sub-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--ink-5); font-weight: 500; }

.pf-side-phase {
  display: flex; align-items: center; gap: 9px; padding: 8px 16px 8px 28px;
  border-bottom: 1px solid var(--line-soft); height: 50px;
}
.pf-side-phase-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.pf-side-phase-name { font-size: 12.5px; color: var(--ink-2); }
.pf-side-phase-meta { font-size: 10.5px; color: var(--ink-4); font-family: var(--f-mono); margin-top: 1px; }

.pf-side-staff {
  display: flex; align-items: center; gap: 9px; padding: 6px 16px 6px 28px;
  border-bottom: 1px solid var(--line-soft); height: 50px;
}
.pf-side-staff-avatar {
  width: 22px; height: 22px; border-radius: 50%; background: var(--bg-sunk);
  border: 1px solid var(--line); color: var(--ink-3);
  display: grid; place-items: center; font-size: 10px; font-weight: 500;
  flex: 0 0 auto;
}
.pf-side-staff-name { font-size: 12.5px; color: var(--ink-2); }
.pf-side-staff-role { font-size: 10.5px; color: var(--ink-4); margin-top: 1px; }

/* Track / axis */
.pf-axis { padding: 0; flex-direction: column; align-items: stretch; height: 48px; }
.pf-axis-months { display: flex; height: 24px; border-bottom: 1px solid var(--line-soft); }
.pf-axis-month {
  padding: 6px 8px; font-size: 11px; color: var(--ink-3); font-family: var(--f-mono);
  border-right: 1px solid var(--line-soft); text-transform: uppercase; letter-spacing: 0.1em;
  display: flex; align-items: center;
}
.pf-axis-weeks { display: flex; height: 24px; }
.pf-axis-week {
  flex: 1; min-width: 28px; border-right: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 9.5px; color: var(--ink-5); font-family: var(--f-mono);
}
.pf-axis-week.first { border-right: 1px solid var(--line); color: var(--ink-3); }

/* Today vertical line */
.pf-past-overlay {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: linear-gradient(to right, rgba(255,255,255,0.18), rgba(255,255,255,0.55));
  pointer-events: none; z-index: 10;
}
[data-theme="dark"] .pf-past-overlay {
  background: linear-gradient(to right, rgba(255,255,255,0.04), rgba(255,255,255,0.14));
}
.pf-today {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--bad); pointer-events: none; z-index: 11;
}
.pf-today-cap {
  position: absolute; top: -22px; left: 0; transform: translateX(-50%);
  background: var(--bad); color: white; font-size: 10px; padding: 2px 6px;
  border-radius: 3px; font-family: var(--f-mono); letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Rows */
.pf-rows { position: relative; min-width: 1400px; }
.pf-row-block { position: relative; }
.pf-row {
  /* Same var as .pf-side-row — these two heights ARE the alignment. */
  position: relative; height: var(--pf-row-h, 68px); border-bottom: 1px solid var(--line-soft);
}
.pf-row-summary { background: var(--bg-card); }
.pf-row-sub-head { height: 24px; background: var(--bg-elev); border-bottom: 1px solid var(--line-soft); }
.pf-row-phase { height: 50px; background: var(--bg-card); }
.pf-row-staff { height: 50px; background: var(--bg-card); }

.pf-bg { position: absolute; inset: 0; display: flex; }
.pf-bg-week {
  flex: 1; border-right: 1px dashed var(--line-soft);
}
.pf-bg-week:nth-child(4n) { border-right: 1px solid var(--line-soft); }
.pf-bg-month { flex: 1; border-right: 1px solid var(--line); }
.pf-bg-month:nth-child(odd) { background: var(--bg-elev); }

/* ── Gantt rows — Monograph-style ────────────────────────────────────────── */

/* Center guide line running through each row */
.pf-row-summary::after,
.pf-row-phase::after {
  content: ""; position: absolute;
  left: 0; right: 0; top: 50%; height: 1px;
  background: var(--line-soft); pointer-events: none; z-index: 1;
}

/* Phase bars — thin pills centered on the guide line */
.pf-phase {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  height: 52px;
  z-index: 2;
}
.pf-phase.paused { opacity: 0.5; }
.pf-phase-bar {
  position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%);
  height: 30px; border-radius: 999px;
  background: var(--indigo-soft); border: 1px solid var(--indigo-line);
  overflow: hidden;
}
.pf-phase-money {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--indigo); border-radius: 999px;
}
.pf-phase-money.over {
  background: var(--bad); border-radius: 999px;
  opacity: 0.85;
}
.pf-phase-label {
  /* right:8 not right:2 — each label is clipped to its OWN bar, so two adjacent
     narrow bars put two truncated labels flush against each other and they read
     as one run-on word ("…REMEN" + "INSTALLATION…" → "REMENINSTALLATION…").
     The gap keeps them legible as separate phases. */
  position: absolute; left: 2px; right: 8px;
  top: calc(50% + 18px);
  font-size: 9.5px; color: var(--ink-4); font-family: var(--f-mono);
  text-transform: uppercase; letter-spacing: 0.07em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pf-phase-thin { }
.pf-phase-thin .pf-phase-bar { height: 22px; }
.pf-phase-thin .pf-phase-label { display: none; }
/* Item 5: calendar-style edge handles for resizing a phase bar's start/end.
   Sit over each end of the bar; faint until the bar is hovered. */
.pf-resize-handle {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 8px; height: 24px; border-radius: 3px;
  cursor: ew-resize; z-index: 4;
  background: var(--indigo, #4f46e5);
  opacity: 0; transition: opacity 120ms ease;
}
.pf-resize-handle-start { left: -2px; }
.pf-resize-handle-end   { right: -2px; }
.pf-phase:hover .pf-resize-handle { opacity: 0.55; }
.pf-resize-handle:hover { opacity: 0.95; }

/* ── Phase 1 economics overlay (Money Gantt) ─────────────────────────────── */
/* Compact margin% chip riding the top-right of a phase bar. Color is set
   inline to the margin-health tone (--ok/--warn/--bad). pointer-events:none so
   it never steals the bar's drag/click. */
.pf-phase-econ-chip {
  position: absolute; top: -2px; right: 2px;
  font-size: 9px; font-weight: 700; font-family: var(--f-mono);
  letter-spacing: 0.03em; line-height: 1;
  color: var(--ink-4); pointer-events: none; z-index: 3;
}
.pf-phase-econ-chip-thin { top: 50%; transform: translateY(-50%); }

/* ── Phase 2: critical path + dependency arrows ──────────────────────────── */
/* Critical-path bars get a red outline (a separate visual channel from the
   Phase-1 margin tone, which colors the bar's left cap + border inline) so the
   two never clash. Violated/over-committed phases get a dashed red outline. */
.pf-phase.pf-critical .pf-phase-bar { outline: 1.5px solid var(--bad); outline-offset: 1px; }
.pf-phase.pf-violated .pf-phase-bar { outline: 1.5px dashed var(--bad); outline-offset: 1px; }
/* Loud negative-slack flag riding the bar's top-left. */
.pf-neg-chip {
  position: absolute; top: -2px; left: 2px;
  font-size: 8.5px; font-weight: 700; font-family: var(--f-mono);
  letter-spacing: 0.02em; line-height: 1; color: var(--bad);
  pointer-events: none; z-index: 3; white-space: nowrap;
}
/* Phase 3: baseline ghost bar — faint outline behind the live phase bar. */
.pf-phase-baseline {
  position: absolute; top: 50%; transform: translateY(-50%);
  height: 8px; border-radius: 4px; z-index: 0; pointer-events: none;
  border: 1px dashed var(--ink-5);
  background: repeating-linear-gradient(45deg, rgba(127,127,127,0.10) 0 4px, transparent 4px 8px);
}
/* Phase 3: resource over-allocation heatmap (warn-only). */
.pf-resources {
  margin-top: 10px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface, var(--bg-1));
}
.pf-resources-empty { color: var(--ink-4); font-size: 12.5px; }
.pf-resources-head {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; font-weight: 600; color: var(--ink-3); margin-bottom: 8px;
}
.pf-res-overflag { font-size: 11px; font-weight: 600; color: var(--bad); }
.pf-res-row { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.pf-res-name {
  width: 150px; flex-shrink: 0; font-size: 12px; color: var(--ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: 6px;
}
.pf-res-badge {
  font-size: 9.5px; font-weight: 700; color: var(--bad);
  background: color-mix(in srgb, var(--bad) 14%, transparent);
  border-radius: 4px; padding: 1px 4px;
}
.pf-res-cells { display: flex; gap: 1px; flex: 1; height: 14px; }
.pf-res-cell { flex: 1; min-width: 2px; border-radius: 2px; }
/* Relative host for the dependency-arrow SVG overlay (rows render inside it
   unchanged). The SVG itself is absolutely positioned + pointer-events:none. */
.pf-dep-wrap { position: relative; }
.pf-dep-arrows { color: var(--ink-4); }
/* Drag-to-connect handle — hidden until you hover the phase row, then a small
   indigo dot at the bar's finish edge you can drag to another bar to link them. */
.pf-connect-handle { opacity: 0; transition: opacity 120ms ease; }
.pf-row-phase-interactive:hover .pf-connect-handle { opacity: 0.55; }
.pf-connect-handle:hover { opacity: 1; }
/* Drop-target highlight while dragging a dependency onto a candidate successor. */
.pf-connect-target { outline: 1.5px dashed color-mix(in srgb, var(--indigo) 55%, transparent); outline-offset: -2px; border-radius: 4px; }
/* Predecessor picker (PhaseForm). */
.pf-dep-picker { margin: 4px 0 2px; }
.pf-dep-row { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; }
.pf-dep-err { font-size: 11.5px; color: var(--bad); margin: 2px 0 6px; }

/* Project header economics badge (left side list, under the meta line). */
.pf-proj-econ {
  display: flex; gap: 5px; align-items: center;
  font-size: 10.5px; color: var(--ink-4); margin-top: 3px;
  /* Fixed line-height so this line's contribution to --pf-proj-lines-h is a
     known 19px (3 margin + 16) and cannot be nudged by a font metric. */
  line-height: 16px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pf-proj-econ-chip { font-weight: 700; }
.pf-proj-econ-warn {
  font-size: 9.5px; font-weight: 600; color: var(--warn);
  /* Own line-height. A border on an INLINE box does not grow the line box, so
     this is not a height-budget fix — it is visual: inheriting the econ row's
     16px would draw a 18px-tall bordered chip overhanging a 16px line. */
  line-height: 12px;
  border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
  border-radius: 4px; padding: 0 4px; margin-left: 2px;
}

/* Explicit + Phase / + Milestone toolbar buttons. */
.pf-add-group { display: inline-flex; gap: 6px; }
.pf-add-btn {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--ink-3);
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-btn); padding: 4px 9px; cursor: pointer;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.pf-add-btn:hover:not(:disabled) { border-color: var(--indigo); color: var(--indigo); }
.pf-add-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Phase 4: schedule-template apply dropdown (toolbar). */
.pf-tpl-select {
  font-size: 12px; font-weight: 600; color: var(--ink-3);
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-btn); padding: 4px 8px; cursor: pointer; max-width: 180px;
}
.pf-tpl-select:disabled { opacity: 0.4; cursor: not-allowed; }

/* Phase 4: Smartsheet-style editable grid pane (sits above the bars). */
.pf-gridpane {
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-card); margin: 10px 0; overflow: hidden;
}
.pf-gridpane-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
  background: var(--bg-hover);
}
.pf-gridpane-title { font-size: 12px; font-weight: 700; color: var(--ink-2); letter-spacing: 0.02em; }
.pf-gridpane-scroll { overflow-x: auto; max-height: 360px; overflow-y: auto; }
.pf-gridtable { width: 100%; border-collapse: collapse; font-size: 12px; }
.pf-gridtable th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; font-weight: 700; color: var(--ink-4);
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 6px 8px; background: var(--bg-card); border-bottom: 1px solid var(--line);
}
.pf-gridtable td { padding: 3px 6px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.pf-gridtable-empty { color: var(--ink-4); text-align: center; padding: 16px; font-style: italic; }
.pf-gridcell {
  width: 100%; box-sizing: border-box;
  font-size: 12px; color: var(--ink-2);
  background: transparent; border: 1px solid transparent;
  border-radius: 5px; padding: 3px 6px;
}
.pf-gridcell:hover { border-color: var(--line); }
.pf-gridcell:focus { outline: none; border-color: var(--indigo); background: var(--bg-card); }
.pf-gridcell-ro { color: var(--ink-4); padding: 3px 6px; white-space: nowrap; }

/* Hover affordance on an empty create-track row. */
.pf-track-hint {
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  text-align: center; font-size: 10.5px; color: var(--ink-5);
  letter-spacing: 0.04em; pointer-events: none; z-index: 2;
  opacity: 0; transition: opacity 140ms ease;
}
.pf-row-phase-interactive:hover .pf-track-hint { opacity: 0.55; }

/* Milestones — circles on the guide line */
.pf-milestone {
  position: absolute; top: 50%; transform: translate(-50%, -50%);
  z-index: 4; cursor: pointer;
}
.pf-ms-dot {
  width: 24px; height: 24px; border-radius: 50%;
  background: color-mix(in oklab, var(--ink) 28%, var(--bg-card)); border: 3px solid var(--ink);
  transition: transform 0.1s;
}
.pf-milestone:hover .pf-ms-dot { transform: scale(1.15); }
.pf-milestone.done .pf-ms-dot { border-color: var(--ink); background: color-mix(in oklab, var(--ink) 28%, var(--bg-card)); }
.pf-milestone.critical .pf-ms-dot { border-color: var(--bad); background: color-mix(in oklab, var(--bad) 28%, var(--bg-card)); }
.pf-milestone-label {
  position: absolute; top: 28px; left: 50%; transform: translateX(-50%);
  font-size: 9.5px; color: var(--ink-4); font-family: var(--f-mono);
  white-space: nowrap; opacity: 0; transition: opacity .12s;
  background: var(--bg-card); padding: 2px 6px; border-radius: 3px;
  border: 1px solid var(--line); pointer-events: none;
}
.pf-milestone:hover .pf-milestone-label { opacity: 1; z-index: 5; }

/* Staff allocation cells */
.pf-staff-cell {
  flex: 1; min-width: 28px; border-right: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-family: var(--f-mono); color: var(--ink-3);
  position: relative;
}
.pf-staff-cell-h {
  position: relative; z-index: 2;
}
.pf-staff-cell::before {
  content: ""; position: absolute; inset: 4px 1px;
  border-radius: 2px; background: transparent;
}
.alloc-0::before    { background: transparent; }
.alloc-low::before  { background: color-mix(in oklab, var(--warn) 18%, transparent); }
.alloc-on::before   { background: color-mix(in oklab, var(--ok) 22%, transparent); }
.alloc-over::before { background: color-mix(in oklab, var(--bad) 26%, transparent); }
.alloc-low  { color: var(--warn); }
.alloc-on   { color: color-mix(in oklab, var(--ok) 70%, var(--ink)); }
.alloc-over { color: var(--bad); font-weight: 500; }


/* ─── Command bar + bus ──────────────────────────────────────────────────── */
.cmd-launcher {
  position: fixed; right: 22px; bottom: 22px; z-index: 60;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--ink); color: var(--bg-elev);
  border: 0; padding: 9px 14px 9px 9px; border-radius: 999px;
  font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  box-shadow: 0 8px 24px rgba(0,0,0,.18), 0 2px 6px rgba(0,0,0,.10);
}
.cmd-launcher:hover { background: color-mix(in srgb, var(--ink) 86%, var(--bg-elev)); } /* fill lightens (both themes); no movement — founder 2026-08-20. SNAPS: color-mix values must never be transitioned */
.cmd-launcher-mark {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--indigo); color: #fff;
  display: grid; place-items: center;
}
.cmd-launcher-text { display: inline-flex; align-items: center; gap: 10px; }
.cmd-launcher-hint {
  font-family: var(--f-mono); font-size: 10.5px; opacity: .55;
  border: 1px solid color-mix(in oklab, var(--bg-elev) 30%, transparent);
  border-radius: 4px; padding: 1px 5px;
}

.cmd-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in oklab, var(--bg-sunk) 60%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 9vh; animation: cmdFade .15s ease;
}
@keyframes cmdFade { from { opacity: 0; } to { opacity: 1; } }
.cmd-shell {
  width: min(960px, calc(100vw - 32px));
  max-height: 82vh;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 30px 80px rgba(0,0,0,.22), 0 4px 12px rgba(0,0,0,.06);
  overflow: hidden; animation: cmdRise .18s ease;
  display: flex; flex-direction: column;
}
@keyframes cmdRise { from { transform: translateY(-8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

.cmd-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
}
.cmd-mark {
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--indigo-soft); color: var(--indigo);
  display: grid; place-items: center; flex: 0 0 auto;
}
.cmd-input {
  flex: 1; border: 0; background: none; outline: none;
  color: var(--ink); font: inherit; font-size: 15px;
}
.cmd-input::placeholder { color: var(--ink-4); }
.cmd-esc {
  font-family: var(--f-mono); font-size: 10.5px;
  border: 1px solid var(--line); border-radius: 4px;
  padding: 2px 6px; color: var(--ink-4); background: var(--bg-sunk);
}

.cmd-body { padding: 14px 16px 16px; max-height: 64vh; overflow: auto; }
.cmd-section-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--ink-5); font-weight: 500; margin-bottom: 8px;
}
.cmd-suggestions { display: flex; flex-direction: column; gap: 4px; }
.cmd-suggestion {
  display: flex; align-items: flex-start; gap: 10px; text-align: left;
  background: none; border: 0; padding: 9px 10px; border-radius: 6px;
  color: var(--ink-2); font: inherit; font-size: 13px;
  cursor: pointer; line-height: 1.45;
}
.cmd-suggestion:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-suggestion .icon { margin-top: 3px; flex: 0 0 auto; }

.cmd-history { display: flex; flex-direction: column; gap: 2px; }
.cmd-history-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 6px;
  font-size: 12.5px; color: var(--ink-3);
}

.cmd-foot-note {
  margin-top: 16px; padding-top: 12px;
  border-top: 1px dashed var(--line);
  font-size: 11.5px; color: var(--ink-4); line-height: 1.5;
}

.cmd-thinking {
  display: flex; align-items: center; gap: 4px;
  padding: 14px 4px; color: var(--ink-3); font-size: 13px;
}

.cmd-proposal { display: flex; flex-direction: column; gap: 14px; }
.cmd-proposal-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
}
.cmd-proposal-eyebrow {
  font-size: 11px; letter-spacing: 0.01em;
  color: var(--ink-4); font-weight: 400; margin-bottom: 6px;
  display: none;
}
.cmd-proposal-title {
  font-size: 14.5px; font-weight: 500; letter-spacing: -0.01em;
  margin-bottom: 6px; color: var(--ink);
}
.cmd-proposal-summary {
  margin-top: 6px; font-size: 13px; color: var(--ink-3); line-height: 1.5; max-width: 56ch;
}

.cmd-diff {
  border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg-elev);
  overflow: hidden;
}
.cmd-diff-empty { padding: 16px; color: var(--ink-4); font-size: 13px; }
.cmd-diff-row {
  display: flex; gap: 11px; padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.cmd-diff-row:last-child { border-bottom: 0; }
.cmd-diff-icon {
  width: 22px; height: 22px; border-radius: 5px;
  background: var(--indigo-soft); color: var(--indigo);
  display: grid; place-items: center; flex: 0 0 auto; margin-top: 1px;
}
.cmd-diff-body { flex: 1; min-width: 0; }
.cmd-diff-line {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap; font-size: 13px;
}
.cmd-diff-field { font-weight: 500; color: var(--ink); }
.cmd-diff-from {
  color: var(--ink-4); text-decoration: line-through;
  text-decoration-color: var(--ink-5); font-feature-settings: "tnum";
}
.cmd-diff-to {
  color: var(--indigo); font-weight: 500;
  background: var(--indigo-soft); padding: 1px 6px; border-radius: 4px;
  font-feature-settings: "tnum";
}
.cmd-diff-meta {
  margin-top: 3px; display: flex; gap: 6px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-4);
}
.cmd-diff-where { color: var(--ink-3); font-weight: 500; }

.cmd-proposal-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 8px 12px; padding-top: 12px; border-top: 1px dashed var(--line);
  flex-wrap: wrap; min-width: 0;
}
.cmd-proposal-actions { display: flex; gap: 6px; flex-wrap: wrap; flex-shrink: 0; margin-left: auto; }

.cmd-toast {
  position: fixed; right: 22px; bottom: 76px; z-index: 70;
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-left: 3px solid var(--ok); border-radius: 8px;
  padding: 10px 14px; box-shadow: 0 12px 32px rgba(0,0,0,.12);
  animation: cmdRise .2s ease;
  max-width: 360px;
}
.cmd-toast .icon { color: var(--ok); flex: 0 0 auto; }
.cmd-toast-title { font-size: 13px; font-weight: 500; color: var(--ink); }
.cmd-toast-sub { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.cmd-toast-undo {
  background: none; border: 0; padding: 0;
  color: var(--indigo); font: inherit; font-size: 11.5px;
  cursor: pointer; text-decoration: underline;
}


/* ─── AI Surfaces ──────────────────────────────────────────────────── */

/* AI inline chip */
.ai-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--indigo-soft); color: var(--indigo-ink);
  border: 1px solid var(--indigo-line); border-radius: 999px;
  padding: 3px 9px 3px 4px; font: inherit; font-size: 11.5px; font-weight: 500;
  cursor: pointer; line-height: 1.2;
}
.ai-chip:hover { background: var(--indigo); color: #fff; }
.ai-chip:hover .ai-chip-mark { background: rgba(255,255,255,.2); color: #fff; }
.ai-chip-mark {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--indigo); color: #fff;
  display: grid; place-items: center;
}
.ai-chip.tone-warn { background: var(--warn-soft); border-color: var(--warn-line); color: var(--warn); }
.ai-chip.tone-warn .ai-chip-mark { background: var(--warn); }
.ai-chip.tone-bad { background: var(--bad-soft); border-color: var(--bad-line); color: var(--bad); }
.ai-chip.tone-bad .ai-chip-mark { background: var(--bad); }

/* Why mark + popover */
.ai-why { position: relative; display: inline-flex; align-items: center; gap: 4px; cursor: help; }
.ai-why-mark {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--indigo-soft); color: var(--indigo);
  display: inline-grid; place-items: center;
  border: 1px solid var(--indigo-line);
}
.ai-why-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  width: 280px; padding: 10px 12px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 12px 32px rgba(0,0,0,.14);
  font-family: var(--f-sans);
}
.ai-why-pop-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--indigo); font-weight: 500; margin-bottom: 6px;
}
.ai-why-pop-body { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.ai-why-pop-foot {
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line);
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}

/* Row flag */
.ai-rowflag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px 2px 3px; border-radius: 999px;
  font: inherit; font-size: 11px; font-weight: 500;
  background: var(--warn-soft); color: var(--warn);
  border: 1px solid var(--warn-line);
  cursor: pointer; line-height: 1.2;
}
.ai-rowflag.tone-bad { background: var(--bad-soft); color: var(--bad); border-color: var(--bad-line); }
.ai-rowflag.tone-indigo { background: var(--indigo-soft); color: var(--indigo); border-color: var(--indigo-line); }
.ai-rowflag-mark {
  width: 12px; height: 12px; border-radius: 50%;
  background: currentColor; color: var(--bg-card);
  display: grid; place-items: center;
  filter: brightness(.9);
}

/* AI brief card */
.ai-brief {
  display: flex; gap: 14px;
  background: linear-gradient(180deg, var(--indigo-soft), var(--bg-card));
  border: 1px solid var(--indigo-line); border-radius: 10px;
  padding: 14px 16px; margin-bottom: 24px;
  position: relative; overflow: hidden;
}
.ai-brief::before {
  content: ""; position: absolute; top: -40%; right: -10%;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(circle, var(--indigo) 0%, transparent 60%);
  opacity: .06; pointer-events: none;
}
.ai-brief-side {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.ai-brief-mark {
  width: 26px; height: 26px; border-radius: 7px;
  background: var(--indigo); color: #fff;
  display: grid; place-items: center; flex: 0 0 auto;
}
.ai-brief-vrule { flex: 1; width: 1px; background: var(--indigo-line); }
.ai-brief-body { flex: 1; }
.ai-brief-eyebrow {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--indigo); font-weight: 500;
}
.ai-brief-title {
  font-size: 16px; font-weight: 500; color: var(--ink);
  margin-top: 4px; letter-spacing: -0.01em;
}
.ai-brief-text { margin-top: 6px; font-size: 13px; line-height: 1.55; color: var(--ink-2); max-width: 70ch; }
.ai-brief-foot {
  margin-top: 12px; display: flex; gap: 14px; align-items: center;
  flex-wrap: wrap;
}
.ai-brief-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.ai-brief-action {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 6px; padding: 5px 10px;
  font: inherit; font-size: 12px; font-weight: 500; color: var(--ink-2);
  cursor: pointer;
}
.ai-brief-action:hover { border-color: var(--indigo); color: var(--indigo); }
.ai-brief-meta { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-left: auto; }


/* ─── Office detail / editable settings ────────────────────────────────── */
.staff-list { display: flex; flex-direction: column; gap: 6px; }
.staff-row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 0;
  border-bottom: 1px dashed var(--line-soft);
}
.staff-row:last-child { border-bottom: 0; }
.staff-name { font-size: 13.5px; color: var(--ink); font-weight: 500; }
.staff-role { font-size: 11.5px; color: var(--ink-4); margin-top: 1px; }
.avatar-sm { width: 28px; height: 28px; font-size: 11px; }

.ed-input {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 5px; padding: 5px 8px;
  font: inherit; font-size: 13px; color: var(--ink); outline: none;
  width: 100%; max-width: 280px;
}
.ed-input:focus { border-color: var(--indigo); }
.ed-num { max-width: 90px; text-align: right; font-feature-settings: "tnum"; }

.settings-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 18px 28px; padding: 4px 0;
}
.setting-field { display: flex; flex-direction: column; gap: 5px; }
.setting-field-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--ink-5); font-weight: 500;
}
.setting-field-value {
  font-size: 14px; color: var(--ink); padding: 5px 0;
}

.setting-list { display: flex; flex-direction: column; }
.switch {
  width: 36px; height: 20px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-sunk);
  position: relative; cursor: pointer; flex: 0 0 auto;
  transition: background .15s, border-color .15s;
}
.switch:disabled { cursor: not-allowed; opacity: .65; }
.switch.on { background: var(--indigo); border-color: var(--indigo); }
.switch-knob {
  position: absolute; top: 1px; left: 1px;
  width: 16px; height: 16px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.18);
  transition: transform .15s;
}
.switch.on .switch-knob { transform: translateX(16px); }

.btn-danger {
  background: var(--bad-soft); color: var(--bad);
  border: 1px solid var(--bad-line);
}
.btn-danger:hover:not(:disabled) { background: var(--bad); color: #fff; }
.btn-danger:disabled { opacity: .55; cursor: not-allowed; }

.office-card-link {
  cursor: pointer;
}
.office-card-link:hover { box-shadow: 0 0 0 1px var(--line), var(--shadow-sm); } /* thicken-outline convention (it's a .card: keep its resting shadow); SNAPS */


/* ─── OfficeClock ─────────────────────────────────────────────────────────── */
.office-clock {
  display: inline-flex; flex-direction: column; align-items: flex-end;
  font-feature-settings: "tnum";
  white-space: nowrap;
}
.office-clock-compact {
  flex-direction: row; align-items: baseline; gap: 6px;
}
.office-clock-time {
  font-family: var(--f-mono, ui-monospace, "SFMono-Regular", monospace);
  color: var(--ink); font-weight: 500; letter-spacing: -0.01em;
}
.office-clock-meta {
  color: var(--ink-4); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 500;
}
.office-clock-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--ink-5); display: inline-block; align-self: center;
}
.office-clock-dot.on { background: var(--ok, #1f8a5b); box-shadow: 0 0 0 3px color-mix(in oklch, var(--ok, #1f8a5b) 18%, transparent); }


/* ─── Billing model selector ─────────────────────────────────────────────── */
.billing-model-row {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  padding: 4px 0;
}
.billing-model-card {
  text-align: left; cursor: pointer;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; padding: 12px 14px;
  display: flex; align-items: flex-start; gap: 10px;
  transition: border-color .12s, background .12s;
  font: inherit;
}
.billing-model-card:hover:not(:disabled) { border-color: var(--ink-5); }
.billing-model-card.active {
  border-color: var(--indigo);
  background: color-mix(in oklch, var(--indigo) 5%, var(--bg-card));
}
.billing-model-card:disabled { cursor: not-allowed; }
.billing-model-card:disabled:not(.active) { opacity: .85; }

.billing-model-radio {
  width: 16px; height: 16px; border-radius: 50%;
  border: 1.5px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; margin-top: 2px;
}
.billing-model-card.active .billing-model-radio { border-color: var(--indigo); }
.billing-model-radio-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: transparent; transition: background .12s;
}
.billing-model-radio-dot.on { background: var(--indigo); }

.billing-model-label {
  font-size: 13.5px; font-weight: 500; color: var(--ink);
}
.billing-model-desc {
  font-size: 12px; color: var(--ink-4); margin-top: 2px; line-height: 1.45;
}


/* ─── Aecos answer (Q&A response) ────────────────────────────────────────── */
.cmd-answer {
  margin-top: 0;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink);
  font-family: var(--f-sans);
  letter-spacing: -0.005em;
}
.cmd-answer + .cmd-proposal-summary {
  margin-top: 8px; font-size: 13px; color: var(--ink-3); line-height: 1.55;
}


/* ─── Chat-style command bar ─────────────────────────────────────────────── */

/* Project sidebar */
.cmd-proj-sidebar-head {
  padding: 12px 14px 6px;
  font-size: 10.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .08em; color: var(--ink-4);
  flex: 0 0 auto;
}
.cmd-proj-item {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px; border: none; background: none;
  cursor: pointer; text-align: left; width: 100%;
  border-radius: 6px; transition: background .1s;
}
.cmd-proj-item:hover { background: var(--bg-hover); }
.cmd-proj-item.active { background: var(--indigo-soft); }
.cmd-proj-dot {
  width: 7px; height: 7px; border-radius: 50%;
  flex: 0 0 7px;
}
.cmd-proj-name {
  font-size: 12.5px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  flex: 1; min-width: 0;
}
.cmd-proj-item.active .cmd-proj-name { color: var(--indigo-ink); }

.cmd-proj-group { margin-bottom: 4px; }
.cmd-proj-group-head {
  padding: 8px 12px 4px;
  font-size: 10.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink-4);
}

/* Main chat area */
.cmd-chat-main {
  flex: 1; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  position: relative;
}
.cmd-chat-head {
  position: absolute; top: 8px; left: 0; right: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition: padding-left 0.25s cubic-bezier(0.4,0,0.2,1);
}
.sidebar.collapsed ~ .app-chat-panel .cmd-chat-head {
  padding-left: 52px;
}
.cmd-chat-title { flex: 1; min-width: 0; }
.cmd-chat-name { font-size: 13.5px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em;
  display: block; width: 100%; flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Project-chat header: the active chat name sits over a small project subtitle. */
.cmd-chat-subtitle { font-size: 11px; color: var(--ink-4); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Per-project chat list (the project acts as a folder of chats). */
.cmd-pchat-back { color: var(--ink-4); }
.cmd-pchat-projhead { display: flex; align-items: center; gap: 7px;
  padding: 4px 12px 8px; }
.cmd-pchat-projname { font-size: 12.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmd-chat-name-input {
  font-size: 13.5px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em;
  background: var(--bg-hover); border: 1px solid var(--indigo-line);
  border-radius: 4px; padding: 1px 6px; outline: none;
  width: 100%;
}
.cmd-chat-head-actions { display: flex; align-items: center; gap: 8px; }

/* Unified left sidebar */
.cmd-left-sidebar {
  width: 155px; flex-shrink: 0;
  border-right: 1px solid var(--line-soft);
  background: var(--bg-elev);
  display: flex; flex-direction: column; overflow: hidden;
}
.cmd-sidebar-tabs {
  display: flex;
  border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.cmd-sidebar-tab {
  flex: 1; padding: 10px 0;
  font-size: 12.5px; font-weight: 500; color: var(--ink-3);
  border: 0; background: none; cursor: pointer;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.12s;
}
.cmd-sidebar-tab:hover { color: var(--ink); }
.cmd-sidebar-tab.active { color: var(--indigo); border-bottom-color: var(--indigo); }

.cmd-sidebar-content {
  flex: 1; overflow-y: auto; display: flex; flex-direction: column;
}

.cmd-select-first-note {
  display: flex; align-items: flex-start; gap: 9px;
  background: var(--bg-hover); border: 1px solid var(--line-soft);
  border-radius: 8px; padding: 11px 14px;
  font-size: 12.5px; color: var(--ink-2); line-height: 1.5;
  margin-bottom: 14px;
}
.cmd-select-first-note svg { flex-shrink: 0; margin-top: 1px; color: var(--indigo); }

.cmd-gside-top {
  display: flex; align-items: center; gap: 4px;
  padding: 10px 10px 8px;
}
.cmd-gside-newchat {
  flex: 1; display: flex; align-items: center; gap: 6px;
  padding: 5px 8px; border-radius: var(--radius-btn); border: 0;
  background: none; color: var(--ink-2); font-size: 12.5px;
  font-weight: 500; cursor: pointer; text-align: left;
  transition: background 0.1s;
}
.cmd-gside-newchat:hover, .cmd-gside-newchat.active { background: var(--bg-hover); color: var(--ink); }
.cmd-gside-top-btns { display: flex; gap: 2px; }
.cmd-gside-icon-btn {
  width: 26px; height: 26px; border-radius: var(--radius-btn-icon); border: 0;
  background: none; color: var(--ink-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.1s;
}
.cmd-gside-icon-btn:hover { background: var(--bg-hover); color: var(--ink); }

.cmd-gside-form {
  padding: 8px 10px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg);
  display: flex; flex-direction: column; gap: 6px;
}
.cmd-gside-edit-form { border-bottom: 0; background: var(--bg-hover); border-radius: 6px; margin: 4px 6px; }
.cmd-gside-input {
  width: 100%; box-sizing: border-box;
  padding: 5px 8px; border-radius: 5px;
  border: 1px solid var(--line); background: var(--bg);
  font-size: 12px; font-family: inherit; color: var(--ink);
  resize: none;
}
.cmd-gside-input:focus { outline: none; border-color: var(--indigo); }
.cmd-gside-instructions { resize: vertical; min-height: 52px; }
.cmd-gside-form-actions { display: flex; gap: 5px; }

.cmd-gside-list {
  flex: 1; overflow-y: auto; padding: 6px 0;
}
.cmd-gside-hint {
  font-size: 11.5px; color: var(--ink-4); padding: 12px 12px;
  line-height: 1.5; text-align: center;
}

.cmd-gside-new-folder-btn { color: var(--ink-4) !important; }
.cmd-gside-new-folder-btn:hover { color: var(--ink-2) !important; }
.cmd-gside-folder-form { margin: 2px 6px 4px; }
.cmd-gside-folder { margin-bottom: 1px; }
.cmd-gside-folder-head {
  width: 100%; display: flex; align-items: center; gap: 7px;
  padding: 5px 10px; border: 0; background: none;
  font-size: 12.5px; font-weight: 400; color: var(--ink-2);
  cursor: pointer; text-align: left; border-radius: var(--radius-btn-icon);
  transition: background 0.1s; font-family: var(--f-sans);
}
.cmd-gside-folder-head:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-gside-folder-head.active { background: rgba(99,102,241,0.08); color: var(--indigo); }
.cmd-gside-folder-icon { flex-shrink: 0; }
.cmd-gside-folder-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmd-gside-folder-chevron { flex-shrink: 0; color: var(--ink-4); }
.cmd-gside-empty-folder { font-size: 11.5px; color: var(--ink-4); padding: 3px 24px 6px; }

.cmd-gside-project {
  position: relative;
}
.cmd-gside-project-btn {
  width: 100%; display: flex; align-items: center; gap: 7px;
  padding: 5px 10px; border: 0; background: none;
  font-size: 12.5px; color: var(--ink-2); cursor: pointer;
  text-align: left; border-radius: var(--radius-btn-icon); transition: background 0.1s;
}
.cmd-gside-folder .cmd-gside-project-btn { padding-left: 22px; }
.cmd-gside-project-btn:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-gside-project.active .cmd-gside-project-btn { background: rgba(99,102,241,0.08); color: var(--indigo); }
.cmd-gside-project-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }

/* Dropdown menu card */
.cmd-gside-menu {
  min-width: 168px; background: var(--bg-card);
  border: 1px solid var(--line); border-radius: var(--radius-menu);
  box-shadow: 0 4px 16px -4px rgba(20,20,30,.14), 0 1px 4px rgba(20,20,30,.06);
  padding: 4px; overflow: hidden;
}
.cmd-gside-menu-item {
  width: 100%; display: flex; align-items: center; gap: 7px;
  padding: 6px 9px; border: 0; background: none;
  font-size: 12.5px; color: var(--ink-2); cursor: pointer;
  text-align: left; border-radius: var(--radius-btn-icon); transition: background 0.1s;
}
.cmd-gside-menu-item:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-gside-menu-danger { color: var(--bad); }
.cmd-gside-menu-danger:hover { background: var(--bad-soft); color: var(--bad); }
.cmd-gside-menu-divider { height: 1px; background: var(--line-soft); margin: 3px 0; }
.cmd-gside-menu-back { color: var(--ink-4); font-size: 12px; }
.cmd-gside-menu-back:hover { color: var(--ink); }
.cmd-gside-menu-active { color: var(--indigo); background: var(--indigo-soft); }
.cmd-gside-menu-active:hover { background: var(--indigo-soft); }
.cmd-gside-menu-arrow { margin-left: auto; color: var(--ink-4); }

/* Pin icon on pinned chats */
.cmd-pin-icon { color: var(--indigo); opacity: 0.7; flex-shrink: 0; }

/* Inline folder rename input */
.cmd-gside-folder-input {
  flex: 1; border: 0; background: none; font-size: 12.5px;
  color: var(--ink); outline: none; padding: 0;
  font-family: var(--f-sans);
}

/* Instructions banner in general thread */
.cmd-proj-instructions {
  background: rgba(99,102,241,0.06); border: 1px solid rgba(99,102,241,0.15);
  border-radius: 8px; padding: 10px 13px; margin-bottom: 2px;
}
.cmd-proj-instructions-label {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600; color: var(--indigo);
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 5px;
}
.cmd-proj-instructions-text { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }

.cmd-chat-scroll {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto;
  padding: 76px 18px 8px;
  display: flex; flex-direction: column; gap: 8px;
  scroll-behavior: smooth;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0px, black 92px);
  mask-image: linear-gradient(to bottom, transparent 0px, black 92px);
}
.cmd-chat-scroll::-webkit-scrollbar { width: 4px; }
.cmd-chat-scroll::-webkit-scrollbar-track { background: transparent; }
.cmd-chat-scroll::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 4px; }
.cmd-chat-scroll::-webkit-scrollbar-thumb:hover { background: var(--ink-5); }

.cmd-chat-empty {
  margin: auto 0;
  padding: 14px 6px 6px;
  text-align: left;
}
.cmd-chat-empty-mark {
  width: 36px; height: 36px; border-radius: 9px;
  background: var(--indigo-soft); color: var(--indigo);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 12px;
}
.cmd-chat-empty-title { font-size: 17px; font-weight: 500; color: var(--ink); letter-spacing: -0.015em; }
.cmd-chat-empty-sub { font-size: 13px; color: var(--ink-3); margin-top: 4px; max-width: 52ch; line-height: 1.5; }

.cmd-chat-row { display: flex; gap: 0; align-items: flex-start; margin-bottom: 2px; }
.cmd-chat-row-user { justify-content: flex-start; margin-bottom: 6px; }
.cmd-chat-row-aecos { margin-bottom: 4px; }
.cmd-chat-avatar { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; flex-shrink: 0; margin-right: 6px; margin-top: 3px; color: var(--ink); }
.cmd-chat-bubble {
  border-radius: 10px; padding: 8px 12px;
  font-size: 13.5px; line-height: 1.5;
  max-width: 100%; letter-spacing: -0.005em;
}
.cmd-chat-bubble-user {
  background: var(--indigo-soft); color: var(--indigo-ink);
  border-radius: 8px; font-family: var(--f-sans);
  font-size: 13.5px; padding: 8px 13px; max-width: 100%;
}
.cmd-chat-bubble-aecos {
  background: none; border: none; border-radius: 0;
  width: 100%; padding: 0 0 2px; box-shadow: none;
}
.cmd-chat-bubble-thinking {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 2px; background: none; border: none;
  width: auto;
}

/* Gentle entrance for each message row — fades + settles, reduced-motion safe. */
.cmd-chat-row { animation: cmd-msg-in var(--duration-base, 180ms) var(--ease-out) both; }
@keyframes cmd-msg-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* Assistant identity — a subtle "named partner" header on each Aecos reply. */
.cmd-aecos-identity {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--ink-4); margin-bottom: 6px; user-select: none;
}
.cmd-aecos-identity-glyph {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--indigo);
}

/* Thinking — a calm, breathing glyph + label + drifting dots, not a spinner. */
.cmd-thinking-avatar {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; flex-shrink: 0; margin-right: 6px; margin-top: 2px;
  color: var(--indigo);
  animation: cmd-thinking-breathe 2.4s var(--ease-in-out, ease-in-out) infinite;
}
.cmd-thinking-label {
  font-size: 12.5px; color: var(--ink-3); margin-right: 8px; letter-spacing: -0.005em;
}
@keyframes cmd-thinking-breathe { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .cmd-chat-row { animation: none; }
  .cmd-thinking-avatar { animation: none; opacity: .8; }
}

.cmd-chat-bubble-aecos .cmd-proposal-head { padding: 0; border: 0; margin-bottom: 0; }
.cmd-chat-bubble-aecos .cmd-diff { margin-top: 12px; border: 1px solid var(--line-soft); border-radius: 8px; overflow: hidden; }
.cmd-chat-bubble-aecos .cmd-proposal-foot { padding: 10px 0 0; margin-top: 10px; border-top: none; }

.cmd-msg-actions {
  display: flex; gap: 2px; margin-top: 8px;
  opacity: 0; transition: opacity 0.15s;
}
.cmd-chat-row-aecos:hover .cmd-msg-actions { opacity: 1; }
.cmd-msg-action-btn {
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 4px 6px; border-radius: var(--radius-btn-icon);
  display: inline-flex; align-items: center;
  transition: background 0.1s, color 0.1s;
}
.cmd-msg-action-btn:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-msg-action-btn.active { color: var(--indigo); }

.cmd-composer-textarea-row {
  padding: 10px 14px 4px;
}
.cmd-composer-actions {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 10px 10px;
}
.cmd-composer-actions-left { display: flex; align-items: center; gap: 2px; }
.cmd-composer-actions-right { display: flex; align-items: center; }
.cmd-expand-btn {
  width: 30px; height: 30px; border-radius: var(--radius-btn-icon);
  background: none; border: none;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-4);
  transition: color 0.12s, background 0.12s;
}
.cmd-expand-btn:hover { color: var(--ink); background: var(--bg-sunk); }
.cmd-mic-btn {
  width: 30px; height: 30px; border-radius: var(--radius-btn-icon);
  background: none; border: none;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-4);
  transition: color 0.12s, background 0.12s;
  position: relative;
}
.cmd-mic-btn:hover { color: var(--ink); background: var(--bg-sunk); }
.cmd-mic-btn.listening { color: var(--bad); }
.cmd-mic-btn.listening::before {
  content: '';
  position: absolute; inset: -3px;
  border-radius: 10px;
  border: 1.5px solid var(--bad);
  animation: mic-ring 1.2s ease-in-out infinite;
  opacity: 0;
}
@keyframes mic-ring {
  0%   { opacity: 0.7; transform: scale(0.85); }
  100% { opacity: 0;   transform: scale(1.2); }
}

/* ⚠️ NOT A PILL. Founder, 2026-08-18: "don't make it a bubble, make it the same
   radius as the rest of the chat — not full bean." This tag carries the ACTION
   RESULT ("Aecos video meeting with Manuel — tomorrow 12:30pm"), which is a
   sentence, not a status word — at 999px a sentence-length tag renders as a long
   green bean that reads as a different kind of object from everything around it.
   --radius-md is 8px, the same value .cmd-chat-bubble uses, so the result now
   sits in the conversation instead of floating on top of it.
   `flex-wrap` + `min-width:0` are part of the same fix: an inline-flex row that
   cannot wrap is what let a long result push past the card's edge. */
.cmd-applied-tag {
  display: inline-flex; align-items: center; gap: 5px;
  flex-wrap: wrap; min-width: 0; max-width: 100%;
  overflow-wrap: anywhere;
  padding: 4px 9px; border-radius: var(--radius-md);
  background: var(--ok-soft); color: var(--good);
  font-size: 11.5px; font-weight: 500;
  border: 1px solid var(--ok-line);
}
.cmd-applied-tag-dim { background: var(--bg-sunk); color: var(--ink-4); border-color: var(--line); }

/* "Needs invite" callout — surfaced when a patch contains staff.add ops with
   status: 'needs_invite'. Shows above the Apply/Discard row in both the
   command bar and the Analyst page. */
.cmd-needs-invite {
  display: flex; gap: 10px; align-items: flex-start;
  margin: 10px 0 0; padding: 10px 12px; border-radius: 8px;
  background: color-mix(in srgb, var(--warn) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 28%, transparent);
  color: var(--ink-2);
  font-size: 12.5px;
}
.cmd-needs-invite > svg { color: var(--warn); margin-top: 2px; flex-shrink: 0; }
.cmd-needs-invite-title { font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.cmd-needs-invite-body { display: flex; flex-wrap: wrap; gap: 4px 8px; margin-bottom: 4px; }
.cmd-needs-invite-name {
  display: inline-block; padding: 2px 8px; border-radius: 4px;
  background: var(--bg-card); border: 1px solid var(--line);
  font-size: 11.5px; color: var(--ink-2);
}
.cmd-needs-invite-note { font-size: 11.5px; color: var(--ink-4); }

.cmd-proj-empty-state {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 76px 22px 32px; gap: 4px; text-align: center;
}
.cmd-proj-empty-title { font-size: 15px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em; }
.cmd-proj-empty-sub { font-size: 13px; color: var(--ink-4); line-height: 1.5; }
.cmd-proj-tab-search {
  padding: 8px 10px 6px; flex-shrink: 0;
}
.cmd-proj-search {
  width: 100%; box-sizing: border-box;
  background: var(--bg-sunk); border: 1px solid transparent;
  border-radius: 7px; padding: 6px 10px;
  font: inherit; font-size: 12.5px; color: var(--ink);
  outline: none; transition: border-color 0.12s, background 0.12s;
}
.cmd-proj-search:focus { border-color: var(--indigo-line); background: var(--bg-card); }
.cmd-proj-search::placeholder { color: var(--ink-4); }

.cmd-proj-empty { padding: 10px 12px; font-size: 12.5px; color: var(--ink-4); }

/* ── General landing screen ──────────────────────────────────────────── */
.cmd-general-landing {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 40px 24px;
  padding-top: 76px;
}
.cmd-general-landing-inner {
  width: 100%; max-width: 500px;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
/* Fullscreen chat: the welcome/new-chat composer was capped at 500px, so the
   text box looked tiny in the expanded panel. Let it use much more width. */
.app-chat-panel.cmd-expanded .cmd-general-landing-inner { max-width: 1040px; }
.cmd-general-landing-icon {
  width: 64px; height: 64px; border-radius: 18px;
  background: var(--bg-elev); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink); margin-bottom: 6px;
}
.cmd-general-landing-heading {
  font-size: 18px; font-weight: 500; color: var(--ink);
  letter-spacing: -0.02em; margin-bottom: 8px;
}
.cmd-general-landing-composer {
  width: 100%; display: flex; flex-direction: column; gap: 0;
  background: var(--bg-card); border: 1.5px solid var(--line);
  border-radius: 16px; padding: 10px 12px 6px;
  box-shadow: 0 4px 24px rgba(0,0,0,.10), 0 1px 4px rgba(0,0,0,.05);
}
.cmd-general-landing-composer .cmd-textarea {
  background: transparent; border: none !important;
  box-shadow: none !important; padding: 2px 0 6px !important; font-size: 14px;
  resize: none; width: 100%;
}
.cmd-general-landing-composer .cmd-textarea:focus {
  outline: none; border: none !important; box-shadow: none !important;
}
.cmd-general-landing-sub {
  font-size: 13.5px; color: var(--ink-3); margin: -4px 0 14px;
  letter-spacing: -0.01em; text-align: center;
}
/* Composer glow on focus — the input feels inviting, one confident accent. */
.cmd-general-landing-composer:focus-within {
  border-color: var(--indigo-line);
  box-shadow: 0 4px 24px rgba(0,0,0,.10), 0 0 0 3px var(--indigo-soft);
  transition: border-color var(--duration-fast, 120ms) var(--ease-out),
              box-shadow var(--duration-fast, 120ms) var(--ease-out);
}
/* Starter prompts — grounded in the firm's real state (see _aiStarterChips). */
.cmd-starter-chips {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin-top: 16px; width: 100%;
}
.cmd-starter-chip {
  font: inherit; font-size: 12.5px; line-height: 1.3;
  color: var(--ink-2); background: var(--bg-card);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 7px 14px; cursor: pointer; text-align: left;
  transition: background var(--duration-fast, 120ms) var(--ease-out),
              border-color var(--duration-fast, 120ms) var(--ease-out),
              color var(--duration-fast, 120ms) var(--ease-out);
}
.cmd-starter-chip:hover {
  background: var(--indigo-soft); border-color: var(--indigo-line);
  color: var(--indigo-ink);
}

/* ── Markdown rendering inside AI answers ────────────────────────────── */
.cmd-md-h1 {
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  margin: 8px 0 3px; letter-spacing: -0.01em;
}
.cmd-md-h2 {
  font-size: 13px; font-weight: 600; color: var(--ink);
  margin: 6px 0 2px;
}
.cmd-md-p {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.6;
  margin-bottom: 4px;
}
.cmd-md-p:last-child { margin-bottom: 0; }
.cmd-md-ul, .cmd-md-ol {
  margin: 2px 0 6px; padding-left: 18px;
}
.cmd-md-ul li, .cmd-md-ol li {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.5; margin-bottom: 2px;
}
/* Markdown tables. renderMarkdown() has emitted .cmd-md-table/-th/-td since it
   was written, but no rule ever existed for them, so every AI table rendered
   as unstyled borderless HTML in every chat. The Studio Review Specialist
   answers "which sheets do these comments hit" as a table, which is what
   surfaced it. Scrolls inside its own box so a wide table never widens the
   chat column. */
.cmd-md-table {
  width: 100%; border-collapse: collapse; margin: 6px 0 10px;
  font-size: 12.5px; display: block; overflow-x: auto;
}
.cmd-md-th, .cmd-md-td {
  border: 1px solid var(--line-soft); padding: 5px 9px;
  text-align: left; vertical-align: top; line-height: 1.45;
}
.cmd-md-th {
  background: var(--bg-sunk); color: var(--ink);
  font-weight: 600; white-space: nowrap;
}
.cmd-md-td { color: var(--ink-2); }

/* ── Sidebar section label (Recent) ──────────────────────────────────── */
.cmd-gside-section-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-4);
  padding: 10px 12px 3px;
}

/* ── Folder contents view ────────────────────────────────────────────── */
.cmd-folder-view {
  flex: 1; overflow-y: auto; padding-top: 64px;
}
.cmd-folder-view-list {
  display: flex; flex-direction: column;
}
.cmd-folder-view-newchat-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 14px 24px; border: 0; background: none;
  font-family: var(--f-sans); font-size: 14px; color: var(--ink-3);
  cursor: pointer; text-align: left; border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s;
}
.cmd-folder-view-newchat-row:hover { background: var(--bg-hover); color: var(--ink); }
.cmd-folder-view-newchat-icon {
  width: 28px; height: 28px; border-radius: 7px;
  background: var(--bg-sunk); display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: var(--ink-3);
}
.cmd-folder-view-newchat-label { font-weight: 500; }
.cmd-folder-view-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  padding: 14px 24px; border: 0; background: none;
  cursor: pointer; text-align: left; width: 100%;
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s;
}
.cmd-folder-view-item:hover { background: var(--bg-hover); }
.cmd-folder-view-item-title {
  font-size: 14px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%;
}
.cmd-folder-view-item-preview {
  font-size: 13px; color: var(--ink-4); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; width: 100%;
}
.cmd-folder-view-empty {
  font-size: 13px; color: var(--ink-4); padding: 16px 24px;
}

.cmd-chat-composer {
  flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: stretch;
  margin: 0 12px 14px;
  background: var(--bg-card);
  border: 1.5px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 4px 24px rgba(0,0,0,.13), 0 1px 4px rgba(0,0,0,.06);
  transition: border-color var(--duration-fast, 120ms) var(--ease-out),
              box-shadow var(--duration-fast, 120ms) var(--ease-out);
}
.cmd-chat-composer:focus-within {
  border-color: var(--indigo-line);
  box-shadow: 0 4px 24px rgba(0,0,0,.13), 0 0 0 3px var(--indigo-soft);
}
.cmd-chat-composer .cmd-input {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 12px;
  font: inherit; font-size: 13px;
  background: var(--bg-card);
  color: var(--ink);
  outline: none;
  transition: border-color .12s;
}
.cmd-chat-composer .cmd-input:focus { border-color: var(--indigo-line); }
.cmd-chat-composer .cmd-input:disabled { opacity: .55; }
.cmd-send {
  width: 30px; height: 30px; border-radius: 50%;
  border: 0; background: var(--ink); color: var(--bg-elev);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; flex: 0 0 auto;
  transition: background .12s, transform .1s;
}
.cmd-send:hover:not(:disabled) { background: var(--indigo); }
.cmd-send:active:not(:disabled) { transform: scale(0.94); }
.cmd-send:disabled { background: var(--bg-sunk); color: var(--ink-4); cursor: not-allowed; }
.cmd-stop {
  width: 30px; height: 30px; border-radius: 50%;
  border: 1.5px solid var(--line); background: var(--bg-card); color: var(--ink-2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; flex: 0 0 auto;
  transition: border-color .12s, color .12s, transform .1s;
}
.cmd-stop:hover { border-color: var(--bad-line); color: var(--bad); }

.cmd-paste-offer {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--indigo-soft);
  font-size: 12.5px; color: var(--indigo-ink);
}
.cmd-paste-offer span { flex: 1; }

/* Composer attachments */
.cmd-attachments {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 10px 14px 0;
}
.cmd-attach-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 10px;
  background: var(--bg-sunk); border: 1px solid var(--line);
  border-radius: 6px; font-size: 12px; color: var(--ink-2);
  max-width: 200px;
}
.cmd-attach-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmd-attach-chip-remove {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--ink-4); display: flex; align-items: center;
  border-radius: 3px; transition: color .12s;
  flex: 0 0 auto;
}
.cmd-attach-chip-remove:hover { color: var(--ink); }

/* Attached files in message bubbles */
.cmd-attach-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.cmd-attach-file {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 6px;
  background: rgba(0,0,0,.07); font-size: 12px;
  border: 1px solid rgba(0,0,0,.1);
}
[data-theme="dark"] .cmd-attach-file { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.1); }
/* Clickable variant — same look, button defaults reset, hover lift */
.cmd-attach-file-btn {
  cursor: pointer; color: inherit; font: inherit; text-align: left;
  max-width: 240px;
  transition: background .12s, border-color .12s;
}
.cmd-attach-file-btn:hover { background: rgba(0,0,0,.12); border-color: rgba(0,0,0,.18); }
[data-theme="dark"] .cmd-attach-file-btn:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.18); }
.cmd-attach-file-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Textarea composer — auto-grows on input via window.AECOS_autoSizeTextarea in
   command-bar.jsx, capped at max-height; past the cap the textarea
   becomes a scroller (overflow-y: auto) so a huge paste stays
   contained. ⚠️ The cap is --chat-composer-max-h and the JS READS it off the
   computed style — do NOT re-state the number in JS. The old instruction here
   ("keep max-height in sync with CMD_TEXTAREA_MAX in JS") had already failed:
   140px vs 220px. */
.cmd-textarea {
  flex: 1; border: none; outline: none; resize: none;
  font: inherit; font-size: 13.5px; line-height: 1.55;
  background: transparent; color: var(--ink);
  min-height: 22px; max-height: var(--chat-composer-max-h); overflow-y: auto;
  padding: 0;
  /* Fill the composer width. Without this a rows=1 <textarea> falls back to its
     intrinsic ~20-col width inside the (non-flex) .cmd-composer-textarea-row, so
     typed text was clipped to the left ~160px and never grew when the chat panel
     was widened / fullscreened. width:100% makes it fluid with the panel. */
  width: 100%; box-sizing: border-box;
}
.cmd-textarea::placeholder { color: var(--ink-4); }
.cmd-attach-btn {
  width: 30px; height: 30px; border-radius: var(--radius-btn-icon); border: none;
  background: none; color: var(--ink-3); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .12s, color .12s; flex: 0 0 auto;
}
.cmd-attach-btn:hover { background: var(--bg-sunk); color: var(--ink); }
.paste-input {
  width: 100%; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 6px;
  font: inherit; font-size: 13px; line-height: 1.6;
  background: var(--bg-elev); color: var(--ink);
  resize: vertical; outline: none;
  transition: border-color .12s;
}
.paste-input:focus { border-color: var(--indigo-line); }
.paste-select {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-btn);
  font: inherit; font-size: 13px; background: var(--bg-elev); color: var(--ink);
  outline: none; cursor: pointer;
}

/* ─── Thinking dots (used in AI chat surfaces) ────────────────────────────── */
.dot-pulse { width: 5px; height: 5px; border-radius: 50%; background: var(--ink-4); display: inline-block; animation: dotPulse 1.2s infinite ease-in-out; }
@keyframes dotPulse { 0%, 80%, 100% { opacity: .3; transform: scale(.8); } 40% { opacity: 1; transform: scale(1.1); } }
@keyframes srDot { 0%, 80%, 100% { opacity: .3; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-4px); } }

/* ─── Project Detail Page ────────────────────────────────────────────────── */

/* breadcrumb link */
.crumb-link {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--indigo); font: inherit; font-size: inherit;
  text-decoration: underline; text-decoration-color: transparent;
  transition: text-decoration-color .12s;
}
.crumb-link:hover { text-decoration-color: var(--indigo); }

/* Phase form */
.phase-form {
  padding: 16px 0 4px;
  display: flex; flex-direction: column; gap: 12px;
}
.phase-form-title { font-weight: 500; font-size: 13.5px; }
.phase-form-err { color: #ef4444; font-size: 12px; }
.phase-form-actions { display: flex; gap: 8px; justify-content: flex-end; padding-top: 4px; }
.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-group { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 120px; }
.field-label { font-size: 11px; color: var(--ink-4); font-weight: 500; text-transform: uppercase; letter-spacing: .04em; }
.field-input, .input-base {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px;
  font: inherit; font-size: 13px; background: var(--bg-elev); color: var(--ink);
  outline: none; transition: border-color .12s; width: 100%;
}
/* Focus aligned with the newer .field__input ring convention (indigo border +
   soft ring) so legacy and new form controls read identically on focus. */
.field-input:focus, .input-base:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}

/* Phase card */
.phases-list { display: flex; flex-direction: column; gap: 12px; }
.phase-db-warn {
  padding: 12px 16px; border-radius: 8px;
  background: #fef9c3; color: #854d0e;
  font-size: 13px; border: 1px solid #fde68a;
  margin-bottom: 4px;
}
.phase-card {
  display: flex; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-card);
}
.phase-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS (var value) */
.phase-card.open { box-shadow: 0 2px 12px rgba(0,0,0,.08); }
.phase-card-stripe { width: 4px; flex: 0 0 4px; }
.phase-card-body { flex: 1; padding: 0; min-width: 0; }
.phase-card-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; cursor: pointer;
  user-select: none; transition: background .1s;
}
.phase-card-head:hover { background: var(--bg-hover); }
.phase-card-chevron { color: var(--ink-4); flex: 0 0 auto; }
.phase-card-info { flex: 1; min-width: 0; }
.phase-card-name { font-weight: 500; font-size: 14px; }
/* Sub-phase attribution chip — names the parent next to a nested phase's own
   name. The indent conveys nesting; this says WHAT it is nested under. */
.phase-card-subtag {
  margin-left: 8px; font-size: 11px; font-weight: 400;
  color: var(--ink-4); background: var(--bg-sunk);
  border: 1px solid var(--line-soft); border-radius: 4px;
  padding: 1px 6px; white-space: nowrap;
  display: inline-block; vertical-align: middle;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis;
}
.phase-card-meta { font-size: 12px; color: var(--ink-4); margin-top: 2px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.phase-card-sep { color: var(--line-strong); }
.phase-bar-wrap { display: flex; align-items: center; gap: 8px; flex: 0 0 160px; }
.phase-bar { flex: 1; height: 5px; background: var(--bg-sunk); border-radius: 999px; overflow: hidden; }
.phase-bar-fill { height: 100%; border-radius: 999px; transition: width .3s; }
.phase-bar-pct { font-size: 11px; color: var(--ink-4); flex: 0 0 30px; text-align: right; }
.phase-card-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.ms-count { font-size: 11px; color: var(--ink-4); white-space: nowrap; }

.phase-card-content { border-top: 1px solid var(--line); }
.phase-tabs { display: flex; gap: 0; border-bottom: 1px solid var(--line); padding: 0 16px; }
.phase-tab {
  padding: 8px 14px; font-size: 13px; border: none; background: none;
  color: var(--ink-3); cursor: pointer; border-bottom: 2px solid transparent;
  margin-bottom: -1px; transition: color .12s, border-color .12s;
}
.phase-tab.active { color: var(--indigo); border-bottom-color: var(--indigo); }
.phase-tab:hover:not(.active) { color: var(--ink); }

.phase-overview { padding: 16px; display: flex; flex-direction: column; gap: 16px; }
.phase-note { font-size: 13px; color: var(--ink-2); line-height: 1.6; }
.phase-budget-section { display: flex; flex-direction: column; gap: 8px; }
.phase-budget-head { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-4); }
.phase-budget-fields { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.phase-budget-field { display: flex; flex-direction: column; gap: 4px; }
.phase-budget-input-wrap { display: flex; align-items: center; gap: 4px; }
.phase-budget-prefix { font-size: 13px; color: var(--ink-3); }
.phase-budget-unit { font-size: 12px; color: var(--ink-4); }
.phase-budget-input { width: 100px !important; }
.phase-budget-progress { flex: 1; min-width: 140px; padding-bottom: 2px; }
.phase-budget-progress-label { display: flex; justify-content: space-between; font-size: 11px; }
.milestone-section { display: flex; flex-direction: column; gap: 4px; }
.milestone-section-head { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-4); margin-bottom: 4px; }

/* Milestone rows */
.milestone-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 6px; transition: background .1s;
}
.milestone-row:hover { background: var(--bg-hover); }
.milestone-row.done .ms-label { text-decoration: line-through; color: var(--ink-4); }
/* Inline-edit state — sunk background + tighter radius so the row's
   text inputs read as "actively being edited" without colliding with
   the resting hover treatment. */
.milestone-row.editing { background: var(--bg-sunk); padding: 6px 8px; gap: 8px; border-radius: 6px; }
.milestone-row.add-row { padding: 6px 8px; gap: 8px; }
.ms-check {
  width: 18px; height: 18px; border-radius: 5px; flex: 0 0 18px;
  border: 1.5px solid var(--line-strong); background: var(--bg-elev);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  color: var(--indigo); transition: background .1s, border-color .1s;
}
.milestone-row.done .ms-check { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.ms-label { flex: 1; font-size: 13px; }
.ms-critical { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: #ef4444; background: #fef2f2; padding: 2px 6px; border-radius: 4px; }
.ms-date { font-size: 12px; color: var(--ink-4); font-family: var(--f-mono); white-space: nowrap; }
.ms-actions { display: flex; gap: 4px; opacity: 0; transition: opacity .12s; }
.milestone-row:hover .ms-actions { opacity: 1; }
.ms-crit-btn, .ms-edit-btn, .ms-del-btn {
  width: 22px; height: 22px; border-radius: var(--radius-btn-icon); border: none;
  background: none; cursor: pointer; display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: var(--ink-4); transition: background .1s, color .1s;
}
.ms-crit-btn:hover { background: var(--bad-soft); color: #ef4444; }
.ms-crit-btn.active { color: #ef4444; }
.ms-edit-btn:hover { background: var(--bg-sunk); color: var(--ink); }
.ms-del-btn:hover { background: #fef2f2; color: #ef4444; }

/* ─── ProjectMilestonesTab (project-detail.jsx ~574-650) ───────────────────
   The standalone Milestones tab inside the project side-panel. Visual
   language deliberately mirrors the .milestone-row family above — same
   tokens, same scale — but each card stands alone with its own border
   instead of relying on the surrounding phase-card surface. Re-uses
   .ms-check / .ms-edit-btn / .ms-del-btn / .ms-critical from the row
   family above (already styled there), so we don't redeclare them. */
.pd-milestones-tab {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px 0;
}
.pd-milestones-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 4px;
}
.pd-milestone-list {
  display: flex; flex-direction: column; gap: 6px;
}
.pd-milestone-card {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-card);
  transition: background .1s, border-color .1s;
}
.pd-milestone-card:hover { background: var(--bg-hover); }
.pd-milestone-card.done .pd-milestone-name {
  text-decoration: line-through; color: var(--ink-4);
}
/* Overdue: tinted left edge + faint warn-tone wash — matches the
   .milestone-row visual idiom (subtle, not loud). */
.pd-milestone-card.overdue {
  border-color: color-mix(in srgb, var(--warn) 40%, var(--line));
  background: color-mix(in srgb, var(--warn) 5%, var(--bg-card));
}
.pd-milestone-check {
  width: 22px; height: 22px; flex: 0 0 22px;
  display: flex; align-items: center; justify-content: center;
}
.pd-milestone-body { flex: 1; min-width: 0; }
.pd-milestone-name {
  font-size: 13px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pd-milestone-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-3); margin-top: 2px;
}
.pd-milestone-actions {
  display: flex; gap: 4px; opacity: 0;
  transition: opacity .12s;
}
.pd-milestone-card:hover .pd-milestone-actions { opacity: 1; }

/* Staff panel */
.staff-panel { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.staff-panel-head { display: flex; justify-content: space-between; align-items: center; font-weight: 500; font-size: 13px; }
.staff-picker { display: flex; flex-direction: column; gap: 2px; padding: 6px 0; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.staff-pick-btn {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: none; background: none; border-radius: var(--radius-btn-icon); cursor: pointer; text-align: left; width: 100%;
  transition: background .1s;
}
.staff-pick-btn:hover { background: var(--bg-hover); }
.staff-pick-name { font-size: 13px; font-weight: 450; }
.staff-pick-role { font-size: 12px; flex: 1; }
.staff-pick-add { font-size: 11px; color: var(--indigo); font-weight: 500; }
.staff-list { display: flex; flex-direction: column; gap: 8px; }
.staff-row { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 8px; border: 1px solid var(--line); }
.staff-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex: 0 0 32px;
  background: var(--indigo); color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
}
.staff-info { flex: 1; min-width: 0; }
.staff-name { font-size: 13px; font-weight: 450; }
.staff-role { font-size: 11.5px; }
.staff-hrs { display: flex; flex-direction: column; gap: 2px; align-items: flex-end; }
.staff-hrs-row { display: flex; align-items: center; gap: 6px; }
.staff-hrs-input { width: 56px !important; text-align: right; padding: 4px 6px !important; }
.staff-hrs-logged { font-size: 11px; color: var(--ink-4); }
.staff-remove { width: 24px; height: 24px; border-radius: var(--radius-btn-icon); border: none; background: none; color: var(--ink-4); cursor: pointer; font-size: 16px; line-height: 1; display: flex; align-items: center; justify-content: center; transition: background .1s, color .1s; flex: 0 0 auto; }
.staff-remove:hover { background: #fef2f2; color: #ef4444; }

/* Timesheet panel */
.timesheet-panel { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.timesheet-head { display: flex; align-items: center; gap: 10px; }
.timesheet-rows { display: flex; flex-direction: column; gap: 6px; }
.timesheet-row { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-radius: 6px; border: 1px solid var(--line); }
.timesheet-name { flex: 1; font-size: 13px; }
.timesheet-input-wrap { display: flex; align-items: center; gap: 5px; }
.timesheet-input { width: 64px !important; text-align: right; padding: 5px 8px !important; }

/* Empty state */
.empty-phases { display: flex; flex-direction: column; align-items: center; padding: 48px 24px; gap: 10px; color: var(--ink-4); }
.empty-phases-icon { opacity: .3; }
.empty-phases-text { font-size: 16px; font-weight: 500; color: var(--ink-3); }
.empty-phases-sub { font-size: 13px; text-align: center; max-width: 320px; }

/* ─── Currency combobox (office settings) ───────────────────────────────── */
.currency-display {
  display: flex; align-items: center; gap: 8px;
}
.currency-flag { font-size: 16px; line-height: 1; }
.currency-code { font-weight: 600; font-size: 14px; }
.currency-name { font-size: 13px; }

.currency-combo { position: relative; }
.currency-combo-input-wrap {
  display: flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-elev); padding: 0 10px;
  transition: border-color .12s;
}
.currency-combo-input-wrap:focus-within { border-color: var(--indigo-line); }
.currency-combo-flag { font-size: 15px; flex: 0 0 auto; }
.currency-combo-input {
  flex: 0 0 52px; border: none !important; background: transparent !important;
  padding: 7px 0 !important; font-weight: 600; font-size: 13px;
  outline: none; min-width: 0;
}
.currency-combo-hint {
  font-size: 12px; color: var(--ink-4); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.currency-dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: var(--shadow-md);
  z-index: 200; max-height: 240px; overflow-y: auto;
  padding: 4px;
}
.currency-dropdown-empty { padding: 10px 12px; font-size: 13px; color: var(--ink-4); }
.currency-dropdown-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 8px 10px; border: none; background: none;
  border-radius: 5px; cursor: pointer; text-align: left;
  transition: background .1s;
}
.currency-dropdown-item:hover { background: var(--bg-hover); }
.currency-dropdown-item.active { background: var(--indigo-soft); }
.currency-dropdown-code { font-weight: 600; font-size: 13px; flex: 0 0 38px; }
.currency-dropdown-sym { font-size: 12px; color: var(--ink-4); font-family: var(--f-mono); flex: 0 0 24px; }
.currency-dropdown-name { font-size: 12.5px; color: var(--ink-3); }

/* Lead combobox avatar */
.lead-combo-avatar {
  width: 24px; height: 24px; border-radius: 50%; flex: 0 0 24px;
  background: var(--indigo); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 600;
}

/* ─── Holiday calendar field ─────────────────────────────────────────────── */
.hol-field { display: flex; flex-direction: column; gap: 0; }
.hol-base { margin-bottom: 12px; }
.hol-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: none; cursor: pointer; padding: 0;
  font-size: 12px; color: var(--ink-4); transition: color .12s;
}
.hol-toggle:hover { color: var(--ink); }
.hol-day-list {
  margin-top: 8px; display: flex; flex-direction: column; gap: 1px;
  border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
}
.hol-day-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px; font-size: 12.5px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--line-soft);
}
.hol-day-row:last-child { border-bottom: none; }
.hol-day-date { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-4); flex: 0 0 48px; }
.hol-day-label { flex: 1; color: var(--ink-2); }
.hol-remove {
  width: 20px; height: 20px; border-radius: 4px; border: none;
  background: none; color: var(--ink-5); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .1s, color .1s; flex: 0 0 auto;
}
.hol-remove:hover { background: #fef2f2; color: #ef4444; }
.hol-custom { display: flex; flex-direction: column; gap: 6px; }
.hol-custom-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; font-weight: 500; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .04em;
  margin-bottom: 2px;
}
.hol-add-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; }

/* ─── Timezone combobox ──────────────────────────────────────────────────── */
.tz-detect-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 12px; border-radius: 7px; margin-bottom: 6px;
  background: var(--indigo-soft); border: 1px solid var(--indigo-line);
  font-size: 12.5px; color: var(--indigo-ink);
}
.tz-detect-banner span { flex: 1; min-width: 0; }
.tz-offset { font-size: 11px; color: var(--ink-4); font-family: var(--f-mono); margin-left: auto; flex: 0 0 auto; }
.tz-cities { font-size: 11px; color: var(--ink-4); margin-top: 1px; }
.tz-clock { font-size: 11.5px; color: var(--ink-4); font-family: var(--f-mono); white-space: nowrap; flex: 0 0 auto; margin-left: 6px; }

/* ─── Project Field — tooltip & popover ─────────────────────────────────── */
.pf-proj-name-link { cursor: pointer; transition: color 0.1s; }
.pf-proj-name-link:hover { color: #1d6fd8; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }

.pf-tooltip {
  position: fixed; z-index: 9000; pointer-events: none;
  background: var(--ink-2); color: #fff; border-radius: 8px;
  padding: 10px 13px; min-width: 200px; max-width: 260px;
  box-shadow: var(--shadow-lg); font-size: 12.5px;
}
.pf-tt-name { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
.pf-tt-dates { color: rgba(255,255,255,0.55); font-size: 11px; margin-bottom: 8px; }
.pf-tt-row { display: flex; justify-content: space-between; align-items: center; font-size: 12px; margin-bottom: 3px; }
.pf-tt-row span:first-child { color: rgba(255,255,255,0.7); }
.pf-tt-bar { height: 5px; border-radius: 3px; background: rgba(255,255,255,0.15); overflow: hidden; margin-bottom: 8px; }
.pf-tt-fill { height: 100%; border-radius: 3px; transition: width 0.2s; }
.pf-tt-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 4px; }
.pf-tt-tag { font-size: 10px; padding: 2px 7px; border-radius: 99px; font-weight: 500; }
.pf-tt-tag.active { background: var(--indigo); color: #fff; }
.pf-tt-tag.paused { background: rgba(255,255,255,0.18); color: rgba(255,255,255,0.8); }
.pf-tt-tag.over { background: var(--bad); color: #fff; }

.pf-popover-backdrop {
  position: fixed; inset: 0; z-index: 8990;
  background: transparent;
}
.pf-popover {
  position: fixed; z-index: 9000;
  background: var(--bg-card); border: 1px solid var(--line-strong);
  border-radius: var(--radius-menu); padding: 14px 16px;
  min-width: 220px; box-shadow: var(--shadow-lg);
}
.pf-popover-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px; }
.pf-popover-title { flex: 1; font-weight: 600; font-size: 14px; color: var(--ink); }
.pf-popover-close {
  flex: 0 0 auto; background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 2px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
}
.pf-popover-close:hover { background: var(--bg-hover); color: var(--ink); }
.pf-popover-date { font-size: 12px; color: var(--ink-4); margin-bottom: 10px; }
.pf-popover-actions { display: flex; gap: 8px; margin-top: 12px; }


/* ── Members page ─────────────────────────────────────────────────────────── */
.members-stats {
  display: flex; gap: 14px; margin-bottom: 24px;
}
.members-stat-card {
  flex: 1; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; padding: 16px 20px;
}
.members-stat-value { font-size: 28px; font-weight: 700; line-height: 1; }
.members-stat-label { font-size: 12px; color: var(--ink-4); margin-top: 5px; }

.members-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.members-filters { display: flex; gap: 4px; }
.members-filter-btn {
  padding: 5px 13px; border-radius: var(--radius-btn); border: 1px solid var(--line);
  background: none; font-size: 12.5px; cursor: pointer; color: var(--ink-3);
  transition: all 0.1s;
}
.members-filter-btn:hover { background: var(--bg-hover); color: var(--ink); }
.members-filter-btn.active { background: var(--indigo); color: #fff; border-color: var(--indigo); }

.members-search {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-card); color: var(--ink-3); min-width: 220px;
}
.members-search input {
  border: none; outline: none; background: none; font-size: 13px;
  color: var(--ink); width: 100%;
}

.members-list { display: flex; flex-direction: column; }
.members-list-head {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 20px; border-bottom: 1px solid var(--line);
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-4);
}
.members-list-row {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 20px; border-bottom: 1px solid var(--line);
  transition: background 0.1s;
}
.members-list-row:last-child { border-bottom: none; }
.members-list-row:hover { background: var(--bg-hover); }
.members-list-row.alt { background: var(--bg-elev); }
.members-list-row.alt:hover { background: var(--bg-hover); }

.members-name, .members-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.members-name { font-size: 13.5px; font-weight: 500; color: var(--ink); }
.members-email { font-size: 12px; color: var(--ink-4); margin-top: 1px; }

/* ── Member panel (slide-over) ────────────────────────────────────────────── */
@keyframes slideInRight {
  from { transform: translateX(100%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.mp-backdrop {
  position: fixed; inset: 0; z-index: 9000;
  background: rgba(0,0,0,0.25); backdrop-filter: blur(1px);
}
.mp-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 9001;
  width: 480px; background: var(--bg-card);
  border-left: 1px solid var(--line-strong);
  display: flex; flex-direction: column;
  box-shadow: -12px 0 40px rgba(0,0,0,0.1);
  animation: slideInRight 0.2s cubic-bezier(0.22,1,0.36,1);
}
.mp-header {
  display: flex; align-items: center; gap: 14px;
  padding: 22px 22px 18px; border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.mp-header-info { flex: 1; min-width: 0; }
.mp-header-name { font-size: 17px; font-weight: 650; color: var(--ink); }
.mp-header-meta { display: flex; align-items: center; gap: 0; margin-top: 5px; flex-wrap: wrap; }
.mp-close {
  flex-shrink: 0; background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 6px; border-radius: 6px;
  display: flex; align-items: center;
}
.mp-close:hover { background: var(--bg-hover); color: var(--ink); }

.mp-tabs {
  display: flex; gap: 0; border-bottom: 1px solid var(--line);
  flex-shrink: 0; padding: 0 22px;
}
.mp-tab {
  padding: 10px 14px; font-size: 13px; font-weight: 500;
  background: none; border: none; cursor: pointer;
  color: var(--ink-3); border-bottom: 2px solid transparent;
  margin-bottom: -1px; transition: color 0.1s;
}
.mp-tab:hover { color: var(--ink); }
.mp-tab.active { color: var(--indigo); border-bottom-color: var(--indigo); }

.mp-body {
  flex: 1; overflow-y: auto; padding: 20px 22px;
}
.mp-section-list { display: flex; flex-direction: column; gap: 0; }
.mp-section-title {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4); margin-bottom: 10px; margin-top: 4px;
}
.mp-field { padding: 10px 0; border-bottom: 1px solid var(--line); }
.mp-field:last-child { border-bottom: none; }
.mp-field-label { font-size: 11.5px; color: var(--ink-4); margin-bottom: 4px; font-weight: 500; }
.mp-field-value { font-size: 13.5px; color: var(--ink); }
/* Read-mode value that hints at editability — pencil fades in on hover and
   clicking enters edit mode (same as the Edit-profile button). */
.mp-field-edithint {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; padding: 0; margin: -2px -4px;
  padding: 2px 4px; border-radius: 5px;
  font: inherit; color: var(--ink); cursor: pointer;
  text-align: left; transition: background 0.1s;
}
.mp-field-edithint:hover { background: var(--bg-hover); }
.mp-edithint-pencil { color: var(--ink-4); opacity: 0; transition: opacity 0.1s; }
.mp-field-edithint:hover .mp-edithint-pencil { opacity: 1; }
.mp-textarea { min-height: 72px; resize: vertical; width: 100%; box-sizing: border-box; }

.mp-toggle-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 0; border-bottom: 1px solid var(--line); gap: 16px;
}
.mp-toggle-row:last-child { border-bottom: none; }
.mp-toggle-label { font-size: 13.5px; color: var(--ink); font-weight: 450; }
.mp-toggle-desc { font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.mp-toggle-readonly { opacity: 0.5; cursor: default !important; pointer-events: none; }

.mp-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 22px; border-top: 1px solid var(--line);
  flex-shrink: 0; background: var(--bg-elev);
}
.mp-remove-btn { color: var(--bad) !important; opacity: 0.8; }
.mp-remove-btn:hover { opacity: 1; background: rgba(239,68,68,0.08) !important; }

/* ── Admin Center · Compensation tab ─────────────────────────────────────── */
.ac-comp-banner {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; background: var(--bg-hover);
  border-radius: var(--radius-btn-icon);
  font-size: 12px; color: var(--ink-3); line-height: 1.45;
}
.ac-comp-banner strong { color: var(--ink-2); font-weight: 600; }
/* Derived-metrics summary — the money an admin actually reads, up top. */
.ac-comp-summary {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  margin-top: 14px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--radius-card);
  overflow: hidden;
}
.ac-comp-metric { background: var(--bg-card); padding: 12px 14px; }
.ac-comp-metric-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-4);
}
.ac-comp-metric-value {
  font-size: 20px; font-weight: 650; color: var(--ink);
  margin-top: 5px; line-height: 1.1; letter-spacing: -0.01em;
}
.ac-comp-metric-unit { font-size: 12px; font-weight: 500; color: var(--ink-4); margin-left: 2px; }
.ac-comp-metric-sub { font-size: 11px; color: var(--ink-4); margin-top: 4px; }
.ac-tone-good { color: var(--good); }
.ac-tone-warn { color: var(--warn); }
.ac-comp-hint { font-size: 11.5px; color: var(--ink-4); margin-top: 4px; line-height: 1.4; }
/* Live edit preview — exactly what will be saved. */
.ac-comp-preview {
  margin-top: 16px; padding: 12px 14px;
  background: var(--bg-hover); border: 1px solid var(--line);
  border-radius: var(--radius-card);
}
.ac-comp-preview-title {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4); margin-bottom: 10px;
}
.ac-comp-preview-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.ac-comp-preview-grid > div { display: flex; flex-direction: column; gap: 2px; }
.ac-comp-preview-k { font-size: 11px; color: var(--ink-4); }
.ac-comp-preview-v { font-size: 14px; font-weight: 600; color: var(--ink); }

/* ── Project Quick Panel ──────────────────────────────────────────────────── */
.pf-qp-panel { width: 500px; }

.pf-qp-header {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 22px 22px 14px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.pf-qp-header-main { flex: 1; min-width: 0; }
.pf-qp-name { font-size: 20px; font-weight: 700; color: var(--ink); line-height: 1.2; }
.pf-qp-meta { font-size: 12.5px; color: var(--ink-3); margin-top: 5px; display: flex; gap: 0; flex-wrap: wrap; align-items: center; }
.pf-qp-dot { margin: 0 6px; color: var(--ink-4); }

.pf-qp-strip {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 22px; border-bottom: 1px solid var(--line);
  background: var(--bg-elev); flex-shrink: 0;
}
.pf-qp-strip-phase {
  font-size: 12px; color: var(--ink-3); padding: 2px 8px;
  background: var(--bg-hover); border-radius: 99px; border: 1px solid var(--line);
}
.pf-qp-invoice { font-size: 12px; font-weight: 600; }

.pf-qp-metrics {
  display: grid; grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 0; border: 1px solid var(--line); border-radius: 10px;
  overflow: hidden; margin-bottom: 22px;
}
.pf-qp-metric {
  padding: 12px 14px; border-right: 1px solid var(--line);
}
.pf-qp-metric:last-child { border-right: none; }
.pf-qp-metric-label { font-size: 10.5px; color: var(--ink-4); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; margin-bottom: 4px; }
.pf-qp-metric-value { font-size: 14px; font-weight: 650; color: var(--ink); }

.pf-qp-section { margin-bottom: 22px; }
.pf-qp-section-title {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4); margin-bottom: 10px;
}

.pf-qp-phase-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.pf-qp-phase-row:last-child { border-bottom: none; }
.pf-qp-phase-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.pf-qp-phase-name { font-size: 13px; font-weight: 500; color: var(--ink); display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.pf-qp-phase-tag {
  font-size: 10px; padding: 1px 6px; border-radius: 99px; font-weight: 600;
  background: rgba(99,102,241,0.1); color: var(--indigo);
}
.pf-qp-phase-tag.over { background: rgba(239,68,68,0.1); color: var(--bad); }
.pf-qp-phase-bar-wrap { display: flex; align-items: center; gap: 8px; }
.pf-qp-phase-bar-track { flex: 1; height: 5px; border-radius: 3px; background: var(--bg-hover); overflow: hidden; }
.pf-qp-phase-bar-fill { height: 100%; border-radius: 3px; transition: width 0.3s; }
.pf-qp-phase-hrs { font-size: 11px; color: var(--ink-4); white-space: nowrap; }
.pf-qp-phase-fee { font-size: 12px; font-weight: 600; color: var(--ink-2); white-space: nowrap; margin-left: 4px; }

.pf-qp-ms-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--line);
}
.pf-qp-ms-row:last-child { border-bottom: none; }
.pf-qp-ms-diamond {
  width: 8px; height: 8px; transform: rotate(45deg); flex-shrink: 0;
  background: var(--ink-3); border-radius: 1px;
}
.pf-qp-ms-diamond.critical { background: var(--bad); }
.pf-qp-ms-label { flex: 1; font-size: 13px; color: var(--ink); }
.pf-qp-ms-date { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; font-variant-numeric: tabular-nums; }

.pf-qp-staff-list { display: flex; flex-direction: column; gap: 0; }
.pf-qp-staff-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.pf-qp-staff-row:last-child { border-bottom: none; }
.pf-qp-staff-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: #fff; letter-spacing: 0.3px;
}
.pf-qp-staff-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.pf-qp-staff-role { font-size: 11.5px; color: var(--ink-4); margin-top: 1px; }

/* ── Project detail — Overview tab grids ──────────────────────────────────────
   Queue 2c0be800. These were three inline, NESTED, fixed column counts with no
   breakpoint of any kind: a `1fr 1fr` page grid → a card whose body was another
   `1fr 1fr` → a `1fr 1fr 1fr` Billing row. On a wide window that is fine. Inside
   the 760px .pd-side-panel (~720px of body, ~674px inside a card) it composes
   down to roughly 100px per Billing column, and "Bi-monthly (1st & 15th)" under
   "Frequency" wrapped across three lines and read as broken layout.

   ⚠️ A @media QUERY ALONE CANNOT FIX THIS. In panel mode the VIEWPORT is wide
   and only the CONTAINER is narrow, so a viewport query never fires. The panel
   case is handled by a `.pd-side-panel` descendant rule — the element that
   actually owns the 760px — and the media queries cover full-page mode on a
   genuinely small window. (Deliberately NOT container queries: `container-type`
   applies `contain: layout`, which makes the element a containing block for
   absolutely/fixed-positioned descendants, and this subtree renders modals.)

   .pd-ov-grid uses auto-fit rather than a breakpoint because it has exactly two
   children: auto-fit collapses the unused tracks, so it can never become three
   columns on a wide monitor, and it drops to one the moment two 380px tracks no
   longer fit — which is precisely the panel. `.pd-ov-fields` stays explicit,
   because it holds 8 children and a plain auto-fit WOULD re-flow them on a wide
   screen, changing a layout that was never broken.
   ⚠️ `.pd-ov-billing` NO LONGER stays explicit — see its own comment below. It
   uses an auto-fit whose floor is a third of the container, which caps it at
   three tracks by construction, so it gets container-keyed behaviour without
   the re-flow this paragraph warns about.

   minmax(0, 1fr) not 1fr: a bare 1fr is minmax(auto, 1fr) and refuses to shrink
   below its content's min size, which overflows the card instead of wrapping. */
.pd-ov-grid {
  display: grid;
  /* ⚠️ min(380px, 100%) — NOT a bare 380px. A track floor LARGER than the
     container cannot shrink to fit it, so the grid overflows its parent and the
     page scrolls sideways. Authenticated mobile web renders this same desktop
     page (Aecos.html toggles allow-mobile for any authed user), so a ~390px
     viewport puts a 380px floor in a ~350px box. `min()` is a no-op at every
     width at or above 380px — verified live: identical computed tracks at a
     1710px viewport with and without it — and only engages where today's rule
     is already broken. */
  grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
  gap: 20px;
}
.pd-ov-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 8px;
}
/* ⭐ INTRINSIC, NOT QUERIED — because the crush is keyed to the CONTAINER and
   every query available here is keyed to the VIEWPORT.
   MEASURED LIVE on production (not computed): with a full-page window the grid
   above is two columns from a ~1710px viewport down to ~1120px, and Billing's
   three tracks shrink with it — 165px → 101px. With this project's short
   "Semi-monthly" the Frequency cell wraps (40px → 61px tall) across viewports
   1120–1170. With the string the founder actually reported, "Bi-monthly (1st
   and 15th)", it wraps across the whole band 1120–1420 — a 300px-wide range of
   ordinary laptop widths. The ≤900px query never reaches any of it, because by
   900px the grid has already dropped to ONE column and Billing is comfortable
   again. This band was unreachable by construction.

   HOW THE FORMULA WORKS, and why it is not the auto-fit the comment above
   warns against: the track floor is `max(150px, one-third-of-the-container)`.
   Because the floor is never below a third, MORE THAN THREE TRACKS CAN NEVER
   FIT — verified at a 2400px viewport, still exactly 3. So the "auto-fit would
   re-flow 4 children on a wide screen" objection does not apply. When a third
   of the container falls under 150px the floor takes over and auto-fit drops
   to two, then one.
   MEASURED with the long string: 3 comfortable columns at ≥1420, then 2 columns
   at 158–228px through 1120, instead of 3 columns crushing to 101px.
   ⚠️ It is a NARROWING, not an elimination: at ~1120 the long string still
   wraps to two lines. Fixing that needs a ~180px floor, which would break the
   normal desktop view into two columns — a worse trade, taken deliberately.

   ⚠️ 24px is the two 12px gaps. If `gap` changes, this changes with it. */
.pd-ov-billing {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(150px, (100% - 24px) / 3), 1fr));
  gap: 12px;
}
/* Panel mode — .pd-ov-grid has already collapsed to one column here (two 380px
   tracks do not fit in ~720px), so each card is full width and Billing gets a
   comfortable 2×2 instead of three cramped columns. */
.pd-side-panel .pd-ov-billing { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Full-page mode on a small window — same shape, driven by the viewport. */
@media (max-width: 900px) {
  .pd-ov-billing { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .pd-ov-fields,
  .pd-ov-billing { grid-template-columns: minmax(0, 1fr); }
}

/* ── Project detail — Contacts tab (ProjectContactsTab, project-detail.jsx) ──
   The per-project contact roster. Every class the tab applies has a rule here:
   ~976 classNames in this repo style NOTHING, and a class with no rule looks
   exactly like a class whose rule was deleted. Radii use the CONTAINER tokens
   (--radius-sm/md/lg) — never --radius-btn, which would lozenge a row. */
.pc-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
.pc-head__text { min-width: 0; }
.pc-head__title { font-size: 14px; font-weight: 600; color: var(--ink); }
.pc-head__sub { font-size: 12.5px; color: var(--ink-4); margin-top: 3px; max-width: 62ch; line-height: 1.5; }
.pc-linkbtn {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--indigo); text-decoration: underline; text-underline-offset: 2px;
}
.pc-linkbtn:hover { color: var(--indigo-ink); }

.pc-list { display: flex; flex-direction: column; gap: 8px; }
.pc-row {
  display: grid; align-items: center; gap: 12px;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.6fr) 170px auto;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--bg-card);
}
.pc-row:hover { background: var(--bg-hover); }
.pc-row.is-primary { border-color: var(--indigo-line); }

.pc-row__main { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pc-row__contactinfo { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 12.5px; }
.pc-row__role { min-width: 0; }
.pc-row__actions { display: flex; align-items: center; gap: 4px; }

.pc-person { min-width: 0; }
.pc-person__name {
  font-size: 13px; font-weight: 550; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pc-person__sub {
  font-size: 11.5px; color: var(--ink-4); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.pc-badge-primary {
  flex: 0 0 auto; font-size: 10.5px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; padding: 2px 7px; border-radius: var(--radius-sm);
  background: var(--indigo-soft); color: var(--indigo-ink); border: 1px solid var(--indigo-line);
}
.pc-link {
  color: var(--ink-3); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pc-link:hover { color: var(--indigo); text-decoration: underline; }
.pc-dash { color: var(--ink-5); }
.pc-note {
  color: var(--ink-4); font-size: 11.5px; font-style: italic;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* The primary-contact star. There is NO `starFilled` glyph in the Icon set —
   an unknown name renders a dashed placeholder box — so the "on" state is done
   in CSS. A CSS declaration beats the SVG's fill="none" presentation attribute,
   which is what makes this work at all. */
.pc-star { color: var(--ink-5); }
.pc-star.is-on { color: var(--warn); fill: currentColor; }

/* ── Add-contact dialog ─────────────────────────────────────────────────── */
.pc-modal { display: flex; flex-direction: column; gap: 14px; }
.pc-modeswitch {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--bg-sunk); border-radius: var(--radius-md); align-self: flex-start;
}
.pc-modeswitch__btn {
  border: 0; background: transparent; cursor: pointer;
  padding: 5px 12px; font-size: 12.5px; font-weight: 500; color: var(--ink-4);
  border-radius: var(--radius-sm);
}
.pc-modeswitch__btn:hover { color: var(--ink-2); }
.pc-modeswitch__btn.is-active { background: var(--bg-card); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .07); }

.pc-picker { display: flex; flex-direction: column; gap: 8px; }
.pc-picker__list {
  display: flex; flex-direction: column; gap: 3px;
  max-height: 232px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius-md); padding: 5px;
}
.pc-picker__msg {
  font-size: 12.5px; color: var(--ink-4); padding: 14px;
  border: 1px dashed var(--line-strong); border-radius: var(--radius-md); text-align: center;
}
.pc-picker__row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 7px 9px; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; font: inherit;
}
.pc-picker__row:hover { background: var(--bg-hover); }
.pc-picker__row.is-picked { background: var(--indigo-soft); border-color: var(--indigo-line); }
.pc-picker__row.is-disabled { opacity: .5; cursor: not-allowed; }
.pc-picker__row.is-disabled:hover { background: transparent; }
.pc-picker__tag { flex: 0 0 auto; font-size: 10.5px; color: var(--ink-4); white-space: nowrap; }

.pc-form { display: flex; flex-direction: column; gap: 10px; }
.pc-hint { font-size: 11.5px; color: var(--ink-4); line-height: 1.5; }
.pc-modal__meta {
  display: flex; flex-direction: column; gap: 10px;
  padding-top: 12px; border-top: 1px solid var(--line);
}
.pc-check { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-2); cursor: pointer; }
.pc-error {
  font-size: 12.5px; color: var(--bad); background: var(--bad-soft);
  border: 1px solid var(--bad-line); border-radius: var(--radius-md); padding: 9px 11px; line-height: 1.5;
}

@media (max-width: 820px) {
  .pc-row { grid-template-columns: minmax(0, 1fr) auto; grid-auto-rows: min-content; }
  .pc-row__contactinfo { grid-column: 1 / -1; }
  .pc-row__role { grid-column: 1 / -1; }
}

/* ── Project detail — side panel mode ────────────────────────────────────── */
.pd-side-panel { width: 760px; }

.pd-sp-header {
  display: flex; align-items: center; gap: 12px;
  padding: 18px 20px 14px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.pd-sp-name { font-size: 18px; font-weight: 700; color: var(--ink); line-height: 1.2; }
.pd-sp-meta { font-size: 12.5px; color: var(--ink-3); margin-top: 4px; }

.pd-sp-metrics {
  display: flex; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.pd-sp-metric {
  flex: 1; padding: 10px 16px; border-right: 1px solid var(--line);
}
.pd-sp-metric:last-child { border-right: none; }
.pd-sp-metric-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-4); margin-bottom: 3px; }
.pd-sp-metric-value { font-size: 13.5px; font-weight: 650; color: var(--ink); }

.pd-sp-body {
  flex: 1; overflow-y: auto; padding: 20px 20px 32px;
}

/* ── Project detail — Files tab: folder sidebar ───────────────────────────────
   Founder report (queue a48ccda9): "'all files' and 'unfiled' need to be
   adjusted to be css styled per aecos styling."

   He was describing an ABSENCE, not a mismatch. project-detail.jsx renders the
   Files tab through .pd-files-layout / .pd-files-sidebar / .pd-folder-row /
   .pd-folder-row-count, and NONE of those four selectors existed anywhere in
   this stylesheet — so the sidebar was a stack of bare <div>s with no layout,
   no hover, no selected state and no drop target. "All files" and "Unfiled"
   read as two loose pieces of text that happened to be clickable, which is
   exactly "two button looking things" that do not look like Aecos.

   Modelled on the established sibling patterns rather than invented: row shape
   and the --indigo-soft selected fill follow .sr-session-item (styles.css
   ~5564), the panel chrome follows .ts-sidebar (~6986). ───────────────────── */
.pd-files-layout {
  display: flex; align-items: flex-start; gap: 16px;
}
.pd-files-sidebar {
  width: 208px; flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
  padding: 6px;
  display: flex; flex-direction: column; gap: 1px;
  position: sticky; top: 12px;
}
.pd-files-main { flex: 1; min-width: 0; }

.pd-folder-row {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px;
  border-radius: 7px;
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  border: 1px solid transparent;
  /* No transition on background/color. Deliberate — but NOT for the reason
     that was recorded here, which was measured on 2026-08-02 and is FALSE.

     THE RETRACTED CLAIM: "a property whose value comes from a custom property
     (var()/color-mix()) STICKS AT ITS FROM-VALUE when transitioned in Chrome."
     Tested against this exact rule, this exact stylesheet, with the transition
     put back: Chrome creates real background-color AND color CSSTransitions
     and settles both on the correct value, checked against a transition:none
     twin. Every one of the 75 distinct from→to token pairs in this stylesheet
     was driven the same way — 75/75 settled correctly, 73 of them a genuine
     value change. There is no var() stick. See scripts/test_css_classes.py.

     WHAT ACTUALLY REPRODUCES THE REPORTED SYMPTOM (class flips, paint stays on
     the old value, so both rows read as selected) is measuring a transition in
     a tab Chrome is not rendering — a background or MCP-driven tab. The
     animation sits at playState "running", currentTime 0, forever. A
     pure-literal #eee→#3355ff transition with no var() anywhere does it too,
     and stops doing it the moment the tab is painted. That is a MEASUREMENT
     hazard, not a CSS one, and it is how this repo Chrome-verifies.

     These rows are left snapping because that is what is shipped and what has
     been seen rendering correctly — not because a fade would break. Re-adding
     one is a visual change: make it on purpose, not to "fix" this. */
}
.pd-folder-row > svg { color: var(--ink-4); flex-shrink: 0; }
.pd-folder-row:hover { background: var(--bg-hover); color: var(--ink); }
.pd-folder-row:focus-visible {
  outline: 2px solid var(--indigo); outline-offset: -1px;
}
.pd-folder-row.active {
  background: var(--indigo-soft);
  color: var(--indigo-ink);
  font-weight: 600;
}
.pd-folder-row.active > svg { color: var(--indigo); }

/* Drag a file onto a folder to file it — the row is a drop target, and until
   now gave no feedback at all that it was one. */
.pd-folder-row.drag-over {
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  border-color: var(--indigo);
  color: var(--indigo-ink);
}

.pd-folder-row-count {
  flex-shrink: 0;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: var(--radius-btn, 999px);
  background: var(--bg-hover);
  font-size: 11px; font-weight: 600;
  color: var(--ink-4);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.pd-folder-row.active .pd-folder-row-count {
  background: color-mix(in srgb, var(--indigo) 16%, transparent);
  color: var(--indigo-ink);
}

.pd-folder-group-label {
  font-size: 10.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-5);
  padding: 10px 9px 4px;
}

/* The sidebar is a luxury on a narrow viewport — fold it to a horizontal
   scroller above the file list rather than squeezing both. */
@media (max-width: 860px) {
  .pd-files-layout { flex-direction: column; gap: 12px; }
  .pd-files-sidebar {
    width: 100%; position: static;
    flex-direction: row; gap: 6px;
    overflow-x: auto; padding: 6px 8px;
  }
  .pd-folder-row { flex-shrink: 0; }
  /* A vertical section label makes no sense once the list runs horizontally —
     the folder icon already distinguishes a real folder from All/Unfiled. */
  .pd-folder-group-label { display: none; }
}

/* ── API key setup panel ─────────────────────────────────────────────────── */
.cmd-key-setup {
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 28px 24px; text-align: center; gap: 10px;
  border-bottom: 1px solid var(--line);
}
.cmd-key-setup-icon { color: var(--indigo); opacity: 0.7; }
.cmd-key-setup-title { font-size: 15px; font-weight: 650; color: var(--ink); }
.cmd-key-setup-sub { font-size: 12.5px; color: var(--ink-4); line-height: 1.5; max-width: 300px; }
.cmd-key-setup-sub a { color: var(--indigo); text-decoration: none; }
.cmd-key-setup-sub a:hover { text-decoration: underline; }
.cmd-key-setup-row { display: flex; gap: 8px; width: 100%; max-width: 340px; margin-top: 4px; }
.cmd-key-input {
  flex: 1; height: 34px; padding: 0 10px; border: 1px solid var(--line);
  border-radius: 6px; font-size: 13px; font-family: var(--f-mono);
  background: var(--bg-elev); color: var(--ink); outline: none;
  transition: border-color 0.15s;
}
.cmd-key-input:focus { border-color: var(--indigo); }
.cmd-key-input::placeholder { font-family: var(--f-sans); color: var(--ink-5); }
.cmd-key-saved {
  display: flex; align-items: center; gap: 6px; justify-content: flex-end;
  padding: 5px 14px; font-size: 11px; color: var(--ok);
  border-top: 1px solid var(--line);
}
.cmd-key-clear {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--ink-4); font-size: 11px; text-decoration: underline;
  margin-left: 4px;
}
.cmd-key-clear:hover { color: var(--ink); }

/* ─── Document viewer modal ──────────────────────────────────────────────── */
/* ── Doc viewer full-canvas (files/PDFs) ─────────────────────────────────── */
.doc-viewer-fs {
  position: absolute; inset: 0; z-index: 400;
  background: var(--bg-card);
  display: flex; flex-direction: column;
  animation: graphFsIn 0.28s cubic-bezier(0.4,0,0.2,1) both;
}
.doc-viewer-fs.exiting { animation: graphFsOut 0.22s cubic-bezier(0.4,0,0.2,1) both; }
.doc-viewer-fs-head {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
}

@keyframes dvOverlayIn  { from { opacity: 0; }                                          to { opacity: 1; } }
@keyframes dvOverlayOut { from { opacity: 1; }                                          to { opacity: 0; } }
@keyframes dvPanelIn    { from { opacity: 0; transform: scale(0.95) translateY(10px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes dvPanelOut   { from { opacity: 1; transform: scale(1) translateY(0); }       to { opacity: 0; transform: scale(0.97) translateY(6px); } }

.doc-viewer-overlay {
  position: absolute; inset: 0; z-index: 400;
  background: rgba(0,0,0,0.35);
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
  animation: dvOverlayIn 0.2s ease both;
}
.doc-viewer-overlay.exiting { animation: dvOverlayOut 0.18s ease both; }
.doc-viewer {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  width: 100%; max-width: 860px;
  height: 88vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 64px rgba(0,0,0,0.22);
  animation: dvPanelIn 0.24s cubic-bezier(0.34,1.3,0.64,1) both;
}
.doc-viewer-overlay.exiting .doc-viewer { animation: dvPanelOut 0.16s ease both; }
.doc-viewer-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--line-soft);
  flex: 0 0 auto;
}
.doc-viewer-name { font-size: 14px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em; }
.doc-viewer-meta { font-size: 11.5px; color: var(--ink-4); margin-top: 3px; }
.doc-viewer-close {
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 4px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.1s, color 0.1s;
}
.doc-viewer-close:hover { background: var(--bg-hover); color: var(--ink); }
.doc-viewer-body { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: 20px; }
.doc-viewer-body--iframe { padding: 0; overflow: hidden; border-radius: 0 0 12px 12px; }
.doc-viewer-pre {
  font-family: var(--f-mono); font-size: 12.5px;
  line-height: 1.65; color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word; margin: 0;
}
.doc-viewer-empty { color: var(--ink-4); font-size: 13px; }

/* ─── PDF Markup Tool (Bluebeam-mirrored) ────────────────────────────────── */
.mu-shell {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  background: var(--bg-card);
  animation: graphFsIn 0.28s cubic-bezier(0.4,0,0.2,1) both;
}
.mu-shell.exiting { animation: graphFsOut 0.22s cubic-bezier(0.4,0,0.2,1) both; }

/* Top bar */
.mu-topbar {
  display: flex; align-items: center; justify-content: space-between;
  height: 44px; padding: 0 16px; gap: 12px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-elev);
  flex-shrink: 0;
}
.mu-topbar-left  { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.mu-topbar-center { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.mu-topbar-right  { display: flex; align-items: center; gap: 6px; flex: 1; justify-content: flex-end; }

.mu-close-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-btn-icon); border: 1px solid var(--line);
  background: none; cursor: pointer; font-size: 11.5px; color: var(--ink-3);
  transition: background 0.1s, color 0.1s; flex-shrink: 0;
}
.mu-close-btn:hover { background: var(--bg-hover); color: var(--ink); }

.mu-file-name {
  font-size: 13px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mu-page-indicator { font-size: 12px; color: var(--ink-3); font-family: var(--f-mono); min-width: 52px; text-align: center; }
.mu-nav-btn {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--radius-btn-icon); border: 1px solid var(--line);
  background: none; cursor: pointer; color: var(--ink-4);
  transition: background 0.1s, color 0.1s;
}
.mu-nav-btn:hover:not(:disabled) { background: var(--bg-hover); color: var(--ink); }
.mu-nav-btn:disabled { opacity: 0.35; cursor: default; }

.mu-zoom-btn {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: var(--radius-btn-icon, 8px); border: 1px solid var(--line);
  background: none; cursor: pointer; color: var(--ink-3); font-size: 14px; font-weight: 600;
  transition: background 0.1s, color 0.1s;
}
.mu-zoom-btn:hover { background: var(--bg-hover); color: var(--ink); }
.mu-zoom-label { font-size: 11.5px; color: var(--ink-3); font-family: var(--f-mono); min-width: 36px; text-align: center; }

.mu-panel-toggle {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-btn-icon, 8px); border: 1px solid var(--line);
  background: none; cursor: pointer; font-size: 11.5px; color: var(--ink-3);
  transition: background 0.1s, color 0.1s;
}
.mu-panel-toggle:hover { background: var(--bg-hover); color: var(--ink); }
.mu-panel-toggle.active { background: var(--indigo-soft); color: var(--indigo); border-color: var(--indigo-line); }

/* Body: left toolbar + canvas + right panel */
.mu-body {
  flex: 1 1 0; display: flex; min-height: 0; overflow: hidden;
}

/* Left toolbar */
.mu-left-toolbar {
  width: 44px; flex-shrink: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 8px 0; gap: 2px;
  background: var(--bg-elev);
  border-right: 1px solid var(--line);
  overflow-y: auto; overflow-x: hidden;
}
.mu-tool-divider {
  width: 26px; height: 1px; background: var(--line-soft);
  margin: 4px 0; flex-shrink: 0;
}
.mu-tool-btn {
  width: 32px; height: 32px; border-radius: 6px; border: none;
  display: flex; align-items: center; justify-content: center;
  background: none; cursor: pointer; color: var(--ink-4);
  transition: background 0.1s, color 0.1s;
  flex-shrink: 0;
}
.mu-tool-btn:hover { background: var(--bg-hover); color: var(--ink); }
.mu-tool-btn.active { background: var(--indigo-soft); color: var(--indigo); }

.mu-tool-wrap { position: relative; }

/* Stamp dropdown */
.mu-stamp-menu {
  position: absolute; left: 38px; top: 0; z-index: 100;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12); padding: 4px; min-width: 180px;
}
.mu-stamp-option {
  display: block; width: 100%; text-align: left;
  padding: 6px 10px; border: none; background: none; cursor: pointer;
  font-size: 12px; color: var(--ink-2); border-radius: 5px;
  transition: background 0.1s;
}
.mu-stamp-option:hover { background: var(--bg-hover); }
.mu-stamp-option.active { background: var(--indigo-soft); color: var(--indigo); }

/* Color swatch */
.mu-color-swatch-wrap { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px 0; position: relative; }
.mu-color-swatch {
  width: 22px; height: 22px; border-radius: 4px; border: 2px solid var(--line);
  cursor: pointer; transition: border-color 0.1s;
}
.mu-color-swatch:hover { border-color: var(--ink-3); }
/* ⚠️ Two fixes here (2026-08-20). (1) The block used to declare display:none
   AND display:flex — the later flex won, so the picker was permanently open
   and the :hover reveal below was a no-op. (2) The picker sits at left:38px
   while the swatch column is ~22px wide → a ~16px dead gap; crossing it ends
   the wrap's :hover and the picker vanishes. The ::before pseudo bridges the
   gap (hitbox only, invisible) so the pointer never leaves the subtree. */
.mu-color-picker {
  display: none; position: absolute; left: 38px; top: 0; z-index: 100;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 8px; flex-wrap: wrap; gap: 5px; width: 120px;
}
.mu-color-picker::before {
  content: ""; position: absolute; right: 100%; top: 0; bottom: 0; width: 18px;
}
.mu-color-swatch-wrap:hover .mu-color-picker { display: flex; }
.mu-color-btn {
  width: 20px; height: 20px; border-radius: 4px; cursor: pointer;
  border: 2px solid transparent;
}
.mu-color-btn:hover { border-color: var(--ink-3); } /* SNAPS; no scale — founder 2026-08-20 */
.mu-color-btn.active { border-color: var(--ink); }

/* Canvas area */
.mu-canvas-area {
  flex: 1 1 0; overflow: auto;
  background: var(--bg-sunk);
  padding: 32px 40px;
  display: flex; flex-direction: column; align-items: center;
}

/* Right panel */
.mu-right-panel {
  width: 260px; flex-shrink: 0;
  border-left: 1px solid var(--line);
  background: var(--bg-card);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.mu-right-tabs {
  display: flex; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.mu-right-tab {
  flex: 1; padding: 10px 0; border: none; background: none; cursor: pointer;
  font-size: 12px; font-weight: 500; color: var(--ink-4);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color 0.1s, border-color 0.1s;
}
.mu-right-tab:hover { color: var(--ink); }
.mu-right-tab.active { color: var(--ink); border-bottom-color: var(--indigo); }

/* Markups list */
.mu-markups-panel { flex: 1 1 0; display: flex; flex-direction: column; overflow: hidden; }
.mu-markups-filter { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); flex-shrink: 0; }
.mu-filter-select {
  width: 100%; padding: 5px 8px; border: 1px solid var(--line); border-radius: var(--radius-btn);
  font-size: 11.5px; background: var(--bg-elev); color: var(--ink-2);
  appearance: none; cursor: pointer;
}
.mu-markups-list { flex: 1 1 0; overflow-y: auto; }
.mu-markups-empty {
  padding: 28px 16px; text-align: center; font-size: 12px; color: var(--ink-5); line-height: 1.6;
}
.mu-markup-row {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 12px; border-bottom: 1px solid var(--line-soft);
  cursor: pointer; transition: background 0.1s;
}
.mu-markup-row:hover { background: var(--bg-hover); }
.mu-markup-row.selected { background: var(--indigo-soft); }
.mu-markup-row-color { width: 4px; min-height: 32px; border-radius: 2px; flex-shrink: 0; margin-top: 2px; }
.mu-markup-row-info { flex: 1; min-width: 0; }
.mu-markup-row-subject { font-size: 12px; font-weight: 500; color: var(--ink); }
.mu-markup-row-meta { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }
.mu-markup-row-text { font-size: 11px; color: var(--ink-3); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 130px; }
.mu-status-chip {
  font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: white; padding: 2px 5px; border-radius: 3px;
}
.mu-delete-ann-btn {
  background: none; border: none; cursor: pointer; color: var(--ink-5); padding: 2px;
  border-radius: 3px; display: flex; align-items: center; opacity: 0.5;
  transition: opacity 0.1s, color 0.1s;
}
.mu-delete-ann-btn:hover { opacity: 1; color: var(--bad); }

/* Properties panel */
.mu-properties-panel { flex: 1 1 0; overflow-y: auto; padding: 4px 0; }
.mu-prop-section { padding: 10px 14px 2px; }
.mu-prop-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; color: var(--ink-5); margin-bottom: 3px; }
.mu-prop-value { font-size: 12.5px; color: var(--ink-2); }
.mu-prop-mono { font-family: var(--f-mono); font-size: 11.5px; }
.mu-text-input {
  width: 100%; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px;
  font-size: 12px; background: var(--bg-elev); color: var(--ink); resize: vertical;
  font-family: var(--f-sans); line-height: 1.5;
}
.mu-text-input:focus { outline: none; border-color: var(--indigo); }

/* ── Settings — Contact tab ──────────────────────────────────────────────── */
.ct-wrap {
  max-width: 660px; padding: 28px 0 40px;
}
.ct-hero {
  display: flex; align-items: center; gap: 18px;
  padding: 0 0 24px; margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.ct-avatar {
  width: 64px; height: 64px; border-radius: 14px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700; color: #fff; letter-spacing: 0.5px;
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
.ct-avatar-btn {
  position: relative; padding: 0; border: 1px solid var(--line);
  cursor: pointer; overflow: hidden;
}
.ct-avatar-btn:hover { border-color: var(--ink-4); } /* SNAPS (var value) — no scale, no shadow */
.ct-avatar-btn.has-img { border-color: var(--line); }
.ct-avatar-initials { pointer-events: none; }
.ct-avatar-overlay {
  position: absolute; inset: 0; background: rgba(0,0,0,0.45);
  color: #fff; display: grid; place-items: center;
  opacity: 0; transition: opacity 0.12s ease; pointer-events: none;
}
.ct-avatar-btn:hover .ct-avatar-overlay,
.ct-avatar-btn.is-uploading .ct-avatar-overlay { opacity: 1; }
.ct-hero-info { display: flex; flex-direction: column; gap: 2px; }
.ct-hero-name { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; }
.ct-hero-sub { font-size: 13px; color: var(--ink-3); }
.ct-hero-email { font-size: 12.5px; color: var(--ink-4); margin-top: 1px; }
.ct-hero-photo-actions { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.ct-link-btn {
  background: none; border: none; padding: 0;
  font-size: 12px; color: var(--indigo); cursor: pointer;
  font: inherit; font-size: 12px;
}
.ct-link-btn:hover { text-decoration: underline; }
.ct-link-btn:disabled { color: var(--ink-4); cursor: default; text-decoration: none; }
.ct-link-btn-danger { color: var(--ink-4); }
.ct-link-btn-danger:hover { color: #ef4444; }
.ct-hero-photo-err { font-size: 11.5px; color: #ef4444; }

.ct-section-head {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--ink-4);
  margin: 0 0 12px; padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.ct-fields {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px;
  margin-bottom: 28px;
}
.ct-field { display: flex; flex-direction: column; gap: 5px; }
.ct-label {
  font-size: 11.5px; font-weight: 600; color: var(--ink-3);
  display: flex; align-items: baseline; gap: 6px;
}
.ct-hint { font-size: 11px; font-weight: 400; color: var(--ink-5); }
.ct-input {
  height: 34px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-elev); color: var(--ink);
  font-size: 13px; font-family: var(--f-sans);
  outline: none; transition: border-color 0.15s, box-shadow 0.15s;
  width: 100%; box-sizing: border-box;
}
.ct-input:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 14%, transparent);
}
.ct-select { appearance: none; cursor: pointer; padding-right: 28px;
  /* Chevron fill matches --ink-4's light value — data-URI SVGs can't consume
     CSS custom properties (no cascade across the resource boundary), so
     dark/mid variants override the whole background-image below instead. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2376787f'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
[data-theme="dark"] .ct-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236f717b'/%3E%3C/svg%3E");
}
.ct-bio {
  height: auto; padding: 8px 10px;
  resize: vertical; line-height: 1.55;
  margin-bottom: 28px;
}

.ct-linked {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 9px; overflow: hidden; margin-bottom: 28px;
}
.ct-linked-row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 9px 14px; border-bottom: 1px solid var(--line);
}
.ct-linked-row:last-child { border-bottom: none; }
.ct-linked-key {
  font-size: 11.5px; font-weight: 600; color: var(--ink-4);
  min-width: 130px; flex-shrink: 0;
}
.ct-linked-val { font-size: 13px; color: var(--ink); }

.ct-save-row {
  display: flex; align-items: center; gap: 12px; padding-top: 4px;
}
.ct-saved-tick {
  display: flex; align-items: center; gap: 5px;
  font-size: 12.5px; color: var(--ok);
}

/* ── Settings — Users & Access tab ──────────────────────────────────────────── */
.ua-wrap { padding: 4px 0 40px; }

.ua-levels {
  display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap;
}
.ua-level-card {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg-elev);
  cursor: pointer; transition: background 0.1s, border-color 0.1s;
  user-select: none;
}
.ua-level-card:hover { background: var(--bg-hover); }
.ua-level-card.active { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 8%, var(--bg)); }
.ua-level-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ua-level-name { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.ua-level-count { font-size: 12px; font-weight: 700; color: var(--ink-4); margin-left: 2px; }

.ua-level-desc {
  font-size: 12.5px; color: var(--ink-3); padding: 8px 12px;
  background: var(--bg-elev); border-radius: 7px;
  border: 1px solid var(--line); margin-bottom: 16px; line-height: 1.5;
}

.ua-table-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.ua-table-title { font-size: 12.5px; font-weight: 600; color: var(--ink-4); }

.ua-table {
  border: 1px solid var(--line); border-radius: 9px; overflow: hidden;
}
.ua-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  transition: background 0.1s;
}
.ua-row:last-child { border-bottom: none; }
.ua-row:hover { background: var(--bg-hover); }

.ua-row-avatar {
  width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700; color: #fff; letter-spacing: 0.3px;
}
.ua-row-info { flex: 1; min-width: 0; }
.ua-row-name {
  font-size: 13px; font-weight: 600; color: var(--ink);
  display: flex; align-items: center; gap: 6px;
}
.ua-you-tag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  padding: 1px 5px; border-radius: 4px;
  background: color-mix(in srgb, var(--indigo) 14%, transparent); color: var(--indigo);
}
.ua-row-meta { font-size: 11.5px; color: var(--ink-4); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ua-row-status {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--ink-4); flex-shrink: 0; min-width: 60px;
}
.ua-status-dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.ua-status-dot.active { background: var(--ok); }
.ua-status-dot.invited { background: var(--warn); }

.ua-row-clearance {
  display: flex; align-items: center; gap: 8px; flex-shrink: 0;
}
.ua-clearance-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px; border-radius: 5px;
  font-size: 11.5px; font-weight: 600; cursor: pointer;
  transition: opacity 0.1s;
}
.ua-clearance-badge:hover { opacity: 0.8; }
.ua-clearance-select {
  height: 28px; padding: 0 8px; border: 1px solid var(--line);
  border-radius: var(--radius-btn); font-size: 12px; background: var(--bg-elev);
  color: var(--ink); outline: none; cursor: pointer;
}
.ua-clearance-select:focus { border-color: var(--indigo); }
.ua-saved-tick {
  display: flex; align-items: center; gap: 4px;
  font-size: 11px; color: var(--ok);
}

/* Invite modal */
.ua-invite-dialog {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 24px 24px 20px;
  width: 420px; max-width: 95vw;
  box-shadow: 0 20px 60px rgba(0,0,0,0.2);
  display: flex; flex-direction: column; gap: 16px;
}
.ua-invite-fields { display: flex; flex-direction: column; gap: 12px; }
.ua-invite-field { display: flex; flex-direction: column; gap: 5px; }
.ua-invite-desc {
  font-size: 12px; color: var(--ink-4); line-height: 1.5;
  margin-top: 4px;
}
.ua-invite-sub {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.55; margin-top: -4px;
}
.ua-region-hint { font-size: 11px; color: var(--ink-4); font-weight: 400; }
.ua-invite-err {
  font-size: 12.5px; color: var(--bad);
  background: var(--bad-soft, rgba(220,38,38,0.08));
  border: 1px solid var(--bad-line, rgba(220,38,38,0.25));
  border-radius: 6px; padding: 8px 10px;
}
.ua-guest-types { display: flex; gap: 8px; flex-wrap: wrap; }
.ua-guest-chip {
  font-size: 12.5px; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-card);
  color: var(--ink-2); cursor: pointer; transition: all 0.12s ease;
}
.ua-guest-chip:hover { border-color: var(--indigo-line, var(--line-strong)); }
.ua-guest-chip.active {
  background: var(--indigo-soft, rgba(99,102,241,0.1));
  border-color: var(--indigo, #6366f1); color: var(--indigo-ink, #6366f1);
  font-weight: 600;
}
.ua-scope-list {
  display: flex; flex-direction: column; gap: 2px;
  max-height: 168px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 8px; padding: 6px;
}
.ua-scope-item {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--ink-2);
  padding: 6px 8px; border-radius: 6px; cursor: pointer;
}
.ua-scope-item:hover { background: var(--bg-hover); }
.ua-scope-item input { margin: 0; cursor: pointer; }

/* ─── Finance / Accounting (.acct-*) ─────────────────────────────────────────── */
.acct-bank-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.acct-bank-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 18px 20px 16px;
  display: flex; flex-direction: column; gap: 6px;
}
.acct-bank-card-header {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.acct-bank-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.acct-bank-inst { font-size: 11.5px; color: var(--ink-4); }
.acct-bank-balance {
  font-size: 26px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.5px; line-height: 1.1; margin: 4px 0;
}
/* A credit-card balance is money OWED. The figure already carries a leading
   "−" and the line under it says "Owed on this card", so the colour is a third,
   redundant cue rather than the only one — the card still reads correctly in
   greyscale or with no colour vision. */
.acct-bank-balance--debt { color: var(--bad); }
.acct-bank-debt-label { font-size: 11.5px; color: var(--bad); margin: -2px 0 4px; }
.acct-bank-limit { font-size: 11.5px; color: var(--ink-4); margin-bottom: 4px; }
.acct-detail-balance--debt { color: var(--bad); }
.acct-bank-meta { font-size: 11.5px; color: var(--ink-4); display: flex; gap: 10px; align-items: center; }
.acct-bank-tag {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 4px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em;
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  color: var(--indigo);
}
.acct-bank-actions { display: flex; gap: 6px; margin-top: 8px; }

/* Transactions table */
.acct-txn-filters {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-bottom: 12px;
}
.acct-txn-filter-btn {
  padding: 5px 12px; border-radius: var(--radius-btn); border: 1px solid var(--line);
  font-size: 12px; background: transparent; color: var(--ink-3);
  cursor: pointer; transition: background 0.1s, color 0.1s;
}
.acct-txn-filter-btn:hover { background: var(--bg-elev); color: var(--ink); }
.acct-txn-filter-btn.active { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.acct-amount-in  { color: var(--ok);  font-variant-numeric: tabular-nums; }
.acct-amount-out { color: var(--bad); font-variant-numeric: tabular-nums; }
.acct-amount-transfer { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.acct-cat-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 4px;
  font-size: 11px; font-weight: 500;
  background: var(--bg-elev); color: var(--ink-3);
  border: 1px solid var(--line-soft); cursor: pointer;
  transition: border-color 0.1s;
}
.acct-cat-pill:hover { border-color: var(--indigo); color: var(--indigo); }
.acct-cat-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
}
.acct-uncat {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 4px;
  font-size: 11px; color: var(--warn);
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 25%, transparent);
  cursor: pointer;
}
.acct-reconcile-badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px; border-radius: 4px;
  font-size: 10.5px; font-weight: 500;
}
.acct-reconcile-badge.reconciled {
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  color: var(--ok);
}
.acct-reconcile-badge.pending {
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  color: var(--warn);
}

/* Payroll */
.acct-payroll-grid { display: flex; flex-direction: column; gap: 10px; }
.acct-payroll-row {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; background: var(--bg-card);
  border: 1px solid var(--line); border-radius: 10px;
}
.acct-payroll-period { font-size: 13.5px; font-weight: 600; color: var(--ink); flex: 1; }
.acct-payroll-meta { font-size: 12px; color: var(--ink-4); }
.acct-payroll-amount {
  font-size: 14px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.acct-payroll-status {
  padding: 3px 9px; border-radius: 5px; font-size: 11px; font-weight: 600;
}
.acct-payroll-status.paid {
  background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok);
}
.acct-payroll-status.scheduled {
  background: color-mix(in srgb, var(--indigo) 12%, transparent); color: var(--indigo);
}

/* Reports */
.acct-report-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}
.acct-report-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 20px;
  display: flex; flex-direction: column; gap: 8px;
  cursor: pointer;
}
.acct-report-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS */
.acct-report-icon {
  width: 36px; height: 36px; border-radius: 8px;
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
  display: flex; align-items: center; justify-content: center;
  color: var(--indigo);
}
.acct-report-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.acct-report-desc { font-size: 12px; color: var(--ink-4); line-height: 1.5; }

/* Reconciliation */
.acct-recon-header {
  display: flex; align-items: flex-end; gap: 24px;
  padding: 18px 20px; background: var(--bg-card);
  border: 1px solid var(--line); border-radius: 12px;
  margin-bottom: 16px;
}
.acct-recon-stat { display: flex; flex-direction: column; gap: 3px; }
.acct-recon-stat-label { font-size: 11px; color: var(--ink-4); text-transform: uppercase; letter-spacing: 0.05em; }
.acct-recon-stat-value { font-size: 20px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.acct-recon-divider { width: 1px; height: 36px; background: var(--line); align-self: center; }

/* ─── Admin / Operations (.adm-*) ────────────────────────────────────────────── */
.adm-overview-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px; margin-bottom: 24px;
}
.adm-contract-table th, .adm-contract-table td { vertical-align: middle; }
.adm-contract-status {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 5px; font-size: 11.5px; font-weight: 600;
}
.adm-contract-status.active {
  background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok);
}
.adm-contract-status.draft {
  background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn);
}
.adm-contract-status.expired {
  background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--bad);
}

/* Proposals */
.adm-prop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.adm-prop-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 8px;
  transition: border-color 0.15s;
}
.adm-prop-card:hover { border-color: var(--indigo); }
.adm-prop-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.adm-prop-name { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.adm-prop-client { font-size: 12px; color: var(--ink-4); }
.adm-prop-fee { font-size: 18px; font-weight: 600; color: var(--ink); letter-spacing: -0.3px; }
.adm-prop-status {
  padding: 3px 9px; border-radius: 5px; font-size: 11px; font-weight: 600; white-space: nowrap;
}
.adm-prop-status.in_progress { background: color-mix(in srgb, var(--indigo) 12%, transparent); color: var(--indigo); }
.adm-prop-status.submitted   { background: color-mix(in srgb, var(--warn) 12%, transparent);   color: var(--warn); }
.adm-prop-status.won         { background: color-mix(in srgb, var(--ok) 12%, transparent);     color: var(--ok); }
.adm-prop-status.on_hold     { background: color-mix(in srgb, var(--ink-4) 14%, transparent);  color: var(--ink-3); }
.adm-prop-status.lost        { background: color-mix(in srgb, var(--bad) 12%, transparent);    color: var(--bad); }
.adm-prop-notes { font-size: 12px; color: var(--ink-4); line-height: 1.5; }
.adm-prop-meta { display: flex; gap: 10px; font-size: 11.5px; color: var(--ink-4); align-items: center; }

/* Documents */
.adm-doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.adm-doc-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 6px;
  transition: border-color 0.15s;
}
.adm-doc-card:hover { border-color: var(--indigo); }
.adm-doc-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.adm-doc-name { font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.adm-doc-type {
  padding: 2px 7px; border-radius: 4px;
  font-size: 10.5px; font-weight: 600; white-space: nowrap;
  background: var(--bg-elev); color: var(--ink-4);
  border: 1px solid var(--line-soft);
}
.adm-doc-meta { font-size: 11.5px; color: var(--ink-4); display: flex; flex-direction: column; gap: 2px; }
.adm-doc-status {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 4px;
  font-size: 11px; font-weight: 500;
  align-self: flex-start;
}
.adm-doc-status.active   { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok); }
.adm-doc-status.expiring { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); }
.adm-doc-status.expired  { background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--bad); }

/* Vendors */
.adm-vendor-row {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 18px; border-bottom: 1px solid var(--line-soft);
}
.adm-vendor-row:last-child { border-bottom: none; }
.adm-vendor-name { font-size: 13px; font-weight: 600; color: var(--ink); flex: 1; }
.adm-vendor-type {
  padding: 2px 8px; border-radius: 4px;
  font-size: 11px; background: var(--bg-elev);
  color: var(--ink-4); border: 1px solid var(--line-soft);
}
.adm-vendor-contact { font-size: 12px; color: var(--ink-4); min-width: 140px; }
.adm-vendor-office {
  font-size: 11.5px; color: var(--ink-4); min-width: 60px;
  font-family: var(--f-mono);
}

/* ── Graph fullscreen (expands inside .app-right, never covers chat) ──────── */
@keyframes graphFsIn  { from { clip-path: inset(5% 4% 5% 4% round 16px); opacity: 0; } to { clip-path: inset(0 0 0 0 round 0px); opacity: 1; } }
@keyframes graphFsOut { from { clip-path: inset(0 0 0 0 round 0px); opacity: 1; } to { clip-path: inset(5% 4% 5% 4% round 16px); opacity: 0; } }
.graph-fs {
  position: fixed; inset: 0; z-index: 9999;
  background: var(--bg-card);
  display: flex; flex-direction: column;
  animation: graphFsIn 0.3s cubic-bezier(0.4,0,0.2,1) both;
}
.graph-fs.exiting { animation: graphFsOut 0.22s cubic-bezier(0.4,0,0.2,1) both; }

/* Command Center summary chart — By-office ⇄ Combined toggle. The chart frame
   stays mounted; only the inner series wrapper is re-keyed by mode, so the
   regroup reads as a soft fade-up rather than a hard component swap. */
@keyframes ocModeFade { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.oc-mode-fade { animation: ocModeFade 0.28s cubic-bezier(0.4,0,0.2,1) both; }

/* ── Meetings ────────────────────────────────────────────────────────────────
   Canonical classes for the Meetings page (MeetingsPage, pages-2.jsx). These
   mirror the design pages first prototyped inline so the page is consistent
   with the system: big Zoom-style action tiles (.meeting-tile) and rich
   upcoming/past rows (.meeting-card). The "Live" dot reuses @keyframes dotPulse
   (defined above); the busy spinner reuses @keyframes spin. Theme-safe — all
   colors come from tokens, so light/mid/dark all resolve correctly.
   ──────────────────────────────────────────────────────────────────────────── */

/* Big action tile — "New meeting" / "Join" / "Personal room" launcher. */
.meeting-tile {
  text-align: left; width: 100%; cursor: pointer;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-2);
  border-radius: 16px; padding: 20px 18px;
  display: flex; flex-direction: column; gap: 12px; min-height: 132px;
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
  transition: box-shadow var(--duration-fast, .16s) var(--ease-out, ease),
              transform var(--duration-fast, .16s) var(--ease-out, ease);
}
.meeting-tile:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(0,0,0,.12);
}
.meeting-tile:disabled { opacity: .65; cursor: default; transform: none; }
/* Brand-filled primary tile (the "New meeting" launcher). */
.meeting-tile--filled {
  border: none; background: var(--brand); color: #fff;
}
/* Tinted glyph chip inside the tile. */
.meeting-tile-glyph {
  width: 46px; height: 46px; border-radius: 13px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--brand);
}
.meeting-tile--filled .meeting-tile-glyph { background: rgba(255,255,255,.18); color: #fff; }
.meeting-tile-title { font-size: 15px; font-weight: 700; }
.meeting-tile-sub   { font-size: 12.5px; margin-top: 2px; color: var(--ink-5); }
.meeting-tile--filled .meeting-tile-sub { color: rgba(255,255,255,.85); }

/* Rich upcoming/past meeting row. container-type powers .hide-narrow below. */
.meeting-card {
  cursor: pointer; container-type: inline-size;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card); padding: 16px;
  display: flex; align-items: center; gap: 16px;
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.meeting-card:hover { box-shadow: 0 0 0 1px var(--line), 0 1px 2px rgba(0,0,0,.04); } /* thicken-outline convention; SNAPS */
.meeting-card--live { border-color: var(--brand); }
.meeting-card--past { opacity: .92; }
/* The live "now" pip — reuses @keyframes dotPulse. */
.meeting-live-dot {
  width: 7px; height: 7px; border-radius: 7px; display: inline-block;
  background: var(--brand); animation: dotPulse 1.4s infinite;
}

/* Responsive utility — collapse non-essential cluster (e.g. the attendee
   AvatarGroup) when the *card* (not the viewport) gets narrow. Driven by the
   container query on .meeting-card so it reacts to sidebar-collapse + window
   width together. Generic enough to reuse on any container-typed card. */
.hide-narrow { display: revert; }
@container (max-width: 460px) {
  .hide-narrow { display: none; }
}

/* ── Meeting room — in-call control tray (MeetingRoomPage) ──────────────────
   Zoom-style labeled controls: circular icon + tiny caption, with hover and
   state tints. The room is a fixed DARK surface independent of the app theme
   (matches the inline #0c0e11 palette used throughout MeetingRoomPage), so
   these use the room's hardcoded darks, not the light/dark tokens. */
.mr-tray {
  display: flex; align-items: flex-start; justify-content: center; gap: 2px;
  padding: 8px 14px 10px; border-top: 1px solid #1b1f25; position: relative;
}
.mr-ctrl {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
  min-width: 64px; padding: 6px 6px 5px; border: none; border-radius: 10px;
  background: transparent; cursor: pointer; transition: background .12s ease;
}
.mr-ctrl:hover:not(:disabled) { background: #171b21; }
.mr-ctrl:disabled { opacity: .45; cursor: not-allowed; }
.mr-ctrl-icon {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #2f353e; color: #fff; transition: background .12s ease;
}
.mr-ctrl:hover:not(:disabled) .mr-ctrl-icon { background: #3a414b; }
.mr-ctrl-label { font-size: 10.5px; line-height: 1; color: #9aa3af; white-space: nowrap; }
.mr-ctrl:hover:not(:disabled) .mr-ctrl-label { color: #e6e9ee; }
/* State tints — hover keeps the tint (only the neutral grey brightens). */
.mr-ctrl--brand .mr-ctrl-icon,  .mr-ctrl--brand:hover:not(:disabled) .mr-ctrl-icon  { background: var(--brand); }
.mr-ctrl--danger .mr-ctrl-icon, .mr-ctrl--danger:hover:not(:disabled) .mr-ctrl-icon { background: #d2433a; }
.mr-ctrl--green .mr-ctrl-icon,  .mr-ctrl--green:hover:not(:disabled) .mr-ctrl-icon  { background: #2f7d4a; }
.mr-ctrl--rec .mr-ctrl-icon,    .mr-ctrl--rec:hover:not(:disabled) .mr-ctrl-icon    { background: #c0392b; }
/* Thin divider between control groups (devices | share tools | leave). */
.mr-sep { width: 1px; align-self: stretch; margin: 6px 5px; background: #1b1f25; flex-shrink: 0; }
/* Device-settings caret riding the mic control (opens the camera/mic/speaker panel). */
.mr-caret {
  position: absolute; top: 1px; right: 3px; width: 18px; height: 18px; z-index: 2;
  border-radius: 50%; border: 1px solid #2b313a; background: #171b21; color: #9aa3af;
  display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
}
.mr-caret:hover { background: #2b313a; color: #fff; }
/* Count badge on a tray control (chat unread). */
.mr-badge {
  position: absolute; top: 0; right: 9px; min-width: 16px; height: 16px; border-radius: 8px;
  background: #d2433a; color: #fff; font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; padding: 0 4px; pointer-events: none;
}
/* Leave — red pill, vertically centered against the labeled controls. */
.mr-leave {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  align-self: center; height: 38px; padding: 0 20px; margin-left: 4px;
  border: none; border-radius: 19px; background: #d2433a; color: #fff;
  font-size: 13px; font-weight: 600; cursor: pointer; transition: background .12s ease;
}
.mr-leave:hover { background: #e05146; }
/* "REC" pill in the room's top bar while recording (reuses @keyframes dotPulse). */
.mr-rec-pill {
  display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em; color: #ff9b90;
  background: rgba(210,67,58,.14); border: 1px solid rgba(210,67,58,.35);
  border-radius: 6px; padding: 2px 7px;
}
.mr-rec-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #e0463a; animation: dotPulse 1.6s ease-in-out infinite; }
/* Its opposite: a recording that DIED without anyone pressing Stop. The absence
   of the REC pill is what let an 86-minute meeting go unrecorded on 2026-08-14
   (see the watchdog in pages-2.jsx) — silence had to become a visible state.
   Amber, static dot: it is a warning, not a live indicator. */
.mr-norec-pill {
  display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em; color: #e8c477;
  background: rgba(232,196,119,.12); border: 1px solid rgba(232,196,119,.38);
  border-radius: 6px; padding: 2px 7px;
}
.mr-norec-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #e8c477; }

/* ── Master portfolio chart — marker tooltip ─────────────────────────────────
   Hover popover for the Command Center finance chart's milestone (triangle) /
   risk (diamond) markers. Rendered as an HTML <div> inside an SVG
   <foreignObject> (SVG <text> can't wrap), so this class governs the box:
   content-sized but capped, with the text WRAPPING inside. Title line is
   bolder; pages sets its color inline to the marker tone (var(--fin-line) /
   --fin-down / --fin-projected). All box colors are token-based → reads
   correctly in light, mid, and dark. */
.mpc-marker-tip {
  display: inline-block;
  width: max-content;            /* size to content … */
  max-width: 220px;              /* … but cap, then wrap */
  box-sizing: border-box;
  padding: 8px 11px;
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--ink-3);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(0,0,0,.18);
  font-size: 11px;
  line-height: 1.35;
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: normal;           /* override any inherited nowrap */
  pointer-events: none;
}
.mpc-marker-tip-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-1);           /* pages overrides inline with marker tone */
  margin-bottom: 2px;
}
.mpc-marker-tip-line { color: var(--ink-3); }

/* ─── Studio Review ─────────────────────────────────────────────────────────── */

/* Page shell */
/* Override .page padding/scroll when studio review is active */
.page:has(.studio-review-page) {
  padding: 0; overflow: hidden; display: flex; flex-direction: column; max-width: none;
}
/* The topbar is an absolute OVERLAY (see .topbar) — the bare `padding: 0` above
   wiped the topbar clearance, sliding the SR DASHBOARD's header ("Review Sessions")
   up UNDER the transparent bar so the topbar title/date rendered on top of it.
   On the DASHBOARD (topbar visible) restore padding-top to the published clearance;
   INSIDE an open session the body gets .sr-session-open (topbar display:none) and
   the canvas keeps padding-top:0 to reclaim full height. Driven by the body class
   directly — NOT by the clearance var reaching 0 — so a full-height canvas never
   depends on the ResizeObserver republishing 0 when the bar hides. No pixels. */
body:not(.sr-session-open) .page:has(.studio-review-page) {
  padding-top: var(--topbar-clearance, 62px);
}
.page:has(.studio-review-page) > * { margin-bottom: 0; }

.studio-review-page {
  display: flex; flex-direction: column; flex: 1 1 0; min-height: 0; overflow: hidden;
}
.studio-review-shell {
  display: flex; flex: 1 1 0; min-height: 0; overflow: hidden;
}

/* ── Dashboard ─────────────────────────────────────────────────────────────── */
.sr-dashboard {
  flex: 1; overflow-y: auto; padding: 28px 32px;
}
.sr-dashboard-head {
  margin-bottom: 28px;
}
.sr-dashboard-title {
  font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink);
}
.sr-dashboard-sub {
  font-size: 13px; color: var(--ink-4); margin-top: 4px; max-width: 520px; line-height: 1.5;
}
.sr-dashboard-actions {
  display: flex; gap: 8px; margin-top: 16px;
}
.sr-metric-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 24px;
}
.sr-section-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;
}
.sr-section-row-3 {
  display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 16px; margin-bottom: 16px;
}

/* Activity feed */
.sr-activity-feed { padding: 0 2px; }
.sr-activity-item {
  display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line-soft);
}
.sr-activity-item:last-child { border-bottom: none; }
.sr-activity-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: var(--indigo-soft); color: var(--indigo);
  display: flex; align-items: center; justify-content: center;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.02em;
}
.sr-activity-body { flex: 1; min-width: 0; }
.sr-activity-msg { font-size: 12px; color: var(--ink-2); line-height: 1.4; }
.sr-activity-time { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }

/* Discipline bar */
.sr-disc-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 0;
}
.sr-disc-label { font-size: 11.5px; color: var(--ink-3); min-width: 88px; }
.sr-disc-bar-wrap {
  flex: 1; height: 7px; background: var(--bg-elev); border-radius: 99px; overflow: hidden;
}
.sr-disc-bar-fill {
  height: 100%; border-radius: 99px; background: var(--indigo); transition: width 0.4s ease;
}
.sr-disc-count { font-size: 11px; color: var(--ink-4); font-family: var(--f-mono); min-width: 18px; text-align: right; }

/* ── Left Panel ────────────────────────────────────────────────────────────── */
.studio-review-sidebar {
  width: 260px; flex-shrink: 0;
  border-right: 1px solid var(--line);
  background: var(--bg-elev);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.sr-sidebar-head {
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.sr-search {
  width: 100%; padding: 6px 10px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-card); color: var(--ink); font-size: 12px;
  outline: none; transition: border-color 0.15s;
}
.sr-search:focus { border-color: var(--indigo); }
.sr-filter-chips {
  display: flex; gap: 4px; margin-top: 8px; flex-wrap: wrap;
}
.sr-chip {
  padding: 3px 9px; border-radius: 99px; font-size: 11px; font-weight: 500;
  border: 1px solid var(--line); background: none; cursor: pointer; color: var(--ink-4);
  transition: all 0.1s;
}
.sr-chip:hover { border-color: var(--indigo); color: var(--indigo); }
.sr-chip.active { background: var(--indigo-soft); border-color: var(--indigo-line); color: var(--indigo); }

.sr-sidebar-body { flex: 1 1 0; overflow-y: auto; padding: 8px 0; }
.sr-sidebar-footer {
  padding: 10px 12px; border-top: 1px solid var(--line-soft); flex-shrink: 0;
  display: flex; flex-direction: column; gap: 6px;
}

/* Project card */
.sr-project-item {
  padding: 0;
}
.sr-project-head {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 12px; cursor: pointer; transition: background 0.1s;
  border-radius: 0;
}
.sr-project-head:hover { background: var(--bg-hover); }
.sr-project-head.active { background: color-mix(in oklab, var(--indigo) 6%, transparent); }
.sr-project-chevron {
  flex-shrink: 0; margin-top: 3px; color: var(--ink-5); transition: transform 0.15s;
}
.sr-project-chevron.open { transform: rotate(90deg); }
.sr-project-info { flex: 1; min-width: 0; }
.sr-project-name { font-size: 12.5px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-project-meta { font-size: 10.5px; color: var(--ink-5); margin-top: 2px; }
.sr-project-stats { display: flex; gap: 8px; margin-top: 4px; }
.sr-project-stat { font-size: 10.5px; color: var(--ink-4); }
.sr-project-stat span { font-weight: 600; color: var(--ink-2); }

/* Session items */
.sr-sessions-list { padding: 2px 0 4px 20px; }
.sr-session-item {
  padding: 6px 12px 6px 10px; cursor: pointer;
  border-radius: 5px; margin: 1px 6px;
  transition: background 0.1s;
  display: flex; align-items: flex-start; gap: 8px;
}
.sr-session-item:hover { background: var(--bg-hover); }
.sr-session-item.active { background: var(--indigo-soft); }
.sr-session-dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; margin-top: 5px;
}
.sr-session-info { flex: 1; min-width: 0; }
.sr-session-name { font-size: 12px; font-weight: 500; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-session-meta { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }

/* ── Workspace body: toolbar + pages panel + canvas ─────────────────────────── */

/* Workspace body: pages panel + canvas */
.sr-workspace-body {
  display: flex; flex: 1 1 0; min-height: 0; overflow: hidden;
}

/* Pages / sheets panel (left) */
.sr-pages-panel {
  width: 176px; flex-shrink: 0;
  border-right: 1px solid var(--line);
  background: var(--bg-elev);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.sr-pages-panel-head {
  padding: 7px 10px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-4); border-bottom: 1px solid var(--line); flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
}
.sr-pages-list { flex: 1 1 0; overflow-y: auto; padding: 3px 0; }

/* Document row — wraps the main button + thumbnail toggle button */
.sr-doc-row {
  display: flex; align-items: stretch;
  border-bottom: 1px solid transparent;
  transition: background 0.1s;
}
.sr-doc-row:hover { background: var(--bg-hover); }
.sr-doc-row.active { background: color-mix(in oklab, var(--indigo) 10%, transparent); }
.sr-doc-main {
  display: flex; align-items: flex-start; gap: 8px; flex: 1; min-width: 0;
  padding: 7px 6px 7px 10px;
  border: none; background: none; cursor: pointer; text-align: left;
  font-family: var(--f-sans);
}
.sr-doc-thumb-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; width: 28px; flex-shrink: 0;
  border: none; background: none; cursor: pointer;
  color: var(--ink-5); border-left: 1px solid transparent;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
  border-radius: 0;
}
.sr-doc-thumb-btn:hover { background: var(--indigo-soft); color: var(--indigo); border-left-color: var(--indigo-line); }
.sr-doc-thumb-btn.open { background: var(--indigo-soft); color: var(--indigo); border-left-color: var(--indigo-line); }
.sr-page-num { font-size: 10px; font-weight: 600; color: var(--ink-3); font-family: var(--f-mono); }
.sr-page-title { font-size: 11px; color: var(--ink-2); margin-top: 1px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-doc-row.active .sr-page-num, .sr-doc-row.active .sr-page-title { color: var(--indigo); }

/* Canvas area */
.sr-canvas-area {
  flex: 1; display: flex; flex-direction: column; overflow: hidden; min-width: 0;
  position: relative;
}

/* Viewer */
.studio-review-viewer {
  flex: 1 1 0; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  background: var(--bg-sunk);
  overflow: hidden;
}
.sr-viewer-topbar {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 14px; border-bottom: 1px solid var(--line);
  background: var(--bg-card); flex-shrink: 0; height: 40px;
}
.sr-viewer-controls { display: flex; align-items: center; gap: 6px; }
.sr-viewer-sep { width: 1px; height: 16px; background: var(--line); }
.sr-viewer-btn {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 5px; border: 1px solid var(--line);
  background: none; cursor: pointer; color: var(--ink-4);
  transition: background 0.1s, color 0.1s; font-size: 13px;
}
.sr-viewer-btn:hover { background: var(--bg-hover); color: var(--ink); }
.sr-viewer-btn:disabled { opacity: 0.35; cursor: default; }
.sr-zoom-label { font-size: 11px; color: var(--ink-4); font-family: var(--f-mono); min-width: 34px; text-align: center; }
.sr-viewer-sheet-info {
  font-size: 11px; color: var(--ink-4); margin-left: auto; display: flex; align-items: center; gap: 12px;
}
.sr-viewer-canvas-wrap {
  flex: 1 1 0; overflow: auto; display: flex; align-items: flex-start; justify-content: center;
  padding: 24px; position: relative;
}
.sr-drawing-sheet {
  position: relative; background: white; box-shadow: 0 4px 32px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.06);
  flex-shrink: 0;
}
.sr-drawing-grid {
  position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(0,0,0,0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,0,0,0.025) 1px, transparent 1px);
  background-size: 40px 40px;
}
.sr-drawing-title-block {
  position: absolute; bottom: 0; right: 0;
  width: 200px; border-left: 1.5px solid #ccc; border-top: 1.5px solid #ccc;
  padding: 8px 10px; background: white;
}
.sr-drawing-border {
  position: absolute; inset: 12px; border: 1.5px solid #bbb; pointer-events: none;
}
.sr-drawing-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  cursor: crosshair;
}
.sr-drawing-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; color: var(--ink-4); text-align: center;
}
.sr-drawing-empty-icon { opacity: 0.3; }
.sr-drawing-empty-title { font-size: 14px; font-weight: 500; color: var(--ink-3); }
.sr-drawing-empty-sub { font-size: 12.5px; color: var(--ink-5); max-width: 280px; line-height: 1.5; }

/* File thumbs */
.sr-file-thumbs {
  display: flex; gap: 6px; padding: 8px 14px 6px;
  border-bottom: 1px solid var(--line-soft);
  overflow-x: auto; flex-shrink: 0;
  background: var(--bg-card);
}
.sr-file-thumb {
  flex-shrink: 0; padding: 5px 10px; border-radius: 6px; border: 1px solid var(--line);
  background: none; cursor: pointer; transition: all 0.1s;
  text-align: left; min-width: 70px;
}
.sr-file-thumb:hover { border-color: var(--indigo); background: var(--indigo-soft); }
.sr-file-thumb.active { border-color: var(--indigo); background: var(--indigo-soft); color: var(--indigo); }
.sr-file-thumb-num { font-size: 10px; font-weight: 700; font-family: var(--f-mono); color: var(--ink-4); }
.sr-file-thumb-title { font-size: 9.5px; color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 80px; }

/* ── Bottom Panel (markups, comments, activity) ────────────────────────────── */
.studio-review-panel {
  height: 256px; flex-shrink: 0; width: 100%;
  border-top: 1px solid var(--line);
  background: var(--bg-card);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.sr-panel-tabs {
  display: flex; border-bottom: 1px solid var(--line); flex-shrink: 0; overflow-x: auto;
}
.sr-panel-tab {
  flex-shrink: 0; padding: 9px 12px; border: none; background: none; cursor: pointer;
  font-size: 11.5px; font-weight: 500; color: var(--ink-4);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  white-space: nowrap; transition: color 0.1s, border-color 0.1s;
}
.sr-panel-tab:hover { color: var(--ink); }
.sr-panel-tab.active { color: var(--ink); border-bottom-color: var(--indigo); }
.sr-panel-body { flex: 1 1 0; overflow-y: auto; }

/* Session cards (dashboard) */
.sr-session-card {
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-card); cursor: pointer;
}
.sr-session-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS */

/* Dashboard toolbar (search + filter + view toggle) */
.sr-dash-toolbar {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
}
.sr-dash-search {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; gap: 6px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px;
  padding: 6px 10px; color: var(--ink-5);
  transition: border-color 0.12s;
}
.sr-dash-search:focus-within { border-color: var(--indigo-line); }
.sr-dash-search input {
  flex: 1; border: none; background: transparent; outline: none;
  font-size: 12.5px; color: var(--ink-2); font-family: var(--f-sans);
}
.sr-dash-search input::placeholder { color: var(--ink-5); }
.sr-dash-search-clear {
  background: none; border: none; cursor: pointer; padding: 2px;
  display: flex; align-items: center; color: var(--ink-5); border-radius: var(--radius-btn-icon, 8px);
}
.sr-dash-search-clear:hover { background: var(--bg-hover); color: var(--ink-2); }

.sr-dash-pill-toggle, .sr-dash-view-toggle {
  display: flex; background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 3px;
  flex-shrink: 0; gap: 2px;
}
.sr-dash-pill-toggle button {
  background: none; border: none; cursor: pointer;
  padding: 5px 14px; font-size: 11.5px; color: var(--ink-4);
  border-radius: var(--radius-btn); font-family: var(--f-sans); font-weight: 500;
  transition: background 0.1s, color 0.1s;
}
.sr-dash-pill-toggle button:hover { color: var(--ink-2); }
.sr-dash-pill-toggle button.active {
  background: var(--indigo-soft); color: var(--indigo);
}

.sr-dash-view-toggle button {
  background: none; border: none; cursor: pointer;
  padding: 5px 9px; color: var(--ink-4); border-radius: var(--radius-btn);
  display: flex; align-items: center; transition: background 0.1s, color 0.1s;
}
.sr-dash-view-toggle button:hover { color: var(--ink-2); }
.sr-dash-view-toggle button.active {
  background: var(--indigo-soft); color: var(--indigo);
}

.sr-dash-filter-row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 0; flex-wrap: wrap;
}
.sr-dash-chips {
  display: inline-flex; gap: 4px;
  padding: 3px; border-radius: 8px; background: var(--bg-elev);
}
.sr-dash-chip {
  padding: 5px 12px; font-size: 12px; font-weight: 500;
  background: transparent; border: none; border-radius: 6px;
  color: var(--ink-3); cursor: pointer; transition: background 0.15s, color 0.15s;
}
.sr-dash-chip:hover { color: var(--ink-2); background: var(--bg-hover); }
.sr-dash-chip.active { background: var(--bg); color: var(--indigo); box-shadow: 0 1px 2px rgba(0,0,0,0.08); }
.sr-dash-sort {
  padding: 5px 28px 5px 12px; font-size: 12px;
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius-btn);
  color: var(--ink-2); cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-4) 50%), linear-gradient(135deg, var(--ink-4) 50%, transparent 50%);
  background-position: calc(100% - 14px) 50%, calc(100% - 9px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.sr-dash-sort:hover { border-color: var(--ink-5); color: var(--ink-1); }

/* Folder grouping */
.sr-dash-folder { margin-bottom: 12px; }
.sr-dash-folder-head {
  display: flex; align-items: center; gap: 6px; width: 100%;
  background: none; border: none; cursor: pointer;
  padding: 6px 4px; text-align: left;
  color: var(--ink-3); font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 6px;
  transition: color 0.1s;
}
.sr-dash-folder-head:hover { color: var(--ink-1); }
.sr-dash-folder-name { flex: 1; }
.sr-dash-folder-count {
  font-size: 10px; color: var(--ink-5);
  background: var(--surface-2, var(--surface)); padding: 2px 7px; border-radius: 9px;
  font-weight: 600; letter-spacing: 0;
}

.sr-dash-list { display: flex; flex-direction: column; gap: 8px; }
.sr-dash-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}

/* Grid-view card */
.sr-dash-grid-card {
  position: relative;
  padding: 11px 12px 11px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-card); cursor: pointer;
  display: flex; flex-direction: column; gap: 6px;
  min-height: 110px;
}
.sr-dash-grid-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS */
.sr-dash-grid-card-head {
  display: flex; align-items: center; gap: 6px;
  padding-right: 24px;
}
.sr-dash-grid-card-title {
  flex: 1; font-size: 12.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sr-dash-grid-card-proj { font-size: 10.5px; color: var(--ink-5); }
.sr-dash-grid-card-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; flex-wrap: wrap; }
.sr-dash-grid-card-avatars { display: flex; }
.sr-dash-avatar {
  width: 19px; height: 19px; border-radius: 50%;
  background: var(--indigo-soft); color: var(--indigo);
  display: flex; align-items: center; justify-content: center;
  font-size: 7.5px; font-weight: 700;
  border: 1.5px solid var(--bg-card);
}
.sr-dash-avatar-ext { background: var(--surface-2, var(--surface)); color: var(--ink-4); font-size: 7px; }
.sr-dash-grid-card-badges { display: flex; gap: 4px; }
.sr-dash-badge {
  font-size: 9.5px; color: var(--ink-4);
  background: var(--surface-2, var(--surface)); padding: 1px 6px; border-radius: 9px;
  display: flex; align-items: center; gap: 3px;
}
.sr-dash-badge-bad { color: var(--bad); background: color-mix(in oklab, var(--bad) 8%, var(--bg-card)); }
.sr-dash-grid-card-due {
  font-size: 10.5px; display: flex; align-items: center; gap: 3px;
}
.sr-dash-grid-card-actions {
  position: absolute; top: 6px; right: 6px;
  display: flex; gap: 2px; opacity: 0; transition: opacity 0.12s;
}
.sr-dash-grid-card:hover .sr-dash-grid-card-actions { opacity: 1; }

/* Compact archive button (used in both list + grid views) */
.sr-dash-card-action {
  width: 24px; height: 24px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-btn-icon, 8px);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  color: var(--ink-4); transition: color 0.1s, border-color 0.1s;
}
.sr-dash-card-action:hover { background: var(--surface-2, var(--surface)); color: var(--ink-2); border-color: var(--indigo-line); }

/* 2-step modal stepper */
.sr-stepper {
  display: flex; align-items: center; gap: 6px; margin-right: 10px;
}
.sr-step {
  width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; color: var(--ink-5); transition: all 0.15s;
}
.sr-step.active { border-color: var(--indigo); background: var(--indigo); color: white; }
.sr-step-line { width: 20px; height: 1.5px; background: var(--line); }

/* External consultant row in modal */
.sr-consultant-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  background: var(--bg-elev); border-radius: 6px; border: 1px solid var(--line);
  margin-bottom: 5px;
}

/* Upload dropzone */
.sr-upload-dropzone {
  border: 2px dashed var(--line); border-radius: 8px; padding: 24px 16px;
  text-align: center; background: var(--bg-sunk); margin-bottom: 14px;
  display: flex; flex-direction: column; align-items: center;
}

/* Upload button in pages panel head */
.sr-upload-btn {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 5px; border: 1px solid var(--line);
  background: none; cursor: pointer; color: var(--ink-4); transition: all 0.1s;
}
.sr-upload-btn:hover { background: var(--indigo-soft); color: var(--indigo); border-color: var(--indigo-line); }

/* Comments */
.sr-comments-filter {
  padding: 10px 12px; border-bottom: 1px solid var(--line-soft); display: flex; gap: 5px; flex-wrap: wrap;
}
.sr-comment-item {
  padding: 10px 12px; border-bottom: 1px solid var(--line-soft); cursor: pointer;
  transition: background 0.1s;
}
.sr-comment-item:hover { background: var(--bg-hover); }
.sr-comment-item.expanded { background: color-mix(in oklab, var(--indigo) 4%, transparent); }
.sr-comment-header { display: flex; align-items: flex-start; gap: 7px; margin-bottom: 5px; }
.sr-comment-status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 4px; }
.sr-comment-body-text { font-size: 12px; color: var(--ink-2); line-height: 1.45; }
.sr-comment-meta { font-size: 10.5px; color: var(--ink-5); margin-top: 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.sr-comment-tags { display: flex; gap: 5px; margin-top: 5px; flex-wrap: wrap; }
.sr-comment-reply-area { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-soft); }
.sr-comment-replies { font-size: 11.5px; color: var(--ink-4); margin-top: 6px; }
.sr-reply-bubble { background: var(--bg-elev); border-radius: 7px; padding: 7px 10px; margin-bottom: 5px; }
.sr-reply-author { font-size: 10.5px; font-weight: 600; color: var(--ink-3); margin-bottom: 2px; }
.sr-reply-text { font-size: 11.5px; color: var(--ink-2); }
.sr-reply-input {
  width: 100%; padding: 6px 10px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-elev); color: var(--ink); font-size: 12px; resize: none;
  font-family: var(--f-sans); margin-top: 6px; outline: none;
  transition: border-color 0.15s;
}
.sr-reply-input:focus { border-color: var(--indigo); }
.sr-add-comment-btn {
  width: 100%; padding: 12px; border: none; background: none;
  color: var(--indigo); font-size: 12.5px; font-weight: 500; cursor: pointer;
  border-top: 1px solid var(--line-soft); display: flex; align-items: center; justify-content: center; gap: 6px;
  transition: background 0.1s;
}
.sr-add-comment-btn:hover { background: var(--indigo-soft); }

/* Markups list */
.sr-markups-list-head {
  padding: 10px 12px; display: flex; align-items: center; gap: 8px;
  border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.sr-markups-search {
  flex: 1; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-elev); color: var(--ink); font-size: 11.5px; outline: none;
}
.sr-markups-search:focus { border-color: var(--indigo); }
.sr-markup-row {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
  cursor: pointer; transition: background 0.1s;
}
.sr-markup-row:hover { background: var(--bg-hover); }
.sr-markup-row.selected { background: var(--indigo-soft); }
.sr-markup-color-strip { width: 3px; height: 32px; border-radius: 2px; flex-shrink: 0; }
.sr-markup-type-icon { flex-shrink: 0; color: var(--ink-4); }
.sr-markup-info { flex: 1; min-width: 0; }
.sr-markup-subject { font-size: 12px; font-weight: 500; color: var(--ink-2); }
.sr-markup-submeta { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }

/* Activity */
.sr-activity-tab { padding: 0 12px; }
.sr-activity-date-group { padding: 10px 0 4px; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; color: var(--ink-5); }
.sr-activity-entry {
  display: flex; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--line-soft);
}
.sr-activity-entry:last-child { border-bottom: none; }
.sr-activity-entry-avatar {
  width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 700; background: var(--indigo-soft); color: var(--indigo);
}
.sr-activity-entry-body { flex: 1; min-width: 0; }
.sr-activity-entry-msg { font-size: 11.5px; color: var(--ink-2); line-height: 1.4; }
.sr-activity-entry-time { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }

/* Files tab */
.sr-files-head {
  padding: 10px 12px; display: flex; gap: 7px; border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.sr-folder-label {
  padding: 8px 12px 4px; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; color: var(--ink-5);
}
.sr-file-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s;
}
.sr-file-row:hover { background: var(--bg-hover); }
.sr-file-icon { flex-shrink: 0; color: var(--ink-4); }
.sr-file-info { flex: 1; min-width: 0; }
.sr-file-name { font-size: 12px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-file-submeta { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }
.sr-checkout-badge {
  font-size: 9.5px; background: color-mix(in oklab, var(--warn) 12%, transparent);
  color: var(--warn); padding: 2px 6px; border-radius: 4px; white-space: nowrap; flex-shrink: 0;
}

/* Session info */
.sr-session-info-tab { padding: 14px; }
.sr-info-row { padding: 8px 0; border-bottom: 1px solid var(--line-soft); display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.sr-info-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; color: var(--ink-5); flex-shrink: 0; }
.sr-info-value { font-size: 12.5px; color: var(--ink-2); text-align: right; }
.sr-attendees-list { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.sr-attendee-row { display: flex; align-items: center; gap: 8px; }
.sr-attendee-avatar {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--indigo-soft); color: var(--indigo);
  display: flex; align-items: center; justify-content: center;
  font-size: 9.5px; font-weight: 700; flex-shrink: 0;
}
.sr-attendee-name { font-size: 12px; color: var(--ink-2); flex: 1; }
.sr-session-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }

/* AI tab */
.sr-ai-tab { padding: 14px 12px; }
.sr-ai-header { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.sr-ai-sub { font-size: 12px; color: var(--ink-4); margin-bottom: 14px; line-height: 1.5; }
.sr-ai-action-btn {
  width: 100%; text-align: left; padding: 9px 12px; border-radius: 7px;
  border: 1px solid var(--line); background: none; cursor: pointer;
  font-size: 12px; color: var(--ink-2); margin-bottom: 6px;
  transition: background 0.1s, border-color 0.1s;
  display: flex; align-items: center; justify-content: space-between;
}
.sr-ai-action-btn:hover { background: var(--indigo-soft); border-color: var(--indigo-line); color: var(--indigo); }
.sr-ai-result {
  background: var(--bg-elev); border: 1px solid var(--line-soft); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 10px; font-size: 12px; color: var(--ink-2); line-height: 1.6;
}
.sr-ai-result-title { font-size: 11px; font-weight: 600; color: var(--ink-4); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
.sr-ai-footer { font-size: 10.5px; color: var(--ink-5); margin-top: 14px; text-align: center; }

/* ── Modals ─────────────────────────────────────────────────────────────────── */
.sr-modal-overlay {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(0,0,0,0.50);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: dvOverlayIn 0.18s ease both;
}
.sr-modal {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-card, 14px);
  width: 100%; max-width: 520px;
  height: 88vh; max-height: 600px; display: flex; flex-direction: column;
  box-shadow: 0 32px 64px -16px rgba(0,0,0,0.28);
  /* fill-mode `backwards` (NOT `both`): the final keyframe carries an identity
     transform, and a persisted transform makes the modal a containing block for
     position:fixed descendants — which would misplace AecosSelect menus. The
     end state is visually identical to the natural style, so nothing flashes. */
  animation: dvPanelIn 0.22s cubic-bezier(0.34,1.2,0.64,1) backwards;
}
.sr-modal-lg { max-width: 780px; }
.sr-modal-xl { max-width: 960px; }
.sr-modal-head {
  padding: 18px 20px 14px; border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: flex-start; justify-content: space-between;
  flex-shrink: 0;
}
.sr-modal-title { font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.sr-modal-sub { font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.sr-modal-close {
  background: none; border: none; cursor: pointer; color: var(--ink-5);
  flex-shrink: 0; width: 26px; height: 26px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-btn-icon); transition: background 0.1s, color 0.1s;
}
.sr-modal-close:hover { background: var(--bg-hover); color: var(--ink); }
.sr-modal-close:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent); outline-offset: 2px;
}
.sr-modal-body { flex: 1 1 0; overflow-y: auto; padding: 18px 20px; }
.sr-modal-footer {
  padding: 14px 20px; border-top: 1px solid var(--line-soft);
  display: flex; justify-content: flex-end; gap: 8px; flex-shrink: 0;
}

/* SR buttons — these class names are used in JSX (signature pad, approvals,
   revisions) but had no CSS → browser-default buttons. Aligned to the native
   .btn family: pill radius, tokens, focus rings. */
.sr-btn-sm, .sr-btn-xs {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border-radius: var(--radius-btn); font-weight: 500; cursor: pointer;
  background: var(--bg-card); color: var(--ink); border: 1px solid var(--line-strong);
  transition: background 0.12s, border-color 0.12s, color 0.12s, box-shadow 0.18s;
  font-family: var(--f-sans);
}
.sr-btn-sm { padding: 5px 11px; font-size: 12px; }
.sr-btn-xs { padding: 3px 9px; font-size: 11.5px; }
.sr-btn-sm:hover, .sr-btn-xs:hover { background: var(--bg-hover); }
.sr-btn-sm:disabled, .sr-btn-xs:disabled { opacity: 0.55; cursor: not-allowed; }
.sr-btn-sm:focus-visible, .sr-btn-xs:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent); outline-offset: 2px;
}
.sr-btn-primary {
  background: linear-gradient(118deg, oklch(44% 0.15 264), oklch(50% 0.18 288), oklch(46% 0.14 254));
  color: #fff; border-color: transparent;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.14), 0 1px 3px rgba(20,20,40,0.14);
}
.sr-btn-primary:hover {
  background: linear-gradient(118deg, oklch(48% 0.16 264), oklch(54% 0.19 288), oklch(50% 0.15 254));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.24), 0 4px 12px -5px rgba(97,87,255,0.50);
}
.sr-btn-ghost { background: transparent; border-color: transparent; color: var(--ink-3); }
.sr-btn-ghost:hover { background: var(--bg-hover); color: var(--ink); }
.sr-btn-danger {
  background: var(--bad-soft); border-color: var(--bad-line, color-mix(in oklab, var(--bad) 30%, transparent));
  color: var(--bad);
}
.sr-btn-danger:hover { background: var(--bad); border-color: var(--bad); color: #fff; }

/* List/grid view toggle (files panel) */
.sr-view-btn {
  width: 26px; height: 24px; border-radius: var(--radius-btn-icon); border: 1px solid transparent;
  background: none; color: var(--ink-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.sr-view-btn:hover { background: var(--bg-hover); color: var(--ink-2); }
.sr-view-btn.active { background: var(--indigo-soft); color: var(--indigo-ink); border-color: var(--indigo-line); }
.sr-view-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent); outline-offset: 1px;
}

/* ── Revision Diff modal — full-screen split view. This whole .sr-diff-* family
   had NO CSS (raw, unstyled stacked divs). Native tokens; side-by-side canvas
   panels. (boxes-layer overlay alignment is verified in-browser.) ── */
.sr-diff-overlay {
  position: fixed; inset: 0; z-index: 520; background: var(--bg-card);
  display: flex; flex-direction: column; animation: dvOverlayIn 0.18s ease both;
}
.sr-diff-header {
  flex-shrink: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 12px 18px; border-bottom: 1px solid var(--line); background: var(--bg-elev);
}
.sr-diff-title { font-size: 13px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.sr-diff-legend { display: flex; align-items: center; gap: 14px; }
.sr-diff-legend-item { font-size: 11px; font-weight: 600; white-space: nowrap; }
.sr-diff-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.sr-diff-panels { flex: 1 1 0; min-height: 0; display: flex; }
.sr-diff-panel {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  border-right: 1px solid var(--line);
}
.sr-diff-panel:last-child { border-right: none; }
.sr-diff-panel-label {
  flex-shrink: 0; padding: 8px 14px; font-size: 11px; color: var(--ink-4);
  background: var(--bg-sunk); border-bottom: 1px solid var(--line-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: var(--f-mono);
}
.sr-diff-canvas-wrap {
  flex: 1 1 0; min-height: 0; position: relative; overflow: auto;
  display: flex; align-items: flex-start; justify-content: center;
  background: var(--bg-sunk); padding: 16px;
}
.sr-diff-canvas { max-width: 100%; display: block; box-shadow: var(--shadow-md); }
.sr-diff-boxes-layer { position: absolute; inset: 16px; pointer-events: none; }
.sr-diff-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--radius-btn-icon);
  font-size: 9px; font-weight: 700; color: #fff;
}

/* Highlighter props — color swatches + opacity presets (were undefined). */
.sr-hl-colors { display: flex; align-items: center; gap: 3px; }
.sr-hl-color-btn {
  width: 18px; height: 18px; border-radius: var(--radius-btn-icon); cursor: pointer;
  border: 2px solid transparent; padding: 0;
}
.sr-hl-color-btn:hover { border-color: var(--ink-3); } /* SNAPS; no scale — founder 2026-08-20 */
.sr-hl-color-btn.active { border-color: var(--ink); }
.sr-hl-opacity-btn {
  height: 20px; min-width: 26px; padding: 0 6px; border-radius: var(--radius-btn-icon);
  border: 1px solid transparent; background: none; cursor: pointer;
  font-size: 10px; color: var(--ink-3); transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.sr-hl-opacity-btn:hover { background: var(--bg-hover); color: var(--ink); }
.sr-hl-opacity-btn.active { background: var(--indigo-soft); border-color: var(--indigo-line); color: var(--indigo-ink); }

/* Signature pad action row */
.sr-sigpad-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }

/* Form elements */
.sr-form-row { margin-bottom: 14px; }
.sr-form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 14px; }
.sr-form-label {
  display: block; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-4); margin-bottom: 5px;
}
.sr-form-input {
  width: 100%; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-btn-icon);
  background: var(--bg-elev); color: var(--ink); font-size: 12.5px; outline: none;
  transition: border-color 0.15s; font-family: var(--f-sans);
}
/* Focus ring snaps in (no transition) — a var()/color-mix()-valued box-shadow
   sticks at the from-value when transitioned in Chrome. */
.sr-form-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 3px var(--indigo-soft); }
.sr-form-select {
  width: 100%; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-elev); color: var(--ink); font-size: 12.5px; outline: none;
  transition: border-color 0.15s; cursor: pointer; appearance: none;
}
.sr-form-select:focus { border-color: var(--indigo); }
.sr-form-section-label {
  font-size: 11.5px; font-weight: 600; color: var(--ink-3);
  padding: 10px 0 6px; border-top: 1px solid var(--line-soft); margin-top: 6px;
  text-transform: uppercase; letter-spacing: 0.06em;
}

/* Attendee checkbox list */
.sr-attendee-check-list { display: flex; flex-direction: column; gap: 5px; }
.sr-attendee-check {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 7px;
  cursor: pointer; transition: background 0.1s;
}
.sr-attendee-check:hover { background: var(--bg-hover); }
.sr-attendee-check.checked { background: var(--indigo-soft); }
.sr-attendee-check input { accent-color: var(--indigo); }

/* Report */
.sr-report-header {
  text-align: center; padding: 24px 0 20px; border-bottom: 2px solid var(--line);
  margin-bottom: 20px;
}
.sr-report-title { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.sr-report-sub { font-size: 12px; color: var(--ink-4); margin-top: 4px; }
.sr-report-section { margin-bottom: 20px; }
.sr-report-section-title {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-4); border-bottom: 1px solid var(--line); padding-bottom: 5px; margin-bottom: 10px;
}
.sr-report-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.sr-report-table th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-5); padding: 5px 8px; border-bottom: 1px solid var(--line);
}
.sr-report-table td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); color: var(--ink-2); }
.sr-report-table tr:last-child td { border-bottom: none; }

/* Status colors */
.sr-status-open      { background: color-mix(in oklab, var(--bad) 12%, transparent);    color: var(--bad); }
.sr-status-inprog    { background: color-mix(in oklab, var(--warn) 14%, transparent);   color: var(--warn); }
.sr-status-resolved  { background: color-mix(in oklab, var(--ok) 12%, transparent);     color: var(--ok); }
.sr-status-closed    { background: color-mix(in oklab, var(--ink-4) 12%, transparent);  color: var(--ink-4); }
.sr-status-active    { background: color-mix(in oklab, var(--indigo) 12%, transparent); color: var(--indigo); }
.sr-status-draft     { background: color-mix(in oklab, var(--ink-4) 12%, transparent);  color: var(--ink-4); }
.sr-status-archived  { background: color-mix(in oklab, var(--ink-5) 10%, transparent);  color: var(--ink-5); }

.sr-priority-critical { color: var(--bad); }
.sr-priority-high     { color: var(--warn); }
.sr-priority-medium   { color: var(--indigo); }
.sr-priority-low      { color: var(--ink-4); }

/* Saved Tools (Review Tools) */
.sr-saved-tools { padding: 8px 6px; }
.sr-saved-tool-label {
  font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
  color: var(--ink-5); padding: 4px 2px; white-space: nowrap; overflow: hidden;
}
.sr-saved-tool-btn {
  width: 32px; height: 32px; border-radius: var(--radius-btn-icon); border: none; background: none;
  display: flex; align-items: center; justify-content: center;
  margin: 1px 0; cursor: pointer; transition: background 0.1s; position: relative;
}
.sr-saved-tool-btn:hover { background: var(--bg-hover); }

/* Color swatch */
.sr-color-swatch-wrap { padding: 4px 6px; }
.sr-color-grid { display: flex; flex-wrap: wrap; gap: 3px; }
.sr-color-dot {
  width: 20px; height: 20px; border-radius: 4px; cursor: pointer; border: 2px solid transparent;
}
.sr-color-dot:hover { border-color: var(--ink-3); } /* SNAPS; no scale — founder 2026-08-20 */
.sr-color-dot.active { border-color: var(--ink); }

/* Stamp picker */
.sr-stamp-picker {
  position: absolute; left: 40px; top: 0; z-index: 200;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-menu);
  box-shadow: var(--shadow-lg); padding: 4px; min-width: 180px;
}
.sr-stamp-option {
  display: block; width: 100%; text-align: left; padding: 6px 10px;
  border: none; background: none; cursor: pointer; font-size: 11.5px;
  color: var(--ink-2); border-radius: 5px; transition: background 0.1s;
}
.sr-stamp-option:hover { background: var(--indigo-soft); color: var(--indigo); }
.sr-stamp-option.active { background: var(--indigo-soft); color: var(--indigo); font-weight: 600; }


/* ── Finance action modals ─────────────────────────────────────────────────── */
.fin-toast {
  position: fixed; bottom: 24px; right: 24px; z-index: 9999;
  background: var(--bg-card); border: 1px solid var(--line); border-left: 4px solid var(--ok);
  border-radius: 8px; padding: 12px 16px;
  display: flex; align-items: center; gap: 10px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.14); max-width: 380px;
  animation: dvPanelIn 0.2s ease both;
}
.fin-export-group { display: flex; flex-direction: column; gap: 8px; }
.fin-export-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-4); margin-bottom: 2px; }
.fin-export-check { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); cursor: pointer; padding: 3px 0; }
.fin-export-check input { cursor: pointer; }
.fin-inv-totals { background: var(--bg-elev); border: 1px solid var(--line-soft); border-radius: 8px; padding: 12px 14px; }
.fin-inv-total-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--ink); padding: 3px 0; }
.fin-inv-preview { background: var(--bg-elev); border: 1px solid var(--line); border-radius: 8px; padding: 16px; font-size: 13px; }

/* ── Integration cards ─────────────────────────────────────────────────────── */
.integration-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 12px;
  background: var(--bg-card);
  transition: border-color 0.15s;
}
.integration-card:last-child { margin-bottom: 0; }
.integration-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 10px;
}
.integration-card-title { font-size: 14px; font-weight: 700; color: var(--ink); }
.integration-card-desc  { font-size: 12.5px; color: var(--ink-4); margin-top: 2px; }
.integration-card-connected { display: flex; flex-direction: column; gap: 4px; }
.integration-card-form { display: flex; flex-direction: column; gap: 0; }
.integration-card-hint {
  font-size: 11.5px;
  color: var(--ink-4);
  margin-top: 10px;
  line-height: 1.6;
}
.integration-code {
  background: var(--bg-elev);
  border: 1px solid var(--line-soft);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: monospace;
  font-size: 11px;
  color: var(--ink-2);
  word-break: break-all;
}

/* ── Office cards ──────────────────────────────────────────────────────────── */
.office-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 12px;
  background: var(--bg-card);
}
.office-card:last-of-type { margin-bottom: 0; }
.office-integ-badge {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--ok) 30%, transparent);
  border-radius: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--ink);
}

/* ── Transaction table (QB-style) ──────────────────────────────────────────── */
.txn-filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.txn-filter-select {
  height: 32px;
  padding: 0 28px 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-btn);
  background-color: var(--bg);
  color: var(--ink);
  font-size: 12.5px;
  cursor: pointer;
  outline: none;
  appearance: none; -webkit-appearance: none;
  /* Native Aecos select chevron (matches .ct-select). Data-URI SVGs can't read
     CSS custom props, so dark/mid override the whole background-image below. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2376787f'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
.txn-filter-select:hover { border-color: var(--ink-4); }
[data-theme="dark"] .txn-filter-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236f717b'/%3E%3C/svg%3E");
}

/* ─── AecosSelect — native-Aecos custom dropdown (replaces browser <select>) ──
   Trigger visually matches .txn-filter-select; the menu is a themed popover
   (position:fixed, so it escapes table/overflow clipping). Both light + dark
   ride CSS tokens (--bg, --bg-card, --line, the --ink ramp, --indigo).

   ⚠️ NEVER PUT A STAR IMMEDIATELY BEFORE A SLASH IN A CSS COMMENT. That is not
   a style note — until 2026-08-02 this line listed the ink ramp as "--ink" with
   a star, directly followed by the slash starting "--indigo". Those two
   characters TERMINATED THIS COMMENT EARLY. The remaining text became live
   CSS, so the parser swallowed it as the start of a selector prelude and ran
   on to the next `{` — which belonged to `.aecos-select`.
   The result: `.aecos-select` had ZERO parsed rules in the CSSOM (verified in
   Chrome against the production stylesheet: a real div with that class
   computed display:block / position:static / vertical-align:baseline instead
   of inline-block / relative / middle). Every AecosSelect in the app lost its
   container box, silently, with no error anywhere. `.aecos-select__btn` below
   survived, which is exactly what made it invisible in review.
   Guarded by scripts/test_css_classes.py — a stray comment terminator outside
   a comment now hard-fails. */
.aecos-select { display: inline-block; vertical-align: middle; position: relative; }
.aecos-select__btn {
  display: inline-flex; align-items: center; gap: 6px;
  width: 100%; height: 32px;
  padding: 0 8px 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-btn);
  background: var(--bg);
  color: var(--ink);
  font-family: inherit; font-size: 12.5px; line-height: 1;
  cursor: pointer; text-align: left;
  transition: border-color 90ms, box-shadow 90ms, background 90ms;
}
.aecos-select__btn--md { height: 36px; font-size: 13px; }
.aecos-select__btn:hover:not(:disabled) { border-color: var(--ink-4); }
.aecos-select__btn:focus-visible,
.aecos-select__btn.is-open {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 22%, transparent);
}
.aecos-select__btn:disabled { opacity: .55; cursor: not-allowed; }
.aecos-select__btn.is-placeholder .aecos-select__val { color: var(--ink-4); }
.aecos-select__val {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.aecos-select__chev { display: inline-flex; color: var(--ink-4); flex: 0 0 auto; }
.aecos-select__btn.is-open .aecos-select__chev { color: var(--indigo); transform: rotate(180deg); }

.aecos-select__menu {
  position: fixed;
  /* 9500, not 390: the menu PORTALS to <body> (ui.jsx), so its z-index competes
     with every fixed overlay — at 390 it opened BEHIND the member panel
     (.mp-panel, z 9001) and looked dead. A select menu is a transient popup the
     user just opened; it must beat any container it was opened from. Kept below
     toasts / veils at 9998-9999. */
  z-index: 9500;
  max-width: min(92vw, 360px);
  max-height: 320px; overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-menu);
  box-shadow: var(--shadow-lg, 0 12px 32px -10px rgba(20,20,30,.28));
  padding: 5px;
  opacity: 0; transform: scale(0.98) translateY(-2px);
  transform-origin: center top;
  transition: opacity 120ms var(--ease-out, ease-out), transform 120ms var(--ease-out, ease-out);
  pointer-events: none;
}
.aecos-select__menu--top { transform-origin: center bottom; }
.aecos-select__menu.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.aecos-select__group {
  padding: 8px 9px 3px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-4);
}
.aecos-select__opt {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 7px 9px;
  border: none; border-radius: var(--radius-btn-icon);
  background: transparent;
  color: var(--ink-2);
  font-family: inherit; font-size: 12.5px; font-weight: 400; line-height: 1.4;
  text-align: left; cursor: pointer;
  transition: background 90ms, color 90ms;
}
.aecos-select__opt:focus { outline: none; }
.aecos-select__opt:focus-visible,
.aecos-select__opt:hover:not(.is-disabled),
.aecos-select__opt[tabindex="0"]:focus {
  background: var(--bg-hover); color: var(--ink);
}
.aecos-select__opt.is-selected { color: var(--ink); font-weight: 600; }
.aecos-select__opt.is-disabled { opacity: .45; cursor: not-allowed; }
.aecos-select__opt-icon { display: inline-flex; color: var(--ink-4); flex: 0 0 auto; }
.aecos-select__opt-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aecos-select__opt-check { display: inline-flex; color: var(--indigo); flex: 0 0 auto; }
/* Option with a `hint`: label + small explanation stacked. The row switches to
   top-alignment so the tick and icon sit against the LABEL, not the middle of a
   two-line block. */
.aecos-select__opt:has(.aecos-select__opt-body) { align-items: flex-start; }
.aecos-select__opt-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.aecos-select__opt-body .aecos-select__opt-label { flex: none; }
.aecos-select__opt-hint {
  font-size: 11px; line-height: 1.35; font-weight: 400;
  color: var(--ink-4); white-space: normal;
}
.aecos-select__opt.is-selected .aecos-select__opt-hint { font-weight: 400; }
.aecos-select__opt--action {
  color: var(--indigo); font-weight: 500;
  margin-bottom: 3px; padding-bottom: 9px;
  border-bottom: 1px solid var(--line-soft, var(--line));
  border-radius: 5px 5px 0 0;
}
.aecos-select__opt--action .aecos-select__opt-label { overflow: visible; }

.txn-search-wrap {
  position: relative;
  flex: 1;
  min-width: 180px;
  max-width: 340px;
}
.txn-search-input {
  width: 100%;
  height: 32px;
  padding: 0 10px 0 30px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
  color: var(--ink);
  font-size: 12.5px;
  outline: none;
  box-sizing: border-box;
}
.txn-search-input:focus { border-color: var(--indigo); }
.txn-search-input::placeholder { color: var(--ink-4); }
.txn-page-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.txn-count-info {
  font-size: 12px;
  color: var(--ink-3);
  white-space: nowrap;
}
.txn-page-label {
  font-size: 12px;
  color: var(--ink-3);
  white-space: nowrap;
}
.txn-page-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: var(--radius-btn-icon);
  background: var(--bg);
  color: var(--ink-3);
  cursor: pointer;
  padding: 0;
}
.txn-page-btn:hover:not(:disabled) { border-color: var(--ink-4); color: var(--ink); }
.txn-page-btn:disabled { opacity: 0.35; cursor: default; }

/* Table layout */
.txn-tbl { table-layout: fixed; width: 100%; }
.txn-tbl thead th {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-4);
  text-transform: uppercase;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg);
  white-space: nowrap;
}
.txn-tbl tbody tr { border-bottom: 1px solid var(--line-soft); }
.txn-tbl tbody tr:last-child { border-bottom: none; }
.txn-tbl tbody td { padding: 11px 12px; vertical-align: middle; }
.txn-row:hover { background: var(--bg-2); }
.txn-row-sel { background: color-mix(in srgb, var(--indigo) 6%, transparent) !important; }
.txn-row-reconciled { opacity: 0.7; }

/* Column widths */
.txn-col-cb   { width: 40px; text-align: center; }
.txn-col-date { width: 110px; }
.txn-col-desc { min-width: 0; }
.txn-col-payee  { width: 130px; }
.txn-col-cat  { width: 200px; }
.txn-col-amt  { width: 110px; text-align: right; }
.txn-col-action { width: 80px; text-align: right; }
.txn-sortable { cursor: pointer; user-select: none; }
.txn-sortable:hover { color: var(--ink); }

/* Cell content */
.txn-desc-main { font-size: 13px; color: var(--ink); line-height: 1.3; }
.txn-desc-sub  { font-size: 11px; color: var(--ink-4); margin-top: 2px; }
.txn-payee-text { font-size: 12.5px; color: var(--ink-3); }

/* Category cell */
.txn-cat-link {
  font-size: 13px;
  color: var(--indigo);
  cursor: pointer;
  text-decoration: none;
}
.txn-cat-link:hover { text-decoration: underline; }
.txn-cat-empty {
  font-size: 12.5px;
  color: var(--ink-4);
  cursor: pointer;
  font-style: italic;
}
.txn-cat-empty:hover { color: var(--indigo); }
.txn-cat-match {
  font-size: 12px;
  color: var(--ok);
  font-weight: 500;
}
.txn-cat-select {
  font-size: 12px;
  padding: 3px 6px;
  height: 28px;
  border: 1px solid var(--indigo);
  border-radius: var(--radius-btn);
  background: var(--bg);
  color: var(--ink);
  outline: none;
  width: 100%;
}

/* Amount — green in, red out, and the +/− is IN the text so colour is never
   the only thing carrying the meaning. --ok/--bad both have light and dark
   definitions, so this holds in either theme. .txn-amt-flat is a transfer or a
   row whose direction cannot be decided: no colour claim is made about it. */
.txn-amount { font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; }
.txn-amt-in   { color: var(--ok); }
.txn-amt-out  { color: var(--bad); }
.txn-amt-flat { color: var(--ink); }

/* Selection bar (shift-click range select) */
.txn-sel-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--indigo) 5%, transparent);
  font-size: 12.5px;
}
.txn-sel-count { font-weight: 600; color: var(--ink); }
.txn-sel-hint  { color: var(--ink-4); }
@media (max-width: 720px) { .txn-sel-hint { display: none; } }

/* Action */
.txn-action-btn {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--indigo);
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 0;
}
.txn-action-btn:hover { text-decoration: underline; }
.txn-action-done {
  font-size: 12px;
  color: var(--ok);
  font-weight: 500;
}

/* ── Banking drill-down ─────────────────────────────────────────────────────── */
.acct-bank-card--clickable {
  cursor: pointer;
  transition: border-color 0.12s, box-shadow 0.12s, transform 0.1s;
}
.acct-bank-card--clickable:hover {
  border-color: var(--indigo-line);
  box-shadow: 0 2px 12px rgba(80,80,160,.08);
  transform: translateY(-1px);
}
.acct-bank-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}
.acct-bank-txn-count { font-size: 12px; color: var(--ink-4); }
.acct-bank-view-link {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--indigo);
}
.acct-bank-uncat-badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 99px;
  background: var(--warn-soft);
  color: var(--warn);
  border: 1px solid var(--warn-line);
  font-size: 11px;
  font-weight: 600;
}

/* Account detail view */
.acct-detail-breadcrumb {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 18px; font-size: 12.5px;
}
.acct-detail-back {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: 0; padding: 0;
  color: var(--ink-3); cursor: pointer; font-size: 12.5px;
  font-family: var(--f-sans);
}
.acct-detail-back:hover { color: var(--ink); }
.acct-detail-sep { color: var(--ink-5); }
.acct-detail-title { color: var(--ink); font-weight: 500; }
.acct-detail-header {
  display: flex; align-items: flex-start; gap: 20px;
  padding: 18px 22px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-bottom: 14px;
}
.acct-detail-info { flex: 1; min-width: 0; }
.acct-detail-name { font-size: 17px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.acct-detail-inst { font-size: 12.5px; color: var(--ink-4); margin-top: 3px; }
.acct-detail-synced { font-size: 11.5px; color: var(--ink-5); margin-top: 4px; }
.acct-detail-right { text-align: right; flex-shrink: 0; }
.acct-detail-balance { font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; }
.acct-detail-bal-label { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.acct-detail-actions {
  display: flex; flex-direction: column; gap: 6px;
  flex-shrink: 0; align-self: center;
}
.acct-detail-alerts {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.acct-detail-alert {
  display: inline-flex; align-items: center;
  padding: 6px 12px; border-radius: 8px;
  font-size: 12.5px; font-weight: 500;
}
.acct-detail-alert.warn {
  background: var(--warn-soft); color: var(--warn);
  border: 1px solid var(--warn-line);
}
.acct-detail-alert.muted {
  background: var(--bg-sunk); color: var(--ink-3);
  border: 1px solid var(--line);
}

/* ── Invoice table (QB-style) ─────────────────────────────────────────────── */
.inv-wrap {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}
.inv-filter-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.inv-batch-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 12px; height: 32px;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg); color: var(--ink-3);
  font: 12.5px var(--f-sans); cursor: pointer;
  transition: border-color 0.1s, color 0.1s;
}
.inv-batch-btn:not(:disabled):hover { border-color: var(--ink-4); color: var(--ink); }
.inv-batch-btn:disabled { opacity: 0.4; cursor: default; }
.inv-filter-group {
  display: flex; align-items: center; gap: 0;
  border: 1px solid var(--line); border-radius: 6px;
  overflow: hidden; height: 32px;
}
.inv-filter-label {
  padding: 0 10px; font-size: 12px; color: var(--ink-3);
  border-right: 1px solid var(--line); white-space: nowrap;
  display: flex; align-items: center;
  background: var(--bg-sunk);
}
.inv-filter-select {
  height: 100%; padding: 0 8px;
  border: none; background: var(--bg);
  color: var(--ink); font: 12.5px var(--f-sans);
  cursor: pointer; outline: none;
}
.inv-table-outer { overflow-x: auto; }
.inv-tbl { width: 100%; border-collapse: collapse; table-layout: fixed; min-width: 700px; }
.inv-tbl thead th {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-4); padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); white-space: nowrap;
  text-align: left;
}
.inv-tbl thead th.inv-col-amount,
.inv-tbl thead th.inv-col-action { text-align: right; }
.inv-tbl thead th.inv-col-cb { text-align: center; }
.inv-tbl tbody td { padding: 13px 14px; vertical-align: middle; border-bottom: 1px solid var(--line-soft); }
.inv-tbl tbody tr:last-child td { border-bottom: none; }
.inv-th-sortable { cursor: pointer; user-select: none; }
.inv-th-sortable:hover { color: var(--ink); }
.inv-sort-arrow { color: var(--ink-3); }

/* Column widths */
.inv-col-cb       { width: 40px; text-align: center; }
.inv-col-date     { width: 90px; }
.inv-col-num      { width: 90px; }
.inv-col-customer { min-width: 0; }
.inv-col-office   { width: 70px; }
.inv-col-amount   { width: 110px; text-align: right; }
.inv-col-status   { width: 160px; }
.inv-col-action   { width: 250px; text-align: right; }

.inv-row { transition: background 0.08s; }
.inv-row:hover { background: var(--bg-hover); }
.inv-row-sel { background: color-mix(in srgb, var(--indigo) 5%, transparent) !important; }

/* Cell text */
.inv-date-text   { font-size: 13px; color: var(--ink-3); }
.inv-num-text    { font-size: 13px; font-family: var(--f-mono); color: var(--ink-3); }
/* The invoice number opens the firm-branded preview. Inherits the cell's mono
   type so the column still reads as a column, not a row of links. */
.inv-num-link {
  background: none; border: 0; margin: 0; padding: 0;
  font: inherit; color: inherit; text-align: left;
  cursor: pointer; border-radius: var(--radius-btn);
}
.inv-num-link:hover { color: var(--indigo); text-decoration: underline; }
.inv-num-link:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.inv-amount-text { font-size: 13px; font-weight: 500; text-align: right; font-variant-numeric: tabular-nums; }
.inv-client-name { font-size: 13px; color: var(--ink); font-weight: 450; }
.inv-proj-name   { font-size: 11px; color: var(--ink-4); margin-top: 2px; }

/* Status cells — render the app's standard badge chips, clickable to cycle. */
.inv-status-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  text-align: left; display: inline-flex;
  border-radius: var(--radius-btn); transition: opacity 0.1s;
}
.inv-status-btn:hover { opacity: 0.78; }
.inv-status-col  { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.inv-status-sub  { font-size: 11px; color: var(--ink-4); padding-left: 2px; }

/* Action cell — all actions stay visible; they wrap right-aligned with even
   column/row gaps so a 2-line wrap in a narrow panel reads as intentional
   (no "|" separators, which orphaned at line ends when the row wrapped). */
.inv-action-cell {
  display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; column-gap: 12px; row-gap: 5px;
}
.inv-action-link {
  background: none; border: none; padding: 0;
  font: 12.5px var(--f-sans); color: var(--indigo);
  cursor: pointer; font-weight: 500; white-space: nowrap;
}
.inv-action-link:hover { text-decoration: underline; }
.inv-action-link--danger { color: var(--danger); }

/* Empty state */
.inv-empty {
  text-align: center; padding: 48px 24px;
  font-size: 13.5px; color: var(--ink-4);
}

/* Panel-mode invoice table (Project slide-over → Finances tab).
   .inv-tbl is table-layout:fixed and its fixed columns sum to ~710px
   (cb 40 + date 90 + num 90 + amount 110 + status 160 + action 220), so
   inside the 760px .pd-side-panel (~718px content) the flexible CUSTOMER
   column collapsed to ~0 — and since fixed-layout cell overflow is visible
   and .inv-client-name had no truncation, the client/project name painted
   straight across the Amount/Status cells (overlapping text). Compact the
   fixed columns + tighten horizontal cell padding so Customer keeps real
   width (~175px), clip + ellipsize the customer cell, and keep a min-width
   floor so anything even narrower scrolls inside .inv-table-outer
   (overflow-x:auto) instead of overlapping. Scoped to .pd-side-panel so
   the full-page table is byte-for-byte unchanged. */
.pd-side-panel .inv-tbl { min-width: 640px; }
.pd-side-panel .inv-tbl thead th,
.pd-side-panel .inv-tbl tbody td { padding-left: 10px; padding-right: 10px; }
.pd-side-panel .inv-col-cb       { width: 34px; }
.pd-side-panel .inv-col-date     { width: 74px; }
.pd-side-panel .inv-col-num      { width: 82px; }
.pd-side-panel .inv-col-office   { width: 60px; }
.pd-side-panel .inv-col-amount   { width: 96px; }
.pd-side-panel .inv-col-status   { width: 108px; }
.pd-side-panel .inv-col-action   { width: 148px; }
.pd-side-panel .inv-col-customer { overflow: hidden; }
.pd-side-panel .inv-client-name,
.pd-side-panel .inv-proj-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Pagination */
.inv-pagination {
  display: flex; align-items: center; justify-content: flex-end; gap: 6px;
  padding: 12px 16px;
  border-top: 1px solid var(--line-soft);
}
.inv-page-btn {
  padding: 4px 11px; height: 28px;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg); color: var(--ink-3);
  font: 12px var(--f-sans); cursor: pointer;
  transition: border-color 0.1s, color 0.1s;
}
.inv-page-btn:not(:disabled):hover { border-color: var(--ink-4); color: var(--ink); }
.inv-page-btn:disabled { opacity: 0.35; cursor: default; }
.inv-page-info { font-size: 12px; color: var(--ink-3); padding: 0 6px; }

/* ── Sales & Get Paid funnel ──────────────────────────────────────────────── */
.sgp-wrap {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 18px 20px 20px;
  margin-bottom: 14px;
}
.sgp-top {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.sgp-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink-3);
}
.sgp-cards {
  display: flex; align-items: stretch; gap: 0;
}
.sgp-card {
  flex: 1; border: 1px solid var(--line); border-radius: 8px;
  padding: 16px 18px; display: flex; flex-direction: column; gap: 6px;
  min-width: 0;
}
.sgp-card-stage {
  border-top: 3px solid var(--ok);
}
.sgp-card-cta {
  background: var(--bg-elev);
  text-align: left; cursor: pointer; font: inherit;
  transition: border-color 0.12s, background 0.12s, box-shadow 0.12s;
}
.sgp-card-cta:hover {
  border-color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 5%, var(--bg-elev));
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.sgp-card-cta:active { box-shadow: none; }
.sgp-arrow {
  display: flex; align-items: center; justify-content: center;
  padding: 0 10px; font-size: 22px; color: var(--ink-4); flex-shrink: 0;
}
.sgp-cta-title { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.sgp-cta-desc  { font-size: 12.5px; color: var(--ink-4); line-height: 1.4; }
.sgp-stage-name { font-size: 13px; color: var(--ink-3); }
.sgp-stage-amt  { font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.03em; line-height: 1.1; }
.sgp-count {
  display: flex; align-items: center; gap: 5px;
  font-size: 12.5px; color: var(--ink-3); margin-top: 2px;
}

/* ── Income over time ─────────────────────────────────────────────────────── */
.inc-wrap {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 18px 20px 16px;
  margin-bottom: 0;
}
.inc-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.inc-title {
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink-3);
}
.inc-source {
  display: inline-block; margin-left: 8px;
  font-size: 11px; color: var(--ink-5);
  text-transform: none; letter-spacing: 0;
  font-weight: 400;
}
.inc-controls { display: flex; align-items: center; gap: 8px; }
.inc-ctrl-label { font-size: 12.5px; color: var(--ink-3); }
.inc-summary { display: flex; align-items: baseline; gap: 8px; }
.inc-total  { font-size: 28px; font-weight: 700; color: var(--ink); letter-spacing: -0.03em; }
.inc-period { font-size: 13px; color: var(--ink-4); }

/* ─── Timesheets ─────────────────────────────────────────────────────────── */

/* Layout */
.ts-layout { display: flex; height: 100%; min-height: 0; }
.ts-sidebar {
  width: 200px; flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elev);
  display: flex; flex-direction: column;
  padding: 0;
  margin: 10px 0 10px 10px;
}

/* Master-chart "now" dot — gentle pulsing halo on the line at today. */
.mpc-now-halo {
  transform-box: fill-box;
  transform-origin: center;
  animation: mpcNowPulse 2.2s ease-in-out infinite;
}
@keyframes mpcNowPulse {
  0%   { transform: scale(1);   opacity: 0.5; }
  70%  { transform: scale(2.8); opacity: 0; }
  100% { transform: scale(2.8); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .mpc-now-halo { animation: none; opacity: 0.3; }
}
.ts-sidebar-head {
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-5); padding: 18px 16px 10px;
}
.ts-sidebar-nav { display: flex; flex-direction: column; gap: 1px; padding: 0 8px; }
.ts-sidebar-item {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border-radius: 7px; border: none;
  background: none; color: var(--ink-3); font-size: 13px; font-weight: 500;
  cursor: pointer; text-align: left; transition: background .12s, color .12s;
}
.ts-sidebar-item:hover { background: var(--bg-hover); color: var(--ink); }
.ts-sidebar-item.active { background: var(--indigo-soft); color: var(--indigo-ink); font-weight: 600; }
.ts-sidebar-timer {
  margin: 12px 10px; padding: 8px 10px;
  background: color-mix(in oklab, var(--bad) 10%, transparent);
  border-radius: 7px; display: flex; align-items: center; gap: 7px;
}
.ts-sidebar-timer-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--bad); animation: ts-pulse 1.2s ease-in-out infinite;
}
.ts-sidebar-timer-label { font-size: 11px; color: var(--bad); font-weight: 600; }
@keyframes ts-pulse { 0%,100%{opacity:1} 50%{opacity:.4} }
.ts-sidebar-hint {
  margin-top: auto; padding: 12px 14px 8px;
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--ink-5); border-top: 1px solid var(--line-soft);
}
/* Sidebar footer action buttons — previously unstyled (raw browser gray).
   Match the app's .btn design language with token colors. */
.ts-sidebar-quicklog,
.ts-sidebar-shortcuts {
  display: flex; align-items: center; gap: 7px;
  width: calc(100% - 20px); margin: 0 10px 6px; box-sizing: border-box;
  padding: 7px 11px; border-radius: 7px; text-align: left;
  font-family: var(--f-sans); font-size: 12.5px; font-weight: 500;
  cursor: pointer; transition: background .12s, border-color .12s, color .12s;
}
.ts-sidebar-quicklog {
  background: var(--bg-card); color: var(--ink); border: 1px solid var(--line-strong);
}
.ts-sidebar-quicklog:hover { background: var(--bg-hover); border-color: var(--ink-5); }
.ts-sidebar-shortcuts {
  background: transparent; color: var(--ink-4); border: 1px solid transparent;
}
.ts-sidebar-shortcuts:hover { background: var(--bg-hover); color: var(--ink-2); }
.ts-kbd {
  margin-left: auto; font-family: var(--f-mono); font-size: 10px; color: var(--ink-5);
  background: var(--bg-sunk); border: 1px solid var(--line-soft);
  border-radius: 4px; padding: 1px 5px; line-height: 1.5;
}
.ts-content { flex: 1; min-width: 0; overflow-y: auto; padding: 14px 28px 28px; display: flex; flex-direction: column; }
.ts-content--calendar { overflow: hidden; padding: 0; }
/* Single-column layout — the internal second sidebar was folded into the main
   nav's contextual rail, so .ts-content now spans the full width (flex:1 with no
   sibling). .ts-layout stays flex so .ts-content keeps filling the height too. */
.ts-layout--single { }
/* Slim action bar at the top of .ts-content — homes the Log time / Start timer
   controls + the synced-calendar toggle that used to live in the second sidebar.
   flex-shrink:0 so it pins above the (scrolling) section content. */
.ts-content-actions {
  flex-shrink: 0; display: flex; align-items: center; gap: 8px;
  padding: 4px 0 12px; margin-bottom: 4px;
}
.ts-content--calendar .ts-content-actions { padding: 8px 28px; margin: 0; border-bottom: 1px solid var(--line-soft); }
.ts-content-actions-spacer { flex: 1; }
.ts-content-actions-hint {
  display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-5);
}
.ts-calsync-drop-wrap { position: relative; }
.ts-calsync-drop-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40;
  min-width: 220px; max-height: 300px; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-menu);
  box-shadow: 0 8px 28px rgba(0,0,0,.18); padding: 6px;
}
.ts-calsync-drop-head {
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-5); padding: 4px 6px 6px;
}
.ts-calsync-drop-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 5px 6px; border-radius: 6px; border: none; background: none;
  cursor: pointer; text-align: left; color: var(--ink-2);
}
.ts-calsync-drop-row:hover { background: var(--bg-hover); }
.ts-calsync-drop-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ts-calsync-drop-name { flex: 1; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ts-calsync-drop-switch {
  position: relative; flex-shrink: 0; width: 26px; height: 15px; border-radius: 8px;
  transition: background .15s;
}
.ts-calsync-drop-knob {
  position: absolute; top: 2px; width: 11px; height: 11px; border-radius: 50%;
  background: #fff; transition: left .15s; box-shadow: 0 1px 2px rgba(0,0,0,.25);
}
/* Friday nudge banner: keep the same inset in every view so it doesn't jump when
   the calendar view drops .ts-content's padding to 0 (full-bleed grid). */
.ts-friday-nudge { flex-shrink: 0; margin-bottom: 10px; }
.ts-content--calendar .ts-friday-nudge { margin: 24px 28px 10px; }
/* Meetings page: pin the header + action tiles, scroll only the meeting list. */
.mtg-list-scroll { overflow-y: auto; min-height: 240px; max-height: calc(100vh - 320px); scrollbar-gutter: stable; }

/* Timer bar */
.ts-timer-bar {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-card); border: 1px solid var(--bad-line);
  border-radius: 10px; padding: 10px 16px; margin-bottom: 18px;
}
.ts-timer-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--bad); flex-shrink: 0; animation: ts-pulse 1.2s ease-in-out infinite;
}
.ts-timer-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.ts-timer-desc { font-size: 12px; color: var(--ink-4); }
.ts-timer-elapsed { font-size: 15px; font-weight: 700; font-family: var(--f-mono); color: var(--ink); margin-left: auto; }
.ts-timer-actions { display: flex; gap: 6px; }
.ts-timer-btn {
  padding: 4px 10px; border-radius: var(--radius-btn); border: 1px solid var(--line);
  background: var(--bg-card); color: var(--ink-3); font-size: 12px; cursor: pointer;
}
.ts-timer-btn--resume { color: var(--ok); border-color: var(--ok-line); }
.ts-timer-btn--stop { background: var(--bad); color: #fff; border-color: var(--bad); font-weight: 600; }

/* Landing */
.ts-landing-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px; margin-bottom: 20px;
}
.ts-landing-actions { display: flex; gap: 8px; flex-shrink: 0; }
.ts-ai-hint {
  font-size: 12px; color: var(--ink-5); margin-top: 6px;
  display: flex; align-items: center; gap: 4px;
}

/* Project grid */
.ts-project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.ts-proj-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; display: flex; flex-direction: column;
}
.ts-proj-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS */
.ts-proj-card--paused { opacity: .65; }
.ts-proj-card-accent { height: 4px; flex-shrink: 0; }
.ts-proj-card-body { padding: 16px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.ts-proj-card-top { display: flex; justify-content: space-between; align-items: flex-start; }
.ts-proj-card-name { font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.ts-proj-card-meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; font-size: 12px; color: var(--ink-4); flex-wrap: wrap; }
.ts-proj-card-archive { background: none; border: none; cursor: pointer; color: var(--ink-5); padding: 2px; }
.ts-proj-card-stats { display: flex; gap: 16px; }
.ts-stat { }
.ts-stat-val { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; font-family: var(--f-mono); }
.ts-stat-val--ok { color: var(--ok); }
.ts-stat-val--muted { color: var(--ink-4); }
.ts-stat-lbl { font-size: 10px; color: var(--ink-5); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 1px; }
.ts-proj-card-foot { display: flex; align-items: center; justify-content: space-between; padding-top: 8px; border-top: 1px solid var(--line-soft); }
.ts-proj-card-last { font-size: 11px; color: var(--ink-5); }

/* Empty state */
.ts-empty { text-align: center; padding: 60px 20px; grid-column: 1/-1; }
.ts-empty-title { font-size: 16px; font-weight: 600; color: var(--ink-2); margin-bottom: 6px; }
.ts-empty-sub { font-size: 13px; color: var(--ink-4); max-width: 360px; margin: 0 auto; }

/* Badges */
.ts-badge {
  display: inline-block; font-size: 10px; font-weight: 600;
  padding: 2px 6px; border-radius: 4px; letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ts-badge--ok { background: var(--ok-soft); color: var(--ok); }
.ts-badge--warn { background: var(--warn-soft); color: var(--warn); }
.ts-badge--muted { background: var(--bg-sunk); color: var(--ink-4); }
.ts-badge--neutral { background: var(--bg-sunk); color: var(--ink-3); }

/* Modals */
.ts-modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.35); backdrop-filter: blur(4px);
}
/* The Send-feedback modal must sit above EVERYTHING (other modals, toasts,
   meeting/annotation layers). Portaled to <body> in shell.jsx so no ancestor
   stacking context can trap it; this z-index beats the app's max (100000). */
.feedback-modal-overlay { z-index: 2147483000; }
.ts-modal {
  position: relative; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; max-height: 90vh; overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0,0,0,.2);
}
.ts-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 20px 24px 16px; border-bottom: 1px solid var(--line-soft);
}
.ts-modal-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.ts-modal-sub { font-size: 12px; color: var(--ink-4); margin-top: 3px; }
.ts-modal-close {
  background: none; border: none; cursor: pointer; color: var(--ink-4);
  padding: 2px; flex-shrink: 0;
}
.ts-modal-close:hover { background: var(--bg-hover); color: var(--ink); border-radius: 5px; }
.ts-modal-body { padding: 18px 24px; display: flex; flex-direction: column; gap: 12px; }
.ts-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 24px 20px; border-top: 1px solid var(--line-soft);
}

/* Form fields */
.ts-error { background: #fef2f2; color: #b91c1c; border-radius: 6px; padding: 7px 10px; font-size: 12.5px; margin-bottom: 4px; }
.ts-checkbox-label { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink); cursor: pointer; padding-top: 18px; white-space: nowrap; }
.ts-checkbox-label input[type=checkbox] { width: 15px; height: 15px; cursor: pointer; accent-color: var(--indigo); }
.ts-checkbox-label input[type=checkbox]:disabled { cursor: not-allowed; opacity: 0.5; }
.ts-field { display: flex; flex-direction: column; gap: 5px; flex: 1; }
.ts-field--toggle { }
.ts-field-row { display: flex; gap: 12px; align-items: flex-end; }
.ts-label { font-size: 11.5px; font-weight: 600; color: var(--ink-4); letter-spacing: 0.04em; text-transform: uppercase; }
.ts-input {
  border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px;
  background: var(--bg-elev); color: var(--ink); font: inherit; font-size: 13px;
  outline: none; transition: border-color .12s;
}
.ts-input:focus { border-color: var(--indigo); }
/* Compact variants — referenced by the paste-week + export modals
   (ts-input--sm / ts-select--sm) but previously undefined, so those rows
   rendered at full control height and overflowed their grid rows. */
.ts-input--sm, .ts-select--sm { padding: 5px 8px; font-size: 12px; border-radius: 6px; }
.ts-select--sm { padding-right: 24px; background-position: right 8px center; }
.ts-paste-textarea {
  display: block; width: 100%; box-sizing: border-box;
  min-height: 140px; resize: vertical; line-height: 1.5;
}
.ts-select {
  border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 8px 10px;
  background: var(--bg-elev); color: var(--ink); font: inherit; font-size: 13px;
  outline: none; cursor: pointer; appearance: none;
  /* Chevron stroke matches --ink-4's light value — data-URI SVGs can't
     consume CSS custom properties, so dark/mid override the image below. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpolyline points='1 1 5 5 9 1' fill='none' stroke='%2376787f' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
  padding-right: 28px;
}
[data-theme="dark"] .ts-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpolyline points='1 1 5 5 9 1' fill='none' stroke='%236f717b' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
}
.ts-select:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.ts-textarea {
  border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px;
  background: var(--bg-elev); color: var(--ink); font: inherit; font-size: 13px;
  resize: vertical; outline: none;
}
.ts-textarea:focus { border-color: var(--indigo); }

/* ── New Event (Outlook-style) composer ──────────────────────────────────── */
.ts-evt-modal .ts-modal-body { max-height: min(72vh, 640px); overflow-y: auto; }
.ts-evt-allday { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); cursor: pointer; user-select: none; }
/* Delete control in the event action popover */
.ts-evt-delete-btn { color: var(--bad); display: inline-flex; align-items: center; gap: 6px; justify-content: center; }
.ts-evt-delete-btn:hover { background: color-mix(in srgb, var(--bad) 10%, transparent); border-color: var(--bad-line, var(--bad)); }
.ts-evt-row { display: flex; gap: 10px; }
.ts-evt-row > .ts-input { flex: 1; min-width: 0; }
.ts-evt-row > .ts-input[type="time"] { flex: 0 0 130px; }
.ts-evt-chips {
  display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
  border: 1px solid var(--line); border-radius: 7px; background: var(--bg-elev);
  padding: 5px 6px; min-height: 38px; cursor: text;
}
.ts-evt-chips:focus-within { border-color: var(--indigo); }
.ts-evt-chip {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  font-size: 12px; line-height: 1.4; padding: 2px 4px 2px 9px; border-radius: 12px;
  background: color-mix(in srgb, var(--indigo) 12%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--indigo) 25%, var(--line));
  color: var(--indigo); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ts-evt-chip-x {
  border: none; background: none; color: inherit; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0 2px; opacity: 0.65;
}
.ts-evt-chip-x:hover { opacity: 1; }
.ts-evt-chip-input {
  flex: 1; min-width: 140px; border: none; outline: none; background: none;
  color: var(--ink); font: inherit; font-size: 13px; padding: 3px 2px;
}

/* ── Video Meetings (Phase 1) — New Meeting composer + list ───────────────── */
.ts-meet-warn {
  font-size: 12px; color: var(--warn); padding: 7px 11px; border-radius: 7px;
  background: color-mix(in srgb, var(--warn) 9%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--warn) 28%, var(--line));
}

/* Grouped "when" card — date/start + duration picker + collapsible fine-tune */
.ts-meet-when {
  display: flex; flex-direction: column; gap: 12px;
  padding: 13px 14px; border-radius: 10px;
  background: var(--bg-sunk); border: 1px solid var(--line-soft);
}
.ts-field--time { flex: 0 0 132px; }
.ts-dur-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ts-dur-chip {
  font: inherit; font-size: 12px; font-weight: 500; line-height: 1;
  padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg-elev); color: var(--ink-3); cursor: pointer;
  transition: background .1s, border-color .1s, color .1s;
}
.ts-dur-chip:hover { border-color: var(--indigo); color: var(--ink); }
.ts-dur-chip.active {
  background: var(--indigo); border-color: var(--indigo); color: #fff;
}
.ts-dur-ends { font-size: 12px; color: var(--ink-4); margin-left: 2px; }
.ts-meet-adv { border-top: 1px solid var(--line-soft); padding-top: 4px; }
.ts-meet-adv-sum {
  font-size: 12px; font-weight: 500; color: var(--ink-4); cursor: pointer;
  list-style: none; padding: 2px 0; user-select: none; display: inline-flex;
  align-items: center; gap: 5px;
}
.ts-meet-adv-sum::-webkit-details-marker { display: none; }
.ts-meet-adv-sum::before {
  content: "›"; display: inline-block; font-size: 15px; line-height: 1;
  transition: transform .12s; color: var(--ink-4);
}
.ts-meet-adv[open] .ts-meet-adv-sum::before { transform: rotate(90deg); }
.ts-meet-adv-sum:hover { color: var(--ink-2); }
.ts-meet-adv-body { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.ts-meet-loc-toggle { max-width: 260px; }
.ts-meet-loc-toggle .ts-toggle-opt {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}

/* ── Aecos-native date & time pickers (meeting scheduler) ─────────────────────
   Replace raw <input type=date/time> — which show white browser chrome +
   unbranded popups in dark mode — with token-styled triggers + portalled,
   position:fixed popovers (escape the modal body's overflow:auto, z above the
   overlay at 300). */
.ts-picker { position: relative; width: 100%; }
.ts-picker-trigger {
  display: flex; align-items: center; gap: 8px; width: 100%;
  border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 8px 10px;
  background: var(--bg-elev); color: var(--ink); font: inherit; font-size: 13px;
  cursor: pointer; text-align: left; transition: border-color .12s, box-shadow .12s;
}
.ts-picker-trigger:hover { border-color: var(--ink-4); }
.ts-picker-trigger.open, .ts-picker-trigger:focus-visible {
  border-color: var(--indigo); outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 22%, transparent);
}
.ts-picker-trigger > svg:first-child { color: var(--ink-4); flex-shrink: 0; }
.ts-picker-val { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-picker-trigger > svg:last-child { color: var(--ink-4); flex-shrink: 0; margin-left: auto; }

.ts-picker-pop {
  /* Portaled to <body>; z-index 9500 matches the AecosSelect menu so it clears
     high-z modals (.mp-panel 9001, .sr-modal-overlay 500) if ever reused inside
     one — same class of bug the AecosSelect fix closed (2026-07-23 polish audit). */
  position: fixed; z-index: 9500;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 34px rgba(0,0,0,0.22); padding: 10px;
}
/* Date picker — month grid */
.ts-datepick-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.ts-datepick-my { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.ts-datepick-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 6px; border: 1px solid transparent;
  background: none; color: var(--ink-3); cursor: pointer; transition: background .1s, color .1s;
}
.ts-datepick-nav:hover { background: var(--bg-hover); color: var(--ink); }
.ts-datepick-dow { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 4px; }
.ts-datepick-dow span { text-align: center; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; color: var(--ink-4); text-transform: uppercase; }
.ts-datepick-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.ts-datepick-cell {
  aspect-ratio: 1; display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-size: 12.5px; border: 1px solid transparent; border-radius: 7px;
  background: none; color: var(--ink-2); cursor: pointer; transition: background .1s, color .1s;
}
.ts-datepick-cell.empty { cursor: default; }
.ts-datepick-cell:not(.empty):not(:disabled):hover { background: var(--bg-hover); color: var(--ink); }
.ts-datepick-cell.today:not(.sel) { border-color: color-mix(in srgb, var(--indigo) 45%, var(--line)); color: var(--indigo); font-weight: 600; }
.ts-datepick-cell.sel { background: var(--indigo); color: #fff; font-weight: 600; }
.ts-datepick-cell:disabled { color: var(--ink-4); opacity: 0.4; cursor: not-allowed; }
.ts-datepick-foot { margin-top: 8px; display: flex; justify-content: flex-end; border-top: 1px solid var(--line-soft); padding-top: 8px; }
.ts-datepick-today {
  font: inherit; font-size: 12px; font-weight: 500; color: var(--indigo);
  background: none; border: none; cursor: pointer; padding: 2px 4px; border-radius: 5px;
}
.ts-datepick-today:hover { text-decoration: underline; }
/* Time picker — 15-min list */
.ts-timepick-pop { padding: 5px; }
.ts-timepick-list { max-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: 1px; }
.ts-timepick-opt {
  font: inherit; font-size: 12.5px; text-align: left; padding: 7px 10px; border-radius: 6px;
  border: none; background: none; color: var(--ink-2); cursor: pointer; white-space: nowrap;
}
.ts-timepick-opt:hover { background: var(--bg-hover); color: var(--ink); }
.ts-timepick-opt.sel { background: color-mix(in srgb, var(--indigo) 14%, transparent); color: var(--indigo); font-weight: 600; }
.ts-meet-members {
  margin-top: 6px; max-height: 168px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: 7px; background: var(--bg-elev);
}
.ts-meet-member {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px; cursor: pointer;
  border-bottom: 1px solid var(--line-soft); font-size: 12.5px;
}
.ts-meet-member:last-child { border-bottom: none; }
.ts-meet-member:hover { background: var(--bg-card); }
.ts-meet-member-name { color: var(--ink-2); font-weight: 500; }
.ts-meet-member-email { color: var(--ink-5); font-size: 11.5px; margin-left: auto; }

/* Invitee picker — member typeahead + member/email chips */
.ts-meet-att-field { position: relative; }
.ts-att-avatar {
  width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--indigo) 18%, var(--bg-card));
}
.ts-att-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ts-att-avatar-i { font-size: 8.5px; font-weight: 700; color: var(--indigo); letter-spacing: 0.02em; }
.ts-evt-chip--member { padding-left: 3px; }
.ts-evt-chip--member .ts-att-avatar { width: 17px; height: 17px; }
.ts-evt-chip--email {
  background: var(--bg-sunk);
  border-color: var(--line); color: var(--ink-2);
}
.ts-evt-chip--email > svg { color: var(--ink-4); }
.ts-meet-typeahead {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 8px 26px rgba(0,0,0,0.16); padding: 4px; max-height: 240px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 1px;
}
.ts-meet-sugg {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 7px 8px; border: none; background: none; cursor: pointer; border-radius: 7px;
}
.ts-meet-sugg:hover, .ts-meet-sugg--active { background: var(--bg-elev); }
.ts-meet-sugg > svg { color: var(--ink-4); flex-shrink: 0; }
.ts-meet-sugg-text { display: flex; flex-direction: column; min-width: 0; }
.ts-meet-sugg-name { font-size: 12.5px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-meet-sugg-email { font-size: 11px; color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-meet-sugg--add .ts-meet-sugg-name { color: var(--indigo); }
.ts-meet-addcontact-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px;
}
.ts-meet-addcontact-hint { font-size: 11px; color: var(--ink-4); }
.ts-meet-addcontact-btn {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; font-weight: 600; color: var(--indigo);
  padding: 3px 9px; border-radius: var(--radius-btn); cursor: pointer;
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 28%, var(--line));
}
.ts-meet-addcontact-btn:hover { background: color-mix(in srgb, var(--indigo) 18%, transparent); }
.ts-meet-addcontact-btn:disabled { opacity: 0.55; cursor: default; }
.ts-meet-addcontact-btn > svg { flex-shrink: 0; }
.ts-meet-group-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-4); margin-bottom: 6px;
}
.ts-meet-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 2px;
  border-bottom: 1px solid var(--line-soft);
}
.ts-meet-row-main { flex: 1; min-width: 0; }
.ts-meet-row-title { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.ts-meet-row-meta { font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.ts-meet-rsvp { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.ts-meet-rsvp-chip {
  font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 9px; white-space: nowrap;
}
.ts-meet-rsvp-chip--yes     { background: color-mix(in srgb, var(--ok) 14%, var(--bg-card)); color: var(--ok); }
.ts-meet-rsvp-chip--maybe   { background: color-mix(in srgb, var(--warn) 14%, var(--bg-card)); color: var(--warn); }
.ts-meet-rsvp-chip--no      { background: color-mix(in srgb, var(--bad) 14%, var(--bg-card)); color: var(--bad); }
.ts-meet-rsvp-chip--pending { background: var(--bg-sunk); color: var(--ink-4); }
.ts-meet-row-actions { display: flex; gap: 4px; flex-shrink: 0; }
.ts-toggle-row { display: flex; }
.ts-toggle-opt {
  flex: 1; padding: 6px 10px; font: inherit; font-size: 12px; font-weight: 500;
  border: 1px solid var(--line); background: var(--bg-elev); color: var(--ink-3);
  cursor: pointer; transition: background .1s, color .1s;
}
.ts-toggle-opt:first-child { border-radius: var(--radius-btn) 0 0 var(--radius-btn); }
.ts-toggle-opt:last-child { border-radius: 0 var(--radius-btn) var(--radius-btn) 0; margin-left: -1px; }
.ts-toggle-opt:hover:not(.active) { border-color: var(--ink-4); color: var(--ink); }
/* Active segment = on-brand indigo fill (theme-tokened), not near-white --ink,
   so the segmented control reads correctly in dark + mid themes. Matches the
   duration-chip active treatment just above it in the meeting composer. */
.ts-toggle-opt.active { background: var(--indigo); color: #fff; border-color: var(--indigo); z-index: 1; }
.ts-err { font-size: 12px; color: var(--bad); padding: 6px 10px; background: var(--bad-soft); border-radius: 6px; }

/* Project search dropdown */
.ts-project-dropdown {
  position: absolute; z-index: 10; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); box-shadow: 0 8px 24px rgba(0,0,0,.12); overflow: hidden;
  margin-top: 4px; min-width: 100%;
}
.ts-project-dropdown-empty { padding: 14px 16px; font-size: 13px; color: var(--ink-4); }
.ts-project-option { padding: 10px 14px; cursor: pointer; transition: background .1s; }
.ts-project-option:hover { background: var(--bg-hover); }
.ts-project-option-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.ts-project-option-meta { display: flex; gap: 8px; align-items: center; margin-top: 2px; font-size: 11px; color: var(--ink-4); }
.ts-project-selected {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ink-3); padding: 6px 4px;
}
.ts-field { position: relative; }

/* Detail view */
.ts-detail-head { margin-bottom: 20px; }
.ts-detail-empty { padding: 40px; text-align: center; color: var(--ink-4); font-size: 14px; }
.ts-back-btn {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ink-4); background: none; border: none;
  cursor: pointer; padding: 0; margin-bottom: 14px;
}
.ts-back-btn:hover { color: var(--ink); }
.ts-detail-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.ts-detail-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-4); margin-top: 4px; flex-wrap: wrap; }
.ts-summary-row { display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.ts-summary-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 16px; min-width: 100px;
}
.ts-summary-val { font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; font-family: var(--f-mono); }
.ts-summary-val--ok { color: var(--ok); }
.ts-summary-val--muted { color: var(--ink-4); }
.ts-summary-val--warn { color: var(--warn); }
.ts-summary-lbl { font-size: 10px; color: var(--ink-5); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 2px; }

/* Filter bar */
.ts-filter-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ts-filter-date { width: 130px; font-size: 12px; padding: 6px 8px; }
.ts-filter-select { min-width: 130px; font-size: 12px; padding: 6px 8px; padding-right: 24px; }
.ts-filter-search { min-width: 180px; font-size: 12px; padding: 6px 8px; }
.ts-show-empty { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-4); cursor: pointer; }

/* Daily log */
.ts-log-wrap { display: flex; flex-direction: column; gap: 0; }
.ts-log-empty { padding: 40px 0; text-align: center; font-size: 13px; color: var(--ink-4); }
.ts-day-group { margin-bottom: 8px; }
.ts-day-header {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; background: var(--bg-elev);
  border: 1px solid var(--line-soft); border-radius: 8px 8px 0 0;
  font-size: 12px;
}
.ts-day-label { font-weight: 700; color: var(--ink-3); width: 30px; }
.ts-day-date { color: var(--ink-4); flex: 1; }
.ts-day-total { font-weight: 600; font-family: var(--f-mono); font-size: 13px; color: var(--ink); }
.ts-day-add {
  background: none; border: 1px dashed var(--line); border-radius: 5px;
  color: var(--ink-5); font-size: 11px; padding: 2px 8px; cursor: pointer;
}
.ts-day-add:hover { border-color: var(--indigo); color: var(--indigo); }
.ts-entry-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; background: var(--bg-card);
  border: 1px solid var(--line-soft); border-top: none;
  font-size: 13px; transition: background .1s;
}
.ts-entry-row:last-child { border-radius: 0 0 8px 8px; }
.ts-entry-row--hover { background: var(--bg-hover); }
.ts-entry-row--empty { padding: 8px 12px; border-radius: 0 0 8px 8px; }
.ts-entry-hours { font-weight: 700; font-family: var(--f-mono); color: var(--ink); min-width: 40px; font-size: 13px; }
.ts-entry-desc { flex: 1; color: var(--ink-2); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-entry-cat { color: var(--ink-4); font-size: 11px; min-width: 140px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-entry-bill { min-width: 60px; }
.ts-entry-status { min-width: 100px; font-size: 11px; }
.ts-entry-amt { font-family: var(--f-mono); font-size: 12px; color: var(--ok); min-width: 70px; text-align: right; }
.ts-entry-actions { display: flex; gap: 6px; opacity: 0; transition: opacity .1s; }
/* ⚠️ `.ts-entry-row--hover` IS APPLIED BY NO FILE — grep every .jsx and .html.
   So this was the only rule that could raise .ts-entry-actions off opacity:0,
   and it never matched: Copy, Tmpl. and Delete have been INVISIBLE on every
   timesheet entry row. Kept (harmless, and something may add the class one day)
   but the real interaction is a plain :hover, plus :focus-within so the buttons
   are reachable from the keyboard. */
.ts-entry-row--hover .ts-entry-actions,
.ts-entry-row:hover .ts-entry-actions,
.ts-entry-row:focus-within .ts-entry-actions { opacity: 1; }
.ts-entry-row--hover { background: var(--bg-hover); }
/* :not(.ts-entry-new) — the blank add-row is a form, not a clickable record,
   and a hover highlight on it reads as "click me to open something". */
.ts-entry-row:hover:not(.ts-entry-new) { background: var(--bg-hover); }
/* The other three row states were rendered by TSEntryRow with no rule either —
   a selected row looked unselected, a drop target gave no feedback, and a
   locked row was indistinguishable from an editable one. */
.ts-entry-row--selected {
  background: color-mix(in srgb, var(--indigo) 8%, var(--bg-card));
  border-color: color-mix(in srgb, var(--indigo) 30%, var(--line-soft));
}
.ts-entry-row--drag-over { box-shadow: inset 0 2px 0 0 var(--indigo); }
.ts-entry-row--locked { color: var(--ink-4); }
.ts-entry-row--locked .ts-entry-hours { color: var(--ink-3); }
.ts-entry-row--editing { background: var(--bg-elev); }
.ts-entry-del { color: var(--bad) !important; }

/* Billable / non-billable pill on an entry row.
   ⚠️ This class has been rendered by TSEntryRow for months with NO CSS RULE AT
   ALL — a naked <button>, browser-default chrome, in the middle of a styled
   row. Exactly the silent-failure shape scripts/test_css_classes.py exists to
   catch. Defined here now, and reused by the inline new-entry row. */
.ts-bill-toggle {
  flex-shrink: 0; min-width: 68px;
  padding: 2px 8px; border-radius: var(--radius-btn);
  border: 1px solid var(--line); background: var(--bg-sunk);
  color: var(--ink-4); font-size: 11px; font-weight: 600;
  cursor: pointer; line-height: 1.6; white-space: nowrap;
}
.ts-bill-toggle:hover:not(:disabled) { border-color: var(--ink-4); color: var(--ink-2); }
.ts-bill-toggle:disabled { opacity: .55; cursor: not-allowed; }
.ts-bill-toggle--on {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 40%, var(--line));
  background: color-mix(in srgb, var(--ok) 10%, var(--bg-card));
}

/* ── Flat project log (TSDetailView) ──────────────────────────────────────────
   The project log used to be day-grouped under a date range. It is now one flat
   list, newest first, with a permanent blank row on top. .ts-entry-row carries
   `border-top: none` because it was designed to stack under a .ts-day-header —
   with the header gone, the first row has to grow its own top edge. */
.ts-log-flat { display: flex; flex-direction: column; margin-bottom: 8px; }
.ts-log-flat > *:first-child { border-top: 1px solid var(--line-soft); border-radius: 8px 8px 0 0; }
.ts-log-flat > *:last-child  { border-radius: 0 0 8px 8px; }
.ts-log-flat-empty {
  padding: 22px 14px; text-align: center;
  font-size: 12.5px; color: var(--ink-4); line-height: 1.5;
  background: var(--bg-card); border: 1px solid var(--line-soft); border-top: none;
}
/* The cap is STATED, never silent — a truncated list that says nothing is how
   the Activity timeline lost events. */
.ts-log-more {
  padding: 9px 12px; text-align: center;
  background: var(--bg-elev); border: 1px solid var(--line-soft); border-top: none;
  color: var(--ink-3); font-size: 12px; font-weight: 600; cursor: pointer;
}
.ts-log-more:hover { color: var(--indigo); }
/* Each row states its own date now that no day header does. */
.ts-entry-date {
  flex-shrink: 0; min-width: 92px;
  font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-4);
  white-space: nowrap;
}

/* ── The blank "add an entry" row that sits on top of the flat log ─────────── */
.ts-entry-new { background: var(--bg-elev); gap: 8px; padding: 7px 12px; }
.ts-entry-new-plus { display: inline-flex; align-items: center; color: var(--ink-5); flex-shrink: 0; }
.ts-entry-new-date  { width: 138px; flex-shrink: 0; }
.ts-entry-new-hours { width: 68px; flex-shrink: 0; text-align: right; font-family: var(--f-mono); }
.ts-entry-new-desc  { flex: 1; min-width: 0; }
.ts-entry-new-cat   { min-width: 130px; flex-shrink: 0; }
.ts-entry-new-add   { flex-shrink: 0; }
.ts-entry-new-err   { font-size: 11px; color: var(--bad); white-space: nowrap; }

/* Calendar */
.ts-cal-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; padding: 8px 20px 10px; }
/* Compact the always-on timer bar inside the calendar so it doesn't crowd the
   grid — the planner needs the vertical room more than the recorder does. */
.ts-cal-wrap > .ts-timer-bar { padding: 5px 12px; margin-bottom: 8px; }
.ts-cal-toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-shrink: 0; }
.ts-cal-toolbar-search { flex-shrink: 0; min-width: 150px; max-width: 220px; }
/* Synced-calendars quick toggle (right side of the calendar toolbar) */
.ts-cal-synced-toggle {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  height: 32px; padding: 0 10px; border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--ink-4); font-size: 12.5px; font-weight: 600;
  cursor: pointer; transition: color 0.12s, border-color 0.12s, background 0.12s; white-space: nowrap;
}
.ts-cal-synced-toggle:hover { border-color: var(--ink-4); }
.ts-cal-synced-toggle.on { color: var(--indigo); border-color: color-mix(in srgb, var(--indigo) 45%, var(--line)); }
.ts-cal-synced-toggle-label { line-height: 1; }
.ts-cal-synced-switch {
  position: relative; width: 30px; height: 16px; border-radius: 999px; flex-shrink: 0;
  background: var(--bg-sunk); border: 1px solid var(--line); transition: background 0.14s, border-color 0.14s;
}
.ts-cal-synced-toggle.on .ts-cal-synced-switch { background: var(--indigo); border-color: var(--indigo); }
.ts-cal-synced-knob {
  position: absolute; top: 1px; left: 1px; width: 12px; height: 12px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.25); transition: transform 0.14s;
}
.ts-cal-synced-toggle.on .ts-cal-synced-knob { transform: translateX(14px); }
/* ── Multi-calendar legend + Overlay/Split layout toggle (Outlook-style) ───── */
.ts-cal-legend-wrap { position: relative; flex-shrink: 0; }
.ts-cal-legend-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 30;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.14);
  width: 280px; padding: 8px; display: flex; flex-direction: column; gap: 2px;
}
.ts-cal-legend-section {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-5); padding: 6px 6px 3px; user-select: none;
}
.ts-cal-legend-row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 4px 6px; border-radius: 5px;
}
.ts-cal-legend-row:hover { background: var(--bg-elev); }
.ts-cal-legend-toggle {
  display: flex; align-items: center; gap: 8px; cursor: pointer; min-width: 0; flex: 1;
  font-size: 12.5px; color: var(--ink-2);
}
.ts-cal-legend-toggle input { accent-color: var(--indigo); flex-shrink: 0; }
.ts-cal-legend-dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.ts-cal-legend-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ts-cal-legend-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.ts-cal-legend-remove {
  border: none; background: none; cursor: pointer; color: var(--ink-5);
  font-size: 12px; line-height: 1; padding: 2px 4px; border-radius: 4px;
}
.ts-cal-legend-remove:hover { color: var(--bad); background: var(--bg-sunk); }
.ts-cal-legend-sep { height: 1px; background: var(--line-soft); margin: 5px 4px; }
.ts-cal-legend-empty { font-size: 12px; color: var(--ink-4); padding: 4px 6px; }
.ts-cal-legend-pool { display: flex; flex-direction: column; gap: 1px; }
.ts-cal-legend-add {
  display: flex; align-items: center; gap: 6px; width: 100%; text-align: left;
  padding: 5px 7px; border: none; background: none; border-radius: 5px; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--ink-2);
}
.ts-cal-legend-add:hover { background: var(--bg-elev); color: var(--ink); }
.ts-cal-legend-note { font-size: 11px; color: var(--ink-5); padding: 7px 6px 2px; line-height: 1.4; }
.ts-cal-layout-toggle {
  display: inline-flex; flex-shrink: 0; border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; height: 32px;
}
.ts-cal-layout-btn {
  border: none; background: var(--bg-card); color: var(--ink-4);
  font: inherit; font-size: 12px; font-weight: 600; padding: 0 11px; cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.ts-cal-layout-btn + .ts-cal-layout-btn { border-left: 1px solid var(--line); }
.ts-cal-layout-btn:hover { background: var(--bg-elev); color: var(--ink); }
.ts-cal-layout-btn.active { background: var(--ink); color: var(--bg-card); }
.ts-cal-block--teammate {
  border-left-width: 3px; opacity: 0.92; cursor: default; z-index: 1;
}
.ts-cal-block--teammate .ts-cal-block-time { color: var(--ink-5); }
/* ── Split view (column per calendar) ─────────────────────────────────────── */
.ts-cal-split-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.ts-cal-split-scroll { flex: 1; min-height: 0; overflow: auto; }
.ts-cal-split-headrow, .ts-cal-split-dayrow { display: flex; position: sticky; top: 0; z-index: 5; background: var(--bg-card); }
.ts-cal-split-dayrow { top: 33px; z-index: 4; }
.ts-cal-split-gutter-head { width: 52px; flex-shrink: 0; border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line); }
.ts-cal-split-cal-head {
  flex: 1; display: flex; align-items: center; gap: 7px; padding: 8px 12px;
  border-bottom: 1px solid var(--line); border-right: 1px solid var(--line-soft);
  font-size: 12.5px; font-weight: 600; color: var(--ink-1);
}
.ts-cal-split-cal-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ts-cal-split-cal-tag {
  font-size: 10px; font-weight: 600; color: var(--ink-5);
  border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; white-space: nowrap;
}
.ts-cal-split-daygroup { flex: 1; display: flex; }
.ts-cal-split-dayhead {
  flex: 1; display: flex; align-items: baseline; justify-content: center; gap: 5px;
  padding: 4px 2px; border-bottom: 1px solid var(--line); border-right: 1px solid var(--line-soft);
  font-size: 11px; color: var(--ink-4);
}
.ts-cal-split-dayhead.is-today { color: var(--indigo); font-weight: 700; }
.ts-cal-split-daynum { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.ts-cal-split-body { display: flex; }
.ts-cal-split-labels { position: sticky; left: 0; z-index: 3; background: var(--bg-card); }
/* flex:1 so each source's column group GROWS to fill its share of the row and
   lines up with its (flex:1) header cal-head. Without it the group collapsed to
   its col-wraps' min-width (132px) and bunched on the left while the headers
   spread full-width — the split view looked broken (headers ≠ body columns). */
.ts-cal-split-calgroup { flex: 1 1 0; display: flex; border-right: 2px solid var(--line); }
.ts-cal-split-calgroup:last-child { border-right: none; }
.ts-cal-split-col-wrap { flex: 1; min-width: 132px; border-right: 1px solid var(--line-soft); }
.ts-cal-split-col { position: relative; width: 100%; }
.ts-cal-split-col .ts-cal-block { left: 3%; width: 94%; }
/* ── Actions dropdown ────────────────────────────────────────────────────── */
.ts-cal-actions-wrap { position: relative; flex-shrink: 0; }
.ts-cal-actions-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 30;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.14);
  min-width: 224px; padding: 4px;
  display: flex; flex-direction: column;
}
.ts-cal-actions-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 5px;
  background: none; border: none; cursor: pointer;
  text-align: left; width: 100%;
  font: inherit; font-size: 12.5px; color: var(--ink-2);
  transition: background 0.1s, color 0.1s;
}
.ts-cal-actions-item:hover { background: var(--bg-elev); color: var(--ink); }
.ts-cal-actions-item:disabled { opacity: 0.55; cursor: not-allowed; }
.ts-cal-actions-item--active { background: color-mix(in srgb, var(--indigo) 10%, transparent); color: var(--indigo); }
.ts-cal-actions-item--active:hover { background: color-mix(in srgb, var(--indigo) 15%, transparent); }
.ts-cal-actions-item--ok { color: var(--ok); }
.ts-cal-actions-item--ok:hover { color: var(--ok); }
.ts-cal-actions-divider {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-5);
  padding: 7px 10px 2px; pointer-events: none; user-select: none;
}
.ts-cal-actions-sep { height: 1px; background: var(--line-soft); margin: 3px 6px; }
.ts-cal-actions-tmpl-list { padding: 1px 4px 4px 20px; display: flex; flex-direction: column; gap: 1px; }
.ts-cal-actions-tmpl-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  padding: 5px 8px; border-radius: 4px; border: none; background: none;
  cursor: pointer; text-align: left; width: 100%; font: inherit;
  transition: background 0.1s;
}
.ts-cal-actions-tmpl-item:hover { background: var(--bg-elev); }
.ts-cal-actions-tmpl-name { font-size: 12px; font-weight: 500; color: var(--ink-1); }
.ts-cal-actions-tmpl-meta { font-size: 11px; color: var(--ink-4); }
/* Shared box that all three calendar views live inside — same size every time */
.ts-cal-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--line); border-radius: 12px; background: var(--bg-card); margin-bottom: 0; }
/* Flex-grows so the per-view date label absorbs width differences — keeps the
   prev/next/Today/toggle cluster and the filter/More on the right from shifting
   when toggling Day/Week/Month. overflow:hidden truncates an over-long label
   rather than pushing siblings. */
.ts-cal-dateinfo { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; overflow: hidden; }
/* Calendar toolbar filter — fixed height matches .btn so the bar height is
   identical across all three views (the box is always rendered, disabled in Month). */
.ts-cal-search-wrap {
  display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: var(--radius-btn); background: var(--bg-elev); box-sizing: border-box;
}
.ts-cal-search-wrap:focus-within { border-color: var(--indigo); }
.ts-cal-search-input {
  flex: 1; min-width: 0; border: none; outline: none; background: none;
  color: var(--ink); font: inherit; font-size: 12.5px;
}
.ts-cal-search-input::placeholder { color: var(--ink-5); }
.ts-cal-search-input:disabled { cursor: not-allowed; color: var(--ink-5); }
.ts-cal-search-wrap:has(.ts-cal-search-input:disabled) { opacity: 0.5; }
.ts-cal-search-clear {
  border: none; background: none; cursor: pointer; color: var(--ink-4);
  display: inline-flex; align-items: center; padding: 0; flex-shrink: 0;
}
.ts-cal-search-clear:hover { color: var(--ink); }
.ts-cal-day { font-size: 14px; font-weight: 700; color: var(--ink); }
.ts-cal-date { font-size: 13px; color: var(--ink-4); }
.ts-cal-day-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ts-cal-grid { display: flex; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }
/* Day-view agenda rows: clickable rows get a hover background. No transition —
   the value is var()-driven and this Chrome sticks var-in-transition (snap it). */
.ts-agenda-item:hover { background: var(--bg-elev); }
.ts-cal-labels { width: 52px; flex-shrink: 0; border-right: 1px solid var(--line-soft); }
.ts-cal-hour-label {
  display: flex; align-items: flex-start; justify-content: flex-end;
  padding: 4px 8px 0 0; font-size: 10px; color: var(--ink-5);
  box-sizing: border-box;
}
/* Secondary-timezone label rails — an extra hour gutter per active zone, drawn
   to the left of the primary. Slightly muted + dashed divider so it reads as a
   reference rail, not the source of truth. Hour cells stay top-aligned with the
   primary gutter (the zone abbrev is an absolute badge so it adds no height). */
.ts-cal-labels--alt {
  position: relative; width: 56px; flex-shrink: 0; opacity: 0.72;
  border-right: 1px dashed var(--line);
}
.ts-cal-tz-head {
  position: absolute; top: 1px; left: 2px; z-index: 3;
  font-size: 8px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--ink-4); pointer-events: none;
  background: var(--bg-1, #0d0d10); padding: 1px 3px; border-radius: 3px;
}
/* Empty spacer keeping the split header/day rows aligned once alt gutters widen
   the left edge. Matches the alt-rail width. */
.ts-cal-split-gutter-head.ts-cal-tz-headspacer { width: 56px; min-width: 56px; flex-shrink: 0; }
/* Legend-menu timezone picker */
.ts-cal-legend-tzcurrent { font-size: 11px; color: var(--ink-4); padding: 2px 4px 4px; }
.ts-cal-legend-tzlist { display: flex; flex-direction: column; gap: 2px; margin-bottom: 4px; }
.ts-cal-legend-tzrow { display: flex; align-items: center; gap: 6px; padding: 2px 4px; }
.ts-cal-legend-tzabbr {
  font-size: 9px; font-weight: 700; color: var(--ink-4);
  background: var(--bg-elev); border: 1px solid var(--line-soft);
  border-radius: 4px; padding: 1px 4px; flex-shrink: 0;
}
.ts-cal-legend-tzname { flex: 1; font-size: 12px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ts-cal-legend-tzadd {
  width: 100%; font-size: 12px; padding: 4px 6px; margin: 2px 0 2px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card); color: var(--ink-2); cursor: pointer;
}
.ts-cal-timeline { flex: 1; position: relative; overflow: hidden; }
.ts-cal-gridline { position: absolute; left: 0; right: 0; height: 1px; background: var(--line-soft); z-index: 0; }
.ts-cal-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--bad); z-index: 1; pointer-events: none; }
.ts-cal-now::before {
  content: ""; position: absolute; left: -3px; top: -3px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--bad);
}
/* ⭐ ONE CURSOR RULE FOR EVERY CALENDAR ITEM (founder, 2026-08-20: "on hover
   the cursor is looking different on each type of event").
   The system, so a future block type does not have to guess:
     · interactive block  -> `grab`  (click opens its popover, drag moves it —
                                      and `pointer` promised only the click)
     · while dragging     -> `grabbing`, held on the GRID (see below)
     · non-interactive    -> `default` (only --teammate, which binds no
                                        handlers at all: a colleague's busy
                                        time is not yours to move)
   ⚠️ Do not set `pointer` on a block that can be dragged. Every one of
   actual / meeting / mtg / planned / external / native binds BOTH a click and
   a drag start, so a hand-with-finger overstates what a click does. */
.ts-cal-block {
  cursor: grab;
  position: absolute; left: 2%; width: 40%;
  border-left: 3px solid; border-radius: 5px;
  padding: 4px 8px; font-size: 11px;
  overflow: hidden; cursor: pointer; box-sizing: border-box;
  z-index: 2;
  transition: box-shadow 0.12s ease, opacity 0.1s ease;
}
.ts-cal-block--planned { background: var(--indigo-soft); border-color: var(--indigo); }
.ts-cal-block--actual { background: var(--ok-soft); border-color: var(--ok); }
.ts-cal-block--actual:hover { box-shadow: 0 3px 12px color-mix(in srgb, var(--ink) 14%, transparent); }
/* ⭐ CONNECTED-CALENDAR EVENTS — ONE COLOUR SOURCE, TWO PROPERTIES.
   `--ts-cal-color` is set INLINE by timesheets.jsx (tsCalColorVar) from the
   connected calendar's OWN colour — `calendar_subscriptions.color`, the exact
   value that used to be handed straight to `border-left-color`. The left rule
   and the fill now BOTH derive from that one custom property, so a second
   connected calendar reads as a second colour with no further work and the two
   can never drift apart.

   ⚠️ Founder 2026-08-18: "don't show the thick dashed outline. just keep a
   separate color for each connected calendar, but outline for the events
   should all be the same. right now the imported outlook calendar also has
   gray fill. i think it should just be red. with black text."
   · THE DASHED TREATMENT IS GONE. It came from an inline `borderStyle:
     "dashed"` in timesheets.jsx, which armed the top/right/bottom borders that
     `.ts-cal-block` deliberately leaves at style:none — computed style read
     `border: 3px; border-style: dashed dashed dashed solid`. A connected event
     now carries EXACTLY the edge an ordinary block carries: the 3px solid left
     rule from `.ts-cal-block`, nothing else. `border-style` is restated here
     rather than merely deleted so a re-added inline dashed style is the only
     way back to the old look, and the guard can see it.
   · THE NEUTRAL GRAY FILL IS GONE. The fill is a TINT of the calendar colour.
     `--ts-cal-tint` is the mix ratio and is raised in dark mode, because a
     low-percentage tint of any hue vanishes into a dark card. Keep it low
     enough that the title stays legible in BOTH themes — this is a tint behind
     text, not a saturated fill.
   · THE OPACITY WASH IS GONE (.78 here, .75 inline). That wash is what made a
     near-black title look gray: opacity dims the TEXT along with the box, so
     "black text" is achieved by removing it, not by restating a colour — the
     theme still owns `--ink`. The only surviving opacity on these blocks is
     the deliberate `isIgnored` 0.3, which means "hidden", not "external".
   ⚠️ NEVER add `background` to `.ts-cal-block`'s transition — it is a
   color-mix() value and Chrome sticks a var()/color-mix() transition at its
   from-value. Only box-shadow/opacity are animated there. */
.ts-cal-block--external {
  --ts-cal-color: var(--ink-3);
  --ts-cal-tint: 16%;
  background: color-mix(in srgb, var(--ts-cal-color) var(--ts-cal-tint), var(--bg-card));
  border-style: none none none solid;
  border-left-width: 3px;
  border-left-color: var(--ts-cal-color);
  z-index: 1;
}
[data-theme="dark"] .ts-cal-block--external { --ts-cal-tint: 28%; }
.ts-cal-block--external:hover { box-shadow: 0 2px 6px color-mix(in srgb, var(--ink) 18%, transparent); }
.ts-cal-block--external .ts-cal-block-name { color: var(--ink); }
.ts-cal-block--external .ts-cal-block-desc,
.ts-cal-block--external .ts-cal-block-time { color: var(--ink-3); }
.ts-cal-block--allday {
  width: 96%; left: 2%;
  background: color-mix(in srgb, var(--warn) 16%, var(--bg-card) 84%);
  font-size: 10px; padding: 2px 6px;
}
/* An external ALL-DAY block is still a connected-calendar block and must carry
   its calendar's tint, not the amber all-day wash. `.ts-cal-block--allday`
   declares its own background LATER at equal specificity, so deleting the
   inline background from timesheets.jsx would have handed every synced all-day
   event to the amber rule. This compound selector is what actually keeps the
   tint on the all-day band. */
.ts-cal-block--external.ts-cal-block--allday {
  background: color-mix(in srgb, var(--ts-cal-color) var(--ts-cal-tint), var(--bg-card));
}
.ts-cal-block--meeting {
  background: color-mix(in srgb, var(--indigo) 12%, var(--bg-card));
  border-color: var(--indigo);
  left: 45%; width: 52%;
}
.ts-cal-block--meeting:hover { box-shadow: 0 3px 12px color-mix(in srgb, var(--indigo) 18%, transparent); }
.ts-cal-block--meeting .ts-cal-block-name { color: var(--indigo); }
.ts-cal-block--meeting .ts-cal-block-time { color: color-mix(in srgb, var(--indigo) 60%, var(--ink-5)); }
/* Aecos-native meeting blocks (attendees + RSVP) — teal, distinct from events */
.ts-cal-block--mtg {
  background: color-mix(in srgb, var(--teal, #0ea5a5) 14%, var(--bg-card));
  border-color: var(--teal, #0ea5a5); left: 45%; width: 52%; cursor: pointer;
}
.ts-cal-block--mtg:hover { box-shadow: 0 3px 12px color-mix(in srgb, var(--teal, #0ea5a5) 22%, transparent); }
.ts-cal-block--mtg .ts-cal-block-name { color: var(--teal, #0ea5a5); }
.ts-cal-block--mtg .ts-cal-block-time { color: color-mix(in srgb, var(--teal, #0ea5a5) 65%, var(--ink-5)); }

/* Drag-to-create block-type picker popover */
.ts-dragpick-backdrop { position: fixed; inset: 0; z-index: 1200; }
.ts-dragpick {
  position: fixed; z-index: 1201; width: 240px; padding: 5px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.18);
  display: flex; flex-direction: column; gap: 2px;
}
.ts-dragpick-head {
  font-size: 11.5px; font-weight: 600; color: var(--ink-4);
  padding: 7px 9px 5px; border-bottom: 1px solid var(--line-soft); margin-bottom: 3px;
}
.ts-dragpick-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 9px; border: none; background: none; cursor: pointer;
  border-radius: 7px; text-align: left; color: var(--ink-2);
}
.ts-dragpick-item:hover { background: var(--bg-elev); }
.ts-dragpick-item > svg { color: var(--ink-4); flex-shrink: 0; }
.ts-dragpick-item-text { display: flex; flex-direction: column; min-width: 0; }
.ts-dragpick-item-label { font-size: 13px; font-weight: 600; color: var(--ink); }
.ts-dragpick-item-meta { font-size: 11px; color: var(--ink-4); }
.ts-cal-block-name { font-weight: 600; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ⭐ "Aecos meeting" ON A VIDEO MEETING BLOCK (founder 2026-08-18: "for the
   aecos meetings, when it is a video meeting, it should show on the event
   'aecos meeting'"). Only a VIDEO meeting gets it — tsMeetingIsVideo() in
   timesheets.jsx is the single test, shared with the detail popover's "Join
   meeting" button, so the label and the button can never disagree.

   ⚠️ WHAT HAPPENS WHEN THE LABEL DOES NOT FIT — the two real squeezes:
   1. HEIGHT. A 30-minute block is 30px tall (PX_PER_HOUR 60; 18px in compact
      view), and after 4px+4px padding its content box holds ONE 11px line.
      A second line would simply be clipped by `.ts-cal-block`'s overflow:hidden
      and the label would be invisible on the single most common meeting length.
      That is why the tag shares the TITLE line instead of sitting under it.
   2. WIDTH. The row is flex, so the tag can never PUSH the title out of the
      block: the title is `flex: 1 1 auto; min-width: 0` and absorbs the whole
      squeeze by ellipsizing, while the tag is `flex: 0 0 auto` and always
      renders whole. The untruncated title stays reachable in the block's
      `title` tooltip, which every one of these blocks already sets.
   3. WEEK COLUMNS are ~1/7th of the grid; a ~70px tag there would leave the
      title a handful of characters, so the tag is hidden in `--week` and the
      existing 👥 / 🔒 glyph carries the signal instead. */
.ts-cal-block-name--row { display: flex; align-items: baseline; gap: 5px; }
.ts-cal-block-name-txt { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-cal-mtg-tag {
  flex: 0 0 auto;
  font-size: 9px; font-weight: 700; line-height: 1.5;
  padding: 0 6px;
  border-radius: var(--radius-btn);
  background: color-mix(in srgb, var(--teal, #0ea5a5) 24%, var(--bg-card));
  color: var(--teal, #0ea5a5);
  white-space: nowrap;
}
.ts-cal-block--week .ts-cal-mtg-tag { display: none; }

/* ─── TSEventActionPopover — the single-click event card ─────────────────────
   Founder 2026-08-20, with an Outlook screenshot: "instead of the pop-up (in
   general for all these calendar pop-ups) it should look like this — coming out
   the side, not top or bottom, looking a little more like a speech bubble."
   The structure is Outlook's; the chrome is deliberately NOT — house tokens,
   house buttons, --radius-btn-icon for the icon-only expand control.

   ⚠️ ONLY `opacity` AND `transform` ARE ANIMATED. Every colour on this card is
   a token or a color-mix(), and Chrome sticks a transition on a var()- or
   color-mix()-valued property at its FROM value — animating background or
   border-color here is the documented way to end up with a popover frozen
   part-way through its fade. The position is set inline by tsPopoverSidePlace
   in timesheets.jsx, so the transform is a small sideways offset ON TOP of it
   (out of the anchor's side) and never fights the placement.

   ⚠️ `--out` kills pointer-events on the same tick dismissal is asked for, so
   Escape and click-outside feel instant even though the fade takes 130ms.
   Under prefers-reduced-motion the component unmounts synchronously and this
   transition is switched off entirely.

   STRUCTURE: the outer .ts-evtpop owns border/background/shadow and NEVER
   scrolls — the arrow hangs 6px outside its edge and an overflow here would
   clip it off. .ts-evtpop-scroll inside owns the max-height and the scrolling. */
.ts-evtpop {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-menu, 10px);
  box-shadow: 0 10px 30px color-mix(in srgb, var(--ink) 14%, transparent);
  font-size: 13px;
  opacity: 0;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
/* The card slides OUT OF the block's side: from the left edge when it sits to
   the block's right, and vice versa. */
.ts-evtpop--right { transform: translateX(-8px) scale(0.98); transform-origin: left center; }
.ts-evtpop--left  { transform: translateX(8px)  scale(0.98); transform-origin: right center; }
.ts-evtpop--in { opacity: 1; transform: none; }
.ts-evtpop--out.ts-evtpop--right { opacity: 0; transform: translateX(-5px) scale(0.985); pointer-events: none; }
.ts-evtpop--out.ts-evtpop--left  { opacity: 0; transform: translateX(5px)  scale(0.985); pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .ts-evtpop, .ts-evtpop--in, .ts-evtpop--out { transition: none; transform: none; }
}
/* The speech-bubble arrow: a rotated square straddling the card edge, painted
   with the card's own tokens so the two borders read as one outline. Its `top`
   is set inline (tsPopoverSidePlace.arrowTop, card-relative, pointing at the
   clicked block's centre); margin-top centres the 12px square on that line. */
.ts-evtpop-arrow {
  position: absolute;
  width: 12px; height: 12px;
  margin-top: -6px;
  background: var(--bg-card);
  transform: rotate(45deg);
  pointer-events: none;
}
.ts-evtpop--right .ts-evtpop-arrow {
  left: -6.5px;
  border-left: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.ts-evtpop--left .ts-evtpop-arrow {
  right: -6.5px;
  border-top: 1px solid var(--line);
  border-right: 1px solid var(--line);
}
/* maxHeight is the last line of defence: on a window too short for the card at
   any offset, the vertical clamp pins it at the 8px margin and this makes the
   overflow SCROLL rather than run off the bottom and hide the action buttons —
   the founder's original 2026-07-27 complaint, and the reason the arrow lives
   OUTSIDE this wrapper. */
.ts-evtpop-scroll {
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  padding: 14px;
  border-radius: inherit;
}
.ts-evtpop-head { display: flex; align-items: flex-start; gap: 8px; }
/* The dot is the block's OWN calendar colour, handed down as --ts-cal-color —
   the same property the block itself is painted from. */
.ts-evtpop-dot {
  flex: 0 0 auto; width: 10px; height: 10px; margin-top: 5px;
  border-radius: 50%; background: var(--ts-cal-color, var(--indigo));
}
.ts-evtpop-title {
  flex: 1 1 auto; min-width: 0;
  font-size: 14.5px; font-weight: 650; line-height: 1.3; color: var(--ink);
  overflow-wrap: anywhere;
}
.ts-evtpop-expand {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; margin: -2px -2px 0 0;
  border: none; background: none; cursor: pointer; color: var(--ink-4);
  border-radius: var(--radius-btn-icon);
}
.ts-evtpop-expand:hover { background: var(--bg-elev); color: var(--ink-2); }
.ts-evtpop-row {
  display: flex; align-items: flex-start; gap: 8px;
  margin-top: 10px; font-size: 12.5px; line-height: 1.4; color: var(--ink-2);
}
.ts-evtpop-row > svg { flex: 0 0 auto; margin-top: 2px; color: var(--ink-4); }
.ts-evtpop-when-2 { color: var(--ink-3); }
.ts-evtpop-desc {
  margin-top: 10px; font-size: 12.5px; line-height: 1.45; color: var(--ink-3);
  white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 120px; overflow-y: auto;
}
.ts-evtpop-desc a { color: var(--indigo); }
.ts-evtpop-att { min-width: 0; font-size: 12px; color: var(--ink-4); white-space: pre-wrap; overflow-wrap: anywhere; }
.ts-evtpop-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
/* Compact label rows for whatever else the builder knows (Project, Duration,
   Rate, Repeats, …) — the card must never know LESS than the modal it replaced. */
.ts-evtpop-extra { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.ts-evtpop-extra-row { display: flex; gap: 10px; font-size: 12px; line-height: 1.4; }
.ts-evtpop-extra-label { flex: 0 0 76px; font-weight: 600; color: var(--ink-5); }
.ts-evtpop-extra-val { flex: 1 1 auto; min-width: 0; color: var(--ink-2); white-space: pre-wrap; overflow-wrap: anywhere; }
/* Full-bleed rule: the card's 14px padding is cancelled so the separator reads
   as a division of the card rather than an underline under the content. */
.ts-evtpop-sep { height: 1px; margin: 12px -14px 0; background: var(--line-soft); }
/* The footer action row — Edit / Cancel / Delete live here, per the reference. */
.ts-evtpop-foot { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.ts-cal-block-desc { color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-cal-block-time { font-size: 10px; color: var(--ink-5); margin-top: 2px; }
.ts-cal-block-actions { display: flex; gap: 5px; margin-top: 4px; }
.ts-cal-block-btn { font-size: 10px; padding: 2px 6px; border: 1px solid var(--line); border-radius: var(--radius-btn-icon); background: var(--bg-card); cursor: pointer; color: var(--indigo); }
.ts-cal-block-btn--del { color: var(--bad); }

/* Reports */
.ts-reports-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ts-report-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.ts-report-row:last-child { border-bottom: none; }
.ts-report-name { width: 160px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; }
.ts-report-bar-wrap { flex: 1; height: 6px; background: var(--bg-sunk); border-radius: 3px; overflow: hidden; }
.ts-report-bar { height: 100%; background: var(--indigo); border-radius: 3px; transition: width .3s; }
.ts-report-bar--cat { background: var(--ok); }
.ts-report-val { font-family: var(--f-mono); font-size: 12px; color: var(--ink); min-width: 40px; text-align: right; }
.ts-report-amt { font-family: var(--f-mono); font-size: 11px; color: var(--ok); min-width: 60px; text-align: right; }
.ts-day-chart { display: flex; align-items: flex-end; gap: 4px; padding: 16px 0 0; height: 110px; overflow-x: auto; }
.ts-day-bar-col { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 32px; }
.ts-day-bar-fill { background: var(--indigo-soft); border: 1px solid var(--indigo-line); border-radius: 3px 3px 0 0; width: 22px; transition: height .3s; }
.ts-day-bar-val { font-size: 9px; font-family: var(--f-mono); color: var(--ink-5); }
.ts-day-bar-lbl { font-size: 10px; color: var(--ink-4); font-weight: 600; }

/* Settings */
.ts-settings-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 0; border-bottom: 1px solid var(--line-soft); gap: 12px;
}
.ts-settings-row:last-child { border-bottom: none; }
.ts-settings-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.ts-settings-meta { font-size: 12px; color: var(--ink-4); margin-top: 2px; }

/* Calendar sync — accounts list + provider picker */
.ts-cal-picker {
  position: absolute; right: 0; top: calc(100% + 6px);
  width: 360px; padding: 6px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 8px 24px color-mix(in srgb, var(--ink) 12%, transparent);
  z-index: 50; display: flex; flex-direction: column; gap: 2px;
}
.ts-cal-picker-row {
  text-align: left; padding: 10px 12px; border: none; background: transparent;
  border-radius: 6px; cursor: pointer; transition: background .12s ease;
}
.ts-cal-picker-row:hover { background: var(--bg-sunk); }
.ts-cal-picker-row--disabled { opacity: .55; cursor: not-allowed; }
.ts-cal-picker-row--disabled:hover { background: transparent; }
.ts-cal-picker-label { font-size: 13px; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.ts-cal-picker-desc { font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.ts-cal-picker-soon {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  background: var(--bg-sunk); color: var(--ink-4); border-radius: 3px; padding: 1px 6px;
}

.ts-cal-account {
  border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 10px; background: var(--bg-card);
}
.ts-cal-account-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding-bottom: 10px; border-bottom: 1px solid var(--line-soft); margin-bottom: 8px;
}
.ts-cal-account-title { font-size: 13.5px; font-weight: 700; color: var(--ink); display: flex; align-items: center; flex-wrap: wrap; }
.ts-cal-sub-list { display: flex; flex-direction: column; gap: 2px; }
.ts-cal-sub-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 6px 4px; border-radius: 5px;
}
.ts-cal-sub-row:hover { background: var(--bg-sunk); }
.ts-cal-sub-toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13px; color: var(--ink); flex: 1; min-width: 0; }
.ts-cal-sub-toggle input[type="checkbox"] { width: 14px; height: 14px; cursor: pointer; accent-color: var(--indigo); }
.ts-cal-sub-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.ts-cal-sub-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-cal-sub-tag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  background: var(--indigo-soft); color: var(--indigo); border-radius: 3px; padding: 1px 5px; margin-left: 6px;
}
.ts-cal-sub-actions { display: flex; align-items: center; gap: 6px; }
.ts-cal-sub-color {
  width: 26px; height: 22px; padding: 0; border: 1px solid var(--line);
  border-radius: 4px; background: transparent; cursor: pointer;
}
.ts-cal-error {
  font-size: 12px; color: var(--bad);
  background: color-mix(in srgb, var(--bad) 8%, var(--bg-card) 92%);
  border-radius: 5px; padding: 6px 10px;
}

/* ── "Send from" / default-sender / connect gate (calendar-as-email-medium) ── */
.ts-sender-toggle { white-space: nowrap; }
.ts-send-from-hint {
  font-size: 11.5px; color: var(--ink-4); margin-top: 5px;
}
.ts-connect-gate {
  border: 1px dashed var(--line); border-radius: 8px;
  padding: 12px; background: color-mix(in srgb, var(--indigo, #6366f1) 6%, var(--bg-card) 94%);
}
.ts-connect-gate-msg {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.45; margin-bottom: 10px;
}
.ts-connect-gate-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Timer inline editing */
.ts-timer-select {
  border: 1px solid rgba(255,255,255,0.15); border-radius: var(--radius-btn);
  background: rgba(255,255,255,0.08); color: inherit;
  font: inherit; font-size: 12px; padding: 4px 22px 4px 8px; cursor: pointer;
  outline: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpolyline points='1 1 4 4 7 1' fill='none' stroke='%23aaa' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 6px center;
  max-width: 160px;
}
.ts-timer-select--cat { max-width: 130px; }
.ts-timer-select:focus { border-color: rgba(255,255,255,0.35); }
.ts-timer-input {
  flex: 1; min-width: 0; border: 1px solid rgba(255,255,255,0.15); border-radius: 5px;
  background: rgba(255,255,255,0.08); color: inherit;
  font: inherit; font-size: 12px; padding: 4px 8px; outline: none;
}
.ts-timer-input:focus { border-color: rgba(255,255,255,0.35); }
.ts-timer-input::placeholder { color: rgba(255,255,255,0.35); }

/* Play button on project cards */
.ts-play-btn {
  width: 28px; height: 28px; border-radius: 50%;
  border: 1.5px solid var(--line); background: var(--bg-elev);
  color: var(--ink-3); font-size: 11px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .12s, color .12s, border-color .12s;
  flex-shrink: 0;
}
.ts-play-btn:hover { background: var(--ok-soft); color: var(--ok); border-color: var(--ok-line); }
.ts-play-btn--active { background: var(--bad-soft); color: var(--bad); border-color: var(--bad-line); font-size: 9px; }

/* Project card description */
.ts-proj-card-desc {
  font-size: 11.5px; color: var(--ink-5); margin-top: 5px;
  line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}

/* Timer bar — make it dark/contrast to stand out */
.ts-timer-bar {
  background: var(--ink-2); color: #fff;
  border-color: var(--ink-2);
  flex-shrink: 0;
}
.ts-timer-bar--idle {
  background: var(--bg-elev); color: var(--ink);
  border-color: var(--line);
}
.ts-timer-bar--idle .ts-timer-select {
  background-color: var(--bg-card); color: var(--ink);
  border-color: var(--line);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpolyline points='1 1 4 4 7 1' fill='none' stroke='%23666' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
}
.ts-timer-bar--idle .ts-timer-select:focus { border-color: var(--ok-line); }
.ts-timer-bar--idle .ts-timer-btn { border-color: var(--ok-line); background: color-mix(in oklab, var(--ok) 10%, transparent); color: var(--ok); }
.ts-timer-btn--start { font-weight: 600; }
.ts-timer-bar .ts-timer-dot { background: #f87171; }
.ts-timer-bar .ts-timer-name { color: #fff; }
.ts-timer-bar .ts-timer-elapsed { color: #fff; }
.ts-timer-btn { border-color: rgba(255,255,255,0.2); background: rgba(255,255,255,0.1); color: #fff; }
.ts-timer-btn--stop { background: #ef4444; border-color: #ef4444; }
.ts-timer-btn--discard { background: transparent; border-color: rgba(255,255,255,0.12); color: rgba(255,255,255,0.45); font-size: 11px; }
.ts-timer-btn--discard:hover { color: rgba(255,255,255,0.75); border-color: rgba(255,255,255,0.25); }

/* ── Floating timer widget ───────────────────────────────────────────────── */
.ts-float-wrap {
  position: fixed; bottom: 76px; right: 24px; z-index: 500;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  pointer-events: none;
}
.ts-float-wrap > * { pointer-events: auto; }

.ts-float-btn {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-btn); padding: 8px 14px 8px 10px;
  cursor: pointer; box-shadow: 0 4px 20px rgba(0,0,0,0.18);
  font-size: 13px; font: inherit;
}
.ts-float-btn:hover { background: var(--bg-hover); } /* quiet fill lift; no movement, no shadow bump — founder 2026-08-20 */
.ts-float-btn--paused { opacity: 0.8; }

.ts-float-pulse-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--ok); flex-shrink: 0;
  animation: tsFloatPulse 1.6s ease-in-out infinite;
}
.ts-float-pulse-dot--paused { background: var(--warn); animation: none; }

@keyframes tsFloatPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.75); }
}

.ts-float-time {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px;
  color: var(--ink); letter-spacing: 0.02em;
}
.ts-float-name {
  font-size: 11px; color: var(--ink-4);
  max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.ts-float-panel {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  padding: 16px; width: 320px; box-sizing: border-box;
  box-shadow: 0 8px 36px rgba(0,0,0,0.2);
  display: flex; flex-direction: column; gap: 12px;
}
.ts-float-panel-head {
  display: flex; align-items: center; justify-content: space-between;
}
.ts-float-panel-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 17px; color: var(--ink);
}
.ts-float-close {
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 4px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
}
.ts-float-close:hover { color: var(--ink); background: var(--bg-elev); }
.ts-float-field { display: flex; flex-direction: column; gap: 4px; }
.ts-float-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-4);
}
.ts-float-field .ts-select,
.ts-float-field .ts-input { width: 100%; box-sizing: border-box; }
.ts-float-actions {
  display: flex; gap: 6px; padding-top: 6px; border-top: 1px solid var(--line-soft);
}

/* ── Project-scoped timer bar ────────────────────────────────────────────── */
.ts-proj-timer-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-radius: 8px; margin-bottom: 14px;
  border: 1px solid var(--line-soft);
}
.ts-proj-timer-bar--idle {
  background: var(--bg-elev); color: var(--ink-5);
}
.ts-proj-timer-bar--active {
  background: color-mix(in oklab, var(--ok) 8%, var(--bg-card));
  border-color: color-mix(in oklab, var(--ok) 30%, transparent);
}
.ts-proj-timer-bar--other {
  background: var(--bg-elev); border-color: color-mix(in oklab, var(--warn) 35%, transparent);
}
.ts-proj-timer-hint { font-size: 12px; color: var(--ink-5); }
.ts-proj-timer-elapsed {
  font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--ok); min-width: 82px; flex-shrink: 0;
}
.ts-proj-timer-select { width: auto; flex-shrink: 0; }
.ts-proj-timer-desc { flex: 1; min-width: 0; }
.ts-proj-timer-other-msg { flex: 1; font-size: 12px; color: var(--ink-4); }
.ts-proj-timer-other-msg strong { color: var(--ink); }

/* ── Calendar view toggle ────────────────────────────────────────────────── */
.ts-cal-view-toggle {
  display: flex; border: 1px solid var(--line); border-radius: var(--radius-btn); overflow: hidden;
  flex-shrink: 0;
}
.ts-cal-toggle-btn {
  padding: 5px 12px; font: inherit; font-size: 12px; font-weight: 500;
  border: none; border-right: 1px solid var(--line);
  background: none; cursor: pointer; color: var(--ink-4);
  transition: background 0.1s, color 0.1s;
}
.ts-cal-toggle-btn:last-child { border-right: none; }
.ts-cal-toggle-btn:hover { background: var(--bg-elev); color: var(--ink); }
.ts-cal-toggle-btn.active { background: var(--ink); color: var(--bg-card); }
.ts-cal-period-label { font-size: 14px; font-weight: 600; color: var(--ink); white-space: nowrap; }

/* ── Week view ───────────────────────────────────────────────────────────── */
.ts-cal-week-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.ts-cal-week-header {
  display: grid; grid-template-columns: 52px repeat(7, 1fr);
  background: var(--bg-card); border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.ts-cal-week-gutter { }
.ts-cal-week-day-head {
  padding: 8px 4px; display: flex; flex-direction: column; align-items: center; gap: 3px;
  cursor: pointer; border-left: 1px solid var(--line-soft); transition: background 0.1s;
}
.ts-cal-week-day-head:hover { background: var(--bg-elev); }
.ts-cal-week-day-head--today { background: color-mix(in oklab, var(--indigo) 6%, var(--bg-card)); }
.ts-cal-week-dow { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-4); }
.ts-cal-week-date { font-size: 17px; font-weight: 700; color: var(--ink); line-height: 1; }
.ts-cal-week-day-head--today .ts-cal-week-date { color: var(--indigo); }
.ts-cal-week-body {
  display: grid; grid-template-columns: 52px repeat(7, 1fr);
  overflow-y: auto; flex: 1; min-height: 0;
}
.ts-cal-week-col {
  position: relative; overflow: hidden; border-left: 1px solid var(--line-soft);
}
.ts-cal-week-col--today { background: color-mix(in oklab, var(--indigo) 3%, var(--bg-card)); }
/* Day-total strip above the week grid (rules lost in the styles.css wipe) */
.ts-cal-week-totals {
  display: grid; grid-template-columns: 52px repeat(7, 1fr);
  border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.ts-cal-week-gutter { border: none; }
.ts-cal-day-total {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  font-size: 10.5px; color: var(--ink-3); padding: 4px 2px;
  border-left: 1px solid var(--line-soft); white-space: nowrap; overflow: hidden;
}
.ts-cal-day-total--today { font-weight: 600; }
.ts-cal-day-total--empty { min-height: 22px; }
.ts-cdt-hours { font-weight: 600; color: var(--ink-2); }
.ts-cdt-sep   { opacity: 0.45; }
/* Week / day summary card under the calendar (rules lost in the wipe).
   Compact + height-capped so it never dominates — the week grid above stays large. */
.ts-week-summary {
  margin: 6px 10px 6px; padding: 7px 12px; border: 1px solid var(--line);
  border-radius: 9px; background: var(--bg-card);
  display: flex; flex-direction: column; gap: 5px;
  flex-shrink: 0; max-height: 24vh; overflow-y: auto;
}
.ts-week-summary-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; flex-shrink: 0;
}
.ts-week-summary-label { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.ts-week-summary-totals { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 12px; }
.ts-week-summary-total { font-weight: 700; color: var(--ink); }
.ts-week-summary-bill--on  { color: var(--ok); }
.ts-week-summary-bill--off { color: var(--ink-4); }
.ts-week-summary-util { font-weight: 600; }
.ts-week-summary-rows { display: flex; flex-direction: column; gap: 3px; }
.ts-week-summary-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ts-week-summary-swatch { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
.ts-week-summary-name {
  font-size: 12px; color: var(--ink-2); width: 180px; flex-shrink: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ts-week-summary-bar-wrap {
  flex: 1; height: 11px; border-radius: 4px; background: var(--bg-sunk);
  overflow: hidden; min-width: 60px;
}
.ts-week-summary-bar {
  height: 100%; border-radius: 4px; min-width: 2px;
  display: flex; align-items: center; justify-content: flex-end;
  font-size: 9.5px; color: #fff; padding: 0 5px;
}
.ts-week-summary-hours { font-size: 11.5px; color: var(--ink-3); width: 64px; text-align: right; flex-shrink: 0; }
/* In week view, blocks fill the full column */
/* Week columns are narrow, so a week block spans the whole column — !important
   because it has to beat `.ts-cal-block`'s left:2%/width:40% day-view split.
   ⚠️ The values come from custom properties so OVERLAP PACKING can move a block
   into its own lane: an !important declaration still resolves its var() at use
   time, whereas an inline `left:` would lose to the !important outright. The
   fallbacks reproduce the pre-packing full-width look exactly, so any block
   without a lane (or any caller that forgets to pass one) is unchanged.
   See tsPackColumns / tsLaneStyle in timesheets.jsx. */
.ts-cal-block--week {
  left:  var(--wk-lane-left,  1px) !important;
  width: var(--wk-lane-width, calc(100% - 2px)) !important;
}

/* ── Month view ──────────────────────────────────────────────────────────── */
/* Wrap fills the whole calendar panel so the grid can expand to full height.
   Row layout keeps the grid large even when the day-detail sidebar is open. */
.ts-cal-month-wrap {
  flex: 1; min-height: 0; display: flex; flex-direction: row; overflow: hidden;
}
.ts-cal-month-grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  grid-template-rows: auto repeat(6, 1fr);
  gap: 1px; background: var(--line-soft);
  flex: 1; min-width: 0; min-height: 0; overflow: hidden;
}
.ts-cal-month-dow {
  padding: 7px 10px; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-4);
  background: var(--bg-elev); text-align: center;
}
.ts-cal-month-cell {
  padding: 8px 10px; background: var(--bg-card);
  cursor: pointer; transition: background 0.1s; min-height: 0;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; overflow: hidden;
}
.ts-cal-month-cell:hover { background: var(--bg-elev); }
.ts-cal-month-cell--today { background: color-mix(in oklab, var(--indigo) 6%, var(--bg-card)); }
.ts-cal-month-cell--outside { opacity: 0.3; pointer-events: none; }
.ts-cal-month-cell-date {
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600; color: var(--ink);
}
.ts-cal-month-cell--today .ts-cal-month-cell-date { background: var(--indigo); color: #fff; }
.ts-cal-month-cell-hours { font-size: 11px; color: var(--ok); font-weight: 600; margin-top: 3px; }
.ts-cal-month-cell-dots { display: flex; gap: 3px; flex-wrap: wrap; margin-top: 4px; align-items: center; }
.ts-cal-month-dot { width: 6px; height: 6px; border-radius: 50%; }
.ts-cal-month-cell-bar-wrap { width: 100%; max-width: 80px; height: 4px; border-radius: 3px; background: var(--bg-sunk); overflow: hidden; margin-top: 2px; }
.ts-cal-month-cell-bar { height: 100%; border-radius: 3px; }
.ts-cal-month-cell-evts { display: flex; flex-direction: column; gap: 2px; margin-top: 3px; width: 100%; overflow: hidden; }
.ts-cal-month-evt { font-size: 10px; line-height: 1.3; padding: 1px 5px; border-radius: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.ts-cal-month-evt--mtg { background: color-mix(in oklab, var(--indigo) 20%, transparent); color: var(--indigo); }
.ts-cal-month-evt--ext { background: var(--bg-sunk); color: var(--ink-3); }
.ts-cal-month-evt-more { font-size: 9.5px; color: var(--ink-4); padding-left: 2px; }

/* Day-detail sidebar — opens beside the grid so the month stays full-height */
.ts-cal-month-detail {
  width: 300px; flex-shrink: 0; border-left: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden; background: var(--bg-card);
}
.ts-cal-month-detail-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
  padding: 14px 16px 10px; border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.ts-cal-month-detail-date { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.ts-cal-month-detail-total { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.ts-cal-month-detail-entries { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 12px; display: flex; flex-direction: column; gap: 6px; }
.ts-cal-month-detail-empty { font-size: 12px; color: var(--ink-4); padding: 16px 4px; text-align: center; }
.ts-cal-month-detail-row { display: flex; align-items: flex-start; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.ts-cal-month-detail-swatch { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; margin-top: 3px; }
.ts-cal-month-detail-info { flex: 1; min-width: 0; }
.ts-cal-month-detail-proj { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.ts-cal-month-detail-desc { font-size: 11px; color: var(--ink-4); margin-top: 1px; }
.ts-cal-month-detail-time { font-size: 10.5px; color: var(--ink-5); margin-top: 1px; }
.ts-cal-month-detail-hrs { font-size: 11.5px; font-weight: 600; color: var(--ink-3); flex-shrink: 0; }
.ts-cal-month-detail-foot { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--line-soft); flex-shrink: 0; }

/* ── Live timer indicator dot (week header / month cells) ────────────────── */
.ts-cal-live-dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ok);
  animation: tsFloatPulse 1.6s ease-in-out infinite;
}

/* ── Live timer growing block ────────────────────────────────────────────── */
.ts-cal-block--live {
  background: color-mix(in oklab, var(--ok) 12%, var(--bg-card)) !important;
  border-left-style: dashed !important;
  border-left-width: 3px !important;
  animation: tsLiveFade 2s ease-in-out infinite;
}
@keyframes tsLiveFade {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.75; }
}

/* ── Team Capacity view ──────────────────────────────────────────────────── */
.ts-capacity-wrap { display: flex; flex-direction: column; gap: 14px; padding: 4px 2px; }

.ts-cap-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.ts-cap-toolbar-left { display: flex; flex-direction: column; gap: 2px; }
.ts-cap-toolbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Legend: horizontal row of labeled color chips */
.ts-cap-legend {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 18px;
  padding: 8px 0; font-size: 12px; color: var(--ink-4);
  border-bottom: 1px solid var(--line-soft);
}
.ts-cap-legend-item { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.ts-cap-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.ts-cap-committed-marker-demo {
  width: 2px; height: 12px; border-radius: 1px; flex-shrink: 0;
  background: var(--ink-2);
}

/* Column headers: horizontal row aligned with member rows */
.ts-cap-col-headers,
.ts-cap-row {
  display: flex; align-items: center; gap: 12px;
}
.ts-cap-col-headers {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--ink-5);
  padding: 0 4px 6px; border-bottom: 1px solid var(--line-soft);
}

.ts-cap-list { display: flex; flex-direction: column; }
.ts-cap-row {
  padding: 10px 4px; border-bottom: 1px solid var(--line-soft);
  cursor: pointer; transition: background 0.1s;
}
.ts-cap-row:hover { background: var(--bg-elev); }
.ts-cap-row--expanded { background: var(--bg-elev); }

.ts-cap-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 11px; font-weight: 700;
}
.ts-cap-identity { flex: 0 0 180px; min-width: 0; }
.ts-cap-name { font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-cap-title { font-size: 11px; color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.ts-cap-bars { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ts-cap-util-track {
  position: relative; height: 10px; border-radius: 5px;
  background: var(--bg-elev); border: 1px solid var(--line-soft); overflow: visible;
}
.ts-cap-util-fill { height: 100%; border-radius: 5px 0 0 5px; transition: width 0.2s; }
.ts-cap-util-over {
  position: absolute; top: 0; right: 0; height: 100%;
  background: repeating-linear-gradient(45deg, var(--bad), var(--bad) 3px, transparent 3px, transparent 6px);
  border-radius: 0 5px 5px 0;
}
.ts-cap-committed-marker {
  position: absolute; top: -2px; width: 2px; height: 14px;
  background: var(--ink-2); border-radius: 1px;
}
.ts-cap-stack { display: flex; height: 6px; border-radius: 3px; overflow: hidden; }
.ts-cap-stack-seg { height: 100%; }

.ts-cap-numbers {
  flex: 0 0 110px; display: flex; align-items: baseline; justify-content: flex-end;
  gap: 4px; text-align: right;
}
.ts-cap-logged { font-size: 13px; font-weight: 700; }
.ts-cap-target { font-size: 12px; color: var(--ink-4); }
.ts-cap-pct { font-size: 11px; font-weight: 600; }
.ts-cap-no-data { font-size: 13px; color: var(--ink-5); }

.ts-cap-status { flex: 0 0 130px; text-align: right; }

.ts-cap-detail {
  padding: 10px 4px 14px 48px; border-bottom: 1px solid var(--line-soft);
  background: var(--bg-elev);
}
.ts-cap-detail-projects { display: flex; flex-direction: column; gap: 6px; }
.ts-cap-detail-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.ts-cap-detail-dot { width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0; }
.ts-cap-detail-pname { flex: 1; min-width: 0; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-cap-detail-hrs { flex: 0 0 60px; text-align: right; font-weight: 600; color: var(--ink); }
.ts-cap-detail-pct { flex: 0 0 50px; text-align: right; color: var(--ink-4); }
.ts-cap-footer { padding-top: 10px; font-size: 12px; color: var(--ink-4); }

/* ─── Studio Review — Revu-style Professional Shell ─────────────────────────── */

/* ─── Studio Review session — uses app theme tokens ─────────────────────────
   Adapts to light/mid/dark themes via :root tokens. Replaces the old hard-
   coded dark palette. ──────────────────────────────────────────────────── */

/* Menu bar */
.sr-menu-bar {
  display: flex; align-items: center; flex-shrink: 0; height: 30px;
  background: var(--bg-sunk); border-bottom: 1px solid var(--line);
  user-select: none; z-index: 200; position: relative;
}
/* SR brand — mirrors the main sidebar logo (.brand/.brand-name in shell.jsx):
   same glyph at --ink, medium weight, tight tracking. */
.sr-menu-logo {
  display: flex; align-items: center; gap: 7px;
  padding: 0 12px; border-right: 1px solid var(--line); height: 100%;
  color: var(--ink); flex-shrink: 0;
}
.sr-menu-logo svg { display: block; flex: 0 0 auto; }
.sr-menu-logo-text {
  font-size: 12.5px; font-weight: 500; letter-spacing: -0.01em;
  color: var(--ink); line-height: 1;
}

/* Shared Tooltip component inside Studio Review — native card look (the
   app-global .tooltip__content stays ink-filled elsewhere). */
.studio-review-page .tooltip__content {
  background: var(--bg-elev); color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.14));
  font-weight: 500;
}
.studio-review-page .tooltip__arrow { display: none; }
.sr-menu-heading {
  position: relative; padding: 0 9px; height: 100%;
  display: flex; align-items: center;
  font-size: 11.5px; color: var(--ink-3);
  cursor: pointer; transition: background 0.1s, color 0.1s; white-space: nowrap;
}
.sr-menu-heading:hover, .sr-menu-heading.open {
  background: var(--bg-hover); color: var(--ink);
}
.sr-menu-drop {
  position: absolute; top: calc(100% + 1px); left: 0; z-index: 1000;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); min-width: 220px;
  box-shadow: var(--shadow-lg); padding: 3px 0;
  max-height: calc(100vh - 48px); overflow-y: auto;
}
.sr-menu-submenu {
  position: fixed; z-index: 1001;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); min-width: 120px;
  box-shadow: var(--shadow-lg); padding: 3px 0;
}
.sr-menu-item-sub { cursor: default; }
.sr-menu-item-sub::after { content: "▸"; font-size: 9px; color: var(--ink-5); }
.sr-menu-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 12px 4px 20px; font-size: 11.5px; cursor: pointer;
  color: var(--ink-2); white-space: nowrap;
  transition: background 0.1s, color 0.08s; gap: 12px;
}
.sr-menu-item:hover { background: var(--indigo-soft); color: var(--indigo-ink); }
.sr-menu-item.disabled { opacity: 0.35; cursor: default; pointer-events: none; }
.sr-menu-key { font-size: 10px; color: var(--ink-5); font-family: var(--f-mono); flex-shrink: 0; }
.sr-menu-sep { height: 1px; background: var(--line-soft); margin: 3px 0; }
.sr-mention-dropdown {
  position: absolute; left: 0; top: 100%; z-index: 50;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); box-shadow: var(--shadow-lg);
  padding: 3px 0; min-width: 200px; max-width: 300px;
  max-height: 220px; overflow-y: auto;
}
.sr-mention-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 12px; font-size: 11.5px; cursor: pointer;
  color: var(--ink-2); gap: 10px;
  transition: background 0.08s;
}
.sr-mention-item:hover { background: var(--indigo-soft); color: var(--indigo-ink); }
.sr-mention-name { font-weight: 500; }
.sr-mention-role { font-size: 10px; color: var(--ink-5); }
.sr-menu-bar-right {
  margin-left: auto; display: flex; align-items: center; height: 100%;
  padding-right: 8px; gap: 0; flex-shrink: 0;
}
.sr-crumb-pill {
  display: flex; align-items: center; gap: 5px; padding: 0 10px; height: 100%;
  font-size: 10.5px; color: var(--ink-4); border-left: 1px solid var(--line);
}
.sr-crumb-pill strong { color: var(--ink-2); font-weight: 500; }
.sr-menu-action-btn {
  display: flex; align-items: center; gap: 4px; padding: 0 8px; height: 100%;
  background: none; border: none; cursor: pointer; border-left: 1px solid var(--line);
  font-size: 10.5px; color: var(--ink-4); transition: color 0.1s, background 0.1s;
}
.sr-menu-action-btn:hover { color: var(--ink); background: var(--bg-hover); }

/* Properties toolbar */
.sr-props-toolbar {
  display: flex; align-items: center; flex-shrink: 0; height: 30px;
  background: var(--bg-card); border-bottom: 1px solid var(--line);
  padding: 0 4px; overflow-x: auto; overflow-y: hidden; gap: 0;
  user-select: none;
}
.sr-props-toolbar::-webkit-scrollbar { height: 2px; }
/* Inline variant — rendered inside the 30px tab bar's props slot (previously
   had no CSS at all, so its groups stacked as unstyled blocks). Same look as
   .sr-props-toolbar minus background/border — the host bar provides those. */
.sr-props-toolbar-inline {
  display: flex; align-items: center; min-width: 0; height: 100%;
  overflow-x: auto; overflow-y: hidden; gap: 0; user-select: none;
  border-left: 1px solid var(--line-soft); padding: 0 4px;
}
.sr-props-toolbar-inline::-webkit-scrollbar { height: 2px; }
.sr-props-grp {
  display: flex; align-items: center; gap: 2px;
  padding: 0 5px; border-right: 1px solid var(--line-soft); flex-shrink: 0; height: 100%;
}
.sr-props-grp:last-child { border-right: none; }
.sr-props-lbl {
  font-size: 9px; color: var(--ink-5); padding-right: 3px;
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
}
.sr-props-btn {
  display: flex; align-items: center; justify-content: center;
  height: 20px; min-width: 20px; padding: 0 5px;
  border: 1px solid transparent; border-radius: 3px;
  background: none; cursor: pointer; font-size: 10px;
  color: var(--ink-3); gap: 3px; white-space: nowrap;
  transition: background 0.1s, color 0.1s;
}
.sr-props-btn:hover { background: var(--bg-hover); color: var(--ink); }
.sr-props-btn.on { background: var(--indigo-soft); border-color: var(--indigo-line); color: var(--indigo-ink); }
.sr-props-swatch {
  width: 18px; height: 16px; border-radius: 3px; border: 1px solid var(--line-strong);
  cursor: pointer; flex-shrink: 0;
}
.sr-props-swatch:hover { border-color: var(--ink-3); } /* SNAPS; no scale — founder 2026-08-20 */
.sr-props-inp {
  height: 18px; background: var(--bg-elev); border: 1px solid var(--line); border-radius: 3px;
  color: var(--ink-2); font-size: 10px; font-family: var(--f-mono); padding: 0 4px;
}
.sr-props-sel {
  height: 18px; background: var(--bg-elev); border: 1px solid var(--line); border-radius: 3px;
  color: var(--ink-2); font-size: 10px; padding: 0 3px; max-width: 90px;
}
/* Compact AecosSelect variant for dense SR chrome (props toolbar, side-panel
   rows, bulk-action bars). Overrides only the trigger metrics — the fixed-
   position menu keeps its normal size/typography for readability. */
.sr-aecos-xs .aecos-select__btn {
  height: 22px; font-size: 10.5px; gap: 4px; padding: 0 6px 0 8px;
}
/* Keyboard focus rings for SR session chrome (buttons/tabs/chips had none). */
.sr-nav-btn:focus-visible,
.sr-rail-btn:focus-visible,
.sr-props-btn:focus-visible,
.sr-btm-tab:focus-visible,
.sr-btm-close:focus-visible,
.sr-menu-action-btn:focus-visible,
.sr-dash-chip:focus-visible,
.sr-cc-mode-btn:focus-visible,
.sr-add-comment-btn:focus-visible,
.sr-modal-close:focus-visible,
.mu-right-tab:focus-visible,
.mu-color-btn:focus-visible,
.mu-delete-ann-btn:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: -2px;
}
.sr-props-tool-chip {
  display: flex; align-items: center; gap: 5px;
  padding: 0 8px 0 6px; height: 100%; border-right: 1px solid var(--line-soft);
  font-size: 10.5px; font-weight: 600; color: var(--ink-2); white-space: nowrap;
}

/* Revu body */
.sr-revu-body {
  display: flex; flex: 1 1 0; min-height: 0; overflow: hidden;
}

/* Left icon rail */
.sr-left-rail {
  width: 44px; flex-shrink: 0;
  background: var(--bg-sunk); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center;
  padding: 4px 0; gap: 2px; overflow: hidden;
}
.sr-rail-btn {
  width: 36px; height: 36px; border-radius: var(--radius-btn-icon); border: none;
  background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-4); transition: background 0.1s, color 0.1s;
  position: relative; flex-shrink: 0;
}
.sr-rail-btn:hover { background: var(--bg-hover); color: var(--ink-2); }
.sr-rail-btn.active { background: var(--indigo-soft); color: var(--indigo-ink); }
.sr-rail-sep { width: 28px; height: 1px; background: var(--line); margin: 3px 0; flex-shrink: 0; }
/* Native Aecos hover tip — subtle elevated card (not the old black window),
   with a short reveal delay so it doesn't flicker while mousing across. */
.sr-rail-tip {
  position: absolute; left: calc(100% + 8px); top: 50%;
  transform: translateY(-50%) translateX(-2px);
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.14));
  padding: 5px 10px; font-size: 11.5px; font-weight: 500; color: var(--ink);
  white-space: nowrap; pointer-events: none; z-index: 300; opacity: 0;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
.sr-rail-btn:hover .sr-rail-tip {
  opacity: 1; transform: translateY(-50%) translateX(0);
  transition-delay: 0.3s;
}

/* Left panel */
.sr-left-panel {
  width: 216px; flex-shrink: 0; background: var(--bg-elev); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.sr-lp-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 8px 0 10px; height: 28px; flex-shrink: 0;
  border-bottom: 1px solid var(--line);
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-5);
}
.sr-lp-close {
  width: 18px; height: 18px; border-radius: var(--radius-btn-icon, 8px); border: none; background: none; cursor: pointer;
  color: var(--ink-5); display: flex; align-items: center; justify-content: center;
  transition: background 0.1s, color 0.1s;
}
.sr-lp-close:hover { background: var(--bg-hover); color: var(--ink-3); }
.sr-lp-body { flex: 1 1 0; overflow-y: auto; }
.sr-lp-body::-webkit-scrollbar { width: 4px; }
.sr-lp-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
.sr-lp-footer {
  padding: 6px 8px; border-top: 1px solid var(--line); flex-shrink: 0;
}
.sr-lp-row {
  display: flex; align-items: center; gap: 6px; padding: 5px 10px;
  border-bottom: 1px solid var(--line-soft); cursor: pointer;
  transition: background 0.1s;
}
.sr-lp-row:hover { background: var(--bg-hover); }
.sr-lp-row.active { background: var(--indigo-soft); border-left: 2px solid var(--indigo); padding-left: 8px; }
.sr-lp-num { font-size: 9.5px; font-weight: 600; color: var(--ink-5); font-family: var(--f-mono); min-width: 28px; }
.sr-lp-title { font-size: 11px; color: var(--ink-2); line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-lp-session-item {
  padding: 7px 10px; cursor: pointer; transition: background 0.1s;
  border-bottom: 1px solid var(--line-soft);
}
.sr-lp-session-item:hover { background: var(--bg-hover); }
.sr-lp-session-item.active { background: var(--indigo-soft); }
.sr-lp-session-item:last-child { border-bottom: none; }
.sr-lp-session-name { font-size: 11px; font-weight: 500; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-lp-session-meta { font-size: 9.5px; color: var(--ink-5); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-lp-search { width: 100%; background: var(--bg-card); border: 1px solid var(--line); border-radius: 4px; color: var(--ink-2); font-size: 11px; padding: 5px 8px; margin-bottom: 6px; outline: none; }
.sr-lp-search:focus { border-color: var(--indigo); }
.sr-lp-layer-row { display: flex; align-items: center; gap: 6px; padding: 4px 10px; cursor: pointer; transition: background 0.1s; font-size: 11px; color: var(--ink-3); }
.sr-lp-layer-row:hover { background: var(--bg-hover); }
.sr-lp-layer-dot { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }

/* Dedicated, always-visible Properties dock — between left rail/panel and canvas */
.sr-props-dock {
  width: 232px; flex-shrink: 0;
  background: var(--bg-elev); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.sr-props-dock-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 8px 0 10px; height: 28px; flex-shrink: 0;
  border-bottom: 1px solid var(--line);
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-5);
}
.sr-props-dock-body { flex: 1 1 0; overflow-y: auto; display: flex; flex-direction: column; }
.sr-props-dock-body::-webkit-scrollbar { width: 4px; }
.sr-props-dock-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
.sr-props-dock-collapse-btn {
  width: 18px; height: 18px; border-radius: var(--radius-btn-icon); border: none; background: none; cursor: pointer;
  color: var(--ink-5); display: flex; align-items: center; justify-content: center;
}
.sr-props-dock-collapse-btn:hover { background: var(--bg-hover); color: var(--ink-3); }

/* Center column */
.sr-center-col {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; overflow: hidden;
}

/* Right tool strip */
.sr-right-tool-strip {
  width: 48px; flex-shrink: 0;
  background: var(--bg-sunk); border-left: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center;
  padding: 4px 0; gap: 2px; overflow-y: auto; overflow-x: hidden;
}
.sr-right-tool-strip::-webkit-scrollbar { width: 3px; }
.sr-tool-btn {
  width: 44px; height: 42px; border-radius: var(--radius-btn-icon); border: 1px solid transparent;
  background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-3); transition: background 0.1s, color 0.1s, border-color 0.1s;
  position: relative; flex-shrink: 0;
}
.sr-tool-btn:hover { background: var(--bg-hover); color: var(--ink); }
.sr-tool-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.sr-tool-btn.active { background: var(--indigo-soft); color: var(--indigo-ink); border-color: var(--indigo-line); }
.sr-tool-btn.ph { opacity: 0.35; cursor: default; }
.sr-tool-btn.ph:hover { background: none; color: var(--ink-5); }
.sr-tool-sep { width: 32px; height: 1px; background: var(--line); margin: 3px 0; flex-shrink: 0; }
/* Native Aecos hover tip — elevated card + delay (matches .sr-rail-tip). */
.sr-tool-tip {
  position: absolute; right: calc(100% + 8px); top: 50%;
  transform: translateY(-50%) translateX(2px);
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.14));
  padding: 5px 10px; font-size: 11.5px; font-weight: 500; color: var(--ink);
  white-space: nowrap; pointer-events: none; z-index: 300; opacity: 0;
  transition: opacity 0.14s ease, transform 0.14s ease;
  display: flex; align-items: center; gap: 7px;
}
.sr-tool-btn:hover .sr-tool-tip {
  opacity: 1; transform: translateY(-50%) translateX(0);
  transition-delay: 0.3s;
}
.sr-tool-tip-key {
  font-size: 9px; color: var(--ink-4); font-family: var(--f-mono);
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px;
  background: var(--bg-card);
}

/* ── SR Keyboard Shortcuts overlay (restored 2026-07-17 — accidentally deleted
   by a landing-page styles.css edit in d9543a35, which left the window unstyled) ── */
.sr-shortcuts-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.5); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); z-index:9100; display:flex; align-items:center; justify-content:center; padding:24px; }
.sr-shortcuts-modal { background:var(--bg-card); border:1px solid var(--line); border-radius:var(--radius-card); width:680px; max-width:95vw; max-height:85vh; display:flex; flex-direction:column; box-shadow:0 32px 64px -16px rgba(0,0,0,0.28); overflow:hidden; }
.sr-shortcuts-header { display:flex; align-items:center; justify-content:space-between; padding:14px 20px; border-bottom:1px solid var(--line); flex-shrink:0; }
.sr-shortcuts-title { font-size:13px; font-weight:600; color:var(--ink-1); }
.sr-shortcuts-close { background:none; border:none; font-size:16px; cursor:pointer; color:var(--ink-5); width:26px; height:26px; padding:0; border-radius:var(--radius-btn-icon); display:flex; align-items:center; justify-content:center; transition:background 0.1s, color 0.1s; }
.sr-shortcuts-close:hover { background:var(--bg-hover); color:var(--ink-1); }
.sr-shortcuts-body { padding:16px 20px; overflow-y:auto; display:grid; grid-template-columns:1fr 1fr; gap:0 32px; }
.sr-shortcuts-section { margin-bottom:20px; }
.sr-shortcuts-section-label { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:0.07em; color:var(--indigo); margin-bottom:8px; }
.sr-shortcuts-grid { display:grid; grid-template-columns:auto 1fr; gap:3px 10px; align-items:baseline; }
.sr-shortcut-key { font-family:var(--f-mono); font-size:9.5px; background:var(--bg-hover); border:1px solid var(--line); border-radius:3px; padding:1px 5px; color:var(--ink-2); white-space:nowrap; }
.sr-shortcut-action { font-size:11.5px; color:var(--ink-3); }
.sr-shortcuts-footer { padding:10px 20px; border-top:1px solid var(--line-soft); font-size:10.5px; color:var(--ink-5); text-align:center; flex-shrink:0; display:flex; align-items:center; justify-content:center; gap:6px; }
/* Hint bubble */
.sr-shortcut-hint { position:fixed; bottom:88px; right:24px; background:var(--bg-elev); border:1px solid var(--line); border-radius:var(--radius-btn); padding:8px 14px; font-size:12px; color:var(--ink-1); box-shadow:var(--shadow-lg); cursor:pointer; z-index:500; display:flex; align-items:center; gap:6px; animation:sr-hint-in 0.2s ease; }
.sr-shortcut-key-sm { font-family:var(--f-mono); font-size:11px; background:var(--bg-sunk); border:1px solid var(--line); border-radius:3px; padding:0 4px; }
@keyframes sr-hint-in { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } }

/* ─── Studio Review — iPad / touch-input parity ──────────────────────────────
   Layout unchanged; these rules only touch-tune. touch-action:none on the canvas
   surface hands ALL gestures to the pointer-event code (pan / pinch / draw) so
   iOS Safari never page-scrolls, page-zooms, double-tap-zooms, or fires the
   long-press callout mid-markup. Scroll containers (panels/lists) keep native
   touch scroll — this rule is scoped to the canvas only. No effect on mouse. */
.sr-viewer-scroll {
  touch-action: none;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
/* Never disable selection / editing inside markup text editors + inputs. */
.sr-viewer-scroll [contenteditable="true"],
.sr-viewer-scroll [contenteditable="plaintext-only"],
.sr-viewer-scroll input,
.sr-viewer-scroll textarea {
  -webkit-user-select: text; user-select: text; -webkit-touch-callout: default;
}
/* Enlarged finger hit-zones for SVG selection/resize handles. Inert on fine
   pointers (mouse keeps pixel precision + no adjacent-handle overlap); live only
   on coarse (touch) pointers. Invisible — no visual / layout change. */
/* Inside an ACTIVE Studio Review session the workspace topbar is hidden so the
   canvas gets its vertical space back (body class set by StudioReviewPage while
   selSessionId is non-null; the SR dashboard/landing keeps the header). The
   topbar is an absolute overlay over .page; display:none makes AppShell's
   ResizeObserver publish --topbar-clearance: 0, so .page reclaims the space.
   In-session controls all live in the SRMenuBar (incl. back). */
body.sr-session-open .app-right > .topbar { display: none; }

.sr-touch-handle { pointer-events: none; }
@media (pointer: coarse) {
  .sr-touch-handle { pointer-events: all; }
  /* Comfortable tap targets for the dormant Bluebeam-mirror markup toolbar. */
  .mu-tool-btn { min-width: 44px; min-height: 44px; }
  .mu-nav-btn, .mu-zoom-btn { min-width: 40px; min-height: 40px; }
  /* Live SR surfaces — finger-sized targets, inert on desktop (fine pointers). */
  .sr-tool-btn { min-height: 44px; }
  .sr-color-dot { width: 28px; height: 28px; }
  .sr-color-grid { gap: 6px; }
  .sr-hud-btn { min-width: 40px; min-height: 40px; font-size: 16px; }
  .sr-btm-resize { height: 14px; margin-top: -5px; }
  .sr-btm-tab { min-height: 40px; }
}

/* Right side panel */
.sr-right-panel-slide {
  width: 256px; flex-shrink: 0; background: var(--bg-elev); border-left: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.sr-right-panel-slide .studio-review-panel {
  background: var(--bg-elev); color: var(--ink-2); border-top: none; height: 100%;
}
.sr-right-panel-slide .sr-panel-tabs {
  background: var(--bg-sunk); border-bottom: 1px solid var(--line);
}
.sr-right-panel-slide .sr-panel-tab {
  color: var(--ink-4); font-size: 10.5px; padding: 6px 8px;
}
.sr-right-panel-slide .sr-panel-tab:hover { color: var(--ink-2); }
.sr-right-panel-slide .sr-panel-tab.active { color: var(--indigo); border-bottom-color: var(--indigo); }
.sr-right-panel-slide .sr-panel-body { background: var(--bg-elev); }

/* SR session chat side panel */
.sr-chat-side-backdrop {
  /* Transparent click-catcher only (floating mode). Opening the chat must NOT
     dim/darken the SR view behind it — no background tint here. */
  position: fixed; inset: 0; z-index: 1009;
  background: transparent;
  opacity: 0; pointer-events: none;
  transition: opacity 0.22s ease;
}
.sr-chat-side-backdrop.open { opacity: 1; pointer-events: auto; }

.sr-chat-side-panel {
  position: fixed; left: 0; top: 0; height: 100vh; width: 380px; z-index: 1010;
  background: var(--bg); border-right: 1px solid var(--line);
  box-shadow: 4px 0 28px rgba(0,0,0,0.2);
  display: flex; flex-direction: column; overflow: hidden;
  transform: translateX(-100%);
  transition: transform 0.28s cubic-bezier(0.4,0,0.2,1);
}
.sr-chat-side-panel.open { transform: translateX(0); }
/* Specialist rail button — keeps the old FAB's indigo identity. */
.sr-rail-btn.sr-rail-btn-specialist {
  background: var(--indigo); color: #fff; border-radius: 9px;
}
.sr-rail-btn.sr-rail-btn-specialist:hover { background: var(--indigo); color: #fff; filter: brightness(1.12); }
.sr-rail-btn.sr-rail-btn-specialist.active {
  background: var(--indigo); color: #fff;
  box-shadow: 0 0 0 3px var(--indigo-soft, rgba(99,102,241,0.25));
}
/* Docked variant — lives in the left rail's switchable panel slot (like Code
   Check / Comments) instead of floating over the canvas. */
.sr-chat-side-panel.docked {
  position: static; height: 100%; width: 100%; z-index: auto;
  transform: none; box-shadow: none; border-right: none; transition: none;
}

.sr-chat-side-header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 13px 16px; min-height: 56px; box-sizing: border-box;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card); flex-shrink: 0;
}
.sr-chat-side-close {
  width: 28px; height: 28px; border-radius: var(--radius-btn-icon, 8px); border: none;
  background: none; cursor: pointer; color: var(--ink-4);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.12s, color 0.12s;
}
.sr-chat-side-close:hover { background: var(--bg-hover); color: var(--ink-2); }

/* The message list now renders .cmd-chat-row (see SRSessionChatPanel), which
   carries its own per-row bottom margin exactly like the main chat. The old
   18px flex gap was tuned for the bespoke .sr-chat-side-msg rows and would
   double up with those margins, so spacing is left to the rows themselves. */
.sr-chat-side-body {
  flex: 1; overflow-y: auto; padding: 16px;
  display: flex; flex-direction: column; gap: 2px;
}
/* Empty state (intro line + suggestion chips) still wants real separation. */
.sr-chat-side-body > .sr-chat-side-intro { margin-bottom: 8px; }
.sr-chat-side-body::-webkit-scrollbar { width: 4px; }
.sr-chat-side-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }

.sr-chat-side-chip {
  text-align: left; background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 8px; padding: 8px 12px; cursor: pointer;
  font-size: 12px; color: var(--ink-2); line-height: 1.4;
  transition: background 0.12s, border-color 0.12s;
}
.sr-chat-side-chip:hover:not(:disabled) { background: var(--bg-hover); border-color: var(--indigo-soft); }
.sr-chat-side-chip:disabled { opacity: 0.55; cursor: not-allowed; }

.sr-chat-side-msg {
  display: flex; gap: 8px; align-items: flex-start;
}
.sr-chat-side-msg.user { flex-direction: row-reverse; }

/* Messages — mirror the main Aecos Intelligence chat (.chat-msg): user turns
   are ink-filled bubbles, assistant turns render as plain flowing text. */
.sr-chat-side-bubble {
  max-width: 100%; font-size: 13px; line-height: 1.6; word-break: break-word;
}
.sr-chat-side-bubble.user {
  background: var(--ink); color: var(--bg-card);
  border-radius: 12px 12px 4px 12px; padding: 10px 14px;
  max-width: 88%;
}
.sr-chat-side-bubble.ai {
  background: none; border: none; padding: 0; color: var(--ink);
}
.sr-chat-side-bubble-title {
  font-weight: 600; font-size: 12.5px; margin-bottom: 4px; color: inherit;
}
/* Markdown body inside AI turns — match the main chat's .ai-body rhythm. */
.sr-chat-md { font-size: 13px; line-height: 1.6; color: var(--ink); }
.sr-chat-md p { margin: 0 0 10px; }
.sr-chat-md p:last-child { margin-bottom: 0; }
.sr-chat-md ul, .sr-chat-md ol { margin: 0 0 10px; padding-left: 18px; }
.sr-chat-md code {
  font-family: var(--f-mono); font-size: 11.5px;
  background: var(--bg-elev); border-radius: 4px; padding: 1px 4px;
}

/* Composer — matches the main chat's .chat-input card treatment. */
.sr-chat-side-input-row {
  display: flex; gap: 8px; align-items: flex-end; flex-shrink: 0;
  margin: 10px 12px 12px; padding: 9px 10px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-card); box-shadow: var(--shadow-sm);
}
.sr-chat-side-textarea {
  flex: 1; resize: none; border: 0; border-radius: 0;
  padding: 4px 4px; font-size: 12.5px; background: none; color: var(--ink);
  outline: none; line-height: 1.5; font-family: inherit; overflow: hidden;
}
.sr-chat-side-textarea::placeholder { color: var(--ink-4); }
.sr-chat-side-send {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: var(--radius-btn-icon, 8px);
  background: var(--bg-hover); border: 1px solid var(--line);
  cursor: default; display: flex; align-items: center; justify-content: center;
  color: var(--ink-4); transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.sr-chat-side-send.active {
  background: var(--indigo); border-color: var(--indigo); color: white; cursor: pointer;
}

/* Nav bar */
.sr-nav-bar {
  display: flex; align-items: center; gap: 2px; flex-shrink: 0; height: 32px;
  background: var(--bg-sunk); border-top: 1px solid var(--line); padding: 0 6px;
  overflow: hidden; user-select: none;
}
.sr-nav-btn {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 24px; border-radius: var(--radius-btn-icon); border: none; flex-shrink: 0;
  background: none; cursor: pointer; color: var(--ink-3);
  transition: background 0.1s, color 0.1s;
}
.sr-nav-btn:hover { background: var(--bg-hover); color: var(--ink); }
.sr-nav-btn:disabled { opacity: 0.3; cursor: default; }
.sr-nav-sep { width: 1px; height: 16px; background: var(--line); margin: 0 5px; flex-shrink: 0; }
.sr-nav-lbl {
  font-size: 11px; color: var(--ink-4); white-space: nowrap;
  font-family: var(--f-mono); padding: 0 5px;
}
.sr-nav-page-inp {
  width: 38px; height: 20px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 3px;
  color: var(--ink-2); font-size: 11px; font-family: var(--f-mono); text-align: center; padding: 0;
}
.sr-nav-center { flex: 1; display: flex; align-items: center; justify-content: center; min-width: 0; }
.sr-nav-file-lbl {
  font-size: 10.5px; color: var(--ink-4); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 280px; font-family: var(--f-mono);
}
.sr-nav-right { margin-left: auto; display: flex; align-items: center; gap: 1px; flex-shrink: 0; }
.sr-nav-zoom-lbl { font-size: 10px; color: var(--ink-5); font-family: var(--f-mono); min-width: 36px; text-align: center; }

/* Live-presence avatars in the nav bar — bounded, in-flow stack so they sit
   in the toolbar row (not on top of the ?/panel-toggle controls), with the
   hover tooltip layered above. */
.sr-presence-group { display: inline-flex; align-items: center; flex-shrink: 0; margin: 0 4px; }
.sr-presence-avatar-wrap { position: relative; line-height: 0; }
.sr-presence-avatar { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; border: 2px solid var(--bg-elev); box-sizing: border-box; display: block; }
.sr-presence-avatar-initials { display: flex; align-items: center; justify-content: center; font-size: 8.5px; font-weight: 700; color: #fff; }
.sr-presence-avatar-overflow { width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 8.5px; font-weight: 700; background: var(--bg-sunk); color: var(--ink-3); border: 2px solid var(--bg-elev); box-sizing: border-box; flex-shrink: 0; }
.sr-presence-tooltip { position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); background: var(--ink); color: var(--bg-elev); font-size: 10.5px; padding: 3px 7px; border-radius: 5px; white-space: nowrap; z-index: 60; pointer-events: none; }

/* Bottom panel */
.sr-btm-panel {
  flex-shrink: 0; background: var(--bg-elev); border-top: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.sr-btm-resize {
  height: 4px; cursor: ns-resize; flex-shrink: 0; background: transparent;
  transition: background 0.1s;
}
.sr-btm-resize:hover { background: var(--indigo-soft); }
.sr-btm-tabs {
  display: flex; align-items: center; height: 26px; flex-shrink: 0;
  background: var(--bg-sunk); border-bottom: 1px solid var(--line); padding: 0 4px;
}
.sr-btm-tab {
  padding: 0 9px; height: 100%; border: none; background: none; cursor: pointer;
  font-size: 10.5px; color: var(--ink-4);
  border-bottom: 2px solid transparent; display: flex; align-items: center;
  transition: color 0.1s, border-color 0.1s; white-space: nowrap;
}
.sr-btm-tab:hover { color: var(--ink-2); }
.sr-btm-tab.active { color: var(--indigo); border-bottom-color: var(--indigo); }
.sr-btm-close {
  margin-left: auto; width: 20px; height: 20px; border: none; background: none;
  cursor: pointer; color: var(--ink-5); display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-btn-icon, 8px); transition: color 0.1s, background 0.1s;
}
.sr-btm-close:hover { color: var(--ink-2); background: var(--bg-hover); }
.sr-btm-body { display: flex; flex-direction: column; flex: 1 1 0; overflow: hidden; }
.sr-btm-body::-webkit-scrollbar { width: 5px; height: 5px; }
.sr-btm-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }

/* Markups spreadsheet */
.sr-mkp-tbl { width: 100%; border-collapse: collapse; font-size: 10.5px; color: var(--ink-2); min-width: 800px; }
.sr-mkp-tbl th {
  text-align: left; padding: 3px 8px; background: var(--bg-sunk);
  border-bottom: 1px solid var(--line); color: var(--ink-5);
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  position: sticky; top: 0; z-index: 1; white-space: nowrap; cursor: pointer;
}
.sr-mkp-tbl th:hover { color: var(--ink-3); }
.sr-mkp-tbl td { padding: 3px 8px; border-bottom: 1px solid var(--line-soft); max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-mkp-tbl tr { cursor: pointer; }
.sr-mkp-tbl tr:hover td { background: var(--bg-hover); }
.sr-mkp-tbl tr.sel td { background: var(--indigo-soft); }
.sr-mkp-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; vertical-align: middle; }
.sr-mkp-status-badge {
  display: inline-block; padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600;
}

/* Status bar */
.sr-status-bar {
  display: flex; align-items: center; height: 20px; flex-shrink: 0;
  background: var(--bg-sunk); border-top: 1px solid var(--line);
  padding: 0 8px; overflow: hidden; user-select: none;
}
.sr-status-msg { flex: 1; font-size: 10px; color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 8px; }
.sr-status-sep { width: 1px; height: 10px; background: var(--line); margin: 0 5px; flex-shrink: 0; }
.sr-status-tog {
  display: flex; align-items: center; gap: 3px; padding: 0 4px; height: 100%;
  font-size: 9.5px; color: var(--ink-5); border: none; background: none;
  cursor: pointer; transition: color 0.1s; white-space: nowrap;
}
.sr-status-tog:hover { color: var(--ink-3); }
.sr-status-tog.on { color: var(--indigo); }
.sr-status-coords { font-family: var(--f-mono); font-size: 9px; color: var(--ink-5); min-width: 110px; text-align: right; }
.sr-status-scale { font-family: var(--f-mono); font-size: 9px; color: var(--ink-4); white-space: nowrap; }
.sr-status-dot { width: 5px; height: 5px; border-radius: 50%; margin-right: 3px; flex-shrink: 0; }
.sr-status-dot.live { background: var(--ok); }
.sr-status-dot.mock { background: var(--warn); }
.sr-status-dot.err { background: var(--bad); }
.sr-status-backend { display: flex; align-items: center; font-size: 9.5px; color: var(--ink-5); border-left: 1px solid var(--line); padding-left: 8px; margin-left: 4px; white-space: nowrap; }

/* Context menu */
.sr-ctx-menu {
  position: fixed; z-index: 9999; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); padding: 3px 0; min-width: 176px;
  box-shadow: var(--shadow-lg); font-size: 11.5px;
}
.sr-ctx-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 12px; cursor: pointer; color: var(--ink-2); gap: 10px;
  transition: background 0.08s;
}
.sr-ctx-item:hover { background: var(--indigo-soft); color: var(--indigo-ink); }
.sr-ctx-item.disabled { opacity: 0.35; pointer-events: none; }
.sr-ctx-sep { height: 1px; background: var(--line-soft); margin: 3px 0; }
.sr-ctx-key { font-size: 9.5px; color: var(--ink-5); font-family: var(--f-mono); }

/* ─── Monetization — plan & usage primitives ─────────────────────────────── */

/* PlanBadge — reuses .pill shape; plan-specific overrides */
.plan-badge-studio_pro { font-style: italic; letter-spacing: 0.01em; }

/* UsageMeter */
.usage-meter { display: flex; flex-direction: column; gap: 6px; }
.usage-meter-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px;
}
.usage-meter-label { color: var(--ink-3); font-weight: 500; }
.usage-meter-count { font-feature-settings: "tnum"; color: var(--ink-3); }
.usage-meter-count-ok      { color: var(--ok); }
.usage-meter-count-warn    { color: var(--warn); }
.usage-meter-count-danger  { color: var(--bad); }
.usage-meter-track {
  height: 5px; background: var(--bg-sunk); border-radius: 3px; overflow: hidden;
}
.usage-meter-fill { height: 100%; border-radius: 3px; transition: width .3s ease; }
.usage-meter-ok     { background: var(--ok); }
.usage-meter-warn   { background: var(--warn); }
.usage-meter-danger { background: var(--bad); }

/* AICreditsMeter footer */
.ai-credits-meter { display: flex; flex-direction: column; gap: 6px; }
.usage-meter-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-4);
}
.usage-meter-reset    { flex: 1; min-width: 0; }
.usage-meter-purchased { color: var(--ok); font-weight: 500; }
.usage-meter-buy {
  background: none; border: none; cursor: pointer; padding: 0;
  font: inherit; font-size: 11.5px; color: var(--indigo);
  transition: opacity .1s;
}
.usage-meter-buy:hover { opacity: 0.75; text-decoration: underline; text-underline-offset: 2px; }

/* ─── CreditMeter (sidebar Intelligence-credit usage meter) ────────────────
   Compact, always-visible variant of UsageMeter mounted in .sidebar-foot
   directly above the profile row. Renders as a borderless button (full-row
   click target → opens Settings → Buy Intelligence credits). Tone tokens
   reuse --ok / --warn / --bad so dark/light theme switching just works.
   Two size modes: default (sidebar expanded) and --collapsed (icon-only). */
.credit-meter {
  appearance: none;
  background: var(--bg-sunk);
  border: 1px solid transparent;
  border-radius: var(--radius-menu);
  padding: 8px 12px;
  margin: 0 0 8px;
  width: 100%;
  display: flex; flex-direction: column; gap: 6px;
  cursor: pointer;
  color: inherit;
  font: inherit;
  text-align: left;
  transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
.credit-meter:hover {
  background: var(--bg-hover);
  border-color: var(--line);
}
.credit-meter:active { transform: translateY(0.5px); }
/* Unlimited (enterprise/comped) has no progress track — a single icon + label,
   so it takes the full pill (a circle when collapsed). Limited-plan meters keep
   the softer --radius-menu since their multi-line track distorts as a stadium. */
.credit-meter--unlimited { border-radius: var(--radius-btn); }
.credit-meter:focus-visible {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 22%, transparent);
}

.credit-meter-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; line-height: 1.2;
  font-feature-settings: "tnum";
  color: var(--ink-2, var(--ink));
}
.credit-meter-icon {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-3);
  flex: 0 0 auto;
}
.credit-meter-count {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}

.credit-meter-track {
  height: 4px;
  background: var(--bg-card);
  border-radius: 3px;
  overflow: hidden;
}
.credit-meter-fill {
  height: 100%;
  border-radius: 3px;
  background: var(--ok);
  /* width transitions (literal numeric); background is var()-valued so it must
     SNAP on a tone-class flip — transitioning a var() color sticks at the
     from-value in this Chrome build (see [[feedback-css-var-transition-stuck]]). */
  transition: width 0.3s ease;
}

.credit-meter-reset {
  font-size: 10.5px;
  color: var(--ink-4);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}

/* Tone modifiers — apply to BOTH the count text and the bar fill so the
   meter reads the same at a glance regardless of which surface the eye
   tracks first. */
.credit-meter--ok     .credit-meter-icon { color: var(--ok); }
.credit-meter--ok     .credit-meter-fill { background: var(--ok); }
.credit-meter--warn   .credit-meter-icon { color: var(--warn); }
.credit-meter--warn   .credit-meter-count{ color: var(--warn); }
.credit-meter--warn   .credit-meter-fill { background: var(--warn); }
.credit-meter--danger .credit-meter-icon { color: var(--bad); }
.credit-meter--danger .credit-meter-count{ color: var(--bad); }
.credit-meter--danger .credit-meter-fill { background: var(--bad); }
.credit-meter--unlimited .credit-meter-icon  { color: var(--indigo); }
.credit-meter--unlimited .credit-meter-count { color: var(--ink-2, var(--ink)); }

/* Collapsed sidebar — icon-only mode. Square hit area, tone-colored dot in
   the bottom-right corner so the user can still read remaining-credit
   health at a glance without text. */
.credit-meter--collapsed {
  position: relative;
  width: 36px; height: 36px;
  padding: 0;
  margin: 0 auto 8px;
  align-items: center; justify-content: center;
  flex-direction: row;
}
.credit-meter--collapsed .credit-meter-icon { color: var(--ink-3); }
.credit-meter--collapsed.credit-meter--ok     .credit-meter-icon { color: var(--ok); }
.credit-meter--collapsed.credit-meter--warn   .credit-meter-icon { color: var(--warn); }
.credit-meter--collapsed.credit-meter--danger .credit-meter-icon { color: var(--bad); }
.credit-meter--collapsed.credit-meter--unlimited .credit-meter-icon { color: var(--indigo); }
.credit-meter-dot {
  position: absolute; right: 4px; bottom: 4px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ok);
  border: 1.5px solid var(--bg-sunk);
}
.credit-meter--collapsed.credit-meter--warn   .credit-meter-dot { background: var(--warn); }
.credit-meter--collapsed.credit-meter--danger .credit-meter-dot { background: var(--bad); }

/* SessionLimitToast — global non-blocking session-cap notice (ui.jsx).
   Fixed bottom-right, above the command bar but below modals. */
.session-limit-toast {
  position: fixed; right: 18px; bottom: 18px; z-index: 1200;
  width: 300px; max-width: calc(100vw - 36px);
  padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.18);
  display: flex; flex-direction: column; gap: 6px;
}
.session-limit-toast-title {
  font-size: 13px; font-weight: 600; color: var(--ink);
}
.session-limit-toast-body {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.45;
}
.session-limit-toast-actions {
  display: flex; align-items: center; gap: 10px; margin-top: 6px;
}
.session-limit-toast-cta {
  border: none; padding: 6px 12px; border-radius: 8px;
  background: var(--indigo); color: #fff;
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.session-limit-toast-cta:hover { filter: brightness(1.08); }
.session-limit-toast-dismiss {
  border: none; background: none; padding: 6px 4px;
  font-size: 12px; color: var(--ink-4); cursor: pointer;
}
.session-limit-toast-dismiss:hover { color: var(--ink-2); }


/* LockedFeatureCard */
.feature-gate-locked {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 20px; border: 1.5px dashed var(--line-strong); border-radius: 10px;
  background: var(--bg-elev);
}
.feature-gate-locked-icon {
  width: 36px; height: 36px; border-radius: 8px;
  background: var(--bg-sunk); border: 1px solid var(--line);
  display: grid; place-items: center; color: var(--ink-4); flex: 0 0 auto;
}
.feature-gate-locked-text { flex: 1; min-width: 0; }
.feature-gate-locked-headline {
  font-size: 13px; font-weight: 500; color: var(--ink); margin: 0 0 2px;
}
.feature-gate-locked-body {
  font-size: 12px; color: var(--ink-4); margin: 0; line-height: 1.4;
}

/* PlanLimitNotice */
.plan-limit-notice {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-radius: 8px;
  background: var(--warn-soft); border: 1px solid var(--warn-line);
  font-size: 13px;
}
.plan-limit-notice-icon { color: var(--warn); flex: 0 0 auto; }
.plan-limit-notice-text {
  flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
.plan-limit-notice-text strong { color: var(--ink); font-weight: 600; white-space: nowrap; }
.plan-limit-notice-text span   { color: var(--ink-3); font-size: 12px; }
.plan-limit-notice-dismiss {
  width: 24px; height: 24px; color: var(--ink-4);
  background: none; border: none; cursor: pointer;
  display: grid; place-items: center; border-radius: 5px;
  flex: 0 0 auto; transition: background .1s, color .1s;
}
.plan-limit-notice-dismiss:hover { background: var(--bg-hover); color: var(--ink); }

/* PricingCard */
.pricing-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  padding: 22px 20px; display: flex; flex-direction: column; gap: 0;
  box-shadow: var(--shadow-sm); flex: 1 1 0; min-width: 160px;
  transition: box-shadow .15s, border-color .15s;
}
.pricing-card-current {
  border-color: var(--indigo-line); background: var(--indigo-soft);
}
.pricing-card-highlight {
  border-color: var(--indigo); box-shadow: 0 0 0 2px var(--indigo-soft), var(--shadow-md);
}
.pricing-card-head { margin-bottom: 16px; }
.pricing-card-price {
  display: flex; align-items: baseline; gap: 2px; margin: 10px 0 6px;
}
.pricing-card-price-amount {
  font-size: 26px; font-weight: 500; letter-spacing: -0.03em; color: var(--ink);
  font-feature-settings: "lnum","tnum";
}
.pricing-card-price-period { font-size: 13px; color: var(--ink-4); }
.pricing-card-price-custom {
  font-size: 20px; font-weight: 500; color: var(--ink); letter-spacing: -0.02em;
}
.pricing-card-desc {
  font-size: 12px; color: var(--ink-4); margin: 0; line-height: 1.45;
}
.pricing-card-features {
  list-style: none; margin: 0 0 20px; padding: 0;
  display: flex; flex-direction: column; gap: 7px; flex: 1;
}
.pricing-card-feature {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 12.5px; color: var(--ink-2); line-height: 1.4;
}
.pricing-card-feature svg { color: var(--ok); flex: 0 0 auto; margin-top: 1px; }
.pricing-card-current .pricing-card-feature svg { color: var(--indigo); }
.pricing-card-cta { width: 100%; justify-content: center; margin-top: auto; }
.pricing-card-cta:disabled { opacity: 0.6; cursor: default; background: var(--bg-sunk); color: var(--ink-3); border-color: var(--line); }

/* CreditPackCard */
.credit-pack-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  padding: 16px 18px; display: flex; align-items: center; gap: 12px;
  box-shadow: var(--shadow-sm); flex: 1 1 0; min-width: 140px;
}
.credit-pack-card-label { flex: 1; font-size: 13px; font-weight: 500; color: var(--ink); }
.credit-pack-card-price { font-size: 15px; font-weight: 500; color: var(--ink); font-feature-settings: "tnum"; }
.credit-pack-preview { flex: 0 0 auto; }
.credit-pack-card-btn { flex: 0 0 auto; white-space: nowrap; }
.credit-pack-card-btn:disabled { opacity: 0.5; cursor: default; }

/* UpgradeModal */
.upgrade-modal-overlay {
  position: fixed; inset: 0; z-index: 800;
  background: rgba(0,0,0,0.38);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: dvOverlayIn 0.18s ease both;
}
.upgrade-modal {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 16px;
  width: 100%; max-width: 1020px; max-height: 90vh;
  display: flex; flex-direction: column;
  box-shadow: 0 32px 80px rgba(0,0,0,0.22);
  animation: dvPanelIn 0.22s cubic-bezier(0.34,1.2,0.64,1) both;
  overflow: hidden;
}
.upgrade-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 22px 24px 18px; border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.upgrade-modal-title { font-size: 18px; font-weight: 600; color: var(--ink); letter-spacing: -0.02em; margin: 0; }
.upgrade-modal-sub   { font-size: 13px; color: var(--ink-4); margin: 3px 0 0; }
.upgrade-modal-body  { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 24px; display: flex; flex-direction: column; gap: 28px; }
.upgrade-modal-tiers { display: flex; gap: 12px; align-items: stretch; flex-wrap: wrap; }
.upgrade-modal-credits-section {
  border-top: 1px solid var(--line-soft); padding-top: 20px;
}
.upgrade-modal-credits-head {
  font-size: 13px; font-weight: 500; color: var(--ink); margin: 0 0 12px;
}
.upgrade-modal-credit-packs { display: flex; gap: 10px; flex-wrap: wrap; }

/* ============================================================================
   Combobox — .combobox + __input + __dropdown + __option etc.
   ============================================================================ */

.combobox { position: relative; display: block; width: 100%; }
.combobox--disabled { opacity: 0.55; pointer-events: none; }

.combobox__input {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  min-height: 34px; padding: 4px 32px 4px 10px; position: relative;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-card); cursor: text;
  transition: border-color 120ms, box-shadow 120ms;
}
.combobox__input:hover:not(.is-disabled) { border-color: var(--line-strong); }
.combobox__input.is-open  { border-color: var(--indigo); box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent); }
.combobox__input.is-disabled { cursor: not-allowed; }

.combobox__text {
  flex: 1; min-width: 80px; border: none; outline: none;
  background: transparent; font-size: 13px; color: var(--ink);
  padding: 0; line-height: 1.4;
}
.combobox__text::placeholder { color: var(--ink-5); }

.combobox__arrow {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  color: var(--ink-4); pointer-events: none; display: flex; align-items: center;
}

/* Pills (multiple mode) */
.combobox__pill {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px 1px 8px; border-radius: 4px;
  background: var(--indigo-soft); color: var(--indigo);
  font-size: 12px; font-weight: 500; line-height: 1.5;
  white-space: nowrap;
}
.combobox__pill-remove {
  display: flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 2px;
  background: none; border: none; cursor: pointer;
  color: var(--indigo); font-size: 14px; line-height: 1;
  padding: 0; transition: background 100ms;
}
.combobox__pill-remove:hover { background: color-mix(in srgb, var(--indigo) 20%, transparent); }

/* Dropdown */
.combobox__dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 320;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.12);
  max-height: 240px; overflow-y: auto;
  animation: cbx-in 120ms var(--ease-out) both;
}
@keyframes cbx-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

.combobox__option {
  display: flex; align-items: center; gap: 7px;
  width: 100%; text-align: left;
  padding: 7px 10px; font-size: 13px; color: var(--ink);
  background: none; border: none; cursor: pointer;
  border-radius: 0; transition: background 80ms;
}
.combobox__option:first-child { border-radius: 7px 7px 0 0; }
.combobox__option:last-child  { border-radius: 0 0 7px 7px; }
.combobox__option:only-child  { border-radius: 7px; }
.combobox__option--active     { background: var(--bg-hover); }
.combobox__option--selected   { color: var(--indigo); }
.combobox__option--disabled   { opacity: 0.45; cursor: not-allowed; }
.combobox__option--create     { color: var(--indigo); font-style: italic; }

.combobox__create-hint { font-style: normal; font-weight: 500; margin-right: 2px; }
.combobox__opt-icon    { display: flex; color: var(--ink-4); flex: 0 0 auto; }
.combobox__opt-badge   { margin-left: auto; font-size: 11px; color: var(--ink-5); background: var(--bg-sunk); border-radius: 4px; padding: 1px 5px; flex: 0 0 auto; }
.combobox__opt-check   { margin-left: auto; color: var(--indigo); flex: 0 0 auto; }

/* Option text container — wraps label + optional description so the option
   button can flex its layout while the text stack keeps its own typography. */
.combobox__opt-text  { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.combobox__opt-label { line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combobox__opt-desc  { font-size: 11.5px; color: var(--ink-4); line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combobox__option--with-desc { padding-top: 8px; padding-bottom: 8px; }

/* Match highlight — the substring that matched the query. Subtle, not
   distracting; uses the indigo brand color at low opacity so the highlighted
   characters read as "this matched" without competing with the option text. */
.combobox__match {
  background: color-mix(in srgb, var(--indigo) 18%, transparent);
  color: inherit;
  font-weight: 600;
  border-radius: 2px;
  padding: 0 1px;
  /* <mark> default styling is yellow + black — reset both */
}

.combobox__empty {
  padding: 10px 12px; font-size: 13px; color: var(--ink-5); text-align: center;
}
.combobox__loading {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; font-size: 13px; color: var(--ink-5);
}
.combobox__spinner {
  display: inline-block; width: 13px; height: 13px;
  border: 2px solid var(--line); border-top-color: var(--indigo);
  border-radius: 50%;
  animation: cbx-spin 0.7s linear infinite;
}
@keyframes cbx-spin { to { transform: rotate(360deg); } }

/* ============================================================================
   MultiSelect — checkable-list dropdown with type-ahead + select-all.
   .multiselect + __trigger + __chevron + __dropdown + __search + __option
                + __check + __opt-icon/text/label/desc/badge + __empty
   Size modifiers: --sm / --md
   ============================================================================ */

.multiselect {
  position: relative;
  display: inline-block;
  min-width: 200px;
}
.multiselect--disabled { opacity: 0.55; pointer-events: none; }

.multiselect__trigger {
  display: inline-flex; align-items: center; gap: 8px;
  width: 100%; min-height: 34px;
  padding: 4px 10px 4px 12px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card);
  font: inherit; font-size: 13px; color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms, box-shadow 120ms;
}
.multiselect__trigger:hover:not(:disabled) { border-color: var(--line-strong); }
.multiselect.is-open .multiselect__trigger {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.multiselect__placeholder { color: var(--ink-5); flex: 1; min-width: 0; }
.multiselect__summary {
  flex: 1; min-width: 0;
  font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.multiselect__chevron { color: var(--ink-4); display: flex; align-items: center; flex: 0 0 auto; }

.multiselect--sm .multiselect__trigger { min-height: 28px; font-size: 12.5px; padding: 2px 8px 2px 10px; }

/* Dropdown panel */
.multiselect__dropdown {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  z-index: 320;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
  max-height: 320px;
  display: flex; flex-direction: column;
  min-width: 240px;
  overflow: hidden;
  animation: cbx-in 120ms var(--ease-out) both;
}

/* Search input row */
.multiselect__search {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line-soft);
  flex: 0 0 auto;
}
.multiselect__search svg { color: var(--ink-4); flex: 0 0 auto; }
.multiselect__search input {
  flex: 1; min-width: 0;
  border: none; outline: none; background: transparent;
  font: inherit; font-size: 12.5px; color: var(--ink);
  padding: 0;
}
.multiselect__search input::placeholder { color: var(--ink-5); }
.multiselect__search-clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px;
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); border-radius: 3px;
  flex: 0 0 auto;
  padding: 0;
}
.multiselect__search-clear:hover { background: var(--bg-hover); color: var(--ink); }

/* Scrollable option list */
.multiselect__list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 4px;
}

/* Option button row */
.multiselect__option {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 6px 10px;
  font: inherit; font-size: 13px; color: var(--ink);
  background: none; border: none; border-radius: 5px;
  cursor: pointer; text-align: left;
  transition: background 80ms;
}
.multiselect__option:hover:not(:disabled):not(.multiselect__option--disabled) {
  background: var(--bg-hover);
}
.multiselect__option--disabled { opacity: 0.45; cursor: not-allowed; }
.multiselect__option--checked   { color: var(--ink); }

/* "Select all" toggle row — visually distinct top divider */
.multiselect__option--all {
  border-bottom: 1px solid var(--line-soft);
  border-radius: 0;
  margin: 0;
  font-weight: 500;
}

.multiselect__option--with-desc { padding-top: 8px; padding-bottom: 8px; }

/* Checkbox marker — square 14px, fills indigo when checked, dash when mixed */
.multiselect__check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; flex: 0 0 auto;
  border: 1.5px solid var(--line-strong);
  border-radius: 3px;
  background: var(--bg-card);
  color: #fff;
  transition: background 120ms, border-color 120ms;
}
.multiselect__check.is-on,
.multiselect__check.is-mixed {
  background: var(--indigo);
  border-color: var(--indigo);
}
.multiselect__check-dash {
  width: 8px; height: 1.5px;
  background: #fff;
  border-radius: 1px;
}

/* Text column inside option (label + optional description) */
.multiselect__opt-icon  { display: flex; color: var(--ink-4); flex: 0 0 auto; }
.multiselect__opt-text  { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.multiselect__opt-label { line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multiselect__opt-desc  { font-size: 11.5px; color: var(--ink-4); line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multiselect__opt-badge { margin-left: auto; font-size: 11px; color: var(--ink-5); background: var(--bg-sunk); border-radius: 4px; padding: 1px 5px; flex: 0 0 auto; }

.multiselect__empty {
  padding: 14px 12px; font-size: 12.5px; color: var(--ink-5); text-align: center;
}

/* ============================================================================
   Form fields — TextField / TextArea / NumberField / Select share .field shell.
   .field + __label + __required + __control + __input + __textarea + __select
   + __leading + __trailing + __affix + __select-chevron + __helper
   Size modifiers: --sm / --md. State modifiers: --error / --disabled.
   ============================================================================ */

.field {
  display: flex; flex-direction: column; gap: 5px;
  width: 100%;
}

.field__label {
  font-size: 12px; font-weight: 500; color: var(--ink-2);
  letter-spacing: -0.005em;
  display: inline-flex; align-items: center; gap: 2px;
}
.field__required { color: var(--bad); font-weight: 600; }

.field__control {
  position: relative;
  display: flex; align-items: stretch;
  width: 100%;
}

/* Base input / textarea / select styling */
.field__input, .field__textarea, .field__select {
  width: 100%;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card); color: var(--ink);
  font-family: inherit; font-size: 13px; line-height: 1.4;
  padding: 7px 10px;
  transition: border-color 120ms, box-shadow 120ms, background-color 120ms;
  outline: none;
}
.field__input::placeholder,
.field__textarea::placeholder { color: var(--ink-5); }

.field__input:hover:not(:disabled),
.field__textarea:hover:not(:disabled),
.field__select:hover:not(:disabled) { border-color: var(--line-strong); }

.field__input:focus,
.field__textarea:focus,
.field__select:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}

/* Size — sm */
.field--sm .field__input,
.field--sm .field__textarea,
.field--sm .field__select {
  padding: 5px 8px; font-size: 12.5px;
}

/* Error state */
.field--error .field__input,
.field--error .field__textarea,
.field--error .field__select {
  border-color: var(--bad);
  background: color-mix(in srgb, var(--bad-soft) 50%, var(--bg-card));
}
.field--error .field__input:focus,
.field--error .field__textarea:focus,
.field--error .field__select:focus {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bad) 18%, transparent);
}

/* Disabled state */
.field--disabled .field__input,
.field--disabled .field__textarea,
.field--disabled .field__select,
.field__input:disabled,
.field__textarea:disabled,
.field__select:disabled {
  opacity: 0.55; cursor: not-allowed;
  background: var(--bg-sunk);
}

/* Leading / trailing icons */
.field__leading, .field__trailing {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center;
  color: var(--ink-4); pointer-events: none;
}
.field__leading  { left: 10px;  }
.field__trailing { right: 10px; }
.field__control--has-leading  .field__input { padding-left: 32px; }
.field__control--has-trailing .field__input { padding-right: 32px; }
.field--sm .field__leading  { left: 8px; }
.field--sm .field__trailing { right: 8px; }
.field--sm .field__control--has-leading  .field__input { padding-left: 28px; }
.field--sm .field__control--has-trailing .field__input { padding-right: 28px; }

/* Affix text (NumberField prefix/suffix — visible text, not icon) */
.field__affix {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center;
  font-size: 12.5px; color: var(--ink-4);
  pointer-events: none; font-feature-settings: "tnum";
}
.field__affix--leading  { left: 10px; }
.field__affix--trailing { right: 10px; }
.field--sm .field__affix { font-size: 11.5px; }

/* NumberField — suppress native spinner buttons */
.field__input--number::-webkit-outer-spin-button,
.field__input--number::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.field__input--number { -moz-appearance: textfield; appearance: textfield; }

/* TextArea — explicit resize directions */
.field__textarea {
  min-height: 80px;
  font-family: inherit;
  line-height: 1.5; /* makes _taAutosize math predictable */
}
.field__textarea--vertical { resize: vertical; }
.field__textarea--none     { resize: none; }
.field__textarea--both     { resize: both; }

/* Autosize mode — JS sets explicit height; CSS removes min-height so collapse
   step in _taAutosize is honored. overflowY is also JS-set per state. */
.field__textarea--autosize {
  resize: none;
  min-height: 0;
  overflow-y: hidden;
}

/* Character counter — bottom-right of the .field__control box.
   pointer-events none so it doesn't intercept clicks targeting the textarea. */
.field__counter {
  position: absolute; right: 8px; bottom: 6px;
  font-size: 10.5px; color: var(--ink-5);
  font-feature-settings: "tnum";
  background: color-mix(in srgb, var(--bg-card) 86%, transparent);
  padding: 1px 5px; border-radius: 3px;
  pointer-events: none;
  user-select: none;
  line-height: 1.4;
}
.field__counter--near { color: var(--warn); }
.field__counter--over { color: var(--bad); font-weight: 600; }

/* Pad textarea's bottom-right so counter doesn't overlap the last line */
.field__textarea { padding-right: 10px; padding-bottom: 22px; }
.field--sm .field__textarea { padding-bottom: 18px; }

/* Select — strip native chevron, render our own */
.field__control--select { /* anchor for chevron */ }
.field__select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 30px; /* room for custom chevron */
  background-image: none;
  cursor: pointer;
}
.field__select-chevron {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  color: var(--ink-4); pointer-events: none;
  display: flex; align-items: center;
}
.field--sm .field__select { padding-right: 26px; }
.field--sm .field__select-chevron { right: 6px; }
/* Leading icon offset for select */
.field__control--select.field__control--has-leading .field__select { padding-left: 32px; }
.field--sm .field__control--select.field__control--has-leading .field__select { padding-left: 28px; }

/* Helper / error text */
.field__helper {
  font-size: 11.5px; color: var(--ink-4); line-height: 1.4;
}
.field--error .field__helper { color: var(--bad); }

/* ============================================================================
   Form + FormSection — container with consistent vertical stacking and
   optional title/description headers. <Form> wraps a real <form> element;
   <FormSection> groups related fields with a smaller sub-heading.
   ============================================================================ */

.form {
  display: flex; flex-direction: column;
  gap: 16px;
  width: 100%;
  /* The native <form> default margin is unwanted in component context. */
  margin: 0;
}
.form--gap-sm { gap: 10px; }
.form--gap-md { gap: 16px; }
.form--gap-lg { gap: 24px; }

.form--disabled { opacity: 0.7; }

.form__header {
  display: flex; flex-direction: column;
  gap: 4px;
  padding-bottom: 4px;
}
.form__title {
  font-size: 16px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.01em; margin: 0; line-height: 1.3;
}
.form__description {
  font-size: 13px; color: var(--ink-4); line-height: 1.55;
  margin: 0; max-width: 60ch;
}

/* The <fieldset> wrapper inherits its parent's `disabled` state and propagates
   to all native form controls inside — even custom buttons. Reset its native
   default styles since we just use it as a semantic disabled-propagator. */
.form__body {
  display: flex; flex-direction: column;
  gap: inherit; /* picks up the .form--gap-* value */
  border: none; padding: 0; margin: 0;
  min-width: 0;
}

/* FormSection — grouped sub-block with smaller heading */
.form-section {
  display: flex; flex-direction: column;
  gap: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--line-soft);
}
.form-section:first-child {
  border-top: none; padding-top: 0;
}

.form-section__header {
  display: flex; flex-direction: column;
  gap: 2px;
}
.form-section__title {
  font-size: 13px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.005em;
  margin: 0; line-height: 1.3;
  text-transform: none;
}
.form-section__description {
  font-size: 12px; color: var(--ink-4); line-height: 1.5;
  margin: 0; max-width: 60ch;
}

.form-section__body {
  display: flex; flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* ============================================================================
   NumberInput — compact numeric stepper with visible −/+ buttons.
   .number-input + __btn (--minus|--plus) + __field + __affix
   Size modifiers: --sm / --md. State: --disabled.
   Standalone control (no field shell) — for quantity / budget / duration.
   ============================================================================ */

.number-input {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card);
  overflow: hidden;
  transition: border-color var(--duration-fast, 120ms) ease-out,
              box-shadow   var(--duration-fast, 120ms) ease-out;
}
.number-input:hover:not(.number-input--disabled) { border-color: var(--line-strong); }
.number-input:focus-within {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.number-input--disabled { opacity: 0.55; pointer-events: none; }

/* Stepper buttons */
.number-input__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px;
  background: var(--bg-sunk);
  border: none;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
  transition: background var(--duration-fast, 120ms) ease-out,
              color      var(--duration-fast, 120ms) ease-out;
  /* user-select off — repeated press shouldn't highlight surrounding text */
  user-select: none; -webkit-user-select: none;
}
.number-input__btn:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--ink);
}
.number-input__btn:active:not(:disabled) {
  background: color-mix(in srgb, var(--indigo) 12%, var(--bg-card));
  color: var(--indigo);
}
.number-input__btn:disabled {
  opacity: 0.35; cursor: not-allowed;
  background: var(--bg-sunk);
}
.number-input__btn--minus { border-right: 1px solid var(--line); }
.number-input__btn--plus  { border-left:  1px solid var(--line); }

/* Input field */
.number-input__field {
  flex: 1 1 auto;
  min-width: 48px; width: 4ch;
  border: none; outline: none; background: transparent;
  text-align: center;
  font: inherit; font-size: 13px; color: var(--ink);
  font-feature-settings: "tnum";
  padding: 7px 4px;
}
.number-input__field::placeholder { color: var(--ink-5); }

/* Inline affix text (e.g., "$" prefix, "%" suffix) — sit inside the input frame
   on the side of the value, before/after the input itself. */
.number-input__affix {
  display: inline-flex; align-items: center;
  font-size: 12.5px; color: var(--ink-4);
  user-select: none;
  font-feature-settings: "tnum";
}
.number-input__affix--leading  { padding-left: 8px; }
.number-input__affix--trailing { padding-right: 8px; }

/* Size: sm */
.number-input--sm .number-input__btn   { width: 26px; }
.number-input--sm .number-input__field { font-size: 12.5px; padding: 5px 4px; min-width: 40px; }
.number-input--sm .number-input__affix { font-size: 11.5px; }

/* Suppress native number-input spinner if anyone uses type="number" */
.number-input__field::-webkit-outer-spin-button,
.number-input__field::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.number-input__field { -moz-appearance: textfield; appearance: textfield; }

/* ============================================================================
   Slider — single-thumb + range slider with optional value tooltip.
   .slider (wrapper) + __track + __fill + __thumb + __mark + __tooltip
   Sizes: --sm (3px track, 14px thumb) / --md (4px track, 16px thumb)
   ============================================================================ */

.slider {
  display: block;
  width: 100%;
  padding: 10px 0;  /* room for thumbs to extend above/below track */
  user-select: none;
  -webkit-user-select: none;
}
.slider--disabled { opacity: 0.55; pointer-events: none; }

.slider__track {
  position: relative;
  width: 100%;
  background: var(--bg-sunk);
  border-radius: 999px;
  cursor: pointer;
}
.slider--sm .slider__track { height: 3px; }
.slider--md .slider__track { height: 4px; }

/* Fill — colored segment between thumb(s) showing the selected value */
.slider__fill {
  position: absolute;
  top: 0; bottom: 0;
  background: var(--indigo);
  border-radius: inherit;
  pointer-events: none;
}

/* Tick marks — small circles under the track */
.slider__mark {
  position: absolute;
  top: 50%;
  width: 4px; height: 4px;
  background: var(--ink-5);
  border: 2px solid var(--bg-card);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.slider__mark--filled { background: var(--indigo); }

/* Thumb — draggable circle */
.slider__thumb {
  position: absolute;
  top: 50%;
  background: var(--bg-card);
  border: 2px solid var(--indigo);
  border-radius: 50%;
  cursor: grab;
  transform: translate(-50%, -50%);
  outline: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  transition: box-shadow var(--duration-fast, 120ms) ease-out,
              transform var(--duration-fast, 120ms) ease-out;
  z-index: 2;
}
.slider--sm .slider__thumb { width: 14px; height: 14px; }
.slider--md .slider__thumb { width: 16px; height: 16px; }

.slider__thumb:hover {
  box-shadow: 0 1px 3px rgba(0,0,0,0.12),
              0 0 0 6px color-mix(in srgb, var(--indigo) 12%, transparent);
}
.slider__thumb:focus-visible {
  box-shadow: 0 1px 3px rgba(0,0,0,0.12),
              0 0 0 4px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.slider__thumb:active {
  cursor: grabbing;
  transform: translate(-50%, -50%) scale(1.08);
}
.slider--disabled .slider__thumb { cursor: not-allowed; }

/* Value tooltip — appears above thumb on hover/focus/drag */
.slider__tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg-card);
  padding: 3px 7px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  font-feature-settings: "tnum";
  pointer-events: none;
  animation: slider-tip-in 100ms var(--ease-out, ease-out) both;
}
.slider__tooltip::after {
  content: "";
  position: absolute;
  bottom: -3px;
  left: 50%;
  transform: translateX(-50%);
  border: 3px solid transparent;
  border-top-color: var(--ink);
  border-bottom: 0;
}
@keyframes slider-tip-in {
  from { opacity: 0; transform: translate(-50%, 2px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .slider__thumb { transition: none; }
  .slider__tooltip { animation: none; }
}

/* ============================================================================
   Toggle — visual switch for boolean settings.
   .toggle (row) + __textgroup + __label + __description + __switch
                + __input (hidden native) + __track + __thumb
   Size modifiers: --sm / --md. State: --disabled.
   Native <input type=checkbox> handles a11y, Space-to-toggle, form submit.
   ============================================================================ */

.toggle {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  cursor: pointer;
  user-select: none;
}
.toggle--disabled { cursor: not-allowed; opacity: 0.55; }

.toggle__textgroup {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.toggle__label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  line-height: 1.4;
}
.toggle__description {
  font-size: 11.5px; color: var(--ink-4); line-height: 1.45;
}

/* Switch — anchor for hidden input + visible track/thumb */
.toggle__switch {
  position: relative; flex: 0 0 auto;
  display: inline-flex; align-items: center;
}
.toggle__input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0; cursor: inherit;
  margin: 0;
}

/* Track */
.toggle__track {
  position: relative;
  display: inline-block;
  background: var(--line-strong);
  border-radius: 999px;
  transition: background var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.toggle--md .toggle__track { width: 34px; height: 20px; }
.toggle--sm .toggle__track { width: 28px; height: 16px; }

/* Thumb */
.toggle__thumb {
  position: absolute; top: 50%;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,.18), 0 1px 1px rgba(0,0,0,.06);
  transition: transform var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.toggle--md .toggle__thumb {
  width: 16px; height: 16px;
  left: 2px; transform: translateY(-50%);
}
.toggle--sm .toggle__thumb {
  width: 12px; height: 12px;
  left: 2px; transform: translateY(-50%);
}

/* Checked state — track turns brand color, thumb slides right */
.toggle__input:checked ~ .toggle__track {
  background: var(--indigo);
}
.toggle--md .toggle__input:checked ~ .toggle__track .toggle__thumb {
  transform: translate(14px, -50%);
}
.toggle--sm .toggle__input:checked ~ .toggle__track .toggle__thumb {
  transform: translate(12px, -50%);
}

/* Focus ring on the track when the hidden input is keyboard-focused */
.toggle__input:focus-visible ~ .toggle__track {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Disabled */
.toggle--disabled .toggle__track  { background: var(--bg-sunk); }
.toggle--disabled .toggle__input:checked ~ .toggle__track { background: color-mix(in srgb, var(--indigo) 50%, var(--line)); }

/* Compact (Switch primitive) — inline, tighter spacing, smaller text. */
.toggle--compact {
  display: inline-flex;
  width: auto;
  gap: 8px;
}
.toggle--compact .toggle__textgroup { gap: 0; }
.toggle--compact .toggle__label { font-size: 12.5px; font-weight: 400; }
/* No description slot in Switch; rule kept defensively in case caller passes one. */
.toggle--compact .toggle__description { display: none; }

/* Label positioning — `end` puts label after switch (row-reverse). Default
   Toggle layout is label-on-left (no modifier), equivalent to label="start". */
.toggle--label-end   { flex-direction: row-reverse; }
.toggle--label-start { flex-direction: row; }

@media (prefers-reduced-motion: reduce) {
  .toggle__track, .toggle__thumb { transition: none; }
}

/* ─── Switch (button[role=switch][aria-checked]) ───────────────────────────
   Decoupled from Toggle. Standalone pill with sliding thumb.
   .switch-row (flex row container) + .switch-track (the <button>)
                                    + .switch-thumb (the moving circle)
                                    + .switch-labels + .switch-label + .switch-description
   Sizes:
     md (default): 52×28 pill, 24px thumb, 24px slide distance
     sm:           40×22 pill, 18px thumb, 18px slide distance
   ───────────────────────────────────────────────────────────────────────── */

.switch-row {
  display: inline-flex; align-items: center;
  gap: 10px;
  min-width: 0;
}
.switch-row--label-end   { flex-direction: row; }
.switch-row--label-start { flex-direction: row-reverse; }
.switch-row--disabled { opacity: 0.55; }
.switch-row--disabled .switch-labels { cursor: not-allowed; }

.switch-labels {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
  cursor: pointer;
  user-select: none;
}
.switch-label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  letter-spacing: -0.005em; line-height: 1.4;
}
.switch-description {
  font-size: 11.5px; color: var(--ink-4); line-height: 1.45;
}

/* The <button role="switch"> — the visible pill */
.switch-track {
  position: relative;
  flex: 0 0 auto;
  display: inline-block;
  background: var(--line-strong);
  border: none; padding: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: background var(--duration-fast, 120ms) ease-out,
              box-shadow var(--duration-fast, 120ms) ease-out;
  /* Reset default button styles */
  -webkit-tap-highlight-color: transparent;
}
.switch-track--md { width: 52px; height: 28px; }
.switch-track--sm { width: 40px; height: 22px; }

.switch-track[aria-checked="true"]  { background: var(--indigo); }
.switch-track[aria-checked="false"] { background: var(--line-strong); }

.switch-track:hover:not(:disabled) {
  filter: brightness(1.04);
}
.switch-track:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 28%, transparent);
}
.switch-track--disabled,
.switch-track:disabled {
  cursor: not-allowed;
}
.switch-track--disabled[aria-checked="true"] {
  background: color-mix(in srgb, var(--indigo) 50%, var(--line));
}

/* The sliding thumb */
.switch-thumb {
  position: absolute;
  top: 50%;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,.20), 0 1px 1px rgba(0,0,0,.06);
  transition: transform var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.switch-track--md .switch-thumb {
  width: 24px; height: 24px;
  left: 2px; transform: translateY(-50%);
}
.switch-track--sm .switch-thumb {
  width: 18px; height: 18px;
  left: 2px; transform: translateY(-50%);
}

/* On state — slide thumb across the track */
.switch-track--md[aria-checked="true"] .switch-thumb { transform: translate(24px, -50%); }
.switch-track--sm[aria-checked="true"] .switch-thumb { transform: translate(18px, -50%); }

@media (prefers-reduced-motion: reduce) {
  .switch-track, .switch-thumb { transition: none; }
}

/* ============================================================================
   Radio + RadioGroup
   .radio (label) + __input (hidden native) + __indicator (visible circle)
                  + __text + __label + __description
   .radio-group (wrapper) + __label + __list
   Sizes: --sm (14px circle) / --md (16px circle)
   Native <input type="radio"> handles a11y, keyboard arrow-nav, form submit.
   ============================================================================ */

/* Group wrapper */
.radio-group {
  display: flex; flex-direction: column;
  gap: 8px;
}
.radio-group__label {
  font-size: 12px; font-weight: 500; color: var(--ink-2);
  letter-spacing: -0.005em;
  margin-bottom: 2px;
}
.radio-group__list {
  display: flex; flex-direction: column;
  gap: 10px;
}
.radio-group--horizontal .radio-group__list {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 16px 20px;
}

/* Individual radio row */
.radio {
  display: flex; align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  min-width: 0;
}
.radio--disabled { cursor: not-allowed; opacity: 0.55; }

/* Hidden native input — overlays the indicator for click/focus */
.radio__input {
  position: absolute;
  opacity: 0; width: 1px; height: 1px;
  margin: 0; padding: 0; border: 0;
  pointer-events: none;
}

/* Visible indicator circle */
.radio__indicator {
  position: relative;
  display: inline-block; flex: 0 0 auto;
  border: 1.5px solid var(--line-strong);
  background: var(--bg-card);
  border-radius: 50%;
  margin-top: 1px; /* baseline-align with label */
  transition: border-color var(--duration-fast, 120ms) ease-out,
              background   var(--duration-fast, 120ms) ease-out,
              box-shadow   var(--duration-fast, 120ms) ease-out;
}
.radio--md .radio__indicator { width: 16px; height: 16px; }
.radio--sm .radio__indicator { width: 14px; height: 14px; }

/* Inner dot — appears when input is :checked. Sized via percentage for crispness */
.radio__indicator::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 0; height: 0;
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  transition: width  var(--duration-fast, 120ms) ease-out,
              height var(--duration-fast, 120ms) ease-out;
}

/* Checked state */
.radio__input:checked ~ .radio__indicator {
  background: var(--indigo);
  border-color: var(--indigo);
}
.radio--md .radio__input:checked ~ .radio__indicator::after { width: 6px;  height: 6px;  }
.radio--sm .radio__input:checked ~ .radio__indicator::after { width: 5px;  height: 5px;  }

/* Hover state (mouse only, not when disabled) */
.radio:not(.radio--disabled):hover .radio__indicator {
  border-color: var(--indigo);
}

/* Focus ring on indicator when hidden input is keyboard-focused */
.radio__input:focus-visible ~ .radio__indicator {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Text */
.radio__text {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
  flex: 1;
}
.radio__label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  line-height: 1.4;
  letter-spacing: -0.005em;
}
.radio__description {
  font-size: 11.5px; color: var(--ink-4);
  line-height: 1.45;
}
.radio--sm .radio__label       { font-size: 12.5px; }
.radio--sm .radio__description { font-size: 11px; }

@media (prefers-reduced-motion: reduce) {
  .radio__indicator,
  .radio__indicator::after { transition: none; }
}

/* ============================================================================
   Checkbox (with indeterminate state)
   .checkbox (label) + __input (hidden native) + __indicator (visible square)
                     + __mark (SVG holding both __check and __dash paths)
                     + __text + __label + __description
   Sizes: --sm (14px box) / --md (16px box) — matches Radio for visual parity
   :checked        → indigo bg + show check polyline
   :indeterminate  → indigo bg + show dash (takes precedence over check)
   ============================================================================ */

.checkbox {
  display: flex; align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  min-width: 0;
}
.checkbox--disabled { cursor: not-allowed; opacity: 0.55; }

/* Hidden native input — same offscreen pattern as Radio */
.checkbox__input {
  position: absolute;
  opacity: 0; width: 1px; height: 1px;
  margin: 0; padding: 0; border: 0;
  pointer-events: none;
}

/* Visible square indicator */
.checkbox__indicator {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  border: 1.5px solid var(--line-strong);
  background: var(--bg-card);
  border-radius: 4px; /* slightly rounded, not pill */
  margin-top: 1px; /* baseline-align with label */
  transition: border-color var(--duration-fast, 120ms) ease-out,
              background   var(--duration-fast, 120ms) ease-out,
              box-shadow   var(--duration-fast, 120ms) ease-out;
}
.checkbox--md .checkbox__indicator { width: 16px; height: 16px; }
.checkbox--sm .checkbox__indicator { width: 14px; height: 14px; }

/* SVG holds both glyphs; opacity toggles which is visible */
.checkbox__mark {
  width: 100%; height: 100%;
  display: block;
  /* Slight padding inside so the check/dash don't touch the box edges */
  padding: 0;
}
.checkbox__check,
.checkbox__dash {
  opacity: 0;
  transition: opacity var(--duration-fast, 120ms) ease-out;
}

/* Checked state — fill bg + reveal check polyline */
.checkbox__input:checked ~ .checkbox__indicator {
  background: var(--indigo);
  border-color: var(--indigo);
}
.checkbox__input:checked ~ .checkbox__indicator .checkbox__check {
  opacity: 1;
}

/* Indeterminate — same fill, dash visible instead of check.
   Browsers reflect the JS-set .indeterminate property to the :indeterminate
   selector, so a ref-driven indeterminate flips this without any extra class. */
.checkbox__input:indeterminate ~ .checkbox__indicator {
  background: var(--indigo);
  border-color: var(--indigo);
}
.checkbox__input:indeterminate ~ .checkbox__indicator .checkbox__check {
  opacity: 0; /* hide check even if also :checked */
}
.checkbox__input:indeterminate ~ .checkbox__indicator .checkbox__dash {
  opacity: 1;
}

/* Hover state */
.checkbox:not(.checkbox--disabled):hover .checkbox__indicator {
  border-color: var(--indigo);
}

/* Focus ring on indicator when hidden input is keyboard-focused */
.checkbox__input:focus-visible ~ .checkbox__indicator {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Text — sizing matches Radio for visual parity */
.checkbox__text {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
  flex: 1;
}
.checkbox__label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  line-height: 1.4;
  letter-spacing: -0.005em;
}
.checkbox__description {
  font-size: 11.5px; color: var(--ink-4);
  line-height: 1.45;
}
.checkbox--sm .checkbox__label       { font-size: 12.5px; }
.checkbox--sm .checkbox__description { font-size: 11px; }

@media (prefers-reduced-motion: reduce) {
  .checkbox__indicator,
  .checkbox__check,
  .checkbox__dash { transition: none; }
}

/* ============================================================================
   SignInButton — provider-branded OAuth buttons (Apple / Google / Microsoft)
   Per each vendor's HIG:
     Apple:     black bg + white logo & text (dark) OR white bg + black (light)
                — official Apple silhouette mark
     Google:    white bg + 4-color G + dark text (light) OR neutral-dark bg
                + 4-color G + white text (dark)
     Microsoft: white bg + 4-square mark + black text (light) OR dark bg
                + 4-square mark + white text (dark)
   Colors locked: brand logos stay full-color in BOTH modes (per all 3 HIGs);
   only the surrounding chrome (bg/text/border) flips per mode.
   ============================================================================ */

.signin-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 10px;
  min-height: 44px; padding: 0 16px;
  border-radius: var(--radius-btn);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px; font-weight: 500; letter-spacing: -0.005em;
  line-height: 1;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background-color 120ms, border-color 120ms, opacity 120ms;
  user-select: none;
  white-space: nowrap;
}
.signin-btn--full { display: flex; width: 100%; border-radius: var(--radius-btn-icon); /* full-width rows stay 8px per token doc */ }
.signin-btn:disabled { opacity: 0.55; cursor: not-allowed; }

.signin-btn__logo {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
}
.signin-btn__logo-svg { display: block; }
.signin-btn__text { display: inline-block; }

/* ── Apple ── */
.signin-btn--apple.signin-btn--light {
  background: #fff; color: #000; border-color: rgba(0,0,0,0.12);
}
.signin-btn--apple.signin-btn--light:hover:not(:disabled) {
  background: #f5f5f7;
}
.signin-btn--apple.signin-btn--dark {
  background: #000; color: #fff; border-color: #000;
}
.signin-btn--apple.signin-btn--dark:hover:not(:disabled) {
  background: #1a1a1a;
}
/* Apple logo color follows currentColor: takes the text color, flipping with mode */
.signin-btn--apple .signin-btn__logo-svg { color: currentColor; }
/* Apple HIG: slight negative top adjustment so the logo's optical center aligns
   with the text x-height — the silhouette has visual weight at the top. */
.signin-btn--apple .signin-btn__logo { margin-bottom: 2px; }

/* ── Google ── */
.signin-btn--google.signin-btn--light {
  background: #fff; color: #1f1f1f; border-color: #dadce0;
}
.signin-btn--google.signin-btn--light:hover:not(:disabled) {
  background: #f8f9fa; border-color: #d2e3fc;
}
.signin-btn--google.signin-btn--dark {
  background: #202124; color: #e8eaed; border-color: #3c4043;
}
.signin-btn--google.signin-btn--dark:hover:not(:disabled) {
  background: #2a2b2e; border-color: #5f6368;
}
/* Google G stays multicolor in both modes — no fill override here. */

/* ── Microsoft ── */
.signin-btn--microsoft.signin-btn--light {
  background: #fff; color: #5e5e5e; border-color: #8c8c8c;
}
.signin-btn--microsoft.signin-btn--light:hover:not(:disabled) {
  background: #fafafa;
}
.signin-btn--microsoft.signin-btn--dark {
  background: #2f2f2f; color: #fff; border-color: #2f2f2f;
}
.signin-btn--microsoft.signin-btn--dark:hover:not(:disabled) {
  background: #404040;
}
/* Microsoft 4-square stays multicolor — no fill override. */

/* Focus ring — match each provider's accent rather than the generic indigo */
.signin-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(0,0,0,0.12), 0 0 0 4px color-mix(in srgb, currentColor 25%, transparent);
}

/* ============================================================================
   SearchInput — .search-input + __icon + __field + __clear + --sm modifier
   ============================================================================ */

.search-input {
  position: relative; display: inline-flex; align-items: center;
  width: 100%; min-width: 160px;
  height: 32px; padding: 0 8px 0 30px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card);
  transition: border-color 120ms, box-shadow 120ms;
}
.search-input:hover:not(.search-input--disabled) { border-color: var(--line-strong); }
.search-input:focus-within {
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.search-input--disabled { opacity: 0.55; pointer-events: none; }

.search-input--sm {
  height: 26px; padding: 0 6px 0 26px;
  border-radius: 5px;
}

.search-input__icon {
  position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; color: var(--ink-4);
  pointer-events: none;
}
.search-input--sm .search-input__icon { left: 7px; }

.search-input__field {
  flex: 1; min-width: 0;
  border: none; outline: none; background: transparent;
  font-size: 13px; color: var(--ink);
  padding: 0; line-height: 1.4;
  font-family: inherit;
}
.search-input--sm .search-input__field { font-size: 12.5px; }
.search-input__field::placeholder { color: var(--ink-5); }
.search-input__field:disabled { cursor: not-allowed; }

.search-input__clear {
  display: flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 4px;
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 0; flex: 0 0 auto;
  margin-left: 4px;
  transition: background 100ms, color 100ms;
}
.search-input__clear:hover { background: var(--bg-hover); color: var(--ink); }
.search-input--sm .search-input__clear { width: 16px; height: 16px; }

/* ============================================================================
   FilterChip + FilterBar — active-filter chip pill + container row.
   .filter-chip + __icon + __label + __count + __remove + tone modifiers
   .filter-bar + __pickers + __separator + __chips + __clear
   ============================================================================ */

/* ── FilterChip ── */
.filter-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 4px 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-card);
  color: var(--ink-2);
  font: inherit; font-size: 11.5px; font-weight: 500; line-height: 1.4;
  white-space: nowrap;
  user-select: none;
  text-decoration: none;
}
/* When removable but not clickable, no padding-right reserved for X — the
   button itself owns its hit target. */
.filter-chip:not(:has(.filter-chip__remove)) { padding-right: 9px; }

/* Tone — default (neutral) is the base above; accent gets indigo treatment */
.filter-chip--accent {
  background: var(--indigo-soft);
  color: var(--indigo-ink);
  border-color: var(--indigo-line);
}

.filter-chip--clickable { cursor: pointer; transition: background 100ms, border-color 100ms; }
.filter-chip--clickable:hover { background: var(--bg-hover); }
.filter-chip--accent.filter-chip--clickable:hover {
  background: color-mix(in srgb, var(--indigo-soft) 70%, var(--indigo));
}
.filter-chip--clickable:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

.filter-chip__icon {
  display: inline-flex; align-items: center;
  color: currentColor; opacity: 0.7; flex: 0 0 auto;
}
.filter-chip__label {
  min-width: 0;
  overflow: hidden; text-overflow: ellipsis; max-width: 240px;
}
.filter-chip__count {
  margin-left: 2px;
  font-feature-settings: "tnum";
  font-size: 10.5px; font-weight: 600;
  color: currentColor; opacity: 0.7;
  padding: 0 4px; min-width: 14px; height: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, currentColor 12%, transparent);
  border-radius: 999px;
  line-height: 1;
}

.filter-chip__remove {
  margin-left: 2px;
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer;
  color: currentColor; opacity: 0.55;
  border-radius: 50%;
  padding: 0; flex: 0 0 auto;
  transition: background 90ms, opacity 90ms;
}
.filter-chip__remove:hover { opacity: 1; background: color-mix(in srgb, currentColor 15%, transparent); }

/* ── FilterBar ── */
.filter-bar {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 10px;
  padding: 4px 0;
}

.filter-bar__pickers {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px 8px;
  flex: 0 1 auto;
}

.filter-bar__separator {
  width: 1px; height: 22px;
  background: var(--line);
  flex: 0 0 auto;
}

.filter-bar__chips {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px;
  flex: 1 1 auto; min-width: 0;
}

.filter-bar__clear {
  background: none; border: none; cursor: pointer;
  padding: 3px 8px; margin-left: 2px;
  font: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--ink-4);
  border-radius: 5px;
  transition: background 90ms, color 90ms;
}
.filter-bar__clear:hover { color: var(--ink); background: var(--bg-hover); }

@media (max-width: 640px) {
  .filter-bar__pickers,
  .filter-bar__chips { flex-basis: 100%; }
  .filter-bar__separator { display: none; }
}

/* ============================================================================
   ChipGroup — filter pills with selected state (multi OR single select).
   .chip-group + __chip + __chip--selected + __chip--disabled
              + __chip-icon + __chip-label + __chip-count
   Size modifiers: --sm / --md
   ============================================================================ */

.chip-group {
  display: inline-flex; flex-wrap: wrap; align-items: center;
  gap: 6px;
  min-width: 0;
}

.chip-group__chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 999px;
  font: inherit; font-size: 12.5px; font-weight: 500; line-height: 1.4;
  color: var(--ink-3);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition: background var(--duration-fast, 120ms) ease-out,
              color      var(--duration-fast, 120ms) ease-out,
              border-color var(--duration-fast, 120ms) ease-out;
}
.chip-group--sm .chip-group__chip {
  padding: 2px 9px;
  font-size: 11.5px;
}

.chip-group__chip:hover:not(.chip-group__chip--selected):not(.chip-group__chip--disabled) {
  background: var(--bg-hover);
  color: var(--ink-2);
  border-color: var(--line-strong);
}
.chip-group__chip:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Selected state — indigo tint, retains the rounded shape and the count chip */
.chip-group__chip--selected {
  background: var(--indigo-soft);
  color: var(--indigo-ink);
  border-color: var(--indigo-line);
}
.chip-group__chip--selected:hover {
  background: color-mix(in srgb, var(--indigo-soft) 70%, var(--indigo));
  color: var(--indigo-ink);
}

.chip-group__chip--disabled {
  opacity: 0.45; cursor: not-allowed;
}

.chip-group__chip-icon {
  display: inline-flex; align-items: center;
  color: currentColor; opacity: 0.7;
  flex: 0 0 auto;
}

.chip-group__chip-label {
  /* lets long labels truncate gracefully if a container constrains width */
  overflow: hidden; text-overflow: ellipsis;
  max-width: 200px;
}

/* Count badge — small dimmed number inside the chip, e.g., "Active 12" */
.chip-group__chip-count {
  margin-left: 1px;
  font-size: 11px; font-weight: 600;
  font-feature-settings: "tnum";
  color: currentColor; opacity: 0.6;
  /* Subtle separator dot via padding-left + ::before would be cleaner; for
     now the opacity drop is enough visual hierarchy. */
}
.chip-group__chip--selected .chip-group__chip-count { opacity: 0.85; }
.chip-group--sm .chip-group__chip-count { font-size: 10.5px; }

@media (prefers-reduced-motion: reduce) {
  .chip-group__chip { transition: none; }
}

/* ============================================================================
   DateRangePicker — .daterange + __input + __dropdown + __presets +
                     __calendar + __nav + __day etc.
   ============================================================================ */

@keyframes drp-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.daterange { position: relative; display: inline-block; }

/* ── Input pill ── */
.daterange__input {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 11px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg-card);
  font-size: 13px; color: var(--ink); cursor: pointer; white-space: nowrap;
  transition: border-color var(--duration-fast) var(--ease-in-out);
}
.daterange__input:hover { border-color: var(--line-strong); }
.daterange__input.is-open { border-color: var(--indigo); box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent); }
.daterange__input svg { color: var(--ink-4); flex-shrink: 0; }
.daterange__input-label { flex: 1; min-width: 0; }

/* ── Dropdown panel ── */
.daterange__dropdown {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 400;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-menu); box-shadow: var(--shadow-lg);
  display: flex; flex-direction: row;
  animation: drp-in var(--duration-base) var(--ease-out) both;
}

/* ── Preset list ── */
.daterange__presets {
  display: flex; flex-direction: column; gap: 1px;
  padding: 10px 8px; min-width: 126px; flex-shrink: 0;
  border-right: 1px solid var(--line-soft);
}
.daterange__preset {
  background: none; border: none; cursor: pointer; text-align: left;
  padding: 6px 10px; border-radius: 6px;
  font-size: 12.5px; color: var(--ink-3);
  transition: background var(--duration-fast) var(--ease-in-out),
              color      var(--duration-fast) var(--ease-in-out);
  white-space: nowrap;
}
.daterange__preset:hover    { background: var(--bg-hover); color: var(--ink); }
.daterange__preset.is-active { color: var(--indigo); background: var(--indigo-soft); font-weight: 500; }

/* ── Calendar panels ── */
.daterange__panels { display: flex; flex-direction: column; padding: 12px 14px 10px; gap: 10px; }

.daterange__nav {
  display: flex; align-items: center; gap: 6px;
}
.daterange__nav-labels {
  flex: 1; display: flex; gap: 24px;
}
.daterange__nav-label {
  flex: 1; text-align: center; font-size: 13px; font-weight: 600; color: var(--ink);
}
.daterange__nav-btn {
  width: 28px; height: 28px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--ink-4);
  border-radius: var(--radius-btn-icon);
  transition: background var(--duration-fast) var(--ease-in-out),
              color      var(--duration-fast) var(--ease-in-out);
}
.daterange__nav-btn:hover { background: var(--bg-hover); color: var(--ink); }

.daterange__calendars { display: flex; gap: 24px; }

/* ── Single month grid ── */
.daterange__calendar { min-width: 196px; }
.daterange__cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
}
.daterange__cal-dow {
  font-size: 11px; font-weight: 600; color: var(--ink-5);
  text-align: center; padding: 3px 0; text-transform: uppercase; letter-spacing: 0.04em;
}

.daterange__day {
  aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; border-radius: 5px; border: none;
  background: none; cursor: pointer; color: var(--ink);
  position: relative;
  transition: background var(--duration-fast) var(--ease-in-out),
              color      var(--duration-fast) var(--ease-in-out);
}
.daterange__day--pad { pointer-events: none; }
.daterange__day:hover:not(.is-disabled):not(.is-start):not(.is-end) {
  background: var(--bg-hover);
}

/* Range fill between start and end */
.daterange__day.in-range {
  background: var(--indigo-soft); border-radius: 0; color: var(--indigo-ink);
}
/* Rounded caps at start of a range row */
.daterange__day.is-start { background: var(--indigo); color: #fff; border-radius: 5px; z-index: 1; }
.daterange__day.is-end   { background: var(--indigo); color: #fff; border-radius: 5px; z-index: 1; }

/* Band connecting start circle to range — extends right half of start cell */
.daterange__day.is-start.in-range::after,
.daterange__day.is-end.in-range::after {
  content: ''; position: absolute; top: 0; bottom: 0; z-index: -1;
  background: var(--indigo-soft);
}
.daterange__day.is-start.in-range::after { left: 50%; right: -2px; border-radius: 0; }
.daterange__day.is-end.in-range::after   { right: 50%; left: -2px; border-radius: 0; }

/* Today dot */
.daterange__day.is-today::before {
  content: ''; position: absolute; bottom: 2px; left: 50%;
  transform: translateX(-50%); width: 3px; height: 3px;
  border-radius: 50%; background: var(--indigo);
}
.daterange__day.is-start.is-today::before,
.daterange__day.is-end.is-today::before { background: rgba(255,255,255,0.7); }

.daterange__day.is-disabled {
  color: var(--ink-5); cursor: not-allowed; opacity: 0.45;
}
.daterange__day.is-disabled:hover { background: none; }

/* Hint text while selecting end */
.daterange__hint {
  font-size: 11.5px; color: var(--ink-4); text-align: center; padding: 4px 0;
  border-top: 1px solid var(--line-soft); margin-top: 2px;
}

/* ── Mobile: stack vertically, single visible month ── */
@media (max-width: 600px) {
  .daterange__dropdown    { flex-direction: column; min-width: 100vw; left: 50%; transform: translateX(-50%); }
  .daterange__presets     { flex-direction: row; flex-wrap: wrap; border-right: none; border-bottom: 1px solid var(--line-soft); padding: 8px; }
  .daterange__calendars   { flex-direction: column; gap: 16px; }
  .daterange__nav-labels  { gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .daterange__dropdown { animation: none; }
  .daterange__day, .daterange__preset, .daterange__nav-btn { transition: none; }
}

/* ============================================================================
   Calendar — month-view grid surface (separate from DatePicker).
   For Deadlines / Timesheets / project month overlays.
   .calendar + __header + __nav-btn + __month-label + __dow-row + __dow
            + __grid + __cell + __daynum + __day-body
   Sizes: --sm (compact density) / --md (default) / --lg (rich event cards)
   ============================================================================ */
.calendar {
  display: flex; flex-direction: column;
  width: 100%;
  font-family: inherit;
}

.calendar__header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 8px 4px 12px;
  flex: 0 0 auto;
}
.calendar__nav-btn {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line);
  border-radius: var(--radius-btn-icon); color: var(--ink-3);
  cursor: pointer;
  transition: background 100ms, color 100ms, border-color 100ms;
}
.calendar__nav-btn:hover { background: var(--bg-hover); color: var(--ink); border-color: var(--line-strong); }
.calendar__month-label {
  font-size: 15px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.01em;
  flex: 1; text-align: center;
}

.calendar__dow-row {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0;
  padding: 0 0 4px;
  border-bottom: 1px solid var(--line);
}
.calendar__dow {
  font-size: 10.5px; font-weight: 600;
  color: var(--ink-5);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: center;
  padding: 4px 0;
}

.calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(80px, 1fr);   /* min cell height; rows can grow */
  gap: 0;
  flex: 1 1 auto;
}
.calendar--sm .calendar__grid { grid-auto-rows: minmax(48px, auto); }
.calendar--md .calendar__grid { grid-auto-rows: minmax(80px, 1fr); }
.calendar--lg .calendar__grid { grid-auto-rows: minmax(112px, 1fr); }

.calendar__cell {
  position: relative;
  display: flex; flex-direction: column;
  align-items: stretch;
  padding: 4px 6px;
  border-right: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg-card);
  font: inherit; color: var(--ink);
  text-align: left;
  overflow: hidden;
}
.calendar__cell:nth-child(7n) { border-right: none; }
/* Last row of cells — no bottom border (visual flush with surrounding) */
.calendar__cell:nth-last-child(-n+7) { border-bottom: none; }

.calendar__cell--outside {
  background: var(--bg-sunk);
  color: var(--ink-5);
}
.calendar__cell--outside .calendar__daynum { opacity: 0.5; }

.calendar__cell--clickable {
  cursor: pointer;
  border: 1px solid var(--line-soft);  /* render the borders we removed when as button */
  border-top: none; border-left: none;
  transition: background var(--duration-fast, 120ms) ease-out;
}
.calendar__cell--clickable:hover { background: var(--bg-hover); }
.calendar__cell--clickable:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--indigo) 30%, transparent);
}

.calendar__cell--hidden { visibility: hidden; }

.calendar__daynum {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-2);
  flex: 0 0 auto;
  margin-bottom: 4px;
}
.calendar--sm .calendar__daynum { width: 20px; height: 20px; font-size: 11px; }
.calendar--lg .calendar__daynum { width: 28px; height: 28px; font-size: 13px; }

/* Today — indigo circle around the day number */
.calendar__cell--today .calendar__daynum {
  background: var(--indigo);
  color: #fff;
}

/* Selected — tinted bg on the whole cell */
.calendar__cell--selected {
  background: var(--indigo-soft);
}
.calendar__cell--selected .calendar__daynum {
  color: var(--indigo-ink);
}
.calendar__cell--selected.calendar__cell--today .calendar__daynum {
  background: var(--indigo);
  color: #fff;
}

.calendar__day-body {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  display: flex; flex-direction: column;
  gap: 2px;
  font-size: 11.5px;
  line-height: 1.3;
}
.calendar__day-body--outside { opacity: 0.5; }

/* Reset native <button> appearance when cells are clickable */
button.calendar__cell {
  font-family: inherit;
}

/* Mobile (≤640px): reduce cell density */
@media (max-width: 640px) {
  .calendar__grid { grid-auto-rows: minmax(56px, auto); }
  .calendar__cell { padding: 2px 4px; }
  .calendar__daynum { width: 20px; height: 20px; font-size: 11px; margin-bottom: 2px; }
  .calendar__day-body { font-size: 10.5px; }
}

/* ============================================================================
   Breadcrumbs — .breadcrumbs + __list + __item + __separator + __back
   Desktop: full path with separator. Mobile (≤640px): "← parent · current".
   ============================================================================ */

.breadcrumbs {
  display: flex; align-items: center;
  font-size: 12.5px; line-height: 1.4;
  min-width: 0;
}
.breadcrumbs__list {
  display: flex; align-items: center; gap: 6px;
  list-style: none; margin: 0; padding: 0;
  flex-wrap: nowrap; min-width: 0;
}
.breadcrumbs__list--mobile  { display: none; }

.breadcrumbs__li {
  display: inline-flex; align-items: center;
  min-width: 0;
}
.breadcrumbs__item {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--ink-4); text-decoration: none;
  max-width: 220px;
  transition: color 100ms;
}
.breadcrumbs__item-icon { color: currentColor; flex: 0 0 auto; opacity: 0.75; }
.breadcrumbs__item-label {
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.breadcrumbs__item--link { cursor: pointer; }
.breadcrumbs__item--link:hover { color: var(--ink); }
.breadcrumbs__item--link:hover .breadcrumbs__item-label {
  text-decoration: underline; text-underline-offset: 2px;
}
.breadcrumbs__item--link:hover .breadcrumbs__item-icon { opacity: 1; }
.breadcrumbs__item--current { color: var(--ink); font-weight: 500; }
.breadcrumbs__item--current .breadcrumbs__item-icon { opacity: 1; color: var(--indigo); }
.breadcrumbs__item--ellipsis {
  padding: 0;
  user-select: none;
  overflow: visible; /* allow the ellipsis dropdown popover to escape */
}
.breadcrumbs__ellipsis-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 20px;
  background: transparent; border: none;
  border-radius: var(--radius-btn-icon);
  cursor: pointer;
  color: var(--ink-5);
  font: inherit; font-size: 14px; line-height: 1;
  padding: 0 4px;
  transition: background 100ms, color 100ms;
}
.breadcrumbs__ellipsis-btn:hover { background: var(--bg-hover); color: var(--ink-2); }
.breadcrumbs__ellipsis-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Size variants */
.breadcrumbs--sm { font-size: 11.5px; }
.breadcrumbs--sm .breadcrumbs__item { max-width: 180px; }
.breadcrumbs--sm .breadcrumbs__ellipsis-btn { min-width: 18px; height: 18px; font-size: 12.5px; padding: 0 3px; }

.breadcrumbs__separator {
  display: inline-flex; align-items: center;
  color: var(--ink-5); flex-shrink: 0;
  font-size: 11px;
}

.breadcrumbs__back {
  display: inline-flex; align-items: center; gap: 2px;
  color: var(--ink-3); text-decoration: none;
  padding: 2px 6px 2px 4px; border-radius: 5px;
  margin-right: 6px;
  transition: background 100ms, color 100ms;
}
.breadcrumbs__back:hover { background: var(--bg-hover); color: var(--ink); }

@media (max-width: 640px) {
  .breadcrumbs__list--desktop { display: none; }
  .breadcrumbs__list--mobile  { display: flex; align-items: center; min-width: 0; }
  .breadcrumbs__item--current { max-width: 60vw; }
}

/* ============================================================================
   Stepper — multi-step progress indicator.
   .stepper (ol) + __step (li) + __marker-col + __marker + __num + __dot
                 + __connector + __text + __label + __description
   States: --complete / --current / --upcoming (set per step)
   Orientation: --horizontal / --vertical
   Variants: --numbered / --dot
   Sizes: --sm / --md
   ============================================================================ */

.stepper {
  list-style: none; margin: 0; padding: 0;
  display: flex;
  font-family: inherit;
  color: var(--ink-3);
}

/* Sizing tokens — set per size on the wrapper so child rules can read */
.stepper--md { --step-marker: 28px; --step-line: 2px;   --step-gap: 12px; }
.stepper--sm { --step-marker: 22px; --step-line: 1.5px; --step-gap: 8px;  }
.stepper--lg { --step-marker: 36px; --step-line: 2.5px; --step-gap: 16px; }

/* ── Horizontal layout ── */
.stepper--horizontal {
  flex-direction: row;
  align-items: flex-start;
  gap: 0;
  width: 100%;
}
.stepper--horizontal .stepper__step {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column;
  gap: 8px;
  position: relative;
}
.stepper--horizontal .stepper__marker-col {
  display: flex; align-items: center;
  width: 100%;
}
/* Horizontal connector — line right of the marker; last step has no line */
.stepper--horizontal .stepper__connector {
  flex: 1 1 0;
  height: var(--step-line);
  background: var(--line);
  margin: 0 4px;
  transition: background 180ms;
}
.stepper--horizontal .stepper__step--complete .stepper__connector,
.stepper--horizontal .stepper__step--current  .stepper__connector {
  /* "Filled" up to the current step — only complete/current have filled trailing line */
  background: var(--indigo);
}
.stepper--horizontal .stepper__step--current .stepper__connector {
  /* Half-fill: gradient from indigo to line so current step shows progress
     without claiming the connector to the next (still-upcoming) step. */
  background: linear-gradient(to right, var(--indigo) 50%, var(--line) 50%);
}
.stepper--horizontal .stepper__text {
  display: flex; flex-direction: column; gap: 1px;
}

/* ── Vertical layout ── */
.stepper--vertical {
  flex-direction: column;
  gap: 0;
}
.stepper--vertical .stepper__step {
  display: flex; flex-direction: row;
  align-items: flex-start;
  gap: var(--step-gap);
  padding-bottom: 16px;
}
.stepper--vertical .stepper__step:last-child { padding-bottom: 0; }
.stepper--vertical .stepper__marker-col {
  display: flex; flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
}
.stepper--vertical .stepper__connector {
  width: var(--step-line);
  flex: 1 1 0; min-height: 16px;
  background: var(--line);
  margin: 4px 0;
  transition: background 180ms;
}
.stepper--vertical .stepper__step--complete .stepper__connector {
  background: var(--indigo);
}
.stepper--vertical .stepper__text {
  display: flex; flex-direction: column; gap: 2px;
  padding-top: 3px; /* baseline-align with marker */
}

/* ── Marker (the circular dot/number/check) ── */
.stepper__marker {
  width: var(--step-marker); height: var(--step-marker);
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--bg-card);
  border: 1.5px solid var(--line);
  color: var(--ink-4);
  font: inherit; font-size: 12px; font-weight: 600;
  cursor: default;
  padding: 0;
  font-feature-settings: "tnum";
  transition: background 180ms, border-color 180ms, color 180ms;
}
.stepper--sm .stepper__marker { font-size: 10.5px; }

.stepper__num {
  display: inline-block; line-height: 1;
}
.stepper__dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ink-5);
  transition: background 180ms;
}

/* State styling on the marker */
.stepper__step--complete .stepper__marker {
  background: var(--indigo);
  border-color: var(--indigo);
  color: #fff;
}
.stepper__step--current .stepper__marker {
  background: var(--bg-card);
  border-color: var(--indigo);
  color: var(--indigo);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 18%, transparent);
}
.stepper__step--current .stepper__dot { background: var(--indigo); }
.stepper__step--upcoming .stepper__dot { background: var(--ink-5); }

/* Error state — per-step override when validation fails. Solid red marker
   with white X icon; supersedes the indigo of complete/current. */
.stepper__step--error .stepper__marker {
  background: var(--bad);
  border-color: var(--bad);
  color: #fff;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 18%, transparent);
}
.stepper__step--error .stepper__dot { background: #fff; }

/* Warning state — softer than error; amber outlined marker. */
.stepper__step--warning .stepper__marker {
  background: var(--warn-soft);
  border-color: var(--warn);
  color: var(--warn);
}
.stepper__step--warning .stepper__dot { background: var(--warn); }

/* Disabled step — locks out clicks regardless of position, fades the marker.
   Use for steps that aren't reachable yet (e.g., conditional flow branches). */
.stepper__step--disabled .stepper__marker {
  cursor: not-allowed;
  opacity: 0.55;
}
.stepper__step--disabled .stepper__label,
.stepper__step--disabled .stepper__description { opacity: 0.6; }

/* Clickable past steps */
.stepper__step--clickable .stepper__marker {
  cursor: pointer;
}
.stepper__step--clickable .stepper__marker:hover {
  filter: brightness(1.08);
}
.stepper__marker:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 30%, transparent);
}
/* Error focus uses red ring instead of indigo */
.stepper__step--error .stepper__marker:focus-visible {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bad) 30%, transparent);
}

/* ── Text (label + description) ── */
.stepper__label {
  font-size: 13px; font-weight: 500;
  color: var(--ink-3);
  letter-spacing: -0.005em;
  line-height: 1.3;
}
.stepper__description {
  font-size: 11.5px; color: var(--ink-5);
  line-height: 1.45;
}
.stepper__step--current .stepper__label   { color: var(--ink); font-weight: 600; }
.stepper__step--complete .stepper__label  { color: var(--ink-2); }
.stepper__step--upcoming .stepper__label  { color: var(--ink-4); }
.stepper__step--error    .stepper__label  { color: var(--bad);  font-weight: 600; }
.stepper__step--warning  .stepper__label  { color: var(--warn); font-weight: 600; }

.stepper--sm .stepper__label       { font-size: 12px; }
.stepper--sm .stepper__description { font-size: 11px; }
.stepper--lg .stepper__label       { font-size: 14px; }
.stepper--lg .stepper__description { font-size: 12px; }

/* Horizontal labels — center-align under the marker */
.stepper--horizontal .stepper__label,
.stepper--horizontal .stepper__description { text-align: center; }
.stepper--horizontal .stepper__text { padding: 0 4px; }

/* Current-step background tint — subtle indigo-soft pill behind the text
   so the active step pops out from the surrounding steps even from a
   distance. Only the text/label area gets the tint (not the marker, which
   has its own indigo ring emphasis); the two emphases stack rather than
   compete. */
.stepper__step--current .stepper__text {
  background: var(--indigo-soft);
  border-radius: 6px;
  padding: 4px 8px;
  transition: background var(--duration-fast, 120ms) ease-out;
}
.stepper--horizontal .stepper__step--current .stepper__text {
  /* override the default horizontal --text padding so the pill reads centered */
  padding: 4px 8px;
}
.stepper--vertical .stepper__step--current .stepper__text {
  /* vertical layout already has 3px top — bump to match the pill rhythm */
  padding: 4px 8px;
}

/* Clickable past steps — light hover tint on the text area so users
   discover the back-nav affordance. Marker-only hover already exists; this
   extends the hover hint to the full text region (larger hit target's
   visual feedback). */
.stepper__step--clickable .stepper__text {
  border-radius: 6px;
  padding: 4px 8px;
  cursor: pointer;
  transition: background var(--duration-fast, 120ms) ease-out;
}
.stepper__step--clickable:hover .stepper__text {
  background: var(--bg-hover);
}

@media (prefers-reduced-motion: reduce) {
  .stepper__text { transition: none; }
}

/* Mobile — horizontal stepper collapses to vertical for readability */
@media (max-width: 640px) {
  .stepper--horizontal:not(.stepper--no-collapse) {
    flex-direction: column;
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__step {
    flex: 0 0 auto; flex-direction: row;
    align-items: flex-start; gap: var(--step-gap);
    padding-bottom: 16px;
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__step:last-child { padding-bottom: 0; }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__marker-col {
    flex-direction: column; align-items: center;
    width: auto;
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__connector {
    width: var(--step-line); height: auto; flex: 1 1 0; min-height: 16px;
    margin: 4px 0;
    background: var(--line);
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__step--complete .stepper__connector {
    background: var(--indigo);
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__step--current .stepper__connector {
    background: var(--line); /* current's trailing line is upcoming on mobile */
  }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__label,
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__description { text-align: left; }
  .stepper--horizontal:not(.stepper--no-collapse) .stepper__text { padding: 3px 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .stepper__marker, .stepper__connector, .stepper__dot { transition: none; }
}

/* ============================================================================
   Accordion — expand/collapse panels.
   .accordion + __item + __heading + __trigger + __title + __icon
              + __content + __content-inner
   Variants: --single / --multi  (set on wrapper)
   States:   .accordion__item--open / __item--disabled
   Smooth animation uses the grid-template-rows: 0fr → 1fr trick — browser
   interpolates without JS height measurement. Chrome 117+ / Safari 17+ /
   Firefox 121+; older browsers degrade to instant show/hide.
   ============================================================================ */

.accordion {
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-card);
  overflow: hidden;
}

.accordion__item {
  border-bottom: 1px solid var(--line-soft);
}
.accordion__item:last-child { border-bottom: 0; }

.accordion__item--disabled { opacity: 0.55; }

.accordion__heading {
  margin: 0;
  font: inherit; /* override default <h3> sizing */
}

.accordion__trigger {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  background: none; border: none; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 500; color: var(--ink);
  text-align: left;
  letter-spacing: -0.005em;
  line-height: 1.4;
  transition: background var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.accordion__trigger:hover:not(:disabled) { background: var(--bg-hover); }
.accordion__trigger:disabled { cursor: not-allowed; }
.accordion__trigger:focus-visible {
  outline: none;
  background: var(--bg-hover);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

/* Title stack — wraps the title + optional subtitle so they stay grouped
   while the leading icon / trailing meta / chevron sit beside them. */
.accordion__title-stack { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.accordion__title       { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.accordion__subtitle {
  font-size: 12px; font-weight: 400; color: var(--ink-4);
  line-height: 1.4;
  letter-spacing: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.accordion--with-subtitle .accordion__trigger,
.accordion__item--with-subtitle .accordion__trigger { padding-top: 12px; padding-bottom: 12px; }

/* Leading icon — sits before the title stack */
.accordion__leading-icon {
  display: inline-flex; align-items: center;
  color: var(--ink-4); flex: 0 0 auto;
}

/* Meta — trailing slot before the chevron. Useful for count badges
   ("12") or status pills ("Configured"). */
.accordion__meta {
  display: inline-flex; align-items: center;
  font-size: 12px; color: var(--ink-4);
  flex: 0 0 auto;
}

.accordion__icon {
  display: inline-flex; align-items: center;
  color: var(--ink-4); flex: 0 0 auto;
  transition: transform var(--duration-base, 180ms) var(--ease-out, ease-out),
              color     var(--duration-fast, 120ms) ease-out;
}
.accordion__item--open .accordion__icon {
  transform: rotate(180deg);
  color: var(--ink-2);
}

/* Content collapse — grid-template-rows 0fr → 1fr animation */
.accordion__content {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-base, 180ms) var(--ease-out, ease-out);
}
.accordion__content > .accordion__content-inner {
  overflow: hidden;
  min-height: 0; /* required for grid-row 0fr to actually collapse */
}
.accordion__item--open .accordion__content {
  grid-template-rows: 1fr;
}
.accordion__content-inner {
  padding: 0 16px 16px;
  font-size: 13.5px; line-height: 1.6;
  color: var(--ink-2);
}
.accordion__content-inner p { margin: 0 0 10px; }
.accordion__content-inner p:last-child { margin: 0; }

/* Size: sm */
.accordion--sm .accordion__trigger { padding: 10px 14px; font-size: 13px; }
.accordion--sm .accordion__content-inner { padding: 0 14px 12px; font-size: 12.5px; }
.accordion--sm .accordion__icon svg { width: 12px; height: 12px; }
.accordion--sm .accordion__subtitle { font-size: 11px; }

/* Size: lg */
.accordion--lg .accordion__trigger { padding: 16px 18px; font-size: 15px; }
.accordion--lg .accordion__content-inner { padding: 0 18px 18px; font-size: 14px; }
.accordion--lg .accordion__icon svg { width: 16px; height: 16px; }
.accordion--lg .accordion__subtitle { font-size: 13px; }

/* Flush variant — strips the outer border + radius so the accordion sits
   inside an existing card or panel without the double-frame look. */
.accordion--flush {
  border: none;
  border-radius: 0;
  background: transparent;
  overflow: visible;
}
.accordion--flush .accordion__item {
  border-bottom: 1px solid var(--line);
}
.accordion--flush .accordion__item:last-child { border-bottom: none; }
.accordion--flush .accordion__trigger {
  padding-left: 0; padding-right: 0;
}
.accordion--flush .accordion__content-inner {
  padding-left: 0; padding-right: 0;
}

@media (prefers-reduced-motion: reduce) {
  .accordion__content { transition: none; }
  .accordion__icon    { transition: none; }
}

/* ============================================================================
   TreeView — collapsible nested list. role=tree + role=treeitem + roving
   tabindex + aria-expanded/level/setsize/posinset.
   .treeview + __item + __row + __chevron + __icon + __label + __meta
   Sizes: --sm / --md.  Modifiers: --lines (vertical indent guides)
   ============================================================================ */
.treeview {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex; flex-direction: column;
  gap: 1px;
  font-size: 13px;
  color: var(--ink-2);
}
.treeview--sm { font-size: 12px; }

.treeview__item {
  margin: 0; padding: 0;
}

.treeview__row {
  display: flex; align-items: center;
  gap: 6px;
  width: 100%;
  padding: 5px 8px;
  background: none;
  border: none;
  border-radius: 5px;
  font: inherit; font-size: inherit; color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--duration-fast, 120ms) ease-out,
              color var(--duration-fast, 120ms) ease-out;
}
.treeview--sm .treeview__row { padding: 3px 6px; gap: 5px; }

.treeview__row:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--ink);
}
.treeview__row:focus-visible {
  outline: none;
  background: var(--bg-hover);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.treeview__row:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

/* Selected row — indigo-soft bg + indigo text, persists on hover too */
.treeview__item--selected > .treeview__row {
  background: var(--indigo-soft);
  color: var(--indigo);
  font-weight: 500;
}
.treeview__item--selected > .treeview__row:hover {
  background: color-mix(in srgb, var(--indigo-soft) 75%, var(--indigo));
}

/* Chevron — fixed-width column so leaf rows align with folder rows.
   Click on the chevron toggles expand without firing the row's select
   handler (stopPropagation in JS). */
.treeview__chevron {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  flex: 0 0 auto;
  color: var(--ink-4);
  border-radius: 3px;
  transition: background 80ms;
}
.treeview__chevron:hover:not(.treeview__chevron--placeholder) {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
}
/* Placeholder (leaf nodes) — invisible same-width spacer so alignment
   matches folder rows. */
.treeview__chevron--placeholder { pointer-events: none; }

.treeview__icon {
  display: inline-flex; align-items: center;
  color: var(--ink-4);
  flex: 0 0 auto;
}
.treeview__item--selected > .treeview__row .treeview__icon { color: var(--indigo); }

.treeview__label {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.4;
}

.treeview__meta {
  flex: 0 0 auto;
  font-size: 11.5px;
  color: var(--ink-5);
  font-feature-settings: "tnum";
  margin-left: auto;
}
.treeview__item--selected > .treeview__row .treeview__meta { color: var(--indigo); }

/* Indent-guide lines variant — vertical lines at each depth level so the
   nesting structure is visible. Renders as a left border on each item
   stepped per depth (caller chooses showLines). */
.treeview--lines .treeview__item {
  position: relative;
}
.treeview--lines .treeview__row::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: calc(var(--tv-depth, 0) * 18px + 14px);
  width: 1px;
  background: var(--line-soft);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .treeview__row, .treeview__chevron { transition: none; }
}

/* ============================================================================
   Tabs — .tabs + .tabs__tab + .tabs__tab--active + .tabs__badge
   variant modifiers: .tabs--underline / .tabs--pill
   size modifiers:    .tabs--sm / .tabs--md / .tabs--lg
   ============================================================================ */

.tabs {
  display: flex; align-items: center;
  /* Mobile: horizontal scroll, hidden scrollbar */
  overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none;
  flex-shrink: 0;
}
.tabs::-webkit-scrollbar { display: none; }

/* ── Overflow affordance: "there are more tabs this way" ──────────────────────
   THE BUG. A project renders up to thirteen tabs (~1180px). Inside the 760px
   .pd-side-panel (styles.css:4442) roughly a third of them — Overview, Files,
   Activity — sit off the right edge. The row scrolls (overflow-x above) but the
   scrollbar is deliberately suppressed, so there was NO indication whatsoever
   that anything existed past the last visible tab. That is a plausible source
   of a whole category of "I couldn't find X".

   ⚠️ DIRECTION-AWARE ON PURPOSE — A STATIC FADE IS A LIE. It must not fade the
   right edge when you are already at the end, nor the left edge at the start,
   nor fade anything at all when the row fits. The two fade widths are
   @property-registered <length>s driven by a scroll-PROGRESS timeline on the
   element's own inline axis, so they track the real scroll position. When the
   row FITS, its scroll timeline is inactive, the animation produces no output,
   and the base widths below (0px / 0px) leave the row completely untouched —
   which is the correct honest state and the whole reason this technique is
   used instead of a fixed gradient.

   ⚠️ NOT A TRANSITION, AND NOTHING var()-VALUED IS TRANSITIONED. This repo has
   a live rule (see scripts/test_css_classes.py) that a transitioned var()- or
   color-mix()-valued property STICKS at its from-value in Chrome. That applies
   to `transition`; these are registered custom properties animated on a scroll
   timeline, which is exactly what @property makes interpolable. No `transition`
   declaration is added anywhere here.

   ⚠️ ORDER MATTERS: the `animation` shorthand resets `animation-timeline` to
   `auto`, so animation-timeline MUST be declared after it. Reversing the two
   lines silently turns this into a time-based animation.

   Vertical tab lists are excluded explicitly — they have no inline overflow, so
   the timeline would be inactive anyway, but a horizontal mask on a column has
   no business being there at all. */
/* ⚠️ THE SCROLL-TIMELINE FADE WAS BUILT, SHIPPED, AND REMOVED THE SAME NIGHT —
   IT RENDERED NOTHING. Verified in Chrome 150 on the live bundle: the animation
   existed, playState was "running", its timeline was a real ScrollTimeline
   whose `source` WAS the element and whose `axis` WAS "inline", the element
   genuinely overflowed (scrollWidth 1166 vs clientWidth 719, overflow-x auto)
   — and `timeline.currentTime` was still null, so --tabs-fade-l/r stayed 0px
   at scroll offset 0, mid, and end. The mask resolved to a no-op gradient.
   Nothing was broken by it; nothing was gained either.

   Not chased further: this is the least valuable of the four Session-1 items
   and the fade was a nicety. Shipping the affordance that demonstrably works
   instead — which is the same principle the fade's own comment argued for:
   prefer the honest simple thing over a decoration that cannot tell the truth.
   A scrollbar appears exactly when there is overflow, shows where you are in
   it, and cannot claim tabs exist when they don't.

   The suppression above (scrollbar-width: none) is DELIBERATELY overridden
   here rather than deleted, so the mobile/other .tabs users keep whatever the
   base rule gives them and only the horizontal bar gets the bar back. */
.tabs:not(.tabs--vertical) {
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.tabs:not(.tabs--vertical)::-webkit-scrollbar { display: block; height: 6px; }
.tabs:not(.tabs--vertical)::-webkit-scrollbar-track { background: transparent; }
.tabs:not(.tabs--vertical)::-webkit-scrollbar-thumb {
  background: var(--line-strong); border-radius: 999px;
}

/* ── Base tab button ── */
.tabs__tab {
  display: inline-flex; align-items: center; gap: 6px;
  white-space: nowrap; flex-shrink: 0;
  background: none; border: none; cursor: pointer;
  font-size: 13px; font-weight: 500; color: var(--ink-4);
  padding: 8px 14px;
  transition:
    color      var(--duration-fast) var(--ease-in-out),
    background var(--duration-fast) var(--ease-in-out);
}
.tabs__tab:hover:not(.tabs__tab--active) { color: var(--ink-2); }
.tabs__tab--active { color: var(--ink); font-weight: 600; }

/* Display-only tabs (no onChange) — don't look clickable */
.tabs--static .tabs__tab { cursor: default; }
.tabs--static .tabs__tab:hover:not(.tabs__tab--active) { color: var(--ink-4); }

.tabs__icon { display: flex; align-items: center; }
.tabs__label { }

.tabs__badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--bg-sunk); color: var(--ink-4);
  font-size: 10px; font-weight: 700; border-radius: 999px;
  line-height: 1;
  transition: background var(--duration-fast) var(--ease-in-out),
              color      var(--duration-fast) var(--ease-in-out);
}
.tabs__tab--active .tabs__badge {
  background: var(--indigo-soft); color: var(--indigo);
}

/* ── Underline variant ── */
.tabs--underline {
  border-bottom: 1px solid var(--line);
  gap: 0;
}
.tabs--underline .tabs__tab {
  border-bottom: 2px solid transparent;
  margin-bottom: -1px; /* overlap container bottom border */
  border-radius: 0;
  padding: 8px 14px;
}
.tabs--underline .tabs__tab--active {
  border-bottom-color: var(--indigo);
}

/* ── Pill variant ── */
.tabs--pill {
  background: var(--bg-sunk); border-radius: 10px; padding: 3px; gap: 2px;
  border: 1px solid var(--line);
}
.tabs--pill .tabs__tab {
  border-radius: 7px; padding: 6px 12px;
}
.tabs--pill .tabs__tab--active {
  background: var(--bg-card);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}

/* ── Size overrides ── */
.tabs--sm .tabs__tab { font-size: 12px; padding: 5px 10px; }
.tabs--sm.tabs--underline .tabs__tab { padding: 6px 10px; }
.tabs--sm.tabs--pill      .tabs__tab { padding: 4px 10px; }

.tabs--lg .tabs__tab { font-size: 14px; padding: 10px 18px; }
.tabs--lg.tabs--underline .tabs__tab { padding: 10px 18px; }
.tabs--lg.tabs--pill      .tabs__tab { padding: 8px 16px; }

/* Disabled tab — muted text, no hover, cursor not-allowed */
.tabs__tab--disabled,
.tabs__tab:disabled {
  opacity: 0.45; cursor: not-allowed;
}
.tabs__tab--disabled:hover,
.tabs__tab:disabled:hover { color: inherit; background: inherit; }

/* Vertical orientation — column layout, indicator on the leading edge */
.tabs--vertical {
  flex-direction: column;
  align-items: stretch;
  border-bottom: none;
  border-right: 1px solid var(--line);
  margin-bottom: 0; margin-right: 16px;
  gap: 0;
}
.tabs--vertical .tabs__tab {
  text-align: left;
  justify-content: flex-start;
  border-bottom: none;
  border-right: 2px solid transparent;
  padding: 8px 14px;
  margin-right: -1px; /* overlap the tablist border so the indicator sits flush */
}
.tabs--vertical .tabs__tab--active {
  border-right-color: var(--indigo);
}

/* Tabpanel — when Tabs renders panels via the `panels` prop. Focusable region
   so keyboard users can land on the content after activating a tab. */
.tabs__panel {
  outline: none;
  /* Mild visual focus indicator that doesn't overpower content */
}
.tabs__panel:focus-visible {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 18%, transparent);
  border-radius: 6px;
}

/* Fade-in transition when a tab panel becomes visible. The animation rule
   only matches when the `hidden` attribute is absent — so each time React
   toggles `hidden` from true → false on a panel (i.e., that tab activates),
   the CSS engine treats it as a fresh rule application and replays the
   animation. The small 2px lift gives the fade an intentional, directional
   feel rather than a flat brightness blink.

   Slightly clipped — `from` starts at opacity 0.4 instead of 0 so the
   content doesn't completely disappear mid-switch (jarring when switching
   rapidly back and forth) and `to` settles in 200ms. */
@keyframes tabs-panel-in {
  from { opacity: 0.4; transform: translateY(2px); }
  to   { opacity: 1;   transform: translateY(0);   }
}
.tabs__panel:not([hidden]) {
  animation: tabs-panel-in 200ms var(--ease-out, ease-out) both;
}

@media (prefers-reduced-motion: reduce) {
  .tabs__panel:not([hidden]) { animation: none; }
}

/* ============================================================================
   SegmentedControl — iOS-style pill row with sliding active indicator.
   .segmented + __indicator + __option + __option--active + __option--disabled
   Size modifiers: --sm / --md
   ============================================================================ */

.segmented {
  position: relative;
  display: inline-flex; align-items: stretch;
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-btn);
  padding: 2px;
  isolation: isolate; /* keep indicator under options without bleed */
}
.segmented--sm { padding: 1.5px; border-radius: var(--radius-btn); }
.segmented--lg { padding: 3px;   border-radius: var(--radius-btn); }
/* fullWidth — fills parent's available width (vs default inline-flex auto) */
.segmented--full { display: flex; width: 100%; }

.segmented__indicator {
  position: absolute;
  top: 2px; bottom: 2px;
  z-index: 0;
  background: var(--bg-card);
  border-radius: var(--radius-btn);
  box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 0 0 1px var(--line);
  /* Transition both `left` AND `width` so future "auto-width options" mode
     can animate width changes too (currently options are equal-width so
     width is constant per active slot, but transitioning costs nothing
     when the value doesn't change). */
  transition: left  var(--duration-base, 180ms) var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
              width var(--duration-base, 180ms) var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
              opacity var(--duration-fast, 120ms) ease-out;
}
.segmented--sm .segmented__indicator { top: 1.5px; bottom: 1.5px; border-radius: var(--radius-btn); }
.segmented--lg .segmented__indicator { top: 3px;   bottom: 3px;   border-radius: var(--radius-btn); }

.segmented__option {
  position: relative; z-index: 1;
  flex: 1 1 0;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-3);
  background: transparent;
  border: none; border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--duration-fast, 120ms) ease-out;
  min-width: 0;
}
.segmented__option:hover:not(.segmented__option--active):not(.segmented__option--disabled) {
  color: var(--ink-2);
}
.segmented__option--active   { color: var(--ink); }
.segmented__option--disabled { opacity: 0.45; cursor: not-allowed; }
.segmented__option svg { color: currentColor; flex: 0 0 auto; }

.segmented--sm .segmented__option {
  padding: 4px 10px;
  font-size: 11.5px;
  gap: 4px;
}
.segmented--lg .segmented__option {
  padding: 8px 18px;
  font-size: 13.5px;
  gap: 7px;
}

.segmented__option:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 30%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .segmented__indicator { transition: none; }
}

/* ============================================================================
   Toolbar — horizontal action group with separators + responsive overflow.
   .toolbar (row) + __item + __btn + __btn--primary/--danger/--icon/--more
                  + __btn-label + __sep + __custom + __overflow
   Size modifiers: --sm / --md
   Items at index ≥ overflowAt get .toolbar__item--overflow and hide at ≤768px,
   while .toolbar__overflow Dropdown trigger appears in their place.
   ============================================================================ */

.toolbar {
  display: inline-flex; align-items: center;
  gap: 2px;
  flex-wrap: nowrap;
  min-width: 0;
  /* When a spacer is present, the toolbar needs to fill available width
     for the spacer's flex:1 to actually push content. Callers control
     outer width via the parent — toolbar respects it via 100% width
     when its parent gives it a definite size. */
  width: 100%;
  max-width: 100%;
}

.toolbar__item {
  display: inline-flex; align-items: center;
  flex: 0 0 auto;
}

/* Button base */
.toolbar__btn {
  display: inline-flex; align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  font: inherit; font-size: 13px; font-weight: 500; line-height: 1.4;
  color: var(--ink-2);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast, 120ms) ease-out,
              color      var(--duration-fast, 120ms) ease-out,
              border-color var(--duration-fast, 120ms) ease-out;
}
.toolbar__btn:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--ink);
}
.toolbar__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.toolbar__btn:disabled { opacity: 0.45; cursor: not-allowed; }
.toolbar__btn svg { color: currentColor; flex: 0 0 auto; }

/* Variants */
.toolbar__btn--primary {
  background: var(--indigo);
  color: #fff;
  border-color: var(--indigo);
}
.toolbar__btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--indigo) 90%, #000);
  color: #fff;
}
.toolbar__btn--danger {
  color: var(--bad);
}
.toolbar__btn--danger:hover:not(:disabled) {
  background: var(--bad-soft);
  color: var(--bad);
}
.toolbar__btn--danger svg { color: currentColor; }

/* Icon-only button — square, label visually hidden but aria-label provides it */
.toolbar__btn--icon {
  padding: 6px;
  min-width: 30px;
  justify-content: center;
  border-radius: var(--radius-btn-icon); /* icon-only stays square-ish per token doc */
}
.toolbar__btn--icon .toolbar__btn-label { display: none; }

/* Size: sm */
.toolbar--sm .toolbar__btn       { padding: 4px 8px; font-size: 12px; gap: 5px; }
.toolbar--sm .toolbar__btn--icon { padding: 4px; min-width: 26px; }

/* Size: lg */
.toolbar--lg .toolbar__btn       { padding: 8px 14px; font-size: 14px; gap: 7px; }
.toolbar--lg .toolbar__btn--icon { padding: 8px; min-width: 38px; }

/* Separator (also matches the "divider" alias) */
.toolbar__sep {
  width: 1px; height: 18px;
  background: var(--line);
  margin: 0 4px;
  flex: 0 0 auto;
}
.toolbar--sm .toolbar__sep { height: 14px; margin: 0 3px; }
.toolbar--lg .toolbar__sep { height: 22px; margin: 0 6px; }

/* Spacer — flexible gap that pushes following items to the right (or
   bottom on stacked toolbars later). Invisible; just consumes space.
   Use case: [Save] [Cancel]  ────────  [Delete] — Delete pushed right. */
.toolbar__spacer {
  flex: 1 1 auto;
  min-width: 0;
}

/* Custom slot — wraps arbitrary children */
.toolbar__custom { display: inline-flex; align-items: center; }

/* Overflow Dropdown trigger — hidden on desktop, shown on mobile */
.toolbar__overflow         { display: none; }
.toolbar__btn--more svg    { /* inherit color */ }

/* Mobile: overflow items hide + "More" Dropdown appears */
@media (max-width: 768px) {
  .toolbar__item--overflow { display: none; }
  .toolbar__overflow       { display: inline-flex; }
}

/* ============================================================================
   Tooltip — .tooltip (wrapper) + .tooltip__content + .tooltip__arrow
   placement modifiers: .tooltip__content--top/right/bottom/left
   ============================================================================ */

.tooltip {
  display: inline-block;
}

.tooltip__content {
  /* 7090 — ceiling of the dialog band (was 600). A Tooltip is used on buttons
     INSIDE dialogs; left at 600 while Modal moved to 7050 it would have been
     swallowed by the very dialog it annotates. Canonical ladder: the
     "⭐⭐ THE DIALOG LAYER" block above .modal-backdrop. */
  position: fixed; z-index: 7090; pointer-events: none;
  background: var(--ink); color: var(--bg);
  font-size: 12px; font-weight: 500; line-height: 1.45;
  padding: 5px 9px; border-radius: 6px;
  max-width: 240px; white-space: normal; word-break: break-word;
  /* enter state; direction-specific translate added by placement modifier below */
  opacity: 0;
  transition:
    opacity   var(--duration-fast) var(--ease-in-out),
    transform var(--duration-fast) var(--ease-out);
}
/* Direction of enter slide (tooltip slides toward anchor, i.e. away from its rest side) */
.tooltip__content--top    { transform: translateY( 3px); }
.tooltip__content--bottom { transform: translateY(-3px); }
.tooltip__content--left   { transform: translateX( 3px); }
.tooltip__content--right  { transform: translateX(-3px); }
/* is-visible resets transform for all placements (must come last) */
.tooltip__content.is-visible { opacity: 1; transform: translate(0, 0); }

/* Arrow — CSS triangle */
.tooltip__arrow {
  position: absolute; width: 0; height: 0; border: 4px solid transparent;
}
.tooltip__content--top    .tooltip__arrow {
  bottom: -7px; left: 50%; transform: translateX(-50%);
  border-width: 4px 4px 0;
  border-top-color: var(--ink);
}
.tooltip__content--bottom .tooltip__arrow {
  top: -7px; left: 50%; transform: translateX(-50%);
  border-width: 0 4px 4px;
  border-bottom-color: var(--ink);
}
.tooltip__content--left   .tooltip__arrow {
  right: -7px; top: 50%; transform: translateY(-50%);
  border-width: 4px 0 4px 4px;
  border-left-color: var(--ink);
}
.tooltip__content--right  .tooltip__arrow {
  left: -7px; top: 50%; transform: translateY(-50%);
  border-width: 4px 4px 4px 0;
  border-right-color: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .tooltip__content { transition: none; transform: none !important; }
}

/* ============================================================================
   HoverCard — preview-on-hover rich card.
   Sits between Tooltip (text-only) and Popover (click-triggered): hover
   opens a richer panel with project/member/client preview content.
   .hover-card-anchor (inline wrapper for trigger) + .hover-card (panel)
   z-index 370 — below Popover (380) so a click-Popover inside a HoverCard
   stays on top.
   ============================================================================ */

.hover-card-anchor {
  display: inline-block;
  position: relative;
}

.hover-card {
  position: fixed;
  /* 7070 — dialog band (was 370). Canonical ladder: the "⭐⭐ THE DIALOG LAYER"
     block above .modal-backdrop. Still below Popover, as documented. */
  z-index: 7070;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 12px 32px -10px rgba(20,20,30,.18), 0 2px 6px rgba(20,20,30,.06);
  padding: 12px 14px;
  font-size: 13px; line-height: 1.5; color: var(--ink);
  max-width: min(360px, calc(100vw - 24px));
  opacity: 0;
  transform: scale(0.96) translateY(2px);
  transform-origin: var(--hc-origin, center top);
  transition:
    opacity   var(--duration-base, 180ms) var(--ease-out, ease-out),
    transform var(--duration-base, 180ms) var(--ease-out, ease-out);
  pointer-events: none;  /* off until visible — prevents flicker on first paint */
}
.hover-card.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

/* Side modifiers — set transform-origin so the scale-in feels anchored */
.hover-card--top    { --hc-origin: center bottom; }
.hover-card--bottom { --hc-origin: center top; }
.hover-card--left   { --hc-origin: right center; }
.hover-card--right  { --hc-origin: left center; }

/* Arrow (optional) — small 8px triangle pointing at the trigger */
.hover-card__arrow {
  position: absolute;
  width: 8px; height: 8px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  transform: rotate(45deg);
  pointer-events: none;
}
.hover-card--top    .hover-card__arrow { bottom: -5px; left: 20px;  border-top: 0; border-left: 0; }
.hover-card--bottom .hover-card__arrow { top: -5px;    left: 20px;  border-bottom: 0; border-right: 0; }
.hover-card--left   .hover-card__arrow { right: -5px;  top: 16px;   border-bottom: 0; border-left: 0; }
.hover-card--right  .hover-card__arrow { left: -5px;   top: 16px;   border-top: 0; border-right: 0; }

@media (prefers-reduced-motion: reduce) {
  .hover-card { transition: opacity 100ms linear; transform: none !important; }
}

/* Touch devices — disable the hover behavior visually. Hover events still
   fire from mouse-emulation taps but the card snaps to invisible (no
   transition) so it doesn't linger awkwardly after a tap. The trigger
   stays clickable as a normal link/button. */
@media (hover: none) {
  .hover-card { display: none !important; }
}

/* ============================================================================
   Popover — anchored floating panel (interactive, unlike Tooltip).
   .popover-anchor (wraps trigger, inline) + .popover-panel (the float)
                  + .popover-arrow + side modifiers
   z-index 380 — above Drawer (360) and Modal (350) so a Popover triggered
   inside a Modal stays on top.
   Distinct namespace from legacy .popover utility (which is unchanged).
   ============================================================================ */

.popover-anchor {
  display: inline-block;
  position: relative; /* keeps trigger flow normal; panel uses position:fixed */
}

.popover-panel {
  position: fixed;
  /* 7080 — dialog band (was 380). MUST stay above .modal-backdrop (7050) and
     .drawer-backdrop (7060): a Popover/Dropdown/context menu opened INSIDE a
     dialog has to paint on top of it. Canonical ladder: the "⭐⭐ THE DIALOG
     LAYER" block above .modal-backdrop. */
  z-index: 7080;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow-lg, 0 12px 32px -10px rgba(20,20,30,.18));
  min-width: 160px; max-width: min(380px, calc(100vw - 24px));
  /* Default 8px padding now lives on --pad-md; the bare .popover-panel
     no longer hardcodes padding so the modifier classes win cleanly. */
  font-size: 13px; color: var(--ink);
  opacity: 0; transform: scale(0.97);
  transform-origin: var(--pop-origin, center top);
  transition:
    opacity   var(--duration-fast, 120ms) var(--ease-out, ease-out),
    transform var(--duration-fast, 120ms) var(--ease-out, ease-out);
  pointer-events: none;
}
.popover-panel.is-visible { opacity: 1; transform: none; pointer-events: auto; }

/* Padding modifiers — `none` for menu/list panels where each row owns its
   own padding; sm/md/lg for filter pickers and form fragments. */
.popover-panel--pad-none { padding: 0; }
.popover-panel--pad-sm   { padding: 6px; }
.popover-panel--pad-md   { padding: 8px; }
.popover-panel--pad-lg   { padding: 12px; }

/* Title slot — header pinned at the top, divider below. Negative horizontal
   margin bleeds through padding so the divider runs edge-to-edge regardless
   of the panel's --pad-* setting (matches Card header behavior). */
.popover-panel__title {
  font-size: 11.5px; font-weight: 600; color: var(--ink-4);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 8px 12px;
  margin: 0 -8px 6px -8px;  /* bleeds through default md padding */
  border-bottom: 1px solid var(--line-soft);
  background: transparent;
  user-select: none;
}
.popover-panel--pad-none .popover-panel__title { margin: 0; padding: 10px 12px; }
.popover-panel--pad-sm   .popover-panel__title { margin: 0 -6px 6px -6px; }
.popover-panel--pad-lg   .popover-panel__title { margin: 0 -12px 8px -12px; }

/* Side modifiers — set transform-origin so the scale-in feels anchored */
.popover-panel--top    { --pop-origin: center bottom; }
.popover-panel--bottom { --pop-origin: center top; }
.popover-panel--left   { --pop-origin: right center; }
.popover-panel--right  { --pop-origin: left center; }

/* Arrow */
.popover-arrow {
  position: absolute; width: 8px; height: 8px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  transform: rotate(45deg);
  pointer-events: none;
}
.popover-panel--top    .popover-arrow { bottom: -5px; left: 50%; margin-left: -4px; border-top: 0; border-left: 0; }
.popover-panel--bottom .popover-arrow { top: -5px;    left: 50%; margin-left: -4px; border-bottom: 0; border-right: 0; }
.popover-panel--left   .popover-arrow { right: -5px;  top: 50%;  margin-top: -4px;  border-bottom: 0; border-left: 0; }
.popover-panel--right  .popover-arrow { left: -5px;   top: 50%;  margin-top: -4px;  border-top: 0; border-right: 0; }

@media (prefers-reduced-motion: reduce) {
  .popover-panel { transition: opacity 80ms linear; transform: none !important; }
}

/* ============================================================================
   Dropdown menu — context / overflow menu.
   .dropdown-anchor (wraps trigger) + .dropdown (the menu, position:fixed)
                  + .dropdown__item + .dropdown__divider + side modifiers
   Same z-index lane as Popover (380) so dropdowns float above modals.
   ============================================================================ */

.dropdown-anchor {
  display: inline-block;
  position: relative;
}

.dropdown {
  position: fixed;
  /* 7080 — same lane as .popover-panel, so dropdowns float above dialogs.
     Canonical ladder: the "⭐⭐ THE DIALOG LAYER" block above .modal-backdrop. */
  z-index: 7080;
  min-width: 168px; max-width: 280px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow-lg, 0 12px 32px -10px rgba(20,20,30,.18));
  padding: 5px;
  font-size: 13px;
  opacity: 0; transform: scale(0.98) translateY(-2px);
  transform-origin: var(--ddrop-origin, center top);
  transition:
    opacity   var(--duration-fast, 120ms) var(--ease-out, ease-out),
    transform var(--duration-fast, 120ms) var(--ease-out, ease-out);
  pointer-events: none;
}
.dropdown.is-visible { opacity: 1; transform: none; pointer-events: auto; }

.dropdown--top    { --ddrop-origin: center bottom; }
.dropdown--bottom { --ddrop-origin: center top; }
.dropdown--left   { --ddrop-origin: right center; }
.dropdown--right  { --ddrop-origin: left center; }

/* Item */
.dropdown__item {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 7px 9px;
  border: none; border-radius: 5px;
  background: transparent;
  color: var(--ink-2);
  font-size: 13px; font-weight: 400; line-height: 1.4;
  text-align: left; cursor: pointer;
  transition: background 90ms, color 90ms;
  font-family: inherit;
}
.dropdown__item:focus { outline: none; }
.dropdown__item:focus-visible,
.dropdown__item:hover:not(:disabled) {
  background: var(--bg-hover); color: var(--ink);
}
/* When keyboard sets tabIndex=0, we also style as active so mouse + kb agree */
.dropdown__item[tabindex="0"]:focus { background: var(--bg-hover); color: var(--ink); }

.dropdown__item-icon  {
  display: inline-flex; align-items: center;
  color: var(--ink-4); flex: 0 0 auto;
}
.dropdown__item:hover:not(:disabled) .dropdown__item-icon,
.dropdown__item:focus-visible        .dropdown__item-icon { color: var(--ink-2); }

.dropdown__item-label    { flex: 1; min-width: 0; }
.dropdown__item-shortcut {
  margin-left: auto;
  font-size: 11px; color: var(--ink-5);
  font-family: var(--f-mono, ui-monospace, Menlo, Consolas, monospace);
  flex: 0 0 auto;
}

/* Danger variant — destructive action */
.dropdown__item--danger { color: var(--bad); }
.dropdown__item--danger .dropdown__item-icon { color: var(--bad); }
.dropdown__item--danger:hover:not(:disabled),
.dropdown__item--danger:focus-visible {
  background: var(--bad-soft);
  color: var(--bad);
}
.dropdown__item--danger:hover:not(:disabled) .dropdown__item-icon,
.dropdown__item--danger:focus-visible        .dropdown__item-icon { color: var(--bad); }

/* Disabled */
.dropdown__item--disabled,
.dropdown__item:disabled {
  opacity: 0.45; cursor: not-allowed;
}

/* Divider */
.dropdown__divider {
  height: 1px; background: var(--line);
  margin: 4px 2px;
}

@media (prefers-reduced-motion: reduce) {
  .dropdown { transition: opacity 80ms linear; transform: none !important; }
}

/* ============================================================================
   Menu — Popover-composed accessible dropdown menu.
   .menu-panel (Popover override) + .menu (role=menu container)
                                  + .menu__item / __divider / etc.
   The Popover provides z-index, positioning, animation, ESC/click-outside;
   Menu adds the role=menu + role=menuitem + roving-tabindex layer.
   ============================================================================ */

/* Override Popover panel defaults when used by Menu — tighten min-width,
   add a touch of internal padding so the divider lines breathe. */
.popover-panel.menu-panel {
  min-width: 168px;
  max-width: 320px;
  padding: 4px;
}

.menu {
  display: flex; flex-direction: column;
  gap: 0;
  min-width: 0;
}

.menu__item {
  display: flex; align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  background: transparent;
  border: none;
  border-radius: 5px;
  font: inherit; font-size: 13px; font-weight: 400; line-height: 1.4;
  color: var(--ink-2);
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  transition: background 90ms, color 90ms;
}
.menu__item:focus { outline: none; }
.menu__item:focus-visible,
.menu__item:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--ink);
}

.menu__item-icon { display: inline-flex; align-items: center; color: var(--ink-4); flex: 0 0 auto; }
.menu__item:hover:not(:disabled) .menu__item-icon,
.menu__item:focus-visible .menu__item-icon { color: var(--ink-2); }

.menu__item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu__item-shortcut {
  margin-left: auto;
  font-size: 11px; color: var(--ink-5);
  font-family: var(--f-mono, ui-monospace, Menlo, Consolas, monospace);
  flex: 0 0 auto;
}

/* Danger variant — destructive action (e.g., Delete, Archive). Red text
   + soft-red hover; soft-red not flat-red so it doesn't read as a button
   already pressed. */
.menu__item--danger { color: var(--bad); }
.menu__item--danger .menu__item-icon { color: var(--bad); }
.menu__item--danger:hover:not(:disabled),
.menu__item--danger:focus-visible {
  background: var(--bad-soft);
  color: var(--bad);
}
.menu__item--danger:hover:not(:disabled) .menu__item-icon,
.menu__item--danger:focus-visible .menu__item-icon { color: var(--bad); }

/* Disabled */
.menu__item--disabled,
.menu__item:disabled {
  opacity: 0.45; cursor: not-allowed;
}

/* Divider — same look as Dropdown's */
.menu__divider {
  height: 1px; background: var(--line);
  margin: 4px 2px;
}

/* ─── ContextMenu — right-click triggered menu at cursor position ──────────
   Wraps children in a span that catches contextmenu events; the menu panel
   reuses the popover-panel + menu CSS for visual parity with <Menu>.
   .ctx-menu-area: display:contents so the wrapper doesn't disturb child
   layout (e.g., flex/grid parents see the children directly).
   .ctx-menu-panel: small entrance animation override (snap-in feel vs
   the popover's hover-then-pop scale-in). */
.ctx-menu-area {
  display: contents;
}
.ctx-menu-panel {
  /* Use a tighter, snappier entrance than Popover's default scale-in.
     Context menus appear at the cursor — they should feel committed
     immediately, not coast in like a hover popover. */
  transform: scale(1) !important;
  opacity: 1 !important;
  animation: ctx-menu-in 100ms var(--ease-out, ease-out) both;
}
@keyframes ctx-menu-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1);    }
}
@media (prefers-reduced-motion: reduce) {
  .ctx-menu-panel { animation: none; }
}

/* ============================================================================
   KbdKey + KeyboardShortcut — styled <kbd> chips + composed shortcut rows
   Used in tooltips, help overlays, and command bar hints.
   ============================================================================ */

.kbd-key {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--f-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 11px; font-weight: 500; line-height: 1;
  color: var(--ink-2);
  background: linear-gradient(180deg, var(--bg-card) 0%, var(--bg-sunk) 100%);
  border: 1px solid var(--line);
  border-bottom-width: 2px;  /* physical-key feel — slightly heavier bottom */
  border-bottom-color: var(--line-strong);
  border-radius: 4px;
  padding: 2px 5px; min-width: 18px;
  white-space: nowrap;
  letter-spacing: 0;
  user-select: none;
  /* Subtle inner highlight on top edge — emulates the slight glossy
     top edge of a real keycap. Layered shadow gives depth without
     blowing out the chip visual weight. */
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--bg-card) 70%, white);
}
.kbd-key--sm {
  font-size: 10px;
  padding: 1px 4px; min-width: 16px;
  border-bottom-width: 1.5px;
}
.kbd-key--lg {
  font-size: 12.5px;
  padding: 4px 8px; min-width: 24px;
  border-radius: 5px;
  border-bottom-width: 2.5px;
}

/* Symbol variant — when the chip renders a unicode glyph (⌘, ⇧, ↵, etc.)
   bump font weight slightly + tighten letter spacing so the symbol reads
   as crisp as the surrounding text rather than tiny inside the chip. */
.kbd-key--symbol {
  font-family: var(--f-sans);    /* fallback to system sans which has better
                                    coverage for unicode keyboard symbols
                                    than monospace fonts */
  font-weight: 600;
  font-size: 12px;
}
.kbd-key--sm.kbd-key--symbol { font-size: 11px; }
.kbd-key--lg.kbd-key--symbol { font-size: 14px; }

.kbd-shortcut {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12.5px;
}
.kbd-shortcut--sm { font-size: 11.5px; gap: 6px; }
.kbd-shortcut--lg { font-size: 14px;   gap: 10px; }
.kbd-shortcut__keys {
  display: inline-flex; align-items: center; gap: 3px;
  flex: 0 0 auto;
}
.kbd-shortcut__sep {
  color: var(--ink-5);
  font-size: 11px;
  padding: 0 1px;
  user-select: none;
}
.kbd-shortcut__desc {
  color: var(--ink-3);
  line-height: 1.4;
}

/* ============================================================================
   Timeline + TimelineEvent — vertical activity feed with marker rail.
   .timeline (ol) + __event (li) + __marker + __dot + __content
                  + __head + __title + __timestamp + __body + __actions
   Tone modifiers: --neutral / --accent / --success / --warning / --danger
   Connector line is drawn by the .timeline::before, with the first/last
   event padding clamping it inside the visible range.
   ============================================================================ */

.timeline {
  position: relative;
  list-style: none; margin: 0; padding: 0;
  /* Marker rail = 24px wide; line is centered inside */
}
.timeline::before {
  content: ""; position: absolute;
  top: 14px; bottom: 14px;       /* clamp ends inside first/last marker */
  left: 11px;                    /* center of 24px marker */
  width: 1px;
  background: var(--line);
}

.timeline__event {
  position: relative;
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 0 16px 0;
}
.timeline__event:last-child { padding-bottom: 4px; }
.timeline__event:first-child { padding-top: 4px; }

.timeline--dense .timeline__event { padding: 8px 0 10px 0; }
.timeline--dense::before { top: 10px; bottom: 10px; }

/* Marker — circle that sits over the connector line */
.timeline__marker {
  position: relative; z-index: 1;
  flex: 0 0 24px;
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--ink-3);
  margin-top: 1px; /* baseline-align with title text */
  box-sizing: border-box;
}
.timeline__event--avatar .timeline__marker {
  /* When showing an avatar, drop the border so the avatar's own ring shows. */
  border: none; padding: 0;
  background: transparent;
}
.timeline__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--ink-4);
}

/* Tones — DRY --tone-fg pattern */
.timeline__event--neutral { --tone-fg: var(--ink-4); --tone-soft: var(--bg-sunk);     --tone-line: var(--line); }
.timeline__event--accent  { --tone-fg: var(--indigo); --tone-soft: var(--indigo-soft); --tone-line: var(--indigo-line); }
.timeline__event--success { --tone-fg: var(--ok);     --tone-soft: var(--ok-soft);    --tone-line: var(--ok-line); }
.timeline__event--warning { --tone-fg: var(--warn);   --tone-soft: var(--warn-soft);  --tone-line: var(--warn-line); }
.timeline__event--danger  { --tone-fg: var(--bad);    --tone-soft: var(--bad-soft);   --tone-line: var(--bad-line); }

.timeline__event:not(.timeline__event--avatar):not(.timeline__event--neutral) .timeline__marker {
  background: var(--tone-soft);
  border-color: var(--tone-line);
  color: var(--tone-fg);
}
.timeline__event:not(.timeline__event--avatar):not(.timeline__event--neutral) .timeline__dot {
  background: var(--tone-fg);
}

/* Avatar inside marker: shrink to 24px to fit the rail */
.timeline__marker .avatar,
.timeline__marker .avatar--xs,
.timeline__marker .avatar--sm,
.timeline__marker .avatar--md,
.timeline__marker .avatar--lg,
.timeline__marker .avatar--xl {
  width: 24px !important; height: 24px !important; font-size: 10px !important;
}

/* Content column */
.timeline__content {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 3px;
}
.timeline__head {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 8px;
}
.timeline__title {
  font-size: 13px; font-weight: 500; color: var(--ink);
  line-height: 1.4; min-width: 0;
}
.timeline__timestamp {
  font-size: 11.5px; color: var(--ink-5); flex: 0 0 auto;
  font-feature-settings: "tnum";
}
.timeline__body {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.5;
}
.timeline__body p { margin: 0 0 4px; }
.timeline__body p:last-child { margin: 0; }
.timeline__actions {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 6px;
}

/* Hover-reveal full timestamp — the relative-time label "2h ago" already
   carries the title attribute; this rule just makes its underline-on-hover
   affordance obvious so users know to hover. Native browser tooltip handles
   the title display. */
.timeline__timestamp[title] { cursor: help; }

/* Date marker — section header that groups subsequent events under a date
   label ("Today", "Yesterday", "Mar 15"). Sits in the same <ol> as events
   so the connector line is interrupted visually at the marker, creating a
   distinct chunk per date group. */
.timeline__date-marker {
  display: flex; align-items: center;
  padding: 10px 0 6px 0;
  position: relative;
  z-index: 1;            /* sit above the connector line */
}
.timeline__date-marker:first-child { padding-top: 2px; }
.timeline--dense .timeline__date-marker { padding: 6px 0 4px 0; }

.timeline__date-label {
  display: inline-flex; align-items: center;
  background: var(--bg-card);      /* hides the line behind the label */
  padding: 2px 8px 2px 0;
  margin-left: -6px;                /* extend left of the marker column for visual breathing */
  padding-left: 6px;
  font-size: 10.5px; font-weight: 600;
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.4;
  user-select: none;
}

/* ============================================================================
   Pagination — count + numbered pages + size/jump controls.
   .pagination + __count + __pages + __btn + __btn--active + __btn--nav
              + __ellipsis + __controls + __pagesize + __jump
   ============================================================================ */

.pagination {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px 24px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-3);
  padding-top: 8px;
}

.pagination__count {
  flex: 0 1 auto;
  font-feature-settings: "tnum";
}
.pagination__count strong { color: var(--ink); font-weight: 600; }

.pagination__pages {
  display: flex; align-items: center; gap: 2px;
  list-style: none; padding: 0; margin: 0;
  flex: 0 0 auto;
}

.pagination__btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px; height: 28px; padding: 0 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-btn-icon);
  background: transparent;
  color: var(--ink-3);
  font-family: inherit; font-size: 12.5px; font-weight: 500;
  font-feature-settings: "tnum";
  cursor: pointer;
  transition: background 90ms, color 90ms, border-color 90ms;
}
.pagination__btn:hover:not(:disabled):not(.pagination__btn--active) {
  background: var(--bg-hover); color: var(--ink);
}
.pagination__btn:disabled { opacity: 0.4; cursor: not-allowed; }
.pagination__btn--nav { padding: 0 6px; }
.pagination__btn--active {
  background: var(--indigo);
  color: #fff;
  border-color: var(--indigo);
}
.pagination__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}

.pagination__ellipsis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; height: 28px;
  color: var(--ink-5); user-select: none;
}

.pagination__controls {
  display: flex; align-items: center; gap: 14px;
  flex-wrap: wrap;
}

.pagination__pagesize {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink-4);
}
.pagination__pagesize-select {
  appearance: none; -webkit-appearance: none;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--ink);
  font: inherit; font-size: 12.5px;
  padding: 4px 22px 4px 8px;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-4) 50%),
    linear-gradient(135deg, var(--ink-4) 50%, transparent 50%);
  background-position:
    calc(100% - 11px) 50%,
    calc(100% - 6px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  transition: border-color 120ms;
}
.pagination__pagesize-select:hover { border-color: var(--line-strong); }
.pagination__pagesize-select:focus {
  outline: none; border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}

.pagination__jump {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink-4);
}
.pagination__jump-input {
  width: 56px; height: 26px;
  padding: 0 6px;
  border: 1px solid var(--line); border-radius: 5px;
  background: var(--bg-card); color: var(--ink);
  font: inherit; font-size: 12.5px;
  font-feature-settings: "tnum";
  text-align: center;
  -moz-appearance: textfield; appearance: textfield;
}
.pagination__jump-input::-webkit-outer-spin-button,
.pagination__jump-input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.pagination__jump-input:focus {
  outline: none; border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.pagination__jump-btn {
  height: 26px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: var(--radius-btn);
  background: var(--bg-card); color: var(--ink-2);
  font: inherit; font-size: 12.5px; font-weight: 500;
  cursor: pointer;
  transition: background 90ms, color 90ms;
}
.pagination__jump-btn:hover { background: var(--bg-hover); color: var(--ink); }

@media (max-width: 640px) {
  .pagination { justify-content: center; }
  .pagination__count { flex-basis: 100%; text-align: center; }
  .pagination__controls { flex-basis: 100%; justify-content: center; }
}

/* ============================================================================
   DataTable — sticky-header table with sortable columns + row selection
   .data-table-wrap (frame) + .data-table-scroll (overflow) + .data-table
   .data-table__head + __th + __sortbtn + __sort-icon
   .data-table__body + __tr + __td + __checkbox
   Density modifiers: --comfortable / --compact
   ============================================================================ */

.data-table-wrap {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.data-table-scroll {
  width: 100%;
  overflow-x: auto;
  overflow-y: visible;
}
.data-table-wrap--sticky .data-table-scroll {
  /* Sticky thead lives inside this scroll context */
  max-height: none; /* let parent decide; for fixed-height tables, callers set max-height on .data-table-wrap */
}

.data-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
  color: var(--ink-2);
  font-feature-settings: "tnum";
}

/* Head */
.data-table__head .data-table__th {
  position: relative;
  text-align: left;
  font-size: 11.5px; font-weight: 500;
  color: var(--ink-4); letter-spacing: 0.02em;
  background: var(--bg-sunk);
  border-bottom: 1px solid var(--line);
  padding: 9px 12px;
  white-space: nowrap;
  user-select: none;
}
.data-table-wrap--sticky .data-table__head .data-table__th {
  position: sticky; top: 0; z-index: 2;
}
.data-table__th--align-left   { text-align: left; }
.data-table__th--align-center { text-align: center; }
.data-table__th--align-right  { text-align: right; }
.data-table__th--select { width: 36px; padding-right: 0; }

.data-table__sortbtn {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  letter-spacing: inherit;
}
.data-table__sortbtn:hover { color: var(--ink-2); }
.data-table__sort-icon {
  display: inline-flex; align-items: center;
  color: var(--ink-5);
  transition: color 100ms, transform 120ms;
}
.data-table__th--sortable:hover .data-table__sort-icon { color: var(--ink-3); }
.data-table__th--sorted-asc  .data-table__sort-icon,
.data-table__th--sorted-desc .data-table__sort-icon { color: var(--indigo); }
.data-table__th--sorted-asc  .data-table__sortbtn,
.data-table__th--sorted-desc .data-table__sortbtn { color: var(--ink); }

/* Body */
.data-table__body .data-table__tr { transition: background 90ms; }
.data-table__body .data-table__tr:not(:last-child) .data-table__td {
  border-bottom: 1px solid var(--line-soft);
}
.data-table__body .data-table__tr--clickable { cursor: pointer; }
.data-table__body .data-table__tr:hover:not(.data-table__loading-row):not(.data-table__empty-row) {
  background: var(--bg-hover);
}
.data-table__body .data-table__tr--selected {
  background: color-mix(in srgb, var(--indigo-soft) 60%, var(--bg-card));
}
.data-table__body .data-table__tr--selected:hover {
  background: color-mix(in srgb, var(--indigo-soft) 80%, var(--bg-card));
}

.data-table__td {
  padding: 10px 12px;
  vertical-align: middle;
  color: var(--ink);
  line-height: 1.45;
}
.data-table__td--align-left   { text-align: left; }
.data-table__td--align-center { text-align: center; }
.data-table__td--align-right  { text-align: right; }
.data-table__td--select { width: 36px; padding-right: 0; }

/* Density */
.data-table-wrap--compact .data-table__th { padding: 6px 10px; font-size: 11px; }
.data-table-wrap--compact .data-table__td { padding: 6px 10px; font-size: 12.5px; }

/* Checkbox */
.data-table__checkbox {
  appearance: auto;
  width: 14px; height: 14px;
  margin: 0;
  cursor: pointer;
  accent-color: var(--indigo);
}

/* Empty / loading rows */
.data-table__empty-row .data-table__td,
.data-table__loading-row .data-table__td {
  padding: 28px 20px;
  text-align: center;
  border-bottom: 0 !important;
}
.data-table__empty-text,
.data-table__loading-text {
  color: var(--ink-4); font-size: 13px;
}

/* Footer (pagination slot) */
.data-table__footer {
  border-top: 1px solid var(--line);
  padding: 8px 12px;
  background: var(--bg-card);
}

/* ████████████████████████████████████████████████████████████████████████
   === MODALS START === DO NOT DELETE — Modal component CSS (.modal-backdrop,
   .modal-card, .modal-header/body/footer, .modal-confirm-*). ~115 lines.
   If you see this marker without "=== MODALS END ===" below, the block has
   been truncated — revert.
   ████████████████████████████████████████████████████████████████████████ */
/* ============================================================================
   ⭐⭐ THE DIALOG LAYER — CANONICAL Z-INDEX LADDER (band 7000–7090)
   ----------------------------------------------------------------------------
   THE BUG THIS BAND EXISTS TO KILL (founder, 2026-08-10, bundle aae11726):
   "Review and send" in the invoice editor looked dead — it lagged, then
   nothing. The modal was NEVER broken: exactly one `.modal-backdrop is-open`
   mounted at opacity 1 with a real 1280×903 rect and the rendered invoice
   inside it. `document.elementFromPoint(centre)` returned the EDITOR's own
   `.field-label`, whose ancestor is `position:absolute; z-index:5000`.
   350 < 5000 — the dialog opened UNDERNEATH the surface that opened it.

   ⚠️ IT WAS NEVER JUST INVOICES. There is a whole "full-screen editor" layer
   at 5000 (InvoiceEditor pages-2.jsx, the proposal preview pages-1.jsx,
   .spec-split-overlay, .ce-workspace, .ctr-editor). ANY dialog opened from
   inside ANY of them was invisible, and the codebase had already grown FOUR
   separate local workarounds rather than fixing the ladder:
     · .spec-tmpl-overlay 6000 / .spec-scap-overlay 6200 / .spec-confirm-layer
       6500 — specifications.jsx hand-hopping over its own 5000 overlay;
     · pages-1.jsx ~13706 — a SECOND nested portal to <body> plus
       `.feedback-modal-overlay` (z 2147483000) to escape the 5000 overlay;
     · pages-2.jsx ~15738 — AdminUserPanel must CLOSE ITSELF before showing a
       ModalConfirm, because .mp-panel (9001) painted over .modal-backdrop;
     · pages-2.jsx ~1993 — InvoicePreviewModal portals to <body> to escape an
       ancestor stacking context.
   A workaround per call site is how a structural bug survives; the ladder is
   the fix.

   ⭐ THE ORDER, AND WHY EACH NEIGHBOUR IS WHERE IT IS:

     …below the band…
        60   .topbar / app chrome        — a dialog must cover the chrome
      5000   full-screen editors         — chosen to cover app chrome; NOT
                                           lowered, or the topbar/sidebar
                                           would paint over a full-screen
                                           editor (that is a worse bug)
      6000   .spec-tmpl-overlay          ·  legacy local hops over 5000; now
      6200   .spec-scap-overlay          ·  redundant, kept so the spec page's
      6500   .spec-confirm-layer         ·  behaviour is unchanged by this move

     ⭐ THE DIALOG BAND — moved as ONE BLOCK so every relative order that was
        previously documented is preserved exactly:
      7000   .modal-overlay      (AnimatedModal utility)   was 300
      7050   .modal-backdrop     (Modal → Dialog, AlertDialog, ModalConfirm;
                                  the substrate for ~82 dialog sites)  was 350
      7060   .drawer-backdrop    (Drawer)                   was 360
      7070   .hover-card                                    was 370
      7080   .popover-panel / .dropdown / .ctx-menu-panel   was 380
      7090   .tooltip__content                              was 600
        (Modal above AnimatedModal; Popover/Dropdown above Drawer AND Modal so
         a menu opened INSIDE a dialog stays on top; Tooltip above all of them.
         Those three sentences were already written in this file — the only
         thing that changed is the base of the band.)

     …above the band, and it MUST STAY above…
      8990   .pf-popover-backdrop        ·  project-field popover + tooltip:
      9000   .pf-popover / .pf-tooltip   ·  same "a float opened from inside a
      9000   .di-pdf-modal-root          ·  dialog stays on top" rule
      9001   .mp-panel                   member panel (keeps its own guard)
      9090/1 .landing-mobile-scrim/menu
      9100   .sr-shortcuts-overlay
      9500   .aecos-select__menu, .ts-picker-pop
             ⚠️ THE SELECT MENU IS THE ONE TO NOT BREAK. It portals to <body>;
             at 390 it opened BEHIND .mp-panel and read as DEAD. The whole
             dialog band is deliberately parked ~2400 BELOW it so this fix
             cannot re-create that bug in reverse.
      9998   .cmd-confirm-backdrop
      9999   .graph-fs, .fin-toast, .sr-ctx-menu
     10000   .toast-container            a toast must be readable over a dialog
    100000   welcome-back modal, .cmd-bgtoast-host
  2147483000 .feedback-modal-overlay     "report a bug" must reach the top from
                                          inside literally anything

   ⚠️ WHY 7000 AND NOT 9200 (which would also have cleared .mp-panel at 9001):
   9200 would put dialogs OVER .pf-popover / .pf-tooltip (9000), and a popover
   under the dialog it was opened from is the same bug pointing the other way.
   7000–7090 is the only band that is above EVERY full-screen editor and below
   EVERY float. .mp-panel keeps its existing close-then-confirm workaround.

   ⚠️ WHAT NEWLY SITS UNDER A DIALOG (audited, all root-level `position:fixed`;
   `position:absolute` dropdowns like .daterange__dropdown 400 and
   .combobox__dropdown 320 are scoped to their own parent's stacking context
   and are unaffected): .doc-viewer-overlay/.doc-modal-overlay/.rfi-panel-
   backdrop 400, .di-panel 401, .lfc-* 490/500, .sr-modal-overlay 500,
   .ts-float-wrap 500, .sr-diff-overlay 520,
   .mfa-modal-overlay + OutOfCreditsModal 600, .upgrade-modal-overlay 800,
   .sr-menu-drop 1000/1001, .sr-chat-side-* 1009/1010, .bup-overlay 1100,
   .ts-dragpick* 1200/1201, .session-limit-toast 1200, .fc-modal-root 2000,
   the subscription lockout 2100. These are all BESPOKE numbers that grew to
   escape page chrome — none of them documents an intent to cover a dialog, and
   .session-limit-toast's own comment says "below modals", which was FALSE at
   1200 vs 350 and is TRUE now. ⚠️ `.loading-overlay` WAS ON THAT LIST AT 500 AND
   HAS BEEN LIFTED OUT OF IT to 7095 (2026-08-10): it is the one entry whose own
   doc-comment declares "Modal action in flight" as its purpose, so leaving it
   under the band left a component that could not do the single thing it is for.
   It is the only non-band member deliberately placed ABOVE the band; everything
   else here stays below. Timesheets (.ts-modal-overlay 300, .ts-dragpick
   1200) has ZERO <Modal> call sites, so that pair cannot collide.

   ⚠️ A BIG NUMBER ON A DESCENDANT IS MEANINGLESS. `Modal` does NOT portal — it
   renders in place. Inside a 5000 overlay the backdrop is clamped to that
   overlay's stacking context (fine: it is above the editor's own content).
   The band is what saves the PORTALLED cases, which is the reported one.

   Guarded by scripts/test_dialog_layer_ladder.py — it derives BOTH sets from
   these files, so renumbering here without renumbering the whole band is red.
   ----------------------------------------------------------------------------
   Modal component — backdrop + card + header/body/footer
   Use: <Modal open onClose title size footer dismissable>
   ============================================================================ */

.modal-backdrop {
  /* 7050 — the dialog band. See the ladder above. Was 350, which lost to the
     z-5000 full-screen editors and made "Review and send" look dead. */
  position: fixed; inset: 0; z-index: 7050;
  background: rgba(0,0,0,0.50); backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-in-out);
}
.modal-backdrop.is-open { opacity: 1 !important; }

/* Override generic .modal-card utility when inside a proper Modal */
.modal-backdrop .modal-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 32px 64px -16px rgba(0,0,0,0.28);
  display: flex; flex-direction: column;
  max-height: 90vh; overflow: hidden;
  outline: none;
  opacity: 0; transform: translateY(8px) scale(0.98);
  transition:
    opacity   var(--duration-base) var(--ease-in-out),
    transform var(--duration-base) var(--ease-out);
}
.modal-backdrop .modal-card.is-open { opacity: 1 !important; transform: translateY(0) scale(1) !important; }
/* Belt-and-braces: a modal that mounts but never receives its open-state
   styles is invisible-yet-blocking (hit live on project Finances preview —
   class present, rule present, computed opacity stayed 0). The animation
   below guarantees entry even if the .is-open transition path fails. */
@keyframes aecosModalIn { to { opacity: 1; } }
.modal-backdrop { animation: aecosModalIn var(--duration-base) var(--ease-in-out) 60ms forwards; }
.modal-backdrop .modal-card { animation: aecosModalIn var(--duration-base) var(--ease-in-out) 60ms forwards; }
/* ⚠️ AND THE SAME GUARANTEE FOR AnimatedModal (.modal-overlay > .modal-card).
   It never had one: it is the OTHER dialog primitive in ui.jsx, it runs the
   same _scheduleReveal → .is-open reveal, and it had NO CSS-only floor at all,
   so the identical "mounted, blocking, opacity 0" failure was reachable
   through it and nothing would have caught it.
   ⚠️ SCOPED TO `.modal-overlay .modal-card`, NOT BARE `.modal-card` — the bare
   utility is deliberately animation-free so a non-dialog consumer can compose
   its own entry. */
.modal-overlay { animation: aecosModalIn var(--duration-base) var(--ease-in-out) 60ms forwards; }
.modal-overlay .modal-card { animation: aecosModalIn var(--duration-base) var(--ease-in-out) 60ms forwards; }

/* ⭐⭐ THE SURFACE. `.modal-card` is a TRANSITION-ONLY utility — opacity and
   transform, no background — and that is exactly what shipped the Stripe
   onboarding dialog as text floating over a blurred page (9762faab). Every DOM
   assertion passed: the element existed, measured 640x224, reported "open".
   `.modal-backdrop .modal-card` has always supplied its own surface; the
   AnimatedModal branch did not, and the ONLY thing standing between the next
   consumer and that bug was remembering to pass a background by hand.
   Background + radius only — no border, no shadow — so the two existing
   consumers (CreditExhaustedModal at radius 16, the Stripe onboarding card at
   --radius-lg) sit flush on top of a same-coloured ground.
   ⚠️ 16px, NOT --radius-card (14px). The radius here must be at least as ROUND
   as the roundest consumer, or that consumer's squarer corners would leave a
   sliver of this background poking out past its own border against the dark
   overlay. 16 covers both; a consumer that wants rounder must raise this. */
.modal-overlay .modal-card {
  background: var(--bg-card);
  border-radius: 16px;
}

/* Size-specific overrides — keep maxWidth driven by the inline style from
   _MODAL_WIDTHS, but use the modifier class to adjust max-height + radius
   per size. .modal-card--full takes more vertical room and slightly larger
   corners to read as "near-full-screen workspace" not "modal popping up". */
.modal-backdrop .modal-card--full {
  max-height: 95vh;
  border-radius: 16px;
}
/* The mobile rule below (≤640px) already forces all sizes to fill the
   viewport edge-to-edge, so --full inherits that without extra rules. */

.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px 16px; border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0; gap: 12px;
}
.modal-title {
  font-size: 15px; font-weight: 650; letter-spacing: -0.015em;
  color: var(--ink); margin: 0; line-height: 1.3; flex: 1 1 0; min-width: 0;
}
.modal-close-btn {
  flex-shrink: 0; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--ink-5);
  border-radius: var(--radius-btn-icon); cursor: pointer; padding: 0;
  transition: color var(--duration-fast) var(--ease-in-out),
              background var(--duration-fast) var(--ease-in-out);
}
.modal-close-btn:hover { color: var(--ink); background: var(--bg-hover); }

/* flex-basis:auto (not 0) so the body grows to its content height before the
   card's max-height kicks in; min-height:0 keeps it scrollable. flex-basis:0
   collapsed the body to ~0 whenever its content sized off the body height
   (e.g. the NewOfficeWizard's full-height inner layout) — the modal showed
   only a thin clipped strip. */
.modal-body   { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 20px; }
.modal-footer {
  flex-shrink: 0; padding: 14px 20px 18px;
  border-top: 1px solid var(--line-soft);
}

/* ModalConfirm helpers */
.modal-confirm-actions {
  display: flex; justify-content: flex-end; gap: 8px;
}
.modal-confirm-desc {
  margin: 0; color: var(--ink-3); font-size: 14px; line-height: 1.55;
}

/* AlertDialog — modal-overlay alert with icon + title + description + single
   action button. Renders inside the Modal shell; this CSS styles only the
   inner content arrangement. Distinct from inline .alert (banner). */
.alert-dialog {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  gap: 14px;
  padding: 8px 4px 4px;
}
.alert-dialog__icon {
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  flex: 0 0 auto;
}
/* Variant tones — icon chip color + bg */
.alert-dialog--info    .alert-dialog__icon { background: color-mix(in srgb, var(--info, var(--indigo)) 14%, var(--bg-card));   color: var(--info, var(--indigo)); }
.alert-dialog--success .alert-dialog__icon { background: var(--ok-soft);   color: var(--ok);   }
.alert-dialog--warning .alert-dialog__icon { background: var(--warn-soft); color: var(--warn); }
.alert-dialog--danger  .alert-dialog__icon { background: var(--bad-soft);  color: var(--bad);  }

.alert-dialog__body {
  display: flex; flex-direction: column; gap: 6px;
  max-width: 44ch;
}
.alert-dialog__title {
  font-size: 17px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.015em; margin: 0; line-height: 1.3;
}
.alert-dialog__description {
  font-size: 13.5px; color: var(--ink-3); line-height: 1.55;
  margin: 0;
}

/* ─── EmailChooser ──────────────────────────────────────────────────────────
   Picker rendered inside the Modal shell (themed for light/mid/dark via the
   app's standard tokens, no hardcoded colors). Read top-to-bottom:
   .email-chooser → __to (address chip) → __choices (button list) → __choice
                                          → __choice-icon / __choice-text
                                          → __choice-chev (hover affordance)
   Modifiers: --gmail | --outlook | --default | --copy (+ .is-copied state)
   ────────────────────────────────────────────────────────────────────────── */
.email-chooser { display: flex; flex-direction: column; gap: 16px; }

/* Address chip — a soft sunken row at the top with a TO label + the
   recipient. Truncates the value with ellipsis so very long addresses
   don't blow out the modal width. */
.email-chooser__to {
  display: flex; align-items: baseline; gap: 10px;
  padding: 10px 12px;
  background: var(--bg-sunk);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  font-size: 13px;
  min-width: 0;
}
.email-chooser__to-label {
  flex: 0 0 auto;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--ink-5);
}
.email-chooser__to-value {
  flex: 1 1 0; min-width: 0;
  color: var(--ink);
  font-weight: 500;
  font-family: var(--f-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.email-chooser__choices {
  display: flex; flex-direction: column; gap: 6px;
}

.email-chooser__choice {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 11px 14px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit; font-size: inherit;
  transition:
    background   var(--duration-fast, 120ms) var(--ease-in-out, ease),
    border-color var(--duration-fast, 120ms) var(--ease-in-out, ease),
    transform    var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.email-chooser__choice:hover {
  background: var(--bg-hover);
  border-color: var(--line-strong);
}
.email-chooser__choice:active { transform: scale(0.99); }
.email-chooser__choice:focus-visible {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 22%, transparent);
}

.email-chooser__choice-icon {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-sunk);
  color: var(--ink-3);
  border-radius: 8px;
  transition:
    background var(--duration-fast, 120ms) var(--ease-in-out, ease),
    color      var(--duration-fast, 120ms) var(--ease-in-out, ease);
}
.email-chooser__choice:hover .email-chooser__choice-icon {
  background: color-mix(in srgb, var(--indigo) 14%, var(--bg-sunk));
  color: var(--indigo);
}

.email-chooser__choice-text {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.email-chooser__choice-label {
  font-size: 14px; font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.email-chooser__choice-sub {
  font-size: 12px;
  color: var(--ink-5);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Right-side chevron — hidden by default, slides in on hover/focus to
   reinforce "this row opens externally." Suppressed on the Copy row
   (which doesn't navigate away). */
.email-chooser__choice-chev {
  flex: 0 0 auto;
  color: var(--ink-5);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transform: translateX(-3px);
  transition:
    opacity   var(--duration-fast, 120ms) var(--ease-in-out, ease),
    transform var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
.email-chooser__choice:hover .email-chooser__choice-chev,
.email-chooser__choice:focus-visible .email-chooser__choice-chev {
  opacity: 1; transform: translateX(0);
}
.email-chooser__choice--copy .email-chooser__choice-chev { display: none; }

/* Copy choice — post-copy state switches to success tone so the user gets
   immediate visual confirmation alongside the icon swap. The button stays
   clickable in case the user wants to copy again. */
.email-chooser__choice--copy.is-copied {
  border-color: color-mix(in srgb, var(--ok, #10b981) 55%, var(--line));
  background: color-mix(in srgb, var(--ok, #10b981) 8%, var(--bg-card));
}
.email-chooser__choice--copy.is-copied .email-chooser__choice-icon {
  background: color-mix(in srgb, var(--ok, #10b981) 18%, var(--bg-card));
  color: var(--ok, #10b981);
}
.email-chooser__choice--copy.is-copied .email-chooser__choice-label {
  color: var(--ok, #10b981);
}

@media (prefers-reduced-motion: reduce) {
  .email-chooser__choice,
  .email-chooser__choice-chev,
  .email-chooser__choice-icon { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  .modal-backdrop,
  .modal-backdrop .modal-card { transition: none !important; transform: none !important; }

  /* ⭐⭐ REDUCED MOTION MUST MEAN "INSTANT", NEVER "ABSENT".
     THE LIVE HOLE THIS CLOSES (found 2026-08-10, deliberately left open then):
     the generic transition-utility block further down this file carries
     `.modal-card { animation: none !important; }` under this same media query.
     `!important` beats specificity, so it killed the aecosModalIn belt-and-
     braces on the DIALOG CARD — while `.modal-backdrop` was NOT in that list and
     kept its own. A reduce-motion user whose `.is-open` failed to land therefore
     got a dark full-screen backdrop with NO CARD IN IT: the same invisible-yet-
     blocking dialog, reachable only by the users least able to work around it.
     Snapping opacity outright (rather than re-declaring the animation) makes the
     floor independent of whether any animation runs at all, so a future
     `animation: none` cannot re-open this. */
  .modal-backdrop,
  .modal-backdrop .modal-card,
  .modal-overlay,
  .modal-overlay .modal-card { opacity: 1 !important; }
}

/* Mobile (≤640px): full-screen modal with safe-area-inset padding so content
   clears iOS notch / Dynamic Island / home indicator / landscape side cutouts.
   Background fills the full viewport edge-to-edge (no letterboxing); only the
   text/control content inside header/body/footer respects the insets.
   Requires <meta name="viewport" content="viewport-fit=cover"> in HTML. */
@media (max-width: 640px) {
  .modal-backdrop { padding: 0; align-items: stretch; }
  .modal-backdrop .modal-card {
    max-width: 100% !important;
    width: 100%;
    max-height: 100%;
    min-height: 100%;
    border-radius: 0;
    border-left: none; border-right: none;
  }
  /* Safe-area: header top + body sides + footer bottom inset from notch/indicator */
  .modal-header {
    padding-top:    calc(20px + env(safe-area-inset-top, 0px));
    padding-right:  calc(18px + env(safe-area-inset-right, 0px));
    padding-bottom: 14px;
    padding-left:   calc(18px + env(safe-area-inset-left,  0px));
  }
  .modal-title  { font-size: 16px; }
  .modal-close-btn {
    /* Tap-target compliance — explicit 44×44 minimum so it doesn't depend on
       the later global tap-target block's cascade order. */
    width: 44px !important; height: 44px !important;
    min-width: 44px; min-height: 44px;
    margin: -5px -8px -5px 0;
    border-radius: 8px;
  }
  .modal-body {
    padding-top:    18px;
    padding-right:  calc(18px + env(safe-area-inset-right, 0px));
    padding-bottom: 18px;
    padding-left:   calc(18px + env(safe-area-inset-left,  0px));
  }
  .modal-footer {
    padding-top:    14px;
    padding-right:  calc(18px + env(safe-area-inset-right, 0px));
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    padding-left:   calc(18px + env(safe-area-inset-left,  0px));
  }
  .modal-confirm-actions { flex-wrap: wrap; }
  .modal-confirm-actions > * { flex: 1 1 auto; }
}

/* ████████████████████████████████████████████████████████████████████████
   === MODALS END === Matches the START marker above.
   ████████████████████████████████████████████████████████████████████████ */

/* ============================================================================
   Drawer — side-panel slide-in (right | left | bottom)
   .drawer-backdrop + .drawer-panel + --side modifier + .drawer-header/body/footer
   ============================================================================ */

.drawer-backdrop {
  /* 7060 — dialog band (was 360); one step above Modal, as before. Canonical
     ladder + rationale: the "THE DIALOG LAYER" block above .modal-backdrop. */
  position: fixed; inset: 0; z-index: 7060;
  background: rgba(0,0,0,0.35);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  opacity: 0; transition: opacity var(--duration-base, 180ms) var(--ease-out, ease-out);
  display: flex;
}
.drawer-backdrop.is-open { opacity: 1; }
/* ⭐ THE SAME BELT-AND-BRACES THE MODAL HAS. Drawer is the THIRD dialog
   primitive in ui.jsx and it was the only one with no CSS-only floor: the
   backdrop declares `opacity: 0` and NOTHING but the `.is-open` flip undoes it,
   so a reveal that missed left a full-viewport, blocking, invisible scrim —
   which is the exact shape of the "Review and send" report.
   ⚠️ THE TRADE, STATED SO IT IS NOT REDISCOVERED AS A BUG: `forwards` pins
   opacity at 1, so the backdrop no longer FADES out on close — it disappears
   when the Drawer unmounts (~260ms later). `.modal-backdrop` has behaved
   exactly this way since the fallback was added. A dialog that is occasionally
   less elegant on exit beats a dialog that is occasionally invisible on entry.
   ⚠️ Deliberately NOT applied to `.drawer-panel--*`: their entry is a TRANSFORM,
   and pinning that with `forwards` would kill the slide-OUT, which is the
   drawer's whole affordance. The panel's floor is the JS one — _scheduleReveal
   in ui.jsx, guarded by scripts/test_modal_reveal.py. */
.drawer-backdrop { animation: aecosModalIn var(--duration-base, 180ms) var(--ease-out, ease-out) 60ms forwards; }

.drawer-panel {
  position: fixed;
  background: var(--bg-card); color: var(--ink);
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg, 0 24px 48px -16px rgba(20,20,30,.18));
  overflow: hidden;
  transition: transform var(--duration-slow, 260ms) var(--ease-out, ease-out),
              opacity   var(--duration-slow, 260ms) var(--ease-out, ease-out);
}

/* Side: right (default) */
.drawer-panel--right {
  top: 0; right: 0; bottom: 0;
  border-left: 1px solid var(--line);
  transform: translateX(100%);
}
.drawer-panel--right.is-open { transform: translateX(0); }

/* Side: left */
.drawer-panel--left {
  top: 0; left: 0; bottom: 0;
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
}
.drawer-panel--left.is-open { transform: translateX(0); }

/* Side: bottom */
.drawer-panel--bottom {
  left: 0; right: 0; bottom: 0;
  border-top: 1px solid var(--line);
  border-radius: 12px 12px 0 0;
  transform: translateY(100%);
}
.drawer-panel--bottom.is-open { transform: translateY(0); }

/* Side: top — slides DOWN from the top edge. Mirrors --bottom but flipped.
   Useful for notification banners, command-palette overlays, or "what's
   new" announcements that should appear above current page content. */
.drawer-panel--top {
  left: 0; right: 0; top: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0 0 12px 12px;
  transform: translateY(-100%);
}
.drawer-panel--top.is-open { transform: translateY(0); }

/* Header / body / footer — mirrors modal structure */
.drawer-header {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.drawer-title {
  flex: 1; min-width: 0;
  font-size: 15px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.01em; margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.drawer-close-btn {
  flex: 0 0 auto;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border: none; background: none; cursor: pointer;
  color: var(--ink-4); border-radius: var(--radius-btn-icon);
  transition: background 100ms, color 100ms;
}
.drawer-close-btn:hover { background: var(--bg-hover); color: var(--ink); }

.drawer-body {
  flex: 1 1 0; min-height: 0;
  overflow-y: auto;
  padding: 16px 18px;
}

.drawer-footer {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--line-soft);
}

@media (prefers-reduced-motion: reduce) {
  .drawer-backdrop,
  .drawer-panel { transition: none !important; }
  .drawer-panel { transform: none !important; }
  /* Reduced motion means INSTANT, never ABSENT — the same floor the modal band
     gets. `transform: none` above already puts the panel on screen without the
     slide; this makes the scrim independent of whether any animation runs, so a
     future blanket `animation: none` cannot take the drawer's visibility with
     it (which is precisely what happened to `.modal-card`). */
  .drawer-backdrop { opacity: 1 !important; }
}

/* Mobile (≤768px) — ALL drawer sides become bottom-sheets for thumb reach.
   Right/left/bottom panels override geometry + slide direction so the panel
   always rises from the bottom edge on touch devices regardless of the `side`
   prop. !important needed to override inline width/height set by the JS.

   Refinements:
   - height: auto + max-height: 80vh so short content doesn't show a half-empty
     80vh sheet (e.g., a 3-row filter sheet sizes to ~280px instead of 700px)
   - safe-area-inset-bottom on the panel itself extends the bg color down past
     the home indicator without pushing content into it; the body keeps its
     own padding so scrollable content also clears the indicator
   - -webkit-overflow-scrolling: touch on the body for native iOS rubber-band
   - drag handle widened to 40×5 for a more conventional iOS bottom-sheet feel */
@media (max-width: 768px) {
  .drawer-panel--right,
  .drawer-panel--left,
  .drawer-panel--top,
  .drawer-panel--bottom {
    top: auto !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: 80vh;
    /* Extend bg through the home-indicator zone; content padding handles
       its own inset below so text doesn't sit on the indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
    border-radius: 14px 14px 0 0;
    border-top: 1px solid var(--line);
    border-left: none !important;
    border-right: none !important;
    border-bottom: none !important;
  }
  .drawer-panel--right,
  .drawer-panel--left,
  .drawer-panel--top {
    /* Replace the X / down-from-top slide-in with a Y slide-up from bottom */
    transform: translateY(100%);
  }
  .drawer-panel--right.is-open,
  .drawer-panel--left.is-open,
  .drawer-panel--top.is-open {
    transform: translateY(0);
  }
  /* Drag-handle affordance — iOS-style 40×5 pill */
  .drawer-panel--right::before,
  .drawer-panel--left::before,
  .drawer-panel--top::before,
  .drawer-panel--bottom::before {
    content: "";
    position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
    width: 40px; height: 5px; border-radius: 3px;
    background: var(--line-strong);
    opacity: 0.5;
    pointer-events: none;
  }
  /* Header clears the drag handle; body adds momentum scroll; footer respects
     home-indicator inset on top of its own padding. */
  .drawer-header { padding-top: 22px; }
  .drawer-body {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain; /* prevent body scroll-chaining into the page beneath */
  }
  .drawer-footer {
    padding-left:  calc(18px + env(safe-area-inset-left,  0px));
    padding-right: calc(18px + env(safe-area-inset-right, 0px));
  }
  .drawer-header {
    padding-left:  calc(18px + env(safe-area-inset-left,  0px));
    padding-right: calc(18px + env(safe-area-inset-right, 0px));
  }
  .drawer-body {
    padding-left:  calc(18px + env(safe-area-inset-left,  0px));
    padding-right: calc(18px + env(safe-area-inset-right, 0px));
  }
}

/* ============================================================================
   Transition utility classes
   All new modals, popovers, panels, and inline expands must use these.
   Toggle .is-open to animate; AnimatedModal (ui.jsx) handles mount/unmount
   timing automatically so you don't need to manage that yourself.
   ============================================================================ */

/* Backdrop */
.modal-overlay {
  /* 7000 — floor of the dialog band (was 300). AnimatedModal's backdrop moves
     with Modal, otherwise every AnimatedModal-based dialog stays invisible
     inside a z-5000 full-screen editor. Canonical ladder + rationale: the
     "⭐⭐ THE DIALOG LAYER" block above .modal-backdrop.
     ⚠️ This class has exactly ONE consumer — AnimatedModal in ui.jsx. The many
     `*-modal-overlay` names elsewhere (.ts-/.sr-/.mfa-/.doc-/.upgrade-/
     .feedback-) are SEPARATE classes and are deliberately NOT moved.
     ⚠️ THIS WHOLE "Transition utility classes" BLOCK IS DUPLICATED VERBATIM in
     styles.css (two `.modal-overlay` rules). The LAST one wins the cascade, so
     both are kept in step — and any reader (or guard) that stops at the first
     match is reading a value the browser never applies. */
  position: fixed; inset: 0; z-index: 7000;
  background: rgba(0,0,0,0.35); backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-in-out);
}
.modal-overlay.is-open { opacity: 1; }

/* Centered card */
.modal-card {
  opacity: 0; transform: translateY(8px) scale(0.98);
  transition:
    opacity   var(--duration-base) var(--ease-in-out),
    transform var(--duration-base) var(--ease-out);
}
.modal-card.is-open { opacity: 1; transform: translateY(0) scale(1); }

/* Small dropdowns / tooltip-style popovers */
.popover {
  opacity: 0; transform: translateY(4px);
  transition:
    opacity   var(--duration-fast) var(--ease-in-out),
    transform var(--duration-fast) var(--ease-out);
  pointer-events: none;
}
.popover.is-open { opacity: 1; transform: translateY(0); pointer-events: auto; }

/* Side panels — RFI/Submittal detail, etc. */
.panel-slide-right {
  transform: translateX(100%);
  transition: transform var(--duration-slow) var(--ease-out);
}
.panel-slide-right.is-open { transform: translateX(0); }

/* Accordions / collapsible sections */
.inline-expand {
  overflow: hidden;
  transition:
    max-height var(--duration-base) var(--ease-in-out),
    opacity    var(--duration-fast) var(--ease-in-out);
}

/* Honor reduced-motion at the system level */
@media (prefers-reduced-motion: reduce) {
  .modal-overlay,
  .modal-card,
  .popover,
  .panel-slide-right,
  .inline-expand {
    transition: none !important;
    transform: none !important;
    animation: none !important;
  }
}

/* ============================================================================
   EmptyState — .empty-state + __icon + __title + __description + __actions
   Centered vertical stack for empty lists / no-data states (Projects empty,
   Reports empty, Timesheets empty, search no-results, etc.).
   Size: --sm (32px pad) / --md (48px pad, default) / --lg (64px pad).
   Tone: --subtle (default, muted icon chip) / --primary (indigo icon chip).
   ============================================================================ */

@keyframes empty-state-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.empty-state {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  gap: 12px;
  width: 100%;
  animation: empty-state-in var(--duration-slow) var(--ease-out) both;
}

/* Size variants — control padding + icon chip dimension */
.empty-state--sm { padding: 32px 20px; }
.empty-state--md { padding: 48px 24px; }
.empty-state--lg { padding: 64px 28px; }

.empty-state__icon {
  border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 4px; flex-shrink: 0;
}
.empty-state--sm .empty-state__icon { width: 40px; height: 40px; }
.empty-state--md .empty-state__icon { width: 52px; height: 52px; }
.empty-state--lg .empty-state__icon { width: 64px; height: 64px; border-radius: 16px; }

.empty-state--subtle .empty-state__icon {
  background: var(--bg-sunk); color: var(--ink-4);
}
.empty-state--primary .empty-state__icon {
  background: var(--indigo-soft); color: var(--indigo);
}

/* Illustration — inline SVG variant that replaces the icon chip. Larger,
   no background chip (the SVG provides its own visual frame), tone-aware
   stroke color so subtle/primary look distinct without per-tone SVG rules. */
.empty-state__illustration {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  margin-bottom: 4px;
}
.empty-state__illustration svg { display: block; }
.empty-state--sm .empty-state__illustration svg { width: 56px;  height: 56px;  }
.empty-state--md .empty-state__illustration svg { width: 72px;  height: 72px;  }
.empty-state--lg .empty-state__illustration svg { width: 96px;  height: 96px;  }

/* Tone — colors the SVG stroke via currentColor */
.empty-state--subtle  .empty-state__illustration { color: var(--ink-4); }
.empty-state--primary .empty-state__illustration { color: var(--indigo); }

/* When the illustration is shown, slightly tighten the gap to the title
   so the larger SVG doesn't feel detached from the text below */
.empty-state--has-illustration { gap: 10px; }

.empty-state__title {
  font-size: 15px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.015em; margin: 0; line-height: 1.3;
}
.empty-state--lg .empty-state__title { font-size: 17px; }
.empty-state--sm .empty-state__title { font-size: 14px; }

.empty-state__description {
  font-size: 13px; color: var(--ink-4); line-height: 1.55;
  margin: 0; max-width: 44ch;
}
.empty-state--lg .empty-state__description { font-size: 13.5px; max-width: 52ch; }
.empty-state--sm .empty-state__description { font-size: 12.5px; max-width: 36ch; }

/* CTA row — supports multiple actions side by side */
.empty-state__actions {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 8px;
  margin-top: 8px;
}
.empty-state--lg .empty-state__actions { margin-top: 12px; }

/* Legacy singular __action class kept for any external consumer not yet
   migrated; behaves identically to __actions */
.empty-state__action { margin-top: 8px; }

@media (prefers-reduced-motion: reduce) {
  .empty-state { animation: none; }
}

/* ============================================================================
   Alert — persistent inline notice banner (different from Toast).
   .alert + __icon + __title + __body + __actions + __action + __dismiss
   Tone modifiers: --info / --success / --warning / --danger
   Same DRY --tone-fg pattern as Badge / ProgressBar.
   ============================================================================ */

.alert {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--tone-line, var(--line));
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--tone-bg, var(--bg-card));
  color: var(--ink);
  width: 100%;
}

.alert--info    { --tone-fg: var(--info, var(--indigo)); --tone-bg: var(--info-soft, var(--indigo-soft)); --tone-line: var(--info-line, var(--indigo-line)); }
.alert--success { --tone-fg: var(--ok);    --tone-bg: var(--ok-soft);    --tone-line: var(--ok-line); }
.alert--warning { --tone-fg: var(--warn);  --tone-bg: var(--warn-soft);  --tone-line: var(--warn-line); }
.alert--danger  { --tone-fg: var(--bad);   --tone-bg: var(--bad-soft);   --tone-line: var(--bad-line); }

.alert__icon {
  display: flex; align-items: center; flex: 0 0 auto;
  color: var(--tone-fg);
  margin-top: 1px; /* baseline-align with title */
}

.alert__content {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
  font-size: 13px; line-height: 1.5;
}

.alert__title {
  font-weight: 600; color: var(--ink); font-size: 13px;
  letter-spacing: -0.005em;
}
.alert__body {
  color: var(--ink-2);
}
.alert__body p { margin: 0 0 4px; }
.alert__body p:last-child { margin-bottom: 0; }
.alert__body a {
  color: var(--tone-fg); text-decoration: underline; text-underline-offset: 2px;
}

.alert__actions {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 6px;
}
.alert__action {
  display: inline-flex; align-items: center;
  padding: 4px 10px; border-radius: 5px;
  font-size: 12px; font-weight: 500; line-height: 1.4;
  background: transparent; color: var(--tone-fg);
  border: 1px solid color-mix(in srgb, var(--tone-fg) 35%, transparent);
  cursor: pointer;
  transition: background 100ms, border-color 100ms;
}
.alert__action:hover { background: color-mix(in srgb, var(--tone-fg) 12%, transparent); }
.alert__action--primary {
  background: var(--tone-fg); color: #fff; border-color: transparent;
}
.alert__action--primary:hover { opacity: 0.9; }

.alert__dismiss {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); border-radius: 4px;
  transition: background 100ms, color 100ms;
}
.alert__dismiss:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }

/* ============================================================================
   Banner — slim inline message strip (between Alert and Announcement).
   .banner + __icon + __message + __action-slot + __action + __dismiss
   Variants: --info / --success / --warning / --error
   Single-line layout; full-width by default; left accent border; subtle bg.
   ============================================================================ */

.banner {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  padding: 8px 12px;
  font-size: 12.5px; line-height: 1.4;
  border: 1px solid var(--tone-line, var(--line));
  border-left-width: 3px;
  border-radius: 6px;
  background: var(--tone-bg, var(--bg-card));
  color: var(--ink);
}

.banner__icon {
  display: inline-flex; align-items: center;
  flex: 0 0 auto;
  color: var(--tone-fg);
}

.banner__message {
  flex: 1 1 auto; min-width: 0;
  color: var(--ink);
  /* Single line by default but allows wrap on narrow viewports */
}

.banner__action-slot {
  flex: 0 0 auto;
  display: inline-flex; align-items: center;
}
.banner__action {
  display: inline-flex; align-items: center;
  padding: 3px 10px; border-radius: 4px;
  background: transparent;
  border: 1px solid currentColor;
  color: inherit;
  font: inherit; font-size: 12px; font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background 100ms;
}
.banner__action:hover { background: color-mix(in srgb, currentColor 12%, transparent); }

.banner__dismiss {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  background: none; border: none; cursor: pointer;
  color: var(--ink-4);
  border-radius: 4px;
  margin-left: 2px;
  transition: background 100ms, color 100ms;
}
.banner__dismiss:hover {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink);
}

/* Variants — same DRY --tone-fg/--tone-bg/--tone-line pattern as Alert. */
.banner--info {
  --tone-fg: var(--info, var(--indigo));
  --tone-bg: var(--info-soft, var(--indigo-soft));
  --tone-line: var(--info-line, var(--indigo-line));
}
.banner--success {
  --tone-fg: var(--ok);
  --tone-bg: var(--ok-soft);
  --tone-line: var(--ok-line);
}
.banner--warning {
  --tone-fg: var(--warn);
  --tone-bg: var(--warn-soft);
  --tone-line: var(--warn-line);
}
.banner--error {
  --tone-fg: var(--bad);
  --tone-bg: var(--bad-soft);
  --tone-line: var(--bad-line);
}

/* Mobile (≤640px): allow message wrap, push action below on overflow */
@media (max-width: 640px) {
  .banner { flex-wrap: wrap; }
  .banner__message { flex-basis: calc(100% - 60px); }
  .banner__action-slot {
    flex-basis: 100%;
    margin-top: 4px;
    padding-left: 22px; /* align under icon */
  }
}

/* ============================================================================
   Announcement — full-width app-shell banner from announcements table.
   .announcement + __icon + __content + __title + __body + __action-slot
                 + __action + __dismiss
   Severity modifiers: --info / --warning / --critical
   Info/warning use soft tinted bg (subtle); critical is solid filled (loud).
   ============================================================================ */

.announcement {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 10px 18px;
  font-size: 13px; line-height: 1.45;
  border-bottom: 1px solid transparent;
}

.announcement__icon {
  display: inline-flex; align-items: center;
  flex: 0 0 auto;
  margin-top: 1px;
}
.announcement__content {
  flex: 1; min-width: 0;
  display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
}
.announcement__title {
  font-weight: 600;
}
.announcement__body {
  font-weight: 400;
  /* Allow long bodies to wrap; clamp to 2 lines on mobile so the banner
     doesn't take half the viewport */
}

.announcement__action-slot {
  flex: 0 0 auto;
  display: inline-flex; align-items: center;
}
.announcement__action {
  display: inline-flex; align-items: center;
  padding: 5px 12px; border-radius: 5px;
  background: transparent; border: 1px solid currentColor;
  color: inherit; font: inherit; font-size: 12.5px; font-weight: 500;
  text-decoration: none; cursor: pointer;
  white-space: nowrap;
  transition: background 100ms;
}
.announcement__action:hover { background: color-mix(in srgb, currentColor 12%, transparent); }

.announcement__dismiss {
  flex: 0 0 auto;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  background: none; border: none; cursor: pointer;
  color: inherit; opacity: 0.7;
  border-radius: 5px;
  transition: background 100ms, opacity 100ms;
}
.announcement__dismiss:hover { opacity: 1; background: color-mix(in srgb, currentColor 12%, transparent); }

/* ── Severity tones ── */
/* Info — soft tinted background */
.announcement--info {
  background: var(--info-soft, var(--indigo-soft));
  color: var(--info-ink, var(--indigo-ink));
  border-bottom-color: var(--info-line, var(--indigo-line));
}
.announcement--info .announcement__icon { color: var(--info, var(--indigo)); }

/* Warning — soft amber */
.announcement--warning {
  background: var(--warn-soft);
  color: var(--ink);
  border-bottom-color: var(--warn-line);
}
.announcement--warning .announcement__icon { color: var(--warn); }
.announcement--warning .announcement__title { color: var(--warn); }

/* Critical — solid filled, demands attention */
.announcement--critical {
  background: var(--bad);
  color: #fff;
  border-bottom-color: var(--bad);
}
.announcement--critical .announcement__icon  { color: #fff; }
.announcement--critical .announcement__action {
  border-color: rgba(255,255,255,0.55);
  background: rgba(255,255,255,0.10);
}
.announcement--critical .announcement__action:hover {
  background: rgba(255,255,255,0.18);
}

/* Mobile — stack action below on narrow viewports; clamp body */
@media (max-width: 640px) {
  .announcement {
    flex-wrap: wrap;
    padding: 10px 14px;
    align-items: flex-start;
  }
  .announcement__content { flex-basis: calc(100% - 50px); }
  .announcement__action-slot {
    flex-basis: 100%;
    margin-top: 6px;
    padding-left: 25px; /* align under content (icon width + gap) */
  }
  .announcement__dismiss {
    position: absolute; top: 8px; right: 10px;
  }
  .announcement { position: relative; padding-right: 44px; }
}

/* ============================================================================
   Skeleton loader — .skeleton-line (text) / .skeleton-circle (avatar)
                   / .skeleton-rect (card)
   Shimmering gradient sweep over a muted base — reads as "loading" more
   clearly than a static pulse, especially when multiple skeletons are
   stacked (the sweep travels across them in unison).
   ============================================================================ */

@keyframes skeleton-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.skeleton {
  background-color: var(--bg-sunk);
  background-image: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--ink) 6%, transparent) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: skeleton-shimmer 1.6s linear infinite;
}
.skeleton-line {
  height: 12px; border-radius: 4px; width: 100%;
}
.skeleton-circle {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
}
.skeleton-rect {
  width: 100%; height: 80px; border-radius: 8px;
}
.skeleton-group {
  display: flex; flex-direction: column; gap: 8px; width: 100%;
}

/* Composed skeleton shapes — SkeletonCard / SkeletonList / SkeletonAvatar */
.skeleton-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  width: 100%;
}
.skeleton-card__title { margin-bottom: 4px; }

.skeleton-list {
  display: flex; flex-direction: column;
  width: 100%;
}
.skeleton-list__row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.skeleton-list__row:last-child { border-bottom: 0; }
.skeleton-list__rowtext {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 6px;
}

.skeleton-avatar { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
  .skeleton {
    animation: none;
    background-image: none;
    background-color: var(--bg-sunk);
    opacity: 0.8;
  }
}

/* ============================================================================
   Spinner + LoadingOverlay — circular indeterminate indicator + blocking
   full-screen overlay. Uses the existing `@keyframes spin` defined elsewhere
   in this file (originally for .classify-spinner).
   ============================================================================ */

.spinner {
  display: inline-block; flex: 0 0 auto;
  border-radius: 50%;
  border-style: solid;
  animation: spin 0.8s linear infinite;
  vertical-align: middle;
}
/* Sizes — width/height + border-width pairs scale together */
.spinner--xs { width: 10px; height: 10px; border-width: 1.5px; }
.spinner--sm { width: 14px; height: 14px; border-width: 1.5px; }
.spinner--md { width: 18px; height: 18px; border-width: 2px;   }
.spinner--lg { width: 28px; height: 28px; border-width: 2.5px; }

/* Tones — ring base + top-color "head" that traces the rotation */
.spinner--neutral { border-color: var(--line-strong); border-top-color: var(--ink); }
.spinner--accent  { border-color: var(--line-strong); border-top-color: var(--indigo); }

/* Variant: inline — explicit baseline tweak so the ring sits at the visual
   midline of adjacent text. Useful inside buttons ("Saving… ◌") and row
   labels where vertical-align: middle alone leaves the ring slightly low. */
.spinner--inline {
  vertical-align: -0.15em;
  margin-right: 2px;
}

/* Variant: centered — flex wrapper that places the ring in the middle of
   whatever parent it lives in. Padded to give the loading state visual
   breathing room (24px md). Renders as a block-level region. */
.spinner-center {
  display: flex; align-items: center; justify-content: center;
  width: 100%;
  padding: 32px 16px;
}
/* Smaller padding when the inner ring is small */
.spinner-center:has(.spinner--xs) { padding: 16px 12px; }
.spinner-center:has(.spinner--sm) { padding: 20px 12px; }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.5s; }
}

/* ── LoadingOverlay — full-screen blocker ────────────────────────────────── */
.loading-overlay {
  /* 7095 — ABOVE the whole dialog band (7000…7090; see the ladder above), and
     it has to be. This component's own doc-comment in ui.jsx names "Modal
     action in flight" as its use case, and at its previous 500 it was listed in
     the ladder comment above under "WHAT NEWLY SITS UNDER A DIALOG" — i.e. the
     one thing it exists to do was the one thing it could not do. First real
     call site is the invoice send (pages-2.jsx), which blocks over a
     `size="full"` Modal, so this had to be settled before it shipped.
     ⚠️ Deliberately still BELOW `.aecos-select__menu` (9500) and
     `.toast-container` (10000): a blocker that hid the toast reporting the
     outcome of the very action it is blocking for would be self-defeating. */
  position: fixed; inset: 0; z-index: 7095;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: loading-overlay-in var(--duration-base, 180ms) var(--ease-out, ease-out) both;
}
@keyframes loading-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.loading-overlay__panel {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 28px 36px;
  background: var(--bg-card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-lg, 0 24px 48px -16px rgba(20,20,30,.18));
  min-width: 220px; max-width: 420px;
  text-align: center;
  animation: loading-overlay-panel-in var(--duration-base, 180ms) var(--ease-out, ease-out) both;
}
@keyframes loading-overlay-panel-in {
  from { opacity: 0; transform: scale(0.96) translateY(4px); }
  to   { opacity: 1; transform: none; }
}

.loading-overlay__message {
  font-size: 13px; font-weight: 500; color: var(--ink); line-height: 1.4;
}
.loading-overlay__children {
  font-size: 12px; color: var(--ink-4); line-height: 1.5;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .loading-overlay,
  .loading-overlay__panel { animation: none; }
}

/* ============================================================================
   Loading — page/section-level loading state. Combines Spinner OR Skeleton
   shapes with an optional message. Distinct from LoadingOverlay (which is a
   full-screen blocker for in-flight actions).
   .loading + __message + __lines
   Variants: --spinner / --skeleton
   Modifiers: --sm / --md / --lg / --full (full-page centered)
   ============================================================================ */

.loading {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px;
  width: 100%;
  padding: 32px 20px;
  text-align: center;
}
.loading--sm { padding: 20px 16px; gap: 10px; }
.loading--md { padding: 32px 20px; gap: 12px; }
.loading--lg { padding: 48px 24px; gap: 14px; }

/* fullPage — takes the parent's full height + vertically centers. Use when
   Loading is the only thing inside a route's page container during fetch. */
.loading--full {
  min-height: 60vh;
  padding-top: 48px;
  padding-bottom: 48px;
}

/* Skeleton variant: stretches the children to fill the width so card/list
   skeletons read as content placeholders, not centered loading widgets. */
.loading--skeleton {
  align-items: stretch;
  text-align: left;
  gap: 12px;
}

.loading__message {
  margin: 0;
  font-size: 13px; color: var(--ink-4);
  line-height: 1.45;
}
.loading--lg .loading__message { font-size: 14px; }
.loading--sm .loading__message { font-size: 12.5px; }

/* When the message appears ABOVE skeletons (skeleton variant), align it
   left + give it a small bottom margin so it reads as a section label. */
.loading__message--top {
  text-align: left;
  font-weight: 500;
  color: var(--ink-3);
  margin-bottom: 2px;
}

/* Stacked text-line skeletons */
.loading__lines {
  display: flex; flex-direction: column;
  gap: 8px;
  width: 100%;
}
.loading--sm .loading__lines { gap: 6px; }
.loading--lg .loading__lines { gap: 10px; }

/* ============================================================================
   AecosSpinner / .aecos-loader — brand-mark loading state.
   Animated Aecos logo glyph for "reading your file…" / processing surfaces.
   The mark reuses the favicon + sidebar brand glyph (4-fold rotational
   symmetry → smooth continuous rotation, no visual jank). currentColor
   driven so the mark inherits ink color from its parent surface.
   Two consumption paths:
     1. <AecosSpinner size label /> — full component (label below the mark).
     2. <svg class="aecos-logo-spin" …>…brand glyph…</svg> — raw utility
        class for non-React surfaces (same animation + reduced-motion fall-
        back as the component).
   ============================================================================ */

@keyframes aecos-logo-spin {
  to { transform: rotate(360deg); }
}
@keyframes aecos-loader-breath {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.aecos-loader {
  display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px;
  color: var(--ink);
  text-align: center;
}
.aecos-loader__mark {
  display: block; color: inherit; flex: 0 0 auto;
}
.aecos-logo-spin {
  transform-origin: 50% 50%;
  animation: aecos-logo-spin 2.4s linear infinite;
}
.aecos-loader__label {
  margin: 0;
  font-size: 13px; font-weight: 500;
  color: var(--ink-3);
  letter-spacing: 0.005em;
  line-height: 1.4;
  animation: aecos-loader-breath 1.8s ease-in-out infinite;
}

/* Size modifiers — label scales; the mark itself is sized via width/height
   SVG attrs from the component, but standalone .aecos-loader markup gets
   sensible defaults via these rules so non-component callers still look
   right. */
.aecos-loader--sm .aecos-loader__label { font-size: 12px; }
.aecos-loader--lg .aecos-loader__label { font-size: 14px; }
.aecos-loader--sm .aecos-loader__mark:not([width]) { width: 20px; height: 20px; }
.aecos-loader--md .aecos-loader__mark:not([width]) { width: 36px; height: 36px; }
.aecos-loader--lg .aecos-loader__mark:not([width]) { width: 56px; height: 56px; }

/* Tones — drives currentColor on the SVG strokes/fills. */
.aecos-loader--ink    { color: var(--ink); }
.aecos-loader--ink-3  { color: var(--ink-3); }
.aecos-loader--accent { color: var(--indigo, var(--ink)); }

@media (prefers-reduced-motion: reduce) {
  .aecos-logo-spin     { animation-duration: 6s; }
  .aecos-loader__label { animation: none; }
}

/* ============================================================================
   Toast notification system — ToastContainer + individual toasts
   ============================================================================ */

@keyframes toast-shrink {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

.toast-container {
  /* Above the full-screen meeting shell (z 9000) + modals (9500) so in-room
     recording toasts are actually visible (2026-07-23). */
  position: fixed; bottom: 24px; right: 24px; z-index: 10000;
  display: flex; flex-direction: column; gap: 8px;
  width: 340px; max-width: calc(100vw - 48px);
  pointer-events: none;
}

.toast {
  /* Only a toast that is actually VISIBLE may swallow clicks. The container is
     pointer-events:none, but the toast used to re-enable them unconditionally —
     so an invisible toast (opacity 0 in the enter or exit phase) still captured
     every click inside its 340×49 box in the bottom-right corner, which is
     exactly where primary buttons ("Add phase", "Save", "Create") sit. That went
     unnoticed because both stuck phases are transient in a foreground tab; in a
     BACKGROUND tab rAF and transitionend are frozen, so a toast fired while the
     user is away never reaches 'open' and never gets removed, leaving a
     permanent invisible dead zone when they come back. */
  pointer-events: none;
  background: var(--bg-card); border: 1px solid var(--line);
  border-left-width: 3px; border-radius: 10px;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 12px 14px 14px;
  box-shadow: var(--shadow-md);
  position: relative; overflow: hidden;
  /* enter state */
  opacity: 0; transform: translateX(16px);
  transition:
    opacity   var(--duration-base) var(--ease-out),
    transform var(--duration-base) var(--ease-out);
}
.toast.toast-phase-open { opacity: 1; transform: translateX(0); pointer-events: all; }
.toast.toast-phase-exit { opacity: 0; transform: translateX(16px); }

/* kind — left border + icon colors */
.toast.toast-success { border-left-color: var(--ok); }
.toast.toast-info    { border-left-color: var(--indigo); }
.toast.toast-warn    { border-left-color: var(--warn); }
.toast.toast-error   { border-left-color: var(--bad); }

.toast-icon-wrap {
  flex-shrink: 0; width: 20px; height: 20px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
}
.toast-success .toast-icon-wrap { color: var(--ok);     background: var(--ok-soft); }
.toast-info    .toast-icon-wrap { color: var(--indigo); background: var(--indigo-soft); }
.toast-warn    .toast-icon-wrap { color: var(--warn);   background: var(--warn-soft); }
.toast-error   .toast-icon-wrap { color: var(--bad);    background: var(--bad-soft); }

.toast-content  { flex: 1 1 0; min-width: 0; }
.toast-title    { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.toast-body     { font-size: 12px; color: var(--ink-3); margin-top: 3px; line-height: 1.45; }
.toast-action-btn {
  display: inline-block; margin-top: 6px;
  font-size: 12px; font-weight: 600; color: var(--indigo);
  background: none; border: none; padding: 0; cursor: pointer;
}
.toast-action-btn:hover { text-decoration: underline; text-underline-offset: 2px; }

.toast-close-btn {
  flex-shrink: 0; width: 20px; height: 20px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: var(--ink-5);
  border-radius: var(--radius-btn-icon); padding: 0; cursor: pointer;
  transition: color var(--duration-fast) var(--ease-in-out),
              background var(--duration-fast) var(--ease-in-out);
}
.toast-close-btn:hover { color: var(--ink); background: var(--bg-hover); }

.toast-progress {
  position: absolute; bottom: 0; left: 0; right: 0; height: 2px; overflow: hidden;
}
.toast-progress-fill {
  height: 100%; width: 100%; transform-origin: left;
  animation: toast-shrink linear forwards;
  animation-play-state: running;
}
.toast-progress-fill.is-paused { animation-play-state: paused; }

.toast-success .toast-progress-fill { background: var(--ok); }
.toast-info    .toast-progress-fill { background: var(--indigo); }
.toast-warn    .toast-progress-fill { background: var(--warn); }
.toast-error   .toast-progress-fill { background: var(--bad); }

@media (prefers-reduced-motion: reduce) {
  .toast                { transition: none !important; transform: none !important; }
  .toast-progress-fill  { animation: none !important; }
  .toast-close-btn      { transition: none; }
}

/* ============================================================================
   TestimonialCard
   ============================================================================ */

.testimonial-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; padding: 24px;
  display: flex; flex-direction: column; gap: 18px;
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform  var(--duration-fast) var(--ease-out);
}
.testimonial-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.testimonial-top {
  display: flex; align-items: center; gap: 12px;
}
.testimonial-avatar {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  background: var(--indigo);
  color: #fff; font-size: 13px; font-weight: 700; letter-spacing: 0.02em;
  display: flex; align-items: center; justify-content: center;
  user-select: none;
}
.testimonial-meta {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.testimonial-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.testimonial-role {
  font-size: 12px; color: var(--ink-4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.testimonial-quote {
  font-size: 14px; font-style: italic; color: var(--ink-2);
  line-height: 1.6; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.testimonial-metrics {
  display: flex; gap: 0; border-top: 1px solid var(--line-soft); padding-top: 16px;
}
.testimonial-metric {
  flex: 1; display: flex; flex-direction: column; gap: 2px; text-align: center;
}
.testimonial-metric + .testimonial-metric {
  border-left: 1px solid var(--line-soft);
}
.testimonial-metric-value {
  font-size: 20px; font-weight: 700; letter-spacing: -0.03em; color: var(--ink);
  line-height: 1.1;
}
.testimonial-metric-label {
  font-size: 11px; color: var(--ink-4); text-transform: uppercase;
  letter-spacing: 0.05em; font-weight: 500;
}

@media (prefers-reduced-motion: reduce) {
  .testimonial-card { transition: none; }
  .testimonial-card:hover { transform: none; }
}

/* ============================================================================
   CreditExhaustedModal
   ============================================================================ */

.credit-exhausted-modal {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 16px; padding: 32px 28px 28px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 0;
}
.credit-exhausted-icon {
  width: 48px; height: 48px; border-radius: 12px;
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 22%, transparent);
  display: flex; align-items: center; justify-content: center;
  color: var(--warn); margin-bottom: 18px;
}
.credit-exhausted-title {
  font-size: 17px; font-weight: 650; letter-spacing: -0.02em;
  color: var(--ink); margin: 0 0 10px; line-height: 1.3;
}
.credit-exhausted-body {
  font-size: 13.5px; color: var(--ink-3); line-height: 1.55;
  margin: 0 0 24px; max-width: 34ch;
}
.credit-exhausted-body strong { color: var(--ink); font-weight: 600; }
.credit-exhausted-actions {
  display: flex; gap: 8px; width: 100%;
}
.credit-exhausted-btn-primary,
.credit-exhausted-btn-secondary {
  flex: 1; padding: 9px 0; border-radius: var(--radius-btn);
  font-size: 13.5px; font-weight: 600; border: none; cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease-in-out);
}
.credit-exhausted-btn-primary  { background: var(--indigo); color: #fff; }
.credit-exhausted-btn-primary:hover  { opacity: 0.88; }
.credit-exhausted-btn-secondary { background: var(--bg-elev); color: var(--ink); border: 1px solid var(--line); }
.credit-exhausted-btn-secondary:hover { background: var(--bg-sunk); }

/* ============================================================================
   FeedbackButton — floating bottom-right pill + modal (stars + comment)
   .feedback-fab + __label, .feedback-form + __rating + __stars + __star
                                + __comment-wrap + __comment, .feedback-thanks
   z-index 320 — above app shell, below modal overlay so opening the modal
   correctly hides the button behind it.
   ============================================================================ */

.feedback-fab {
  position: fixed;
  z-index: 320;
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding: 0 14px 0 11px;
  border-radius: 999px;
  background: var(--indigo); color: #fff;
  border: 1px solid color-mix(in srgb, var(--indigo) 70%, #000);
  font: inherit; font-size: 12.5px; font-weight: 500;
  box-shadow: 0 6px 16px rgba(20, 20, 30, 0.18), 0 2px 4px rgba(20, 20, 30, 0.08);
  cursor: pointer;
  transition: transform var(--duration-fast, 120ms) ease-out,
              box-shadow var(--duration-fast, 120ms) ease-out;
}
.feedback-fab:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(20, 20, 30, 0.24), 0 2px 4px rgba(20, 20, 30, 0.08);
}
.feedback-fab:focus-visible {
  outline: none;
  box-shadow: 0 6px 16px rgba(20, 20, 30, 0.18),
              0 0 0 3px color-mix(in srgb, var(--indigo) 30%, transparent);
}
.feedback-fab__label { line-height: 1; }
.feedback-fab svg { color: #fff; flex: 0 0 auto; }

.feedback-fab--bottom-right { right: 20px; bottom: 20px; }
.feedback-fab--bottom-left  { left:  20px; bottom: 20px; }

/* Mobile: icon-only pill (drop the text label) — saves space for thumb */
@media (max-width: 640px) {
  .feedback-fab { padding: 0; width: 44px; height: 44px; justify-content: center; }
  .feedback-fab__label { display: none; }
}

/* ── Modal contents ── */
.feedback-form {
  display: flex; flex-direction: column; gap: 18px;
}

.feedback-rating {
  display: flex; flex-direction: column; gap: 8px;
}
.feedback-rating__label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  letter-spacing: -0.005em;
}

.feedback-stars {
  display: flex; align-items: center; gap: 4px;
}
.feedback-star {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  padding: 0;
  background: none; border: none; border-radius: 8px;
  cursor: pointer;
  color: var(--ink-5);
  transition: color var(--duration-fast, 120ms) ease-out,
              background var(--duration-fast, 120ms) ease-out,
              transform var(--duration-fast, 120ms) ease-out;
}
.feedback-star:hover  { background: var(--bg-hover); }
.feedback-star:active { transform: scale(0.95); }
.feedback-star:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.feedback-star.is-filled {
  color: #f5b400;          /* warm yellow for filled stars */
}
.feedback-star.is-filled svg {
  fill: currentColor;       /* fill the star shape, not just stroke it */
}

/* ── Comment ── */
.feedback-comment-wrap {
  display: flex; flex-direction: column; gap: 6px;
}
.feedback-comment__label {
  font-size: 12px; font-weight: 500; color: var(--ink-2);
  letter-spacing: -0.005em;
}
.feedback-comment__hint {
  font-weight: 400; color: var(--ink-5);
}
.feedback-comment {
  width: 100%;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg-card); color: var(--ink);
  font: inherit; font-size: 13px; line-height: 1.5;
  padding: 8px 10px;
  min-height: 96px;
  resize: vertical;
  transition: border-color var(--duration-fast, 120ms),
              box-shadow var(--duration-fast, 120ms);
}
.feedback-comment::placeholder { color: var(--ink-5); }
.feedback-comment:hover:not(:disabled) { border-color: var(--line-strong); }
.feedback-comment:focus {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 15%, transparent);
}
.feedback-comment:disabled { opacity: 0.55; cursor: not-allowed; }

/* ── Thanks state ── */
.feedback-thanks {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  padding: 24px 8px 8px;
  text-align: center;
}
.feedback-thanks__icon {
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: var(--ok-soft); color: var(--ok);
  border-radius: 50%;
}
.feedback-thanks p {
  margin: 0;
  font-size: 14px; font-weight: 500; color: var(--ink);
  line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
  .feedback-fab, .feedback-star { transition: none; }
}

/* ============================================================================
   Pricing page primitives — BillingToggle, PriceCard, FeatureBullet,
   FreeTierCallout, IncludedCredit
   ============================================================================ */

.billing-toggle {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--bg-sunk); border: 1px solid var(--line); border-radius: 999px;
  padding: 3px;
}
.billing-toggle-opt {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 500; color: var(--ink-4);
  padding: 5px 14px; border-radius: 999px; border: none;
  background: transparent; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.billing-toggle-opt.active {
  background: var(--bg-card); color: var(--ink);
  box-shadow: 0 1px 3px rgba(0,0,0,0.10);
}
.billing-toggle-save {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  padding: 1px 6px; border-radius: 999px;
}

.price-card {
  flex: 1 1 220px; min-width: 200px; max-width: 280px;
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card);
  position: relative; overflow: hidden;
  transition: box-shadow 0.18s, transform 0.18s;
}
.price-card:hover { box-shadow: 0 6px 24px rgba(0,0,0,0.09); transform: translateY(-1px); }
.price-card.highlighted {
  border-color: var(--indigo); box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 18%, transparent);
}
.price-card.full-width { max-width: 100%; flex: 1 1 100%; }
.price-card.is-current { border-color: var(--ok); }
.price-card-ribbon {
  background: var(--indigo); color: #fff;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  text-align: center; padding: 4px 0; width: 100%;
}
.price-card-inner {
  display: flex; flex-direction: column; flex: 1 1 0;
  padding: 20px;
}
.price-card-top { margin-bottom: 16px; }
.price-card-price {
  display: flex; align-items: baseline; gap: 2px;
  margin: 10px 0 4px;
}
.price-card-currency { font-size: 20px; font-weight: 600; color: var(--ink-3); align-self: flex-start; margin-top: 4px; }
.price-card-num      { font-size: 44px; font-weight: 700; color: var(--ink); letter-spacing: -0.04em; line-height: 1; }
.price-card-per      { font-size: 14px; color: var(--ink-4); margin-left: 2px; }
.price-card-billed-note { font-size: 11.5px; color: var(--ink-5); margin-bottom: 8px; }
.price-card-desc { font-size: 13px; color: var(--ink-4); line-height: 1.5; margin: 6px 0 10px; }
.price-card-features {
  list-style: none; margin: 0 0 20px; padding: 0;
  display: flex; flex-direction: column; gap: 7px;
  flex: 1 1 0;
}
.price-card-action { margin-top: auto; }
.price-card-btn {
  width: 100%; padding: 9px 0; border-radius: var(--radius-btn-icon); border: none;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.price-card-btn.upgrade  { background: var(--indigo); color: #fff; }
.price-card-btn.upgrade:hover { opacity: 0.88; }
.price-card-btn.free     { background: var(--bg-elev); color: var(--ink); border: 1px solid var(--line); }
.price-card-btn.free:hover { background: var(--bg-sunk); }
.price-card-btn.current  { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok); cursor: default; }

.feature-bullet {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 13px; color: var(--ink);
}
.feature-bullet.muted { color: var(--ink-4); }
.feature-bullet.soon  { color: var(--ink-4); }
.feature-bullet-icon {
  flex-shrink: 0; margin-top: 1px;
  color: var(--ok);
}
.feature-bullet.muted .feature-bullet-icon,
.feature-bullet.soon  .feature-bullet-icon { color: var(--ink-5); }
.feature-bullet-text { flex: 1 1 0; line-height: 1.4; }
.feature-bullet-soon-chip {
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--ink-5); background: var(--bg-sunk);
  border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 5px; white-space: nowrap; flex-shrink: 0;
}

.free-tier-callout {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-5); text-align: center; padding: 6px 0;
}

.included-credit {
  display: flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--ink-4);
  background: color-mix(in srgb, var(--indigo) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 18%, transparent);
  border-radius: 6px; padding: 5px 9px; margin-top: 8px;
}
.included-credit > svg { flex-shrink: 0; color: var(--indigo); }

@media (prefers-reduced-motion: reduce) {
  .price-card, .billing-toggle-opt { transition: none; }
}

/* ============================================================================
   Mobile gate — show a static "use desktop" notice on phones / tablets.
   The rest of the app is hidden on these viewports. Added 2026-05-20.
   ============================================================================ */
#mobile-gate { display: none; }

/* R6: the gate also covers LANDSCAPE phones (coarse pointer + short viewport
   — e.g. 844×390 escapes the width clause). Keep in sync with mobile.css's
   top-level media + the JS twin window.AECOS_MOBILE.isPhone(). */
@media (max-width: 768px), ((pointer: coarse) and (max-height: 500px)) {
  html, body { height: 100%; background: #fff; }
  #root { display: none; }
  #mobile-gate {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 100vh; padding: 32px 24px;
    text-align: center; color: #15161a;
    font-family: var(--f-sans);
  }
  #mobile-gate svg { width: 64px; height: 64px; margin-bottom: 24px; color: #000; }
  #mobile-gate h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 12px; }
  #mobile-gate p {
    font-size: 14.5px; line-height: 1.55; color: #4a4c55;
    margin: 0 0 10px; max-width: 32ch;
  }
  #mobile-gate .mg-note { font-size: 12.5px; color: #76787f; margin-top: 16px; }
}

/* Override the mobile gate for routes that allow or require mobile viewports. */
body.allow-mobile #mobile-gate { display: none !important; }
body.allow-mobile #root        { display: block !important; }

body.is-landing #mobile-gate   { display: none !important; }
body.is-landing #root          { display: block !important; }

/* Landing/marketing pages render the responsive site and scroll as a normal
   document. Override the app-shell overflow lock (html/body { overflow:hidden }
   at the top of this file) when on landing routes.
   DESKTOP ONLY (min-width:769px). This MUST NOT apply on phones: the
   `html:has(body.is-landing){ overflow-y:auto }` below beats the mobile
   `html.is-landing{ overflow-y:visible }` on :has specificity, which turns the
   ROOT into a content-sized overflow:auto box. Safari tolerates that, but
   CHROME MOBILE refuses to touch-scroll it — the landing was frozen on first
   load in Chrome until a reflow. The ≤768 block (search "single natural scroller")
   keeps the root overflow:visible so the viewport is the natural scroller, which
   Chrome touch-scrolls correctly. Scoping this to desktop is what those separate
   mobile rules always assumed ("this version covers desktop"). */
@media (min-width: 769px) {
  html:has(body.is-landing) { height: auto; overflow-y: auto; }
  /* body must NOT be a scroll container (html is the landing scroller): clip-x +
     visible-y keeps it out of scroll-container status so position:sticky pins to
     the viewport. (overflow-x:hidden + overflow-y:visible would compute to
     hidden/auto — a non-scrolling scroll container that breaks the sticky pin.) */
  body.is-landing           { height: auto; overflow-x: clip; overflow-y: visible; -webkit-overflow-scrolling: touch; }
  body.is-landing #root     { height: auto; overflow: visible; display: block; }

  /* Aecos-styled document scrollbar on the landing (which scrolls on the root),
     replacing the default browser scrollbar chrome with the thin, rounded,
     token-driven bar used across the app (chat / studio-review). Desktop only —
     phones use overlay/touch scrollbars. The 3px transparent border + padding-box
     clip insets the thumb so it reads as the ~4px Aecos rail with a comfortable
     hit area. */
  html:has(body.is-landing) { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
  html:has(body.is-landing)::-webkit-scrollbar { width: 12px; height: 12px; }
  html:has(body.is-landing)::-webkit-scrollbar-track { background: transparent; }
  html:has(body.is-landing)::-webkit-scrollbar-thumb {
    background: var(--line-strong); border-radius: 8px;
    border: 3px solid transparent; background-clip: padding-box;
  }
  html:has(body.is-landing)::-webkit-scrollbar-thumb:hover {
    background: var(--ink-5); background-clip: padding-box; border: 3px solid transparent;
  }
  html:has(body.is-landing)::-webkit-scrollbar-corner { background: transparent; }
}

/* ============================================================================
   Pass-26 — Touch tap-target minimums at ≤768px viewports.
   iOS HIG (44pt) + WCAG 2.5.5 (Target Size, Enhanced — 44×44 CSS px).
   Last cascade so nothing earlier overrides these mins. Single @media block.

   Two patterns:
   1. Standalone interactive elements grow to min 44×44 directly.
   2. Inline-mini buttons (chip ×, search clear, combobox pill ×) keep their
      visual size but extend the hit area via an absolute ::before overlay,
      so chips/pills don't visually explode.
   ============================================================================ */
@media (max-width: 768px) {

  /* ── Standalone buttons / role=button / .btn-sm ── */
  .btn,
  .btn-sm,
  .btn-ghost,
  .btn-primary,
  .btn-secondary,
  .btn-danger,
  [role="button"],
  a.btn,
  .nav-item,
  .sidebar-collapse-btn,
  .appearance-toggle,
  .avatar-btn,
  .topbar-firm {
    min-height: 44px;
    padding-top: 10px; padding-bottom: 10px;
  }
  /* .btn-sm keeps tighter visual but still has 44px hit */
  .btn-sm { padding-top: 8px; padding-bottom: 8px; font-size: 13px; }

  /* ── Icon-only square buttons (modal X, drawer X, sidebar collapse, etc.) ── */
  .modal-close-btn,
  .drawer-close-btn,
  .alert__dismiss,
  .sidebar-collapse-btn,
  .appearance-toggle,
  .field__select,
  .pagination__btn,
  .pagination__btn--nav,
  .pagination__jump-btn,
  .credit-exhausted-btn-primary,
  .credit-exhausted-btn-secondary,
  .toast-close,
  .upgrade-modal-credits-section button {
    min-width: 44px; min-height: 44px;
  }

  /* ── Tabs / Segmented / Dropdown items / Breadcrumbs back ── */
  .tabs__tab,
  .segmented__option,
  .dropdown__item,
  .breadcrumbs__back,
  .filter-bar__clear {
    min-height: 44px;
    padding-top: 10px; padding-bottom: 10px;
  }

  /* ── Form inputs ── */
  .field__input,
  .field__textarea,
  .field__select,
  .search-input,
  .search-input__field,
  .combobox__input,
  .daterange__input,
  .pagination__pagesize-select,
  .pagination__jump-input {
    min-height: 44px;
  }
  /* TextArea: keep growable, but ensure baseline */
  .field__textarea { min-height: 96px; }

  /* ── Toggle / Switch label row ── */
  .toggle { min-height: 44px; align-items: center; }
  /* The track itself stays visually compact — the whole <label> is the hit zone */

  /* ── DataTable: sort button + per-row cell row ── */
  .data-table__sortbtn { min-height: 44px; padding: 10px 0; }
  .data-table__tr      { /* row height grows naturally via td padding below */ }
  .data-table__td      { padding-top: 14px; padding-bottom: 14px; }
  .data-table__th      { padding-top: 12px; padding-bottom: 12px; }
  .data-table__checkbox { width: 22px; height: 22px; } /* easier thumb hit */

  /* ── Timeline / Pagination tighteners ── */
  .pagination__btn { padding: 0 12px; }

  /* ── Inline-mini buttons: extend hit area via ::before without visual growth ── */
  .filter-chip__remove,
  .search-input__clear,
  .combobox__pill-remove,
  .field__select-chevron,
  .data-table__checkbox {
    position: relative;
  }
  .filter-chip__remove::before,
  .search-input__clear::before,
  .combobox__pill-remove::before {
    content: "";
    position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
    /* transparent overlay — extends tap area, no visible footprint */
  }

  /* ── KbdKey/Badge stay visually small — these are labels, not tap targets ── */
}

/* ████████████████████████████████████████████████████████████████████████
   === LANDING START === DO NOT DELETE — entire public marketing CSS lives
   between this marker and "=== LANDING END ===" below. ~4830 lines / 289
   selectors (.landing-* / .hcc-* / .cmd-center-walk* / .fc-rr-mobile).
   Deleted twice by timesheets-touches-styles.css commits — see 23621a1
   for the most recent restore. If you see this marker without the
   matching END marker in a diff, the block has been truncated — revert.
   ████████████████████████████████████████████████████████████████████████ */
/* ============================================================================
   Landing Page — public marketing surface (LandingPage component).
   Uses app CSS tokens so it respects light/mid/dark theme automatically.
   ============================================================================ */
.landing-wrap {
  min-height: 100vh;
  background: var(--bg-card);
  color: var(--ink);
  font-family: var(--f-sans);
  /* clip (not hidden): clips horizontal overflow WITHOUT becoming a scroll
     container — otherwise overflow-x:hidden forces overflow-y:auto and breaks
     position:sticky pinning for scrollytelling sections (e.g. .lsc-sticky). */
  overflow-x: clip;
  scroll-behavior: smooth;
}

/* Shared content width — used by the container AND the scrolled nav pill so the
   floating bar lines up exactly with the content column. Widened to ~1400px so the
   hero + product sections breathe like claude.ai / chatgpt.com. */
:root { --landing-max: 1400px; }
.landing-container {
  max-width: var(--landing-max);
  margin: 0 auto;
  padding: 0 48px;
}

/* Nav logo — logomark + wordmark side by side */
.landing-nav-logo {
  display: flex; align-items: center; gap: 9px;
  text-decoration: none; color: inherit;
}

/* Nav — legacy rule, no longer applied (the <nav> now uses .lp-nav, see
   "LP NAV MORPH" below). Kept harmless; nothing carries the .landing-nav class. */
.landing-nav {
  position: sticky; top: 0; z-index: 200;
  background: color-mix(in srgb, var(--bg-elev) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

/* === LP NAV MORPH ===
   A single <nav.lp-nav> morphs between a full-width, transparent "anchored" bar
   at the top of the page and a centered, blurred "floating" pill once scrolled
   (>24px, toggled by useNavScrolled). The nav is position:fixed and .lp-nav-spacer
   holds its place in flow, so the rest of the page never shifts. Every morphable
   property shares the same 280ms cubic-bezier(0.22,1,0.36,1) so they animate as
   one — width/padding/radius only, no transform (which would blur the text). */
:root {
  /* Apple-iOS frosted glass: more transparent + stronger blur/saturate. */
  --lp-nav-bg: rgba(255, 255, 255, 0.52);
  --lp-nav-border: rgba(0, 0, 0, 0.07);
  --lp-nav-shadow: 0 8px 32px rgba(20, 22, 50, 0.10);
  --lp-nav-blur: blur(28px) saturate(180%);
}
[data-theme="dark"] {
  --lp-nav-bg: rgba(20, 20, 22, 0.52);
  --lp-nav-border: rgba(255, 255, 255, 0.08);
  --lp-nav-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
}
/* Scroll-LINKED morph: every property interpolates off --np (0 at the top → 1 once
   scrolled, set continuously by useNavScrolled). At the top the bar is full-bleed,
   flat, no chrome; as you scroll it eases inward to a contained rounded pill at
   --landing-max width with its chrome (bg/border/shadow/blur) cross-fading in. A
   short transition glides over coarse wheel ticks so the morph never snaps. */
.lp-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 200;
  display: flex; justify-content: center;
  --np: 0;
  padding-top: calc(10px + 2px * var(--np, 0));
  padding-left: calc(16px * var(--np, 0));
  padding-right: calc(16px * var(--np, 0));
  pointer-events: none;                 /* transparent gutters pass scroll/clicks through */
  transition: padding 120ms ease-out;
}
.lp-nav-spacer { height: 64px; flex-shrink: 0; }
/* The morphing element — geometry (width/padding) interpolates off --np; its pill
   chrome lives on a pseudo so it can cross-fade independently. Overrides the
   .landing-container max-width/padding and sets the fixed nav height. */
.lp-nav .landing-nav-inner {
  position: relative;
  pointer-events: auto;
  width: 100%; box-sizing: border-box; height: 52px;
  /* TWO-STATE morph. At rest (np=0): FULL-BLEED — max-width 100% with ~28px
     gutters, so the logo sits near the left viewport edge and the action
     cluster near the right edge. On scroll (np→1) it eases into a contained,
     content-aligned pill (max-width --landing-max, 48px gutters) while the
     ::before glass cross-fades in via --np.
     NOTE: no `isolation: isolate` here — it would make this element a
     backdrop-root and stop the dropdown panels' backdrop-filter from blurring
     the page beneath the nav. The pill ::before stays behind the nav content
     because in-flow nav children paint above a negative z-index pseudo. */
  max-width: calc(100% - (100% - var(--landing-max)) * var(--np, 0));
  margin: 0 auto;
  padding: 0 calc(28px + 20px * var(--np, 0));
  transition: max-width 120ms ease-out, padding 120ms ease-out;
}
.lp-nav .landing-nav-inner::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-radius: 26px;
  background: var(--lp-nav-bg);
  border: 1px solid var(--lp-nav-border);
  box-shadow: var(--lp-nav-shadow);
  -webkit-backdrop-filter: var(--lp-nav-blur);
  backdrop-filter: var(--lp-nav-blur);
  opacity: var(--np, 0);
  transition: opacity 140ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .lp-nav, .lp-nav .landing-nav-inner, .lp-nav .landing-nav-inner::before { transition: none; }
}
@media (max-width: 768px) {
  /* slightly tighter gutters; the inner still goes near-full-width because
     --landing-max far exceeds the viewport, so the max-width calc resolves to 100%. */
  .lp-nav {
    padding-top: calc(8px + 2px * var(--np, 0));
    padding-left: calc(12px * var(--np, 0));
    padding-right: calc(12px * var(--np, 0));
  }
  .lp-nav .landing-nav-inner { padding: 0 20px; }  /* match .landing-container mobile gutter */
  .lp-nav-spacer { height: 60px; }
}
.landing-nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  height: 60px;
}
.landing-logo {
  font-size: 14px; font-weight: 500; letter-spacing: -0.01em;
  color: var(--ink); cursor: default;
}
.landing-footer-logo { font-size: 16px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink); }
.landing-nav-links {
  display: flex; align-items: center; gap: 20px;
}
/* Hamburger button — hidden on desktop, shown on mobile via @media (max-width: 768px) */
.landing-nav-hamburger { display: none; }
.landing-nav-link {
  font-size: 13.5px; color: var(--ink-3); text-decoration: none;
  background: none; border: none; cursor: pointer; padding: 0;
  transition: color 0.15s;
}
.landing-nav-link:hover, .landing-nav-link-btn:hover { color: var(--ink); }

/* ── Grouped nav dropdowns ─────────────────────────────────────────────────
   Hover/focus reveals a card panel of destinations. Theme-aware via tokens. */
.lnav-dd { position: relative; display: inline-flex; }
.lnav-dd-trigger {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--f-sans);
}
.lnav-dd-trigger.is-open { color: var(--ink); }
.lnav-dd-caret { transition: transform 0.16s ease; opacity: 0.7; }
.lnav-dd-trigger.is-open .lnav-dd-caret { transform: rotate(180deg); }
/* Panel = positioning + hover-bridge wrapper. It TOUCHES the trigger (top:100%)
   and the visual gap is a TRANSPARENT padding-top that's part of the panel's own
   hover area — so there's no dead gap to lose :hover across moving trigger→card. */
.lnav-dd-panel {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  padding-top: 10px;
  z-index: 60;
}
/* The visible card — frosted glass IDENTICAL to the navbar pill
   (.lp-nav .landing-nav-inner::before): same --lp-nav-* tokens + blur(20px)
   saturate(160%) + -webkit- prefix, so it reads as the same material and flips
   light/dark with the theme. */
.lnav-dd-card {
  min-width: 244px; max-width: 320px;
  display: flex; flex-direction: column; gap: 1px;
  border-radius: 14px; padding: 8px;
  background: var(--lp-nav-bg);
  border: 1px solid var(--lp-nav-border);
  box-shadow: var(--lp-nav-shadow);
  -webkit-backdrop-filter: var(--lp-nav-blur);
  backdrop-filter: var(--lp-nav-blur);
  animation: lnav-dd-in 0.16s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes lnav-dd-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.lnav-dd-item {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 12px; border-radius: 9px; text-decoration: none;
  transition: background 0.13s ease;
}
.lnav-dd-item:hover, .lnav-dd-item:focus-visible {
  background: var(--bg-hover); outline: none;
}
.lnav-dd-item-label { font-size: 13.5px; font-weight: 550; color: var(--ink); letter-spacing: -0.01em; }
.lnav-dd-item-desc  { font-size: 12px; color: var(--ink-4); line-height: 1.4; }

/* Theme toggle — sun (light) ⇄ moon (dark), icons cross-fade + rotate. */
.landing-theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid transparent; border-radius: 8px;
  background: none; color: var(--ink-3); cursor: pointer;
  transition: color 150ms var(--ease-out, ease),
              background 150ms var(--ease-out, ease),
              border-color 150ms var(--ease-out, ease);
}
.landing-theme-toggle:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  border-color: var(--line);
}
.landing-theme-glyph {
  position: relative; width: 17px; height: 17px;
  display: inline-block;
}
.landing-theme-sun, .landing-theme-moon {
  position: absolute; top: 50%; left: 50%;
  transform-origin: center;
  transition: opacity 280ms var(--ease-out, ease),
              transform 360ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
/* Light mode (default): sun visible, moon tucked away. */
.landing-theme-sun  { opacity: 1; transform: translate(-50%, -50%) rotate(0deg)   scale(1); }
.landing-theme-moon { opacity: 0; transform: translate(-50%, -50%) rotate(-90deg) scale(0.5); }
/* Dark mode: moon visible, sun rotates out. */
.landing-theme-glyph.is-dark .landing-theme-sun  { opacity: 0; transform: translate(-50%, -50%) rotate(90deg) scale(0.5); }
.landing-theme-glyph.is-dark .landing-theme-moon { opacity: 1; transform: translate(-50%, -50%) rotate(0deg)  scale(1); }

@media (prefers-reduced-motion: reduce) {
  .landing-theme-sun, .landing-theme-moon { transition: opacity 120ms linear; }
}

/* Hero — STACKED + CENTERED: title/subhead/CTAs centered on top, the product
   film below, centered and wide. (Was a 2-column flex; the film used to be
   absolutely anchored to the right.) */
.landing-hero {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  gap: 52px;
  padding: 104px 0 84px;
}

.landing-hero-svg {
  position: absolute; right: 0; top: 0; bottom: 0;
  height: 100%; width: 60%;
  color: var(--ink); opacity: 0.5;
  pointer-events: none;
}
.landing-hero-content {
  position: relative; z-index: 10;
  max-width: 480px;
}
.landing-hero-text {
  position: relative; z-index: 10;
  /* Wide enough for the single-line headline + subtitle at desktop; capped to
     94vw so the nowrap lines never force horizontal scroll. Narrows back to a
     wrapping column below 1024px (see the max-width:1023px block). */
  width: 100%; max-width: min(1080px, 94vw); margin: 0 auto;
  display: flex; flex-direction: column; align-items: center;
}

/* ── Editorial split hero: headline LEFT, supporting copy + CTA bottom-RIGHT.
   The two columns bottom-align (align-items:end) so the sub's baseline sits
   with the last line of the headline — the classic magazine-cover look.
   Collapses to a single centered column at ≤1023px (see that media block). */
.landing-hero-split {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: end;            /* bottom-align: headline + sub sit on one baseline */
  text-align: left;
  width: 100%;
  /* Match the feature-tab button row below (its natural one-row width), so the
     headline's left edge and the sub's right edge line up with the buttons'
     outer edges. */
  max-width: min(1400px, 96vw);
}
.landing-hero-lead {
  display: flex; flex-direction: column; align-items: flex-start;   /* headline flush-left */
}
.landing-hero-aside {
  display: flex; flex-direction: column; align-items: flex-end;     /* sub block flush-right */
}
.landing-hero-split .landing-headline {
  white-space: normal;          /* wrap freely in the left column */
  font-size: clamp(32px, 4.2vw, 56px);
  font-weight: 500;             /* lighter than the default 700 — airier hero */
  letter-spacing: -0.02em;
  margin: 0;
}
/* Linked, gradient words inside the hero headline ("intelligence" → the
   Intelligence page, "building" → Products). Pairs with .aecos-sheen-text for
   the animated fill and sets no colour/weight of its own, so it inherits the
   headline's lighter weight. The underline needs an explicit colour, or it would
   take the gradient's transparent fill and disappear. */
.landing-head-link {
  text-decoration: underline;
  text-decoration-color: oklch(63% 0.19 292);
  text-decoration-thickness: 3px;
  text-underline-offset: 6px;
  cursor: pointer;
  transition: text-underline-offset 160ms var(--ease-out, ease), text-decoration-color 160ms var(--ease-out, ease);
}
.landing-head-link:hover { text-underline-offset: 8px; text-decoration-color: oklch(70% 0.16 262); }
/* Reusable Aecos-palette flowing-gradient text — used on the hero headline AND
   inline accents like the "Intelligence" section title. The characters live
   permanently in the brand colours: a vivid indigo→violet→periwinkle gradient
   that drifts continuously across them (no ink/white stops, so it never resolves
   to a plain colour). The stop list is a palindrome over a 200% track so the
   drift loops seamlessly. Works on inline spans too (clips to the word's box). */
.aecos-sheen-text {
  background: linear-gradient(92deg,
    oklch(58% 0.17 264),
    oklch(63% 0.19 292),
    oklch(69% 0.15 254),
    oklch(63% 0.19 292),
    oklch(58% 0.17 264));
  background-size: 200% auto;
  background-position: 0% center;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: aecos-headline-sheen 9s linear infinite;
}
@keyframes aecos-headline-sheen {
  to { background-position: 200% center; }
}
.landing-hero-split .landing-sub {
  white-space: normal;
  max-width: 46ch;
  font-size: 19px;             /* a touch larger than the base sub */
  line-height: 1.6;
  margin: 0;
}
/* Feature-tab row keeps its natural width (one row, content-sized, centred); the
   hero split above is widened to match it so their outer edges line up. */
.landing-hero-split .landing-ctas { justify-content: flex-start; }
.landing-hero-split .landing-hero-note { margin-top: 14px; }
/* Inline text CTA woven into the hero sub — the word "Start" as an underlined
   link instead of a separate button, so the call to action reads as part of the
   sentence. Pairs with .aecos-sheen-text (the animated brand gradient), so this
   sets NO color of its own — the fill comes from the gradient. The underline
   needs an explicit text-decoration-color, otherwise it'd inherit the gradient's
   transparent fill and vanish. */
.landing-sub-cta {
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: oklch(63% 0.19 292);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: text-underline-offset 150ms var(--ease-out, ease), text-decoration-color 150ms var(--ease-out, ease);
}
.landing-sub-cta:hover { text-underline-offset: 4px; text-decoration-color: oklch(70% 0.16 262); }

/* ── Mac-style ambient aurora (product sections) ──────────────────────────
   GPU-only, clearly-visible aurora for the PRODUCT/feature sections (the hero
   no longer uses it). Two saturated colour blobs drift via TRANSFORM only —
   compositor work, never background-position or filter, so there are no
   large-area repaints during scroll. The animation runs ONLY while the section
   is on-screen: an IntersectionObserver in LandingPage toggles .aurora-anim,
   which is also where will-change lives, so off-screen sections hold no
   compositor layer. Frozen under prefers-reduced-motion. Theme-aware. */
.aecos-aurora {
  position: relative; isolation: isolate; overflow: hidden;
  background-color: var(--aurora-base, color-mix(in srgb, var(--indigo) 9%, var(--bg)));
}
.aecos-aurora::before,
.aecos-aurora::after {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  width: 68%; aspect-ratio: 1 / 1; border-radius: 50%;
  transform: translate3d(0, 0, 0);
}
.aecos-aurora::before {
  left: -12%; top: -34%;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--indigo) 78%, transparent) 0%,
    color-mix(in srgb, #4f9bff 56%, transparent) 38%,
    transparent 70%);
}
.aecos-aurora::after {
  right: -14%; bottom: -36%;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, #a974ff 74%, transparent) 0%,
    color-mix(in srgb, #46d6b4 54%, transparent) 42%,
    transparent 72%);
}
.aecos-aurora.aurora-anim::before {
  will-change: transform;
  animation: aurora-float-a 8s ease-in-out infinite alternate;
}
.aecos-aurora.aurora-anim::after {
  will-change: transform;
  animation: aurora-float-b 10s ease-in-out infinite alternate;
}
@keyframes aurora-float-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(22%, 26%, 0) scale(1.22); }
}
@keyframes aurora-float-b {
  from { transform: translate3d(0, 0, 0) scale(1.14); }
  to   { transform: translate3d(-24%, -20%, 0) scale(1); }
}
/* Dark theme: deeper base + slightly eased blobs so the aurora glows on ink. */
[data-theme="dark"] .aecos-aurora {
  background-color: var(--aurora-base, color-mix(in srgb, var(--indigo) 20%, var(--bg)));
}
[data-theme="dark"] .aecos-aurora::before,
[data-theme="dark"] .aecos-aurora::after { opacity: 0.8; }
@media (prefers-reduced-motion: reduce) {
  .aecos-aurora.aurora-anim::before,
  .aecos-aurora.aurora-anim::after { animation: none; }
}

/* ── Enterprise plan card: subtle moving brand-aurora ──────────────────────────
   The Enterprise tier (landing teaser .lp2-ent + the #pricing page .pricing-tier-card)
   carries the SAME drifting brand aurora as the product sections, but at LOW opacity —
   a gentle, living distinction, never a loud highlight. The card keeps its own SOLID
   background so the blobs only tint the corners faintly; content sits above them
   (z-index) and stays fully legible. Every other plan card stays neutral. */
.lp2-ent--aurora.aecos-aurora        { background-color: var(--bg-elev); }
.pricing-tier-card--aurora.aecos-aurora { background-color: var(--bg-card); }
.lp2-ent--aurora.aecos-aurora::before,
.lp2-ent--aurora.aecos-aurora::after,
.pricing-tier-card--aurora.aecos-aurora::before,
.pricing-tier-card--aurora.aecos-aurora::after { opacity: 0.18; }
/* content above the z-index:-1 blobs — explicit, so text never washes out */
.lp2-ent--aurora > *,
.pricing-tier-card--aurora > * { position: relative; z-index: 1; }
/* dark theme needs a touch more presence to read, still subtle (the base aurora
   dark rule sets 0.8; scope ours lower) */
[data-theme="dark"] .lp2-ent--aurora.aecos-aurora::before,
[data-theme="dark"] .lp2-ent--aurora.aecos-aurora::after,
[data-theme="dark"] .pricing-tier-card--aurora.aecos-aurora::before,
[data-theme="dark"] .pricing-tier-card--aurora.aecos-aurora::after { opacity: 0.24; }

.landing-eyebrow {
  font-size: 13px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--indigo);
  margin-bottom: 18px;
}
.landing-headline {
  font-family: var(--f-sans);
  font-size: clamp(40px, 5.5vw, 68px);
  font-weight: 700; line-height: 1.08; letter-spacing: -0.03em;
  color: var(--ink); margin: 0 0 24px;
  white-space: nowrap; /* one line at desktop; wraps again ≤1023px */
}
/* Announcement chip — surfaced above the headline only when social sign-in is
   configured (see <LandingAnnounceChip>). */
.landing-announce-chip {
  display: inline-flex; align-items: center; gap: 8px;
  margin-bottom: 22px; padding: 5px 12px 5px 5px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 99px; cursor: pointer;
  font-size: 12.5px; color: var(--ink-2, var(--ink));
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.landing-announce-chip:hover {
  border-color: var(--indigo); transform: translateY(-1px);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--indigo) 12%, transparent);
}
.landing-announce-tag {
  font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: #fff; background: var(--indigo); padding: 3px 8px; border-radius: 99px;
}
.landing-announce-text { font-weight: 500; }
.landing-announce-chip svg { color: var(--ink-4); transition: transform 0.15s, color 0.15s; }
.landing-announce-chip:hover svg { transform: translateX(2px); color: var(--indigo); }

/* ── Welcome-back modal (<LandingWelcomeBack>, portaled to <body>) ──────────────
   White card in light mode via --bg-card (stays dark-mode compatible rather than
   a jarring pure-white panel on the dark landing). Floats above everything. */
.lwb-overlay {
  position: fixed; inset: 0; z-index: 100000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px; background: rgba(0,0,0,0.35);
  animation: lwb-fade 0.2s ease both;
}
.lwb-card {
  position: relative; width: 100%; max-width: 420px;
  background: var(--bg-card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 20px;
  padding: 34px 30px 26px;
  box-shadow: 0 28px 80px rgba(0,0,0,0.30), 0 6px 18px rgba(0,0,0,0.14);
  font-family: var(--f-sans);
  animation: lwb-pop 0.26s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes lwb-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lwb-pop { from { opacity: 0; transform: translateY(10px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }
.lwb-x {
  position: absolute; top: 16px; right: 16px;
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  border: none; background: transparent; color: var(--ink-4); cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.lwb-x:hover { background: var(--bg-sunk, var(--bg-elev)); color: var(--ink); }
.lwb-title { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; margin: 0; color: var(--ink); }
.lwb-sub { font-size: 14px; color: var(--ink-4); margin: 6px 0 22px; }
/* Stack of remembered accounts */
.lwb-accounts { display: flex; flex-direction: column; gap: 8px; }
/* Account row — main click target + a separate "forget" button (no nested buttons) */
.lwb-account {
  display: flex; align-items: stretch; gap: 4px;
  border: 1px solid var(--line); border-radius: 13px; overflow: hidden;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.lwb-account:hover { border-color: var(--indigo); box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 12%, transparent); }
.lwb-account-main {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: none; background: transparent; cursor: pointer;
  text-align: left; color: inherit; font-family: inherit;
}
.lwb-avatar {
  flex-shrink: 0; width: 40px; height: 40px; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--indigo); color: #fff;
  font-size: 14px; font-weight: 600;
}
.lwb-avatar img { width: 100%; height: 100%; object-fit: cover; }
.lwb-account-text { display: flex; flex-direction: column; min-width: 0; gap: 1px; }
.lwb-account-name { font-size: 14.5px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lwb-account-email { font-size: 12.5px; color: var(--ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lwb-forget {
  flex-shrink: 0; width: 34px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--ink-5); cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.lwb-forget:hover { background: color-mix(in srgb, var(--bad, #e5484d) 12%, transparent); color: var(--bad, #e5484d); }
.lwb-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0; color: var(--ink-5); font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em;
}
.lwb-divider::before, .lwb-divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.lwb-pill {
  display: block; width: 100%; margin-top: 10px;
  padding: 11px 16px; border-radius: 99px;
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  font-size: 14px; font-weight: 500; font-family: inherit; cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.lwb-pill:hover { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 6%, transparent); }
@media (prefers-reduced-motion: reduce) {
  .lwb-overlay, .lwb-card { animation: none; }
}
@media (max-width: 480px) {
  .lwb-overlay { padding: 14px; }
  .lwb-card { padding: 28px 22px 22px; border-radius: 18px; }
}

/* ── Footer feedback widget (<FeedbackButton>) ──────────────────────────────── */
.lfb-trigger {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: inherit; color: var(--ink-4);
  transition: color 0.15s;
}
.lfb-trigger:hover { color: var(--ink); }
.lfb-trigger svg { flex-shrink: 0; }
.lfb-card { text-align: center; }
.lfb-stars { display: flex; justify-content: center; gap: 8px; margin: 4px 0 18px; }
.lfb-star {
  background: none; border: none; padding: 2px; cursor: pointer;
  color: var(--ink-5); fill: transparent; line-height: 0;
  transition: color 0.12s, fill 0.12s, transform 0.12s;
}
.lfb-star:hover { transform: translateY(-1px); }
.lfb-star.on { color: #f59e0b; fill: #f59e0b; }
.lfb-textarea {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 84px;
  border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px;
  font-family: inherit; font-size: 13.5px; color: var(--ink); background: var(--bg-card);
  margin-bottom: 16px;
}
.lfb-textarea:focus { outline: none; border-color: var(--indigo); box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 14%, transparent); }
.lfb-submit { margin-top: 0; }
.lfb-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.lfb-submit:disabled:hover { border-color: var(--line); background: transparent; }
.lfb-thanks { text-align: center; }
.lfb-thanks-mark {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #16a34a; background: color-mix(in srgb, #16a34a 14%, transparent);
}
.lfb-thanks .lwb-pill { margin-top: 18px; }

.landing-sub {
  font-size: 17px; line-height: 1.65; color: var(--ink-3);
  max-width: none; white-space: nowrap; /* one line at desktop; wraps again ≤1023px */
  margin: 0 0 36px;
}
.landing-ctas {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
}
.landing-cta-primary {
  font-size: 14.5px; padding: 11px 28px; border-radius: var(--radius-btn);
}
/* ghost / outline button — same height as the primary CTA */
.landing-cta-secondary {
  font-size: 14.5px; padding: 11px 28px; border-radius: var(--radius-btn);
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-1, var(--ink));
  transition: border-color 150ms var(--ease-out, ease), color 150ms var(--ease-out, ease);
}
.landing-cta-secondary:hover { border-color: var(--indigo); color: var(--indigo); }

/* Generic section */
.landing-section {
  padding: 96px 0;
  border-top: none;
}
.landing-hero + .landing-section { border-top: none; }
.landing-section-title {
  font-family: var(--f-sans);
  font-size: clamp(28px, 3.5vw, 44px);
  font-weight: 700; line-height: 1.12; letter-spacing: -0.025em;
  color: var(--ink); margin: 0 0 20px;
}
.landing-body-copy {
  font-size: 16px; line-height: 1.7; color: var(--ink-3);
  max-width: 60ch; margin: 0;
}
.landing-body-copy-center { text-align: center; margin: 0 auto 48px; }

/* Centered-header treatment (mirrors the Intelligence/AI-demo section): center the
   eyebrow, title, and intro body for every content section EXCEPT the hero. The
   section grids/demos below keep their own layout — only the header copy centers.
   Applied via the .landing-section-centered modifier on each section. */
.landing-section-centered > .landing-container > .landing-eyebrow,
.landing-section-centered > .landing-container > .landing-section-title {
  text-align: center;
}
.landing-section-centered > .landing-container > .landing-body-copy {
  text-align: center; max-width: 60ch; margin-left: auto; margin-right: auto;
}

/* Problem section */
.landing-problem { background: var(--bg-card); }

/* Solution */
.landing-solution { border-top: none; padding: 64px 0; }  /* flat purple replaced by .aecos-aurora backdrop */
.landing-solution-text {
  font-family: var(--f-serif);
  font-style: italic;
  font-size: clamp(22px, 3vw, 34px);
  font-weight: 400; line-height: 1.3; letter-spacing: -0.01em;
  color: var(--indigo-ink); text-align: center;
  max-width: 700px; margin: 0 auto;
}

/* Feature grid */
.landing-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px; margin-top: 48px;
  align-items: stretch; /* equal-height cards per row so each demo bottom-aligns
                           identically regardless of heading line-count */
}
.landing-feature-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px; padding: 24px;
  display: flex; flex-direction: column; gap: 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
  cursor: default;
}
.landing-feature-card:hover {
  border-color: var(--indigo-line);
  box-shadow: 0 4px 18px color-mix(in srgb, var(--indigo) 8%, transparent);
}
.landing-feature-icon {
  color: var(--indigo); display: flex; align-items: center;
  width: 36px; height: 36px;
  background: var(--indigo-soft); border-radius: 8px;
  justify-content: center; flex-shrink: 0;
}
.landing-feature-title {
  font-size: 15px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.01em;
}
.landing-feature-body {
  font-size: 13.5px; line-height: 1.6; color: var(--ink-3);
}

/* ── Product feature tabs (.lft-*, <LandingFeatureTabs>) ──────────────────────
   ChatGPT-style segmented switcher: a centered pill row drives one crossfading
   panel (heading + summary + centered benefit chips, then the active feature's
   demo). The panel is keyed by the active tab so it remounts + crossfades, and
   the demo replays, on every switch. */
/* ── Product capability page: large centered demo + scannable spec cards ──── */
.product-hero-demo {
  width: 100%; margin: 36px auto 0;
  /* flex column + align-items:center so the full-bleed .lft-stage band centres
     on the viewport (same mechanism as the home teaser). */
  display: flex; flex-direction: column; align-items: center;
  /* Same smooth eased crossfade as the home teaser on each keyed capability
     switch (this panel remounts via key={tab.id} and previously SNAPPED). */
  animation: lft-fade 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.product-hero-demo .lft-stage { min-height: clamp(300px, 48vh, 540px); }
.product-spec-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; max-width: 880px; margin: 28px auto 0;
}
.product-spec-card {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px 18px; border-radius: 12px;
  background: var(--bg-card); border: 1px solid var(--line);
}
.product-spec-check {
  display: inline-flex; flex-shrink: 0; margin-top: 1px;
  color: var(--indigo);
}
.product-spec-text { font-size: 14px; line-height: 1.45; color: var(--ink-2); }
@media (max-width: 720px) {
  .product-spec-grid { grid-template-columns: 1fr; max-width: 460px; }
}

/* ── Product capability page — depth template (pd-*) ───────────────────────────
   One consistent structure across every #product/<id>: How-it-works flow +
   alternating text/diagram benefit rows + a reused-animation showcase. Theme-aware
   via tokens; shared grid + rhythm keep all pages on the same clean format. */
.pd-center { text-align: center; }
.pd-section { padding-top: clamp(48px, 7vh, 88px); padding-bottom: clamp(48px, 7vh, 88px); }
.pd-h2 { font-size: clamp(22px, 2.6vw, 32px); margin-bottom: 8px; }

/* How-it-works flow */
.pd-flow {
  list-style: none; margin: 40px auto 0; padding: 0; max-width: 1040px;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; align-items: start;
}
.pd-flow-step { position: relative; padding: 0 18px; text-align: center; }
.pd-flow-num {
  width: 34px; height: 34px; border-radius: 50%; margin: 0 auto 14px;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 28%, transparent);
}
.pd-flow-label { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 6px; line-height: 1.3; }
.pd-flow-desc { font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.pd-flow-arrow { position: absolute; top: 8px; right: -11px; color: var(--ink-5); }
.pd-flow-step:last-child .pd-flow-arrow { display: none; }

/* Benefit rows — alternating text/visual on a shared grid */
.pd-rows-section .landing-container { max-width: 1040px; }
.pd-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 64px);
  align-items: center; padding: clamp(36px, 5vh, 60px) 0;
}
.pd-row + .pd-row { border-top: 1px solid var(--line); }
.pd-row--flip .pd-row-text { order: 2; }
.pd-row--flip .pd-row-visual { order: 1; }
.pd-row-kicker { font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--indigo); margin-bottom: 12px; }
.pd-row-title { font-size: clamp(19px, 2vw, 24px); font-weight: 600; line-height: 1.28; letter-spacing: -0.01em; color: var(--ink); margin: 0 0 14px; }
.pd-row-body { font-size: 15px; line-height: 1.6; color: var(--ink-3); margin: 0; }
.pd-row-visual { display: flex; align-items: center; justify-content: center; }

/* Visual primitives */
/* ── Project → Files tab: the file card ──────────────────────────────────────
   ⚠️ ALL SIX OF THESE CLASSES HAD NO CSS RULE AT ALL (found 2026-08-03, part of
   the 976-strong report-only sweep in test_css_classes.py). The tab rendered as
   plain stacked text — no card, no separation, and the size ran straight into
   the date ("156.4 KBInvalid Date") because nothing set a gap. It looked
   half-broken rather than empty, which is worse: it read as a rendering failure
   of the files themselves.
   It went unnoticed for the same reason the Invalid Date did — project_documents
   held ZERO ROWS database-wide, so this component had never rendered a single
   card on real data. */
.pd-file-list { display: flex; flex-direction: column; gap: 8px; }
.pd-file-card {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-card); transition: border-color .12s ease, background .12s ease;
}
.pd-file-card:hover { border-color: var(--line-strong, var(--line)); background: var(--bg-elev); }
.pd-file-card-info { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; cursor: pointer; }
.pd-file-card-name {
  font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* the gap here is the fix for "156.4 KBInvalid Date" — two adjacent spans with
   nothing between them */
.pd-file-card-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 11.5px; }
.pd-file-card-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
/* The THREE siblings the 2026-08-03 fix did not reach — still ruleless until
   the preview shipped. Without them the leading icon had no box of its own (so
   a long filename shoved it around) and the trailing action buttons were laid
   out by the card's own flex with no gap between them. */
.pd-file-card-icon {
  flex-shrink: 0;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-4);
  margin-top: 1px;
}
/* Never fully hidden: hover-only actions are unreachable on touch. */
.pd-file-card-actions {
  display: flex; align-items: center; gap: 2px;
  flex-shrink: 0; opacity: 0.6;
  transition: opacity .12s ease;
}
.pd-file-card:hover .pd-file-card-actions { opacity: 1; }
.pd-file-action-btn {
  padding: 5px;
  border-radius: var(--radius-btn-icon);   /* icon-only, so 8px — not the pill */
  color: var(--ink-4);
}
.pd-file-action-btn:hover { color: var(--ink); }

.pd-card {
  width: 100%; max-width: 384px; border-radius: 14px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg-card);
  box-shadow: 0 16px 44px -22px rgba(20, 22, 50, 0.30);
}
.pd-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 16px; border-bottom: 1px solid var(--line); background: var(--bg-elev); }
.pd-card-title { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.pd-card-badge { font-size: 10.5px; font-weight: 600; color: var(--indigo); background: color-mix(in srgb, var(--indigo) 12%, transparent); padding: 3px 9px; border-radius: 20px; white-space: nowrap; }
.pd-card-body { padding: 4px 16px 12px; }
.pd-card-line { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.pd-card-line:last-child { border-bottom: none; }
.pd-card-line-label { font-size: 12px; color: var(--ink-4); flex-shrink: 0; }
.pd-card-line-value { font-size: 12.5px; font-weight: 600; color: var(--ink-2, var(--ink)); text-align: right; }
.pd-card-line--bad .pd-card-line-value { color: var(--bad, #AC312A); }
.pd-card-line--warn .pd-card-line-value { color: var(--warn, #B16512); }

.pd-stats { display: flex; gap: 14px; width: 100%; max-width: 430px; }
.pd-stat { flex: 1; border-radius: 14px; border: 1px solid var(--line); background: var(--bg-card); padding: 18px 12px; text-align: center; }
.pd-stat-value { font-size: clamp(22px, 2.4vw, 30px); font-weight: 700; letter-spacing: -0.02em; color: var(--ink); }
.pd-stat-label { font-size: 12px; color: var(--ink-4); margin-top: 5px; }
.pd-stat--good .pd-stat-value { color: var(--good, #307A4F); }
.pd-stat--warn .pd-stat-value { color: var(--warn, #B16512); }
.pd-stat--bad .pd-stat-value { color: var(--bad, #AC312A); }

.pd-list { width: 100%; max-width: 400px; border-radius: 14px; overflow: hidden; border: 1px solid var(--line); background: var(--bg-card); }
.pd-list-head { font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-4); padding: 13px 16px 9px; }
.pd-list-item { display: flex; align-items: center; gap: 10px; padding: 11px 16px; border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.pd-list-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-5); flex-shrink: 0; }
.pd-list-item--bad .pd-list-dot { background: var(--bad, #AC312A); }
.pd-list-item--warn .pd-list-dot { background: var(--warn, #B16512); }
.pd-list-label { flex: 1; font-size: 12.5px; line-height: 1.3; color: var(--ink-2, var(--ink)); }
.pd-list-badge { flex-shrink: 0; font-size: 11px; font-weight: 600; color: var(--ink-4); }
.pd-list-item--bad .pd-list-badge { color: var(--bad, #AC312A); }
.pd-list-item--warn .pd-list-badge { color: var(--warn, #B16512); }

/* Showcase (reused animated demo) */
.pd-showcase-section { background: color-mix(in srgb, var(--indigo) 4%, transparent); }
.pd-showcase-sub { margin: 0 auto 8px; }
.pd-showcase-stage { max-width: 720px; margin: 30px auto 0; }

@media (max-width: 860px) {
  .pd-flow { grid-template-columns: 1fr; gap: 24px; max-width: 380px; }
  .pd-flow-arrow { display: none; }
  .pd-row { grid-template-columns: 1fr; gap: 22px; padding: 30px 0; }
  .pd-row--flip .pd-row-text { order: 1; }
  .pd-row--flip .pd-row-visual { order: 2; }
  .pd-row-visual { order: 2; }
}

/* Landing teaser panel: title + visual flip + "See <product> →" link only. */
.lft-teaser {
  display: flex; flex-direction: column; align-items: center;
  gap: 22px; margin-top: 30px;
  /* Slow, gentle eased fade+rise on every keyed tab switch (was a snappy 0.42s).
     Literal values only — no var()-valued transition (Chrome sticks at from-value). */
  animation: lft-fade 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.lft-teaser-title {
  font-family: var(--f-sans); font-size: clamp(20px, 2.6vw, 30px);
  font-weight: 700; letter-spacing: -0.02em; color: var(--ink);
  text-align: center; max-width: 720px; margin: 0;
}
/* (.lft-stage is now a full-bleed aurora band — see the .lft-stage rule below.) */
.lft-teaser-link {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600; color: var(--indigo);
  text-decoration: none; padding: 9px 18px; border-radius: 999px;
  border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 30%, transparent));
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 8%, transparent));
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.lft-teaser-link:hover { transform: translateY(-1px); border-color: var(--indigo); }
.lft-teaser-link svg { transition: transform 0.15s ease; }
.lft-teaser-link:hover svg { transform: translateX(2px); }

/* "Building now" badge — honest marker for in-development capabilities. */
.building-badge {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--indigo-ink, var(--indigo));
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 10%, transparent));
  border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 28%, transparent));
  border-radius: 999px; padding: 5px 12px;
}
.building-badge-dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--indigo); flex-shrink: 0;
  animation: building-pulse 1.8s ease-in-out infinite;
}
@keyframes building-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .building-badge-dot, .mnd-rec-dot { animation: none; } }

/* Meeting Notes concept demo — illustrative (feature in development, no real
   screenshot yet), theme-aware, GPU-only (only the REC dot pulses via opacity). */
.mnd {
  width: 100%; aspect-ratio: 16 / 10; overflow: hidden;
  display: flex; flex-direction: column; gap: 12px;
  padding: clamp(16px, 2.4vw, 26px);
  background: var(--bg-card); color: var(--ink);
  font-family: var(--f-sans); text-align: left;
}
.mnd-bar { display: flex; align-items: center; gap: 10px; }
.mnd-rec { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.08em; color: var(--bad, #e5484d); }
.mnd-rec-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--bad, #e5484d); animation: building-pulse 1.4s ease-in-out infinite; }
.mnd-bar-title { font-size: 13px; font-weight: 600; color: var(--ink); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mnd-bar-time { font-size: 12px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.mnd-wave { display: flex; align-items: center; gap: 3px; height: 32px; }
.mnd-wave span { flex: 1; min-width: 0; border-radius: 2px; background: color-mix(in srgb, var(--indigo) 45%, transparent); }
.mnd-speakers { display: flex; gap: 10px; flex-wrap: wrap; }
.mnd-spk { font-size: 12px; color: var(--ink-2); background: var(--bg-sunk); border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; }
.mnd-spk b { color: var(--indigo); font-weight: 700; }
.mnd-card { flex: 1; min-height: 0; overflow: hidden; background: var(--bg-elev); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.mnd-card-h { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--indigo); margin-bottom: 9px; }
.mnd-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.mnd-list li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-2); line-height: 1.4; }
.mnd-tag { flex-shrink: 0; font-size: 10px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; border-radius: 5px; padding: 2px 6px; }
.mnd-tag-dec { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); }
.mnd-tag-act { color: var(--ok, #2a9d5c); background: color-mix(in srgb, var(--ok, #2a9d5c) 14%, transparent); }
.mnd-tag-rfi { color: var(--warn, #c77d12); background: color-mix(in srgb, var(--warn, #c77d12) 16%, transparent); }
.mnd-foot { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-3); }
.mnd-foot svg { color: var(--indigo); flex-shrink: 0; }
.mnd-foot b { color: var(--ink); }

.lft-wrap { margin-top: 44px; }
.lft-tabs {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin-bottom: 30px;
}
/* Product-page capability row: keep the pills on ONE line (never wrap). The
   product-page row is width-capped by .landing-container (unlike the homepage
   showcase's fuller-width section), so its pills would wrap; force a single row
   that scrolls if the viewport is genuinely too narrow. `safe center` centers
   when there's room but falls back to start-alignment (so nothing is clipped)
   when it overflows. */
.lft-tabs--scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  justify-content: safe center;
  max-width: 100%;
  min-width: 0;
}
.lft-tabs--scroll .lft-tab { flex: 0 0 auto; }
.lft-tab {
  padding: 9px 17px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-card);
  font-family: var(--f-sans); font-size: 13.5px; font-weight: 500;
  color: var(--ink-3); cursor: pointer; white-space: nowrap;
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.lft-tab:hover { border-color: var(--indigo-line); color: var(--ink); }
.lft-tab:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--indigo); }
.lft-tab.is-active {
  background: var(--ink); color: var(--bg); border-color: var(--ink);
}
/* Two-column panel: SUMMARY on the LEFT, demo on the RIGHT. Keyed remount
   crossfades on each tab switch. */
.lft-panel {
  animation: lft-fade 0.9s cubic-bezier(0.22, 1, 0.36, 1) both;
  display: grid;
  grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}
@keyframes lft-fade {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.lft-copy { text-align: left; }
.lft-heading {
  font-family: var(--f-sans); font-size: clamp(21px, 2.5vw, 29px);
  font-weight: 700; letter-spacing: -0.02em; color: var(--ink); margin: 0 0 12px;
}
.lft-summary { font-size: 15.5px; line-height: 1.65; color: var(--ink-3); margin: 0; }
.lft-bullets {
  list-style: none; margin: 18px 0 0; padding: 0;
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
}
.lft-bullet {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13.5px; color: var(--ink-2);
}
.lft-bullet svg { color: var(--indigo); flex-shrink: 0; }

/* Demo stage — soft pale-indigo "desktop" gradient (Aecos palette). The demo
   floats on it as a rounded, soft-shadowed window. Lives in the RIGHT column. */
/* Product-showcase band — FULL-BLEED, carrying the animated aurora (the
   .aecos-aurora class on .lft-stage brings the moving colour-mesh; FeatureTabDemo
   toggles .aurora-anim while on-screen). Generous padding so the gradient shows
   around all four sides of the floating card. The .aecos-aurora class also sets
   position/isolation/overflow:hidden + the base tint, so we don't repeat them. */
.lft-stage {
  /* Contained rounded band (ChatGPT-landing style): inset from the viewport
     edges by symmetric gutters, wider than the text container, centred by the
     parent's align-items:center (teaser / product-hero-demo / lai-stage-wrap
     are all flex columns). overflow:hidden on .aecos-aurora clips the blobs to
     the rounded corners. */
  width: calc(100vw - clamp(32px, 8vw, 96px));
  max-width: 1640px;
  border-radius: clamp(28px, 3vw, 32px);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(28px, 4.5vh, 60px) clamp(24px, 6vw, 88px);
  min-height: clamp(300px, 46vh, 520px);
}
/* Feature-showcase (LandingFeatureTabs → .lft-teaser) stage ONLY: PIN a fixed
   height so the aurora band can't change size between slides. Different slides
   have different natural heights (Gantt/Projects ~437px, others up to ~536px at
   an 812px viewport), and the base `min-height` above is only a floor — the band
   grew to fit each slide, reflowing the constellation animation below on every
   auto-advance. A fixed `height` reserves ONE size; the flex align/justify:center
   inherited from the base rule centres shorter slides in the reserved space.
   Scoped to `.lft-teaser .lft-stage` so the `.product-hero-demo` and
   `.lai-stage-wrap` stages (which have no constellation below them) keep their
   content-driven `min-height` sizing.
   Height math: the tallest slide's content box ≈463px (window ~448 + heading)
   plus vertical padding 2×clamp(28,4.5vh,60) = 56–120px → natural tallest ranges
   ~519px (short viewports, padding at the 28px floor) to ~583px (very tall
   viewports, padding at the 60px cap). `clamp(560px, 62vh, 620px)` brackets that
   at EVERY viewport height without clipping: 62vh matches the measured 536@812
   tallest, the 560px floor covers short viewports (natural ≤~544 there), and the
   620px cap sits above the ~583 tall-viewport maximum. Errs slightly tall so
   shorter slides simply centre with a little extra breathing room. overflow is
   already hidden via .aecos-aurora; restated here for intent. */
.lft-teaser .lft-stage {
  height: clamp(560px, 62vh, 620px);
  overflow: hidden;
}
/* Showcase heading sitting ON the aurora band, just above the floating card.
   Fades + slides up when the band scrolls into view (one-shot via .lft-revealed;
   re-runs on tab switch because FeatureTabDemo remounts). */
.lft-stage-heading {
  position: relative; z-index: 1;
  width: 100%; max-width: 1080px;
  text-align: center;
  font-family: var(--f-sans);
  font-size: clamp(20px, 2.5vw, 34px); font-weight: 600; letter-spacing: -0.025em;
  line-height: 1.18; color: var(--ink);
  opacity: 0; transform: translateY(18px);
  transition: opacity 0.62s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.62s cubic-bezier(0.22, 1, 0.36, 1);
}
.lft-stage.lft-revealed .lft-stage-heading { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .lft-stage-heading { transition: none; opacity: 1; transform: none; }
}
/* Floating product card — generously large, rounded, soft drop shadow, sitting
   above the aurora blobs (which are at z-index:-1). */
.lft-window {
  position: relative; z-index: 1; overflow: hidden;
  width: 100%; max-width: min(1080px, 100vh);
  display: flex; align-items: center;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 44px 110px -30px rgba(20, 22, 50, 0.55), 0 14px 40px -16px rgba(20, 22, 50, 0.32);
}
/* Real-asset demos (Projects slices / Studio Review overlay) bring their own
   frame — flatten it so .lft-window is the only frame.
   transform:none + margin:0 are REQUIRED, not cosmetic: at ≤768px the standalone
   `.srd-shell`/`.prd-shell` full-bleed rules (search "full-bleed on phones")
   apply `width:100vw; margin-left:50%; transform:translateX(-50%)` to break the
   demo out to the viewport edge. Inside the product slideshow that shell is NOT
   full-bleed (it lives in the fixed-ratio `.lft-window`); the `margin:0`/`width`
   reset below already neutralised margin+width, but the leaked `translateX(-50%)`
   still shifted the screenshot left by half its width — clipping the left half
   under `.lft-window { overflow:hidden }` and leaving the right half as the bare
   white `.lft-window` card background. That was the "SR screenshot cut off halfway,
   shows white" bug. This higher-specificity (0,2,0) rule wins over the (0,1,0)
   mobile full-bleed rules regardless of source order, so it stays fixed. */
.lft-window .prd-shell, .lft-window .srd-shell { margin: 0; width: 100%; max-width: 100%; transform: none; }
.lft-window .prd-frame, .lft-window .srd-frame { border-radius: 0; border: none; box-shadow: none; }
.lft-window .sr-reveal { opacity: 1 !important; transform: none !important; }

/* Intelligence tab (demo:"ai") floats the self-running LandingAiDemo card
   directly on the aurora band — no .lft-window frame (avoids a card-in-card).
   Cap + float it exactly like .lai-stage-wrap so the gradient shows all around. */
.lft-ai-stage .landing-demo-wrap {
  position: relative; z-index: 1;
  max-width: 760px;
  box-shadow: 0 44px 110px -30px rgba(20, 22, 50, 0.55), 0 14px 40px -16px rgba(20, 22, 50, 0.32);
}
/* The feature-teaser band is a FIXED height (.lft-teaser .lft-stage) and also
   carries the showcase heading above the card, so trim the demo body a little
   here so the card (topbar + body + scene controls) fits without clipping the
   dots. The dedicated IntelligencePage stage keeps the roomier default. */
.lft-teaser .lft-ai-stage .landing-demo-body { min-height: 330px; padding-top: 24px; padding-bottom: 22px; }

/* Film-shot demo — a real product screenshot as a static base + a light,
   GPU-only sheen sweep (transform-only; frozen under reduced-motion). */
.fsd { position: relative; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; }
.fsd-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top center; display: block;
}
.fsd-sheen {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,0.20) 50%, transparent 60%);
  transform: translateX(-130%); will-change: transform;
  animation: fsd-sweep 7s cubic-bezier(0.4, 0, 0.2, 1) infinite; animation-delay: 1.1s;
}
@keyframes fsd-sweep {
  0%, 66% { transform: translateX(-130%); }
  100%    { transform: translateX(130%); }
}
@media (prefers-reduced-motion: reduce) { .fsd-sheen { animation: none; opacity: 0; } }

/* Stack the panel (summary on top, demo below) once the two columns get tight. */
@media (max-width: 980px) {
  .lft-panel { grid-template-columns: 1fr; gap: 26px; }
  .lft-copy { text-align: center; max-width: 760px; margin: 0 auto; }
  .lft-summary { margin: 0 auto; }
  .lft-bullets { flex-flow: row wrap; align-items: center; justify-content: center; gap: 8px 18px; }
}
@media (max-width: 768px) {
  .lft-wrap { margin-top: 32px; }
  /* The tab row is a CONTAINED horizontal scroll strip on phones — bound it to
     the viewport (min-width:0 + max-width:100vw) so its ~1400px of pills scroll
     inside instead of pushing the whole hero (and the page) wider than the
     screen. That page-wide overflow was what made the buttons fall off the edges
     and broke vertical scrolling. */
  .lft-tabs { flex-wrap: nowrap; overflow-x: auto; justify-content: flex-start; margin-bottom: 22px; -webkit-overflow-scrolling: touch; width: 100%; max-width: 100vw; min-width: 0; }
  .lft-tab { flex-shrink: 0; }
  /* Feature-showcase container must fill (not shrink-wrap) its content, or the
     tab row would still stretch it wide. */
  .landing-hero-features { width: 100%; max-width: 100%; align-self: stretch; }
  /* No full-bleed breakout on phones (the container clips overflow-x); keep the
     aurora band at content width so it never triggers a horizontal scrollbar. */
  .lft-stage { width: 100%; max-width: 100%; margin-left: 0; transform: none; min-height: 0; padding: clamp(18px, 5vw, 28px); }
  /* Pin the feature-teaser band to ONE consistent PORTRAIT ratio on phones. The
     mockups (and their in-slide animations) each have a different natural height,
     and a content-driven band grew/shrank on every slide + every animation frame —
     shoving the whole page up and down, which the founder reported as "super jumpy
     and unusable." A fixed aspect-ratio reserves the SAME size for every slide;
     width-driven (not vh/dvh) so the mobile address bar showing/hiding can't
     re-jitter it either. 4/5 is portrait so the band fills a phone screen better
     than the wide desktop band; overflow:hidden + the inherited flex centering keep
     each mockup centred in the reserved space. Matches the desktop rule's (0,2,0)
     specificity and comes later in source, so it wins inside this media query. */
  .lft-teaser .lft-stage { height: auto; aspect-ratio: 4 / 5; overflow: hidden; }
  /* Inside that fixed portrait band, STACK the caption above the screenshot. On
     desktop the heading + screenshot sit in a 2-column row; on a phone that row
     stayed put and squeezed the screenshot to ~half the band width (a tiny ~206px
     strip floating in empty aurora). Column layout gives the screenshot the FULL
     band width. Centred vertically so it reads as a framed shot. The AI slide uses
     .lft-ai-stage (not .lft-stage) and is unaffected. */
  .lft-teaser .lft-stage { flex-direction: column; justify-content: center; gap: 12px; }
  .lft-teaser .lft-stage > .lft-stage-heading { width: 100%; max-width: 100%; text-align: center; font-size: clamp(16px, 4.6vw, 22px); }
  .lft-teaser .lft-window { width: 100%; max-width: 100%; }
}

/* ── Feature card hover-expand interaction (LandingFeatureGrid) ── */
.lfc-wrap { position: relative; }

/* Backdrop dims the page; z-index below the expanded card */
.lfc-backdrop {
  position: fixed; inset: 0; z-index: 490;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(2px);
  animation: lfc-fade-in 0.18s ease both;
}
@keyframes lfc-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Cursor hint on hoverable cards */
.lfc-card { cursor: pointer; }

/* Expanded overlay — fixed, centred, pointer-events forwarded to card */
.lfc-expanded-overlay {
  position: fixed; inset: 0; z-index: 500;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.lfc-expanded-card {
  position: relative;
  width: 80vw; height: 80vh;
  max-width: 1040px; max-height: 720px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 24px 80px rgba(0,0,0,0.28), 0 0 0 1px rgba(255,255,255,0.04);
  display: flex; flex-direction: column;
  pointer-events: all;
  animation: lfc-expand-in 0.22s cubic-bezier(0.18, 0, 0.1, 1) both;
}
.lfc-no-anim { animation: none !important; }
@keyframes lfc-expand-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}
.lfc-expanded-header {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 20px 24px 18px; border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.lfc-expanded-icon { color: var(--indigo); flex-shrink: 0; margin-top: 1px; }
.lfc-expanded-title { font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.lfc-expanded-sub   { font-size: 12px; color: var(--ink-4); margin-top: 3px; line-height: 1.5; max-width: 560px; }
.lfc-expanded-body  {
  flex: 1; overflow: hidden; padding: 24px;
  display: flex; flex-direction: column;
}
.lfc-close-btn {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.12s, color 0.12s;
}
.lfc-close-btn:hover { background: var(--bg-hover); color: var(--ink); }

/* Stub placeholder */
.lfc-stub-demo {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px; color: var(--ink-4);
}
.lfc-stub-label { font-size: 13px; }

/* prefers-reduced-motion: no backdrop or card animations */
@media (prefers-reduced-motion: reduce) {
  .lfc-backdrop    { animation: none; }
  .lfc-expanded-card { animation: none !important; }
}

/* ── CmdCenter demo ── */
.lfc-cc-wrap {
  display: flex; flex-direction: column; gap: 18px; height: 100%; overflow-y: auto;
}
.lfc-cc-greeting {
  font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em;
}
.lfc-cc-briefing {
  display: flex; flex-direction: column; gap: 9px;
  font-size: 13.5px; line-height: 1.55; color: var(--ink-2);
}
.lfc-cc-line {
  display: flex; align-items: flex-start; gap: 9px;
  animation: lfc-fade-in 0.35s ease both;
}
.lfc-cc-projects {
  display: flex; gap: 14px; margin-top: 6px; flex-wrap: wrap;
}
.lfc-cc-proj-card {
  flex: 1; min-width: 160px;
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 16px; display: flex; flex-direction: column; gap: 10px;
  animation: lfc-fade-in 0.35s ease both;
}
.lfc-cc-proj-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.lfc-cc-proj-meta { display: flex; align-items: center; gap: 7px; }
.lfc-cc-proj-days { font-size: 11px; color: var(--ink-4); }
.lfc-cc-proj-bar-wrap {
  flex: 1; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden;
}
.lfc-cc-proj-bar { height: 100%; border-radius: 2px; transition: width 0.6s ease; }

/* ── Feature Card 1: Command Center (scroll-activated mini-demo) ───────────── */
.fc-cc-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px;
  display: flex; flex-direction: column;
}
.fc-cc-eyebrow {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo);
  margin-bottom: 10px;
}
.fc-cc-heading {
  font-size: 19px; font-weight: 650; line-height: 1.25;
  color: var(--ink-1, var(--ink));
  margin-bottom: 6px;
}
.fc-cc-subheading {
  font-size: 13px; line-height: 1.4;
  color: var(--ink-3, var(--ink-4));
  margin-bottom: 18px;
}

/* The miniature live Command Center — fades up + pulses once on scroll-in. */
.fc-cc-mock {
  min-height: 280px;
  margin-top: auto; /* push demo to the card bottom for uniform alignment */
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
  background: var(--bg, var(--bg-card));
  display: flex; flex-direction: column; gap: 12px;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 300ms var(--ease-out, ease),
    box-shadow   300ms var(--ease-out, ease);
}
.fc-cc-mock.is-active { opacity: 1; transform: translateY(0); }
/* One-time indigo border glow at the end of the sequence. */
.fc-cc-mock.is-pulse {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px var(--indigo-soft, color-mix(in srgb, var(--indigo) 18%, transparent));
}
.fc-cc-no-anim .fc-cc-mock,
.fc-cc-mock.fc-cc-no-anim { opacity: 1; transform: none; transition: none; }

/* 2×2 mini stat grid */
.fc-cc-stat-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}
.fc-cc-stat {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
}
.fc-cc-stat-value {
  font-size: 20px; font-weight: 700; line-height: 1;
  color: var(--ink-1, var(--ink));
  font-variant-numeric: tabular-nums;
}
.fc-cc-stat-unit { font-size: 11px; font-weight: 600; color: var(--ink-4); margin-left: 1px; }
.fc-cc-stat-label {
  font-size: 10px; line-height: 1.2; margin-top: 4px;
  color: var(--ink-4);
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* Mini briefing card */
.fc-cc-briefing {
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 8%, transparent));
  border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 22%, transparent));
  border-radius: 8px;
  padding: 10px 11px;
  display: flex; flex-direction: column; gap: 7px;
}
.fc-cc-briefing-head {
  display: flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--indigo);
}
.fc-cc-bullet {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 11.5px; line-height: 1.35;
  color: var(--ink-2, var(--ink));
  min-height: 15px; /* reserve row height so typing doesn't reflow */
}
.fc-cc-bullet-dot {
  flex-shrink: 0; width: 5px; height: 5px; margin-top: 5px;
  border-radius: 50%; background: var(--indigo);
}
.fc-cc-bullet-text { flex: 1; }
.fc-cc-caret {
  display: inline-block; width: 1px; height: 11px;
  margin-left: 1px; vertical-align: text-bottom;
  background: var(--indigo);
  animation: fc-cc-blink 0.8s step-end infinite;
}
@keyframes fc-cc-blink { 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .fc-cc-mock { opacity: 1; transform: none; transition: none; }
  .fc-cc-caret { animation: none; }
}

/* ── Feature Card 2: Projects — real-asset gantt thumb (shares .fc-sr-card chrome
   + the .prd-* demo; see <FeatureCardProjects> / <ProjectsAnimation>) ────────── */
.fc-proj-thumb {
  position: relative;
  margin-top: auto;            /* bottom-align like the sibling cards' demos */
  aspect-ratio: 1 / 1;         /* square — matches the sibling cards' demo footprint */
  border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line);
}
/* Crop the landscape gantt to a square left-window (project names → ~MAY column)
   so the card matches the sibling demos' square footprint with no distortion. The
   .prd-frame keeps the image's native 2437×1790 aspect (bg undistorted, overlay in
   lockstep); the square thumb shows a sub-window via overflow:hidden + an oversized,
   absolutely-positioned shell. Crop ≈ image px (40,66) over side 1690:
   width 2437/1690 = 144.20%, left -40/1690 = -2.37%, top -66/1690 = -3.91%. */
.fc-proj-thumb .prd-shell {
  position: absolute; top: -3.91%; left: -2.37%;
  width: 144.20%; max-width: none; margin: 0;
}
.fc-proj-thumb .prd-frame { border-radius: 0; border: none; box-shadow: none; }
/* The card shows the full (expanded) gantt frozen; the row-expansion reveal is the
   reward in the modal. Force the middle strip open + kill the cue/animation so the
   three strips reproduce the whole image at its native 2437×1790 aspect (the 144.20%
   oversized-shell crop math above depends on that). */
.fc-proj-thumb .prx-mid { animation: none; padding-bottom: 26.385%; }
.fc-proj-thumb .prx-cue { display: none; }

/* ── Feature Card 3: Studio Review (scroll-activated mini-demo) ────────────── */
.fc-sr-card {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px;
  display: flex; flex-direction: column;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.fc-sr-card:hover, .fc-sr-card:focus-visible {
  border-color: var(--indigo-line);
  box-shadow: 0 6px 22px color-mix(in srgb, var(--indigo) 10%, transparent);
  outline: none;
}
.fc-sr-card:focus-visible { box-shadow: 0 0 0 2px var(--indigo), 0 6px 22px color-mix(in srgb, var(--indigo) 12%, transparent); }
.fc-sr-eyebrow {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo);
  margin-bottom: 10px;
}
.fc-sr-heading {
  font-size: 19px; font-weight: 650; line-height: 1.25;
  color: var(--ink-1, var(--ink));
  margin-bottom: 6px;
}
.fc-sr-subheading {
  font-size: 13px; line-height: 1.4;
  color: var(--ink-3, var(--ink-4));
  margin-bottom: 18px;
}

/* Mock canvas: tool palette (left) + PDF sheet + overlaid markups. */
.fc-sr-mock {
  position: relative;
  min-height: 280px;
  margin-top: auto; /* push demo to the card bottom for uniform alignment */
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 10px 10px 44px; /* leave room for the left palette */
  background: var(--bg, var(--bg-card));
  overflow: hidden;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-sr-mock.is-active { opacity: 1; transform: translateY(0); }

/* Left tool palette */
.fc-sr-palette {
  position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 5px;
  padding: 5px; border-radius: 8px;
  background: var(--bg-card);
  border: 1px solid var(--line);
}
.fc-sr-tool {
  width: 24px; height: 24px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-4);
  transition: background 200ms var(--ease-out, ease), color 200ms var(--ease-out, ease), box-shadow 200ms var(--ease-out, ease);
}
.fc-sr-tool.is-selected {
  color: var(--indigo);
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent));
  box-shadow: inset 0 0 0 1.5px var(--indigo);
}

/* PDF sheet (synthetic floor plan) */
.fc-sr-sheet { display: block; width: 100%; height: auto; max-height: 230px; }
.fc-sr-sheet-edge { fill: var(--bg-card); stroke: var(--line); stroke-width: 1; }
.fc-sr-grid   { stroke: var(--line); stroke-width: 0.6; stroke-dasharray: 3 3; }
.fc-sr-bubble { fill: var(--bg-card); stroke: var(--ink-4); stroke-width: 0.8; }
.fc-sr-bubble-tx { fill: var(--ink-3, var(--ink-4)); font-size: 7px; font-weight: 700; text-anchor: middle; }
.fc-sr-wall   { stroke: var(--ink-3, var(--ink)); stroke-width: 1.6; fill: none; stroke-linejoin: round; }
.fc-sr-door   { stroke: var(--ink-4); stroke-width: 1; fill: none; }
.fc-sr-titleblock rect { fill: var(--bg-card); stroke: var(--ink-4); stroke-width: 0.8; }
.fc-sr-titleblock line { stroke: var(--ink-4); stroke-width: 0.6; }
.fc-sr-tb-tx  { fill: var(--ink-3, var(--ink-4)); font-size: 6.5px; font-weight: 600; }

/* Revision cloud — strokes itself on via dashoffset. */
.fc-sr-cloud {
  fill: none; stroke: #7C3AED; stroke-width: 1.6; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 800ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-sr-cloud.is-drawn { stroke-dashoffset: 0; }
.fc-sr-cloud.is-pulse { filter: drop-shadow(0 0 4px color-mix(in srgb, var(--indigo) 70%, transparent)); }

/* Callout leader line — draws toward its anchor. */
.fc-sr-leader {
  stroke: var(--bad); stroke-width: 1.2; stroke-linecap: round;
  stroke-dasharray: 60; stroke-dashoffset: 60;
  transition: stroke-dashoffset 350ms var(--ease-out, ease) 120ms;
}
.fc-sr-leader.is-in { stroke-dashoffset: 0; }

/* Callout pin — drops in with a small bounce. */
.fc-sr-pin {
  position: absolute; top: 32px; right: 38%;
  opacity: 0; transform: translateY(-10px) scale(0.6);
  pointer-events: none;
}
.fc-sr-pin.is-in { animation: fc-sr-drop 420ms var(--ease-out, cubic-bezier(0.34, 1.56, 0.64, 1)) forwards; }
@keyframes fc-sr-drop {
  0%   { opacity: 0; transform: translateY(-10px) scale(0.6); }
  60%  { opacity: 1; transform: translateY(2px)   scale(1.08); }
  100% { opacity: 1; transform: translateY(0)     scale(1); }
}

/* Comment thread — slides in from the right. */
.fc-sr-thread {
  position: absolute; right: 8px; bottom: 8px;
  width: 52%; max-width: 168px;
  display: flex; flex-direction: column; gap: 6px;
}
.fc-sr-comment {
  display: flex; gap: 6px; align-items: flex-start;
  opacity: 0; transform: translateX(16px);
  transition:
    opacity   320ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 320ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-sr-comment.is-in { opacity: 1; transform: translateX(0); }
.fc-sr-comment.is-reply { margin-left: 14px; }
.fc-sr-avatar {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 8px; font-weight: 700;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  color: var(--indigo);
}
.fc-sr-bubble-box {
  flex: 1; min-width: 0;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px; padding: 5px 7px;
}
.fc-sr-comment-head { display: flex; justify-content: space-between; align-items: baseline; gap: 4px; }
.fc-sr-comment-name { font-size: 9.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.fc-sr-comment-ago  { font-size: 8px; color: var(--ink-4); flex-shrink: 0; }
.fc-sr-comment-text { font-size: 10px; line-height: 1.3; color: var(--ink-2, var(--ink)); margin-top: 1px; }

/* AI Summary — Claude's read on the session. Springs up from below (bottom-left,
   left of the comment thread) as the finale, with a glow pulse + sparkle. */
.fc-sr-ai {
  position: absolute; left: 48px; right: 54%; bottom: 8px;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--indigo) 35%, var(--line));
  border-radius: 8px; padding: 7px 9px;
  opacity: 0; transform: translateY(14px) scale(0.96);
  transition:
    opacity   420ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 480ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.fc-sr-ai.is-in {
  opacity: 1; transform: translateY(0) scale(1);
  animation: fc-sr-ai-glow 1100ms var(--ease-out, ease) forwards;
}
@keyframes fc-sr-ai-glow {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--indigo) 45%, transparent); }
  40%  { box-shadow: 0 6px 22px color-mix(in srgb, var(--indigo) 38%, transparent),
                     0 0 0 2px color-mix(in srgb, var(--indigo) 40%, transparent); }
  100% { box-shadow: 0 6px 18px color-mix(in srgb, var(--indigo) 20%, transparent),
                     0 0 0 1px color-mix(in srgb, var(--indigo) 28%, transparent); }
}
.fc-sr-ai-head { display: flex; align-items: center; gap: 4px; margin-bottom: 3px; }
.fc-sr-ai-spark { color: var(--indigo); opacity: 0; flex-shrink: 0; }
.fc-sr-ai.is-in .fc-sr-ai-spark { animation: fc-sr-spark 900ms var(--ease-out, ease) 140ms forwards; }
@keyframes fc-sr-spark {
  0%   { opacity: 0; transform: scale(0.4) rotate(-30deg); }
  55%  { opacity: 1; transform: scale(1.25) rotate(8deg); }
  100% { opacity: 0.95; transform: scale(1) rotate(0deg); }
}
.fc-sr-ai-label {
  font-size: 8.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo);
}
.fc-sr-ai-text { font-size: 9.5px; line-height: 1.35; color: var(--ink-2, var(--ink)); }
.fc-sr-ai-text strong { font-weight: 700; color: var(--ink-1, var(--ink)); }

.fc-sr-no-anim .fc-sr-mock { opacity: 1; transform: none; transition: none; }
.fc-sr-no-anim .fc-sr-cloud { stroke-dashoffset: 0; transition: none; }
.fc-sr-no-anim .fc-sr-leader { stroke-dashoffset: 0; transition: none; }
.fc-sr-no-anim .fc-sr-pin { opacity: 1; transform: none; animation: none; }
.fc-sr-no-anim .fc-sr-comment { opacity: 1; transform: none; transition: none; }
.fc-sr-no-anim .fc-sr-ai {
  opacity: 1; transform: none; transition: none; animation: none;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--indigo) 18%, transparent);
}
.fc-sr-no-anim .fc-sr-ai-spark { opacity: 0.95; animation: none; }

@media (prefers-reduced-motion: reduce) {
  .fc-sr-mock { opacity: 1; transform: none; transition: none; }
  .fc-sr-cloud, .fc-sr-leader { stroke-dashoffset: 0; transition: none; }
  .fc-sr-pin { opacity: 1; transform: none; animation: none; }
  .fc-sr-comment { opacity: 1; transform: none; transition: none; }
  .fc-sr-ai {
    opacity: 1; transform: none; transition: none; animation: none;
    box-shadow: 0 6px 18px color-mix(in srgb, var(--indigo) 18%, transparent);
  }
  .fc-sr-ai-spark { opacity: 0.95; animation: none; }
}


/* ── Studio Review card v2 — expand affordance + thumbnail + lightbox modal ──────
   Stripe-style: the whole .fc-sr-card is a click target; an expand icon (two
   outward diagonal arrows) sits top-right; the thumbnail is a calm (animation-
   paused) mini of the real StudioReviewAnimation; clicking opens .fc-modal-root
   with the FULL animated demo over a dimmed + blurred backdrop. */
.fc-expand-btn {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  border-radius: 9px; color: var(--ink-3, var(--ink-4));
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  border: 1px solid var(--line);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.fc-sr-card:hover .fc-expand-btn, .fc-sr-card:focus-visible .fc-expand-btn {
  color: var(--indigo); background: var(--indigo-soft); border-color: var(--indigo-line);
}

/* thumbnail: faithful mini of the real demo, held near-static (calm preview) */
.fc-sr-thumb {
  position: relative;
  margin-top: auto;            /* bottom-align like the sibling cards' demos */
  aspect-ratio: 1050 / 1082;   /* ~square — matches the sibling cards' demo footprint */
  border-radius: 10px; overflow: hidden;
  border: 1px solid var(--line);
}
/* Crop the thumbnail to a ~square window of the canvas — plan + the orange "Verify
   hood clearance" markup + arrow — so it matches the sibling demos' proportions with
   no distortion or letterbox. The frame keeps the image's native 3420×1896 aspect
   (bg undistorted, SVG overlay aligned in lockstep); the square thumb just shows a
   sub-window of it via overflow:hidden + an oversized, absolutely-positioned shell.
   Crop ≈ image px (1700,250)-(2750,1332): width 3420/1050 = 325.71%,
   left -1700/1050 = -161.90%, top -250/1050 over the thumb height = -23.11%. */
.fc-sr-thumb .srd-shell {
  position: absolute; top: -23.11%; left: -161.90%;
  width: 325.71%; max-width: none; margin: 0;
}
.fc-sr-thumb .srd-frame { border-radius: 0; border: none; box-shadow: none; }
/* freeze the overlay on its final populated composition — no busy loop in the card */
.fc-sr-thumb .srd-cursor, .fc-sr-thumb .srd-mk-box, .fc-sr-thumb .srd-mk-arrow,
.fc-sr-thumb .srd-arrow-line, .fc-sr-thumb .srd-mk-row, .fc-sr-thumb .srd-mk-count {
  animation: none !important;
}

/* ── lightbox modal ── */
.fc-modal-root {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  padding: 5vh 4vw;
  opacity: 0; visibility: hidden;
  transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}
.fc-modal-root.is-open { opacity: 1; visibility: visible; transition: opacity 0.22s ease; }
.fc-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(10,10,14,0.58);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
}
.fc-modal-panel {
  position: relative; width: min(1100px, 92vw);
  transform: scale(0.965) translateY(10px);
  transition: transform 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}
.fc-modal-root.is-open .fc-modal-panel { transform: none; }
/* scrollable detail body: Stripe-style — header (title+CTA left, checklist right),
   demo band, then Intelligence icon grid. The close X lives on the non-scrolling
   panel so it stays accessible; Esc + backdrop close still work. */
.fc-modal-scroll {
  max-height: 90vh; overflow-y: auto; overflow-x: hidden;
  background: var(--bg-card); border-radius: 16px;
  box-shadow: 0 30px 90px rgba(0,0,0,0.5);
  -webkit-overflow-scrolling: touch;
}
.fc-modal-scroll:focus { outline: none; }
.fc-modal-panel .srd-shell { margin: 0; max-width: 100%; }
.fc-modal-panel .srd-frame { box-shadow: none; }
.fc-modal-panel .prd-shell { margin: 0; max-width: 100%; }
.fc-modal-panel .prd-frame { box-shadow: none; }

/* header: title + subtitle + CTA (left), benefit checklist (right) */
.fc-modal-head {
  display: grid; grid-template-columns: 1.55fr 1fr; gap: 32px; align-items: start;
  padding: clamp(26px, 3.2vw, 38px) clamp(20px, 3.5vw, 38px) 22px;
}
.fc-modal-title {
  font-size: clamp(24px, 3vw, 31px); font-weight: 700; letter-spacing: -0.02em;
  line-height: 1.1; color: var(--ink-1, var(--ink)); margin: 0 0 12px;
}
.fc-modal-subtitle {
  font-size: 15px; line-height: 1.6; color: var(--ink-3); margin: 0 0 20px; max-width: 560px;
}
.fc-modal-cta { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.fc-modal-cta-link { font-size: 13.5px; font-weight: 600; color: var(--indigo); text-decoration: none; }
.fc-modal-cta-link:hover { text-decoration: underline; }
.fc-modal-checks {
  list-style: none; margin: 0; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 13px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid var(--line); border-radius: 12px;
}
.fc-modal-check { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; line-height: 1.4; color: var(--ink-2, var(--ink)); }
.fc-modal-check-ic { flex: none; color: var(--indigo); margin-top: 1px; }

/* demo band (the existing animation, framed mid-modal) */
.fc-modal-demo { padding: 0 clamp(20px, 3.5vw, 38px) 8px; }
.fc-modal-demo .srd-shell { margin: 0; max-width: 100%; }
.fc-modal-demo .srd-frame { border-radius: 12px; border: 1px solid var(--line); box-shadow: 0 10px 30px rgba(0,0,0,0.12); }
.fc-modal-demo .prd-shell { margin: 0; max-width: 100%; }
.fc-modal-demo .prd-frame { border-radius: 12px; border: 1px solid var(--line); box-shadow: 0 10px 30px rgba(0,0,0,0.12); }

/* feature section — Intelligence icon grid */
.fc-modal-body { padding: 26px clamp(20px, 3.5vw, 38px) 36px; }
.fc-modal-sec-title {
  font-size: 12px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--indigo); margin: 0 0 18px;
}
.fc-modal-feat-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 22px 28px;
}
.fc-modal-feat { display: flex; gap: 13px; align-items: flex-start; }
.fc-modal-feat-ic {
  flex: none; width: 36px; height: 36px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center;
  color: var(--indigo); background: var(--indigo-soft); border: 1px solid var(--indigo-line);
}
.fc-modal-feat-txt { min-width: 0; }
.fc-modal-feat-label { font-size: 14.5px; font-weight: 650; color: var(--ink-1, var(--ink)); margin-bottom: 3px; }
.fc-modal-feat-desc { font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.fc-modal-close {
  position: absolute; top: -16px; right: -16px; z-index: 3;
  width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; background: rgba(28,28,34,0.92);
  border: 1px solid rgba(255,255,255,0.16); cursor: pointer;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  transition: background 0.15s;
}
.fc-modal-close:hover { background: rgba(48,48,56,0.96); }
@media (max-width: 768px) {
  .fc-modal-panel { width: 100vw; }
  .fc-modal-scroll { max-height: 92vh; border-radius: 12px; }
  .fc-modal-close { top: 8px; right: 8px; }
  .fc-modal-head { grid-template-columns: 1fr; gap: 20px; }
  .fc-modal-feat-grid { grid-template-columns: 1fr; gap: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .fc-modal-root, .fc-modal-panel { transition: none; }
  .fc-modal-panel { transform: none; }
}

/* ── Feature Card 4: Timesheets & Calendar (scroll-activated mini-demo) ────── */
.fc-ts-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px;
  display: flex; flex-direction: column;
}
.fc-ts-eyebrow {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo);
  margin-bottom: 10px;
}
.fc-ts-heading {
  font-size: 19px; font-weight: 650; line-height: 1.25;
  color: var(--ink-1, var(--ink));
  margin-bottom: 6px;
}
.fc-ts-subheading {
  font-size: 13px; line-height: 1.4;
  color: var(--ink-3, var(--ink-4));
  margin-bottom: 18px;
}

/* Mini weekly calendar */
.fc-ts-mock {
  position: relative;
  min-height: 280px;
  margin-top: auto; /* push demo to the card bottom for uniform alignment */
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  background: var(--bg, var(--bg-card));
  display: flex; flex-direction: column;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-ts-mock.is-active { opacity: 1; transform: translateY(0); }

.fc-ts-aipill {
  align-self: flex-end;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9.5px; font-weight: 700;
  padding: 3px 8px; margin-bottom: 8px;
  border-radius: 999px;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent));
  color: var(--indigo);
}

.fc-ts-head {
  display: grid; grid-template-columns: 26px repeat(5, 1fr); gap: 0;
  margin-bottom: 4px;
}
.fc-ts-corner { }
.fc-ts-day {
  font-size: 9px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-4); text-align: center;
}

.fc-ts-body { position: relative; flex: 1; display: grid; grid-template-columns: 26px 1fr; min-height: 200px; }
.fc-ts-hours { position: relative; }
.fc-ts-hour {
  position: absolute; left: 0; right: 4px;
  transform: translateY(-50%);
  font-size: 7.5px; color: var(--ink-4); text-align: right;
  font-variant-numeric: tabular-nums;
}
.fc-ts-cols { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); }

/* z-index discipline mirrors the real TimesheetsPage:
   gridline 0 · now-line 1 (pointer-events none) · block 2 */
.fc-ts-gridline {
  position: absolute; left: 0; right: 0; height: 1px;
  background: var(--line-soft, var(--line));
  z-index: 0;
}
.fc-ts-now {
  position: absolute; left: 0; right: 0; height: 2px;
  background: var(--bad); z-index: 1; pointer-events: none;
}
.fc-ts-now::before {
  content: ""; position: absolute; left: -2px; top: -2px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--bad);
}
.fc-ts-col { position: relative; border-left: 1px solid var(--line-soft, var(--line)); }
.fc-ts-col:first-child { border-left: none; }

.fc-ts-block {
  position: absolute; left: 2px; right: 2px; z-index: 2;
  border-radius: 4px; padding: 3px 5px; overflow: hidden;
  border: 1px solid transparent;
  font-size: 8.5px; line-height: 1.15;
}
.fc-ts-block-name { display: block; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fc-ts-block-desc { display: block; opacity: 0.8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* faint, italic external calendar events — fade in (staggered via inline delay) */
.fc-ts-block--external {
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  border-color: var(--line);
  color: var(--ink-3, var(--ink-4));
  font-style: italic;
  opacity: 0;
  transition: opacity 320ms var(--ease-out, ease);
}
.fc-ts-block--external.is-in { opacity: 1; }

/* new timesheet block — springs in from above with overshoot */
.fc-ts-block--new {
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent));
  border-color: var(--indigo);
  color: var(--indigo);
  opacity: 0; transform: translateY(-20px);
  transition:
    opacity   500ms var(--ease-out, ease),
    transform 500ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)),
    box-shadow 300ms var(--ease-out, ease);
}
.fc-ts-block--new.is-in { opacity: 1; transform: translateY(0); }
.fc-ts-block--new.is-pulse {
  box-shadow: 0 0 0 3px var(--indigo-soft, color-mix(in srgb, var(--indigo) 18%, transparent));
}

.fc-ts-no-anim .fc-ts-mock { opacity: 1; transform: none; transition: none; }
.fc-ts-no-anim .fc-ts-block--external { opacity: 1; transition: none; }
.fc-ts-no-anim .fc-ts-block--new { opacity: 1; transform: none; transition: none; }

@media (prefers-reduced-motion: reduce) {
  .fc-ts-mock { opacity: 1; transform: none; transition: none; }
  .fc-ts-block--external { opacity: 1; transition: none; }
  .fc-ts-block--new { opacity: 1; transform: none; transition: none; }
}

/* ── Feature Card 5: Financial Studio (scroll-activated mini-demo) ─────────── */
.fc-fin-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px;
  display: flex; flex-direction: column;
}
.fc-fin-eyebrow {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo);
  margin-bottom: 10px;
}
.fc-fin-heading {
  font-size: 19px; font-weight: 650; line-height: 1.25;
  color: var(--ink-1, var(--ink));
  margin-bottom: 6px;
}
.fc-fin-subheading {
  font-size: 13px; line-height: 1.4;
  color: var(--ink-3, var(--ink-4));
  margin-bottom: 18px;
}

.fc-fin-mock {
  min-height: 280px;
  margin-top: auto; /* push demo to the card bottom for uniform alignment */
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
  background: var(--bg, var(--bg-card));
  display: flex; flex-direction: column; gap: 14px;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-fin-mock.is-active { opacity: 1; transform: translateY(0); }

/* Invoice card */
.fc-fin-invoice {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 11px 12px;
  background: var(--bg-card);
  display: flex; flex-direction: column; gap: 10px;
}
.fc-fin-inv-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.fc-fin-inv-no { font-size: 11.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.fc-fin-inv-proj { font-size: 10px; color: var(--ink-4); margin-top: 1px; }
.fc-fin-inv-amt { font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink)); font-variant-numeric: tabular-nums; }
.fc-fin-inv-bottom { display: flex; align-items: center; gap: 8px; }

/* Status pill — Draft (neutral) → Sent (indigo, spring pop). No "Paid" state. */
.fc-fin-status {
  font-size: 10px; font-weight: 700;
  padding: 2px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink-3, var(--ink-4));
  transition:
    background 300ms var(--ease-out, ease),
    color 300ms var(--ease-out, ease),
    transform 300ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.fc-fin-status.is-sent {
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  color: var(--indigo);
  transform: scale(1.08);
}
.fc-fin-stripe {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9.5px; font-weight: 600;
  color: var(--indigo);
}

/* Fee burn */
.fc-fin-fee-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.fc-fin-fee-label { font-size: 10.5px; font-weight: 600; color: var(--ink-2, var(--ink)); }
.fc-fin-fee-val { font-size: 10px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.fc-fin-fee-track { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.fc-fin-fee-bar {
  height: 100%; border-radius: 3px; width: 0;
  background: var(--indigo);
  transition: width 600ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

/* P&L sparkline */
.fc-fin-pnl { margin-top: auto; }
.fc-fin-pnl-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-4); margin-bottom: 6px; }
.fc-fin-pnl-bars { display: flex; align-items: flex-end; gap: 6px; height: 40px; }
.fc-fin-pnl-bar {
  flex: 1; border-radius: 3px 3px 0 0;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 30%, transparent));
  transform: scaleY(0); transform-origin: bottom;
  transition: transform 320ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-fin-pnl-bar:last-child { background: var(--indigo); }
.fc-fin-pnl-bar.is-in { transform: scaleY(1); }

.fc-fin-no-anim .fc-fin-mock { opacity: 1; transform: none; transition: none; }
.fc-fin-no-anim .fc-fin-status { transition: none; }
.fc-fin-no-anim .fc-fin-fee-bar { transition: none; }
.fc-fin-no-anim .fc-fin-pnl-bar { transform: scaleY(1); transition: none; }

@media (prefers-reduced-motion: reduce) {
  .fc-fin-mock { opacity: 1; transform: none; transition: none; }
  .fc-fin-status, .fc-fin-fee-bar { transition: none; }
  .fc-fin-pnl-bar { transform: scaleY(1); transition: none; }
}

/* ── Feature Card 6: Multi-office (scroll-activated mini-demo) ─────────────── */
.fc-mo-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px;
  display: flex; flex-direction: column;
}
.fc-mo-eyebrow {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo);
  margin-bottom: 10px;
}
.fc-mo-heading {
  font-size: 19px; font-weight: 650; line-height: 1.25;
  color: var(--ink-1, var(--ink));
  margin-bottom: 6px;
}
.fc-mo-subheading {
  font-size: 13px; line-height: 1.4;
  color: var(--ink-3, var(--ink-4));
  margin-bottom: 18px;
}

.fc-mo-mock {
  min-height: 280px;
  margin-top: auto; /* push demo to the card bottom for uniform alignment */
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 16px 14px;
  background: var(--bg, var(--bg-card));
  display: flex; flex-direction: column; justify-content: center; gap: 20px;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity   400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 400ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-mo-mock.is-active { opacity: 1; transform: translateY(0); }

/* Two office cards + center connector */
.fc-mo-offices { display: flex; align-items: center; gap: 6px; }
.fc-mo-office {
  flex: 1; min-width: 0;
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 10px;
  background: var(--bg-card);
  display: flex; flex-direction: column; gap: 7px;
  opacity: 0;
  transition:
    opacity   500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-mo-office--left  { transform: translateX(-20px); }
.fc-mo-office--right { transform: translateX(20px); }
.fc-mo-mock.is-active .fc-mo-office { opacity: 1; transform: translateX(0); }
.fc-mo-office-head { display: flex; align-items: center; gap: 5px; color: var(--indigo); }
.fc-mo-city { font-size: 11px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.fc-mo-clock {
  font-size: 13px; font-weight: 700; color: var(--ink-2, var(--ink));
  font-variant-numeric: tabular-nums;
  transition: transform 300ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)), color 300ms ease;
}
.fc-mo-clock.is-pulse { transform: scale(1.12); color: var(--indigo); }
.fc-mo-avatars { display: inline-flex; }
.fc-mo-avatar {
  width: 18px; height: 18px; border-radius: 50%; margin-left: -5px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 8px; font-weight: 700;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  color: var(--indigo);
  border: 1.5px solid var(--bg-card);
}
.fc-mo-avatar:first-child { margin-left: 0; }

/* Center connector: drawing line + shared-project pill */
.fc-mo-connector {
  position: relative; flex-shrink: 0; width: 60px; height: 40px;
  display: flex; align-items: center; justify-content: center;
}
.fc-mo-line-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.fc-mo-line {
  stroke: var(--indigo); stroke-width: 1.4; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 600ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fc-mo-line.is-in { stroke-dashoffset: 0; }
.fc-mo-node { fill: var(--indigo); }
.fc-mo-shared {
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%) scale(0.8);
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 8.5px; font-weight: 700;
  padding: 2px 7px; border-radius: 999px;
  background: var(--bg-card);
  border: 1px solid var(--indigo);
  color: var(--indigo);
  opacity: 0;
  transition: opacity 300ms var(--ease-out, ease), transform 300ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.fc-mo-shared.is-in { opacity: 1; transform: translateX(-50%) scale(1); }
.fc-mo-shared-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--indigo); }

/* Role-based access hierarchy */
.fc-mo-roles { display: flex; flex-direction: column; gap: 7px; }
.fc-mo-roles-label { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-4); }
.fc-mo-role-badges { display: flex; flex-wrap: wrap; gap: 5px; }
.fc-mo-role {
  font-size: 9.5px; font-weight: 600;
  padding: 3px 8px; border-radius: 6px;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 10%, transparent));
  color: var(--indigo);
  opacity: 0; transform: translateY(6px);
  transition:
    opacity   300ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 300ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
/* hierarchy weight: first badge (Principal) reads as the strongest */
.fc-mo-role:first-child { background: var(--indigo); color: #fff; }
.fc-mo-role.is-in { opacity: 1; transform: translateY(0); }

.fc-mo-no-anim .fc-mo-mock { opacity: 1; transform: none; transition: none; }
.fc-mo-no-anim .fc-mo-office { opacity: 1; transform: none; transition: none; }
.fc-mo-no-anim .fc-mo-line { stroke-dashoffset: 0; transition: none; }
.fc-mo-no-anim .fc-mo-shared { opacity: 1; transform: translateX(-50%); transition: none; }
.fc-mo-no-anim .fc-mo-role { opacity: 1; transform: none; transition: none; }

@media (prefers-reduced-motion: reduce) {
  .fc-mo-mock, .fc-mo-office { opacity: 1; transform: none; transition: none; }
  .fc-mo-line { stroke-dashoffset: 0; transition: none; }
  .fc-mo-shared { opacity: 1; transform: translateX(-50%); transition: none; }
  .fc-mo-role { opacity: 1; transform: none; transition: none; }
}

/* ── RiversideReportDemo — fullscreen variant (/#demo:riverside-report) ────── */
.fc-rr-fullscreen {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; flex-direction: column;
  background:
    radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--indigo) 10%, transparent), transparent 60%),
    var(--bg, #fff);
  padding: 18px clamp(16px, 4vw, 56px) 24px;
  animation: fc-rr-fade 280ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) both;
}
@keyframes fc-rr-fade { from { opacity: 0; } to { opacity: 1; } }

.fc-rr-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-shrink: 0; margin-bottom: 10px;
}
.fc-rr-back {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600;
  padding: 7px 14px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg-card);
  color: var(--ink-1, var(--ink)); cursor: pointer;
  transition: border-color 150ms var(--ease-out, ease), background 150ms var(--ease-out, ease);
}
.fc-rr-back:hover { border-color: var(--indigo); }
.fc-rr-hint { font-size: 12px; color: var(--ink-4); }
.fc-rr-hint kbd {
  font: inherit; font-size: 11px;
  padding: 1px 6px; border-radius: 4px;
  border: 1px solid var(--line); background: var(--bg-card);
  color: var(--ink-3, var(--ink-4));
}

/* Stage gives the absolutely-positioned .hcc-wrap a sized, centered box. */
.fc-rr-stage { position: relative; flex: 1; min-height: 0; }
.fc-rr-stage .hcc-wrap {
  position: absolute; inset: 0; width: 100%;
  justify-content: center; pointer-events: none;
}
.fc-rr-stage .hcc-wrap::after { display: none; } /* drop the hero edge-fade mask */
.fc-rr-stage .hcc-frame {
  margin: 0 auto;
  width: min(94%, 1180px); height: min(88%, 760px);
}

.fc-rr-controls {
  display: flex; justify-content: center; gap: 10px;
  flex-shrink: 0; margin-top: 14px;
}
.fc-rr-ctrl {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600;
  padding: 8px 18px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-card);
  color: var(--ink-1, var(--ink)); cursor: pointer;
  transition: border-color 150ms var(--ease-out, ease), color 150ms var(--ease-out, ease), background 150ms var(--ease-out, ease);
}
.fc-rr-ctrl:hover { border-color: var(--indigo); color: var(--indigo); }

@media (prefers-reduced-motion: reduce) {
  .fc-rr-fullscreen { animation: none; }
}

/* ── Proof Strip (quantified value, below the hero) ─────────────────────────── */
.ls-proof {
  background: var(--bg-card);
  border-top: 1px solid var(--line);
  padding: 96px 0;
}
.ls-proof-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 36px; align-items: start;
}
.ls-proof-col {
  text-align: center;
  opacity: 0; transform: translateY(16px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-proof-grid.is-on .ls-proof-col { opacity: 1; transform: translateY(0); }
.ls-proof-num {
  font-family: var(--f-sans);
  font-size: clamp(56px, 7vw, 88px); font-weight: 600;
  line-height: 1; letter-spacing: -0.04em;
  color: var(--indigo);
  font-feature-settings: "lnum", "tnum";
}
.ls-proof-ctx {
  font-size: 14.5px; line-height: 1.5; color: var(--ink-3);
  max-width: 30ch; margin: 14px auto 0;
}
.ls-proof-foot {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 8px 16px; margin-top: 52px;
  padding-top: 28px; border-top: 1px solid var(--line);
  opacity: 0; transform: translateY(12px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-proof-foot.is-on { opacity: 1; transform: translateY(0); }
.ls-proof-note {
  font-size: 13px; line-height: 1.5; color: var(--ink-4);
  text-align: center; letter-spacing: 0.01em;
}
.ls-proof-demo {
  font-size: 13px; font-weight: 600; color: var(--indigo);
  text-decoration: none; white-space: nowrap;
  transition: opacity 150ms var(--ease-out, ease);
}
.ls-proof-demo:hover { opacity: 0.75; text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
  .ls-proof-col, .ls-proof-foot { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 768px) {
  .ls-proof { padding: 56px 0; }
  .ls-proof-grid { grid-template-columns: 1fr; gap: 28px; }
  .ls-proof-num { font-size: 48px; }
  .ls-proof-foot { margin-top: 36px; flex-direction: column; }
}

/* ── How firms use Aecos (illustrative workflow cards) ──────────────────────── */
.ls-wf { background: var(--bg-card); }
.ls-wf-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 20px; margin-top: 44px;
}
.ls-wf-card {
  display: flex; flex-direction: column;
  background: var(--bg, var(--bg-card));
  border: 1px solid var(--line); border-radius: 14px;
  padding: 24px;
  opacity: 0; transform: translateY(18px);
  transition:
    opacity 520ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 520ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-wf-grid.is-on .ls-wf-card { opacity: 1; transform: translateY(0); }
.ls-wf-icon {
  width: 42px; height: 42px; border-radius: 11px; margin-bottom: 14px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  color: var(--indigo);
}
.ls-wf-icon svg { width: 22px; height: 22px; }
.ls-wf-role {
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 8px;
}
.ls-wf-desc {
  margin: 0 0 18px; flex: 1 1 auto;
  font-size: 14.5px; line-height: 1.6; color: var(--ink-2, var(--ink));
}
.ls-wf-outcomes {
  list-style: none; margin: 0; padding: 16px 0 0;
  border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px;
}
.ls-wf-outcome {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13px; line-height: 1.4; color: var(--ink-3);
}
.ls-wf-outcome svg { flex-shrink: 0; margin-top: 1px; color: var(--indigo); }

@media (prefers-reduced-motion: reduce) {
  .ls-wf-card { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 768px) {
  .ls-wf-grid { grid-template-columns: 1fr; gap: 16px; margin-top: 32px; }
}

/* ── Tailored Solutions pages (#solutions/<type>) ─────────────────────────── */
.sol-pains-grid, .sol-map-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin-top: 30px; text-align: left; }
.sol-pain, .sol-map {
  border: 1px solid var(--line); border-radius: 14px; padding: 20px 22px;
  background: var(--bg-card);
}
.sol-pain-t { font-size: 15.5px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.sol-pain-d { font-size: 14px; line-height: 1.55; color: var(--ink-3); margin: 0; }
.sol-map-cap { font-size: 11.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--indigo); margin-bottom: 9px; }
.sol-map-why { font-size: 15.5px; font-weight: 600; line-height: 1.42; color: var(--ink); margin: 0 0 8px; }
.sol-map-pain { font-size: 13.5px; line-height: 1.5; color: var(--ink-4); margin: 0; }
.sol-pos { max-width: 780px; margin: 22px auto 0; text-align: center; }
.sol-pos-line { font-size: 17px; line-height: 1.6; color: var(--ink-2); margin: 0; }
.sol-pos-points { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 28px; text-align: left; }
.sol-pos-point { border: 1px solid var(--line); border-radius: 12px; padding: 15px 17px; background: var(--bg-card); }
.sol-pos-name { font-size: 13px; font-weight: 700; color: var(--ink); margin-bottom: 5px; }
.sol-pos-pt-line { font-size: 13.5px; line-height: 1.5; color: var(--ink-3); margin: 0; }
.sol-index-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 34px; text-align: left; }
.sol-index-card {
  border: 1px solid var(--line); border-radius: 16px; padding: 26px 28px;
  background: var(--bg-card); text-decoration: none; display: block;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.sol-index-card:hover { border-color: var(--indigo); transform: translateY(-2px); box-shadow: 0 10px 30px -16px rgba(20, 22, 50, 0.22); }
.sol-index-card-label { font-size: 18px; font-weight: 600; color: var(--ink); margin-bottom: 8px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sol-index-card-label svg { color: var(--indigo); flex-shrink: 0; }
.sol-index-card-desc { font-size: 14px; line-height: 1.55; color: var(--ink-3); margin: 0; }
.sol-other { margin-top: 28px; display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; justify-content: center; }
.sol-other-label { font-size: 13.5px; color: var(--ink-4); }
@media (max-width: 768px) {
  .sol-pains-grid, .sol-map-grid, .sol-pos-points, .sol-index-grid { grid-template-columns: 1fr; }
}

/* ── How Aecos compares (honest competitor table) ───────────────────────────── */
.ls-vs-wrap {
  margin-top: 44px;
  opacity: 0; transform: translateY(18px);
  transition:
    opacity 520ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 520ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-vs-wrap.is-on { opacity: 1; transform: translateY(0); }
.ls-vs-table {
  width: 100%; border-collapse: collapse; table-layout: fixed;
}
.ls-vs-table th, .ls-vs-table td {
  text-align: left; vertical-align: top;
  padding: 13px 14px;
  border-top: 1px solid var(--line);
  font-size: 13px; line-height: 1.4;
}
/* Header row */
.ls-vs-table thead th { border-top: none; }
.ls-vs-corner { width: 16%; }
.ls-vs-ph {
  font-size: 14px; font-weight: 700; color: var(--ink-1, var(--ink));
}
.ls-vs-ph-aecos {
  color: var(--indigo);
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  border-radius: 10px 10px 0 0;
}
/* Row labels */
.ls-vs-rowlabel {
  font-weight: 600; color: var(--ink-2, var(--ink));
  font-size: 12.5px;
}
/* Cells */
.ls-vs-cell { color: var(--ink-3); }
.ls-vs-cell-aecos {
  color: var(--ink-1, var(--ink)); font-weight: 500;
  background: color-mix(in srgb, var(--indigo) 7%, transparent);
}
.ls-vs-table tbody tr:last-child .ls-vs-cell-aecos { border-radius: 0 0 10px 10px; }
/* Row hover highlight — skips the Aecos column so its indigo tint stays distinct. */
.ls-vs-table tbody tr { transition: background 120ms var(--ease-out, ease); }
.ls-vs-table tbody tr:hover .ls-vs-rowlabel,
.ls-vs-table tbody tr:hover .ls-vs-cell:not(.ls-vs-cell-aecos) {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}
.ls-vs-table tbody tr:hover .ls-vs-cell-aecos {
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
}
/* Color-coded marks: green = best on that row, gray = does it too / weaker. */
.ls-vs-mk {
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: -2px; margin-right: 6px;
  width: 16px; height: 16px; border-radius: 5px; flex: none;
}
.ls-vs-mk-win { color: #16a34a; background: color-mix(in srgb, #16a34a 13%, transparent); }
.ls-vs-mk-has { color: var(--ink-4, #9aa0aa); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.ls-vs-mk-no  { color: var(--ink-5, #b6bac1); background: transparent; }

.ls-vs-cta { text-align: center; margin-top: 32px; }
.ls-vs-disclaimer { font-size: 12px; color: var(--ink-5); margin: 14px 0 0; }

@media (prefers-reduced-motion: reduce) {
  .ls-vs-wrap { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 768px) {
  /* Dense 5-column table — let it scroll horizontally rather than crush. */
  .ls-vs-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-left: -20px; margin-right: -20px; padding: 0 20px; }
  .ls-vs-table { min-width: 840px; }
  .ls-vs-table th, .ls-vs-table td { padding: 11px 12px; font-size: 12.5px; }
}

/* ── Security / trust page (/#security) ─────────────────────────────────────── */
.secpage-hero { border-top: none; padding-bottom: 24px; text-align: center; }
.secpage-headline { margin-bottom: 18px; }
.secpage-sub { max-width: 60ch; margin: 0 auto; }
.secpage-body { border-top: none; padding-top: 16px; }
.secpage-blocks { max-width: 860px; margin: 0 auto; }
.secpage-block {
  display: grid; grid-template-columns: 230px 1fr; gap: 32px;
  padding: 28px 0; border-top: 1px solid var(--line);
  opacity: 0; transform: translateY(14px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.secpage-blocks.is-on .secpage-block { opacity: 1; transform: none; }
.secpage-block-title {
  font-size: 16px; font-weight: 700; color: var(--ink-1, var(--ink));
  letter-spacing: -0.01em; margin: 0;
}
.secpage-block-body { font-size: 14.5px; line-height: 1.65; color: var(--ink-3); }
.secpage-block-body p { margin: 0 0 10px; }
.secpage-block-body p:last-child { margin-bottom: 0; }
.secpage-block-body strong { color: var(--ink-2, var(--ink)); font-weight: 600; }
.secpage-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
.secpage-list li { line-height: 1.5; }
.secpage-badges { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.secpage-badge {
  font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line);
}
.secpage-badge-progress {
  color: var(--indigo);
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent));
  border-color: color-mix(in srgb, var(--indigo) 30%, transparent);
}
.secpage-badge-no { color: var(--ink-4); background: var(--bg-sunk, var(--bg-elev)); }
.secpage-fine { font-size: 12.5px; color: var(--ink-5); margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .secpage-block { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 768px) {
  .secpage-block { grid-template-columns: 1fr; gap: 8px; padding: 22px 0; }
}

/* ── Changelog page (/#changelog) ───────────────────────────────────────────── */
.clog-filters { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 26px; }
.clog-chip {
  font-size: 13px; font-weight: 600; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-3);
  cursor: pointer; transition: background 150ms var(--ease-out, ease), color 150ms var(--ease-out, ease), border-color 150ms var(--ease-out, ease);
}
.clog-chip:hover { color: var(--ink); border-color: var(--ink-4); }
.clog-chip.is-active { background: var(--indigo); color: #fff; border-color: var(--indigo); }
/* Latest deploys strip — raw commit subjects, auto-updated on deploy. */
.clog-latest {
  max-width: 760px; margin: 0 auto 36px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px;
  padding: 18px 20px;
}
.clog-latest-head {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 12px; margin-bottom: 6px; border-bottom: 1px solid var(--line);
}
.clog-latest-head svg { color: var(--indigo); flex-shrink: 0; }
.clog-latest-title { font-size: 12.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.clog-latest-note { font-size: 11.5px; color: var(--ink-4); margin-left: auto; }
.clog-latest-list { list-style: none; padding: 0; margin: 0; }
.clog-latest-item {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 0; font-size: 13px; line-height: 1.45; color: var(--ink-2, var(--ink));
}
.clog-latest-dot {
  flex-shrink: 0; width: 5px; height: 5px; border-radius: 50%;
  background: var(--indigo); transform: translateY(-1px);
}
.clog-latest-text { font-family: var(--f-mono, ui-monospace, monospace); font-size: 12.5px; color: var(--ink-2, var(--ink)); }
@media (max-width: 768px) {
  .clog-latest-note { display: none; }
}
.clog-wrap { max-width: 760px; margin: 0 auto; }
.clog-group { margin-bottom: 36px; }
.clog-group-head {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-4); margin-bottom: 14px;
}
.clog-entry {
  display: grid; grid-template-columns: 124px 1fr auto; gap: 16px; align-items: start;
  padding: 16px 0; border-top: 1px solid var(--line);
}
.clog-badge {
  justify-self: start; font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  border: 1px solid transparent;
}
.clog-badge-feature  { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); }
.clog-badge-polish   { color: var(--ink-3); background: var(--bg-sunk, var(--bg-elev)); border-color: var(--line); }
.clog-badge-security { color: var(--warn, #9a6b00); background: color-mix(in srgb, var(--warn, #c98a00) 14%, transparent); }
.clog-main { min-width: 0; }
.clog-title { font-size: 14.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.clog-desc { font-size: 13px; line-height: 1.5; color: var(--ink-3); margin-top: 2px; }
.clog-date {
  font-size: 12px; font-weight: 600; color: var(--ink-4); white-space: nowrap;
  padding: 3px 9px; border-radius: 6px; background: var(--bg-sunk, var(--bg-elev));
}
.clog-empty { text-align: center; color: var(--ink-4); padding: 32px 0; }
.clog-subscribe {
  max-width: 760px; margin: 16px auto 0; padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 12px;
  font-size: 14px; color: var(--ink-3); text-align: center;
}

@media (max-width: 768px) {
  .clog-entry { grid-template-columns: 1fr auto; gap: 4px 12px; }
  .clog-badge { grid-row: 1; grid-column: 1; }
  .clog-date  { grid-row: 1; grid-column: 2; justify-self: end; }
  .clog-main  { grid-row: 2; grid-column: 1 / -1; }
}

/* ── Integrations page (/#integrations) ─────────────────────────────────────── */
.intg-section-head {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-3); margin: 8px 0 18px;
}
.intg-section-head-soon { color: var(--ink-4); margin-top: 44px; }
.intg-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
}
.intg-grid-soon { grid-template-columns: repeat(4, 1fr); }
.intg-card {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px; padding: 18px;
  background: var(--bg, var(--bg-card));
  opacity: 0; transform: translateY(16px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.intg-grid.is-on .intg-card { opacity: 1; transform: translateY(0); }
.intg-grid-soon .intg-card { opacity: 1; transform: none; transition: none; } /* soon grid is static */
.intg-card-soon { background: var(--bg-card); }
.intg-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.intg-logo {
  width: 38px; height: 38px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent));
  color: var(--indigo);
}
.intg-logo-soon { background: var(--bg-sunk, var(--bg-elev)); color: var(--ink-4); }
.intg-name { font-size: 14.5px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 4px; }
.intg-blurb { font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.intg-badge {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.intg-badge-live { color: var(--ok, #1a7f4b); background: color-mix(in srgb, var(--ok, #1a7f4b) 14%, transparent); }
.intg-badge-beta { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.intg-badge-soon { color: var(--ink-4); background: var(--bg-sunk, var(--bg-elev)); border: 1px solid var(--line); }
.intg-badge-sandbox { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.intg-badge-setup { color: var(--ink-3, var(--ink-4)); background: var(--bg-sunk, var(--bg-elev)); border: 1px solid var(--line); }
.intg-request {
  margin-top: 24px; display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 6px 12px; text-align: center;
  font-size: 14px; color: var(--ink-3);
}
.intg-request-link { font-size: 14px; font-weight: 600; color: var(--indigo); text-decoration: none; white-space: nowrap; }
.intg-request-link:hover { text-decoration: underline; }
.intg-byo {
  margin-top: 44px; padding: 24px; border-radius: 14px;
  border: 1px dashed color-mix(in srgb, var(--indigo) 32%, var(--line));
  background: color-mix(in srgb, var(--indigo) 5%, transparent);
  text-align: center;
}
.intg-byo-title { font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 6px; }
.intg-byo-body { font-size: 14px; line-height: 1.6; color: var(--ink-3); margin: 0; max-width: 60ch; margin: 0 auto; }

@media (prefers-reduced-motion: reduce) {
  .intg-card { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 900px) { .intg-grid-soon { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) {
  .intg-grid, .intg-grid-soon { grid-template-columns: 1fr; }
}

/* ── Latest from Aecos — homepage news row (Anthropic-style cards) ────────────
   Same visual language as the rest of the landing: var(--line) border, --bg
   card surface, --indigo eyebrow/CTA, --ink-* type scale, --ease-out motion.
   Subtle hover-lift + border highlight; the whole card is a clickable <a>. */
.news-row {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
  margin-top: 32px; text-align: left;
}
.news-card {
  display: flex; flex-direction: column; gap: 10px;
  border: 1px solid var(--line); border-radius: 16px;
  padding: 22px 22px 20px;
  background: var(--bg, var(--bg-card));
  text-decoration: none; color: inherit;
  transition:
    transform 240ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 240ms ease,
    box-shadow 240ms ease;
}
.news-card:hover {
  transform: translateY(-3px);
  border-color: var(--indigo);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.10);
}
.news-card-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo);
}
.news-card-title {
  font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ink-1, var(--ink));
}
.news-card-desc {
  font-size: 13.5px; line-height: 1.55; color: var(--ink-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.news-card-foot {
  margin-top: auto; padding-top: 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  font-size: 12px; color: var(--ink-4);
}
.news-card-cta {
  color: var(--indigo); font-weight: 600;
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
}
@media (max-width: 860px) { .news-row { grid-template-columns: 1fr; } }

/* ── Learn surface (/#learn hub + /#learn:slug article) ──────────────────────
   Owned by the aecos-learn minion. Scoped under .learn-* (plus the article-only
   .learn-md-* typography). Reuses the secpage hero/body shell from landing. */

/* Category filter chips (mirror .clog-chip) */
.learn-cat-filters { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 28px; }
.learn-chip {
  font-size: 13px; font-weight: 600; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-3);
  cursor: pointer;
  transition: background 150ms var(--ease-out, ease), color 150ms var(--ease-out, ease), border-color 150ms var(--ease-out, ease);
}
.learn-chip:hover { color: var(--ink); border-color: var(--ink-4); }
.learn-chip.is-active { background: var(--indigo); color: #fff; border-color: var(--indigo); }

/* Category groups on the hub */
.learn-group { margin-bottom: 56px; }
.learn-group:last-of-type { margin-bottom: 24px; }
.learn-group-head { margin-bottom: 20px; }
.learn-group-title { font-size: 22px; font-weight: 700; color: var(--ink); margin: 0 0 4px; letter-spacing: -0.01em; }
.learn-group-blurb { font-size: 14.5px; line-height: 1.5; color: var(--ink-3); margin: 0; }

/* Article cards */
.learn-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.learn-card {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px; padding: 20px;
  background: var(--bg, var(--bg-card)); text-decoration: none;
  transition: border-color 180ms var(--ease-out, ease), transform 180ms var(--ease-out, ease), box-shadow 180ms var(--ease-out, ease);
}
.learn-card:hover { border-color: var(--ink-4); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.learn-card-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.learn-card-read { font-size: 12px; font-weight: 600; color: var(--ink-4); }
.learn-card-title { font-size: 16px; font-weight: 700; line-height: 1.35; color: var(--ink-1, var(--ink)); margin-bottom: 8px; letter-spacing: -0.01em; }
.learn-card-summary { font-size: 13.5px; line-height: 1.55; color: var(--ink-3); flex: 1; }
.learn-card-cta { font-size: 13px; font-weight: 600; color: var(--indigo); margin-top: 16px; }

/* Kind badge (Guide / Tutorial) */
.learn-kind {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.learn-kind-guide { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.learn-kind-tutorial { color: var(--ok, #1a7f4b); background: color-mix(in srgb, var(--ok, #1a7f4b) 14%, transparent); }

/* Hub help footer */
.learn-empty { text-align: center; color: var(--ink-4); font-size: 15px; padding: 48px 0; }
.learn-help { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; margin-top: 12px; text-align: center; }
.learn-help-text { font-size: 14.5px; color: var(--ink-3); }
.learn-help-link { font-size: 14.5px; font-weight: 600; color: var(--indigo); text-decoration: none; }
.learn-help-link:hover { text-decoration: underline; }

/* ── Article reader ── */
.learn-article-section { border-top: none; padding-top: 12px; }
.learn-article-container { max-width: 760px; }
.learn-breadcrumb { display: flex; align-items: center; gap: 8px; font-size: 13px; margin-bottom: 20px; }
.learn-breadcrumb-link { color: var(--ink-4); text-decoration: none; font-weight: 600; }
.learn-breadcrumb-link:hover { color: var(--indigo); }
.learn-breadcrumb-sep { color: var(--ink-4); }
.learn-article-head { margin-bottom: 32px; padding-bottom: 28px; border-bottom: 1px solid var(--line); }
.learn-article-meta { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.learn-article-read { font-size: 12.5px; font-weight: 600; color: var(--ink-4); }
.learn-article-title { font-size: clamp(28px, 4vw, 40px); font-weight: 800; line-height: 1.15; letter-spacing: -0.02em; color: var(--ink); margin: 0 0 16px; }
.learn-article-lede { font-size: 18px; line-height: 1.55; color: var(--ink-3); margin: 0; }

/* Article body typography (.learn-md-*) */
.learn-md { font-size: 16.5px; line-height: 1.7; color: var(--ink-2); }
.learn-md-p { margin: 0 0 20px; }
.learn-md-h2 { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); margin: 40px 0 16px; }
.learn-md-h3 { font-size: 18.5px; font-weight: 700; color: var(--ink); margin: 30px 0 12px; }
.learn-md-ul, .learn-md-ol { margin: 0 0 20px; padding-left: 24px; }
.learn-md-li { margin-bottom: 9px; line-height: 1.6; }
.learn-md-ul { list-style: disc; }
.learn-md-ol { list-style: decimal; }
.learn-md-li-check { list-style: none; position: relative; padding-left: 28px; }
.learn-md-li-check::before {
  content: ""; position: absolute; left: 0; top: 2px; width: 16px; height: 16px;
  border: 1.5px solid var(--ink-4); border-radius: 4px;
}
.learn-md-link { color: var(--indigo); text-decoration: none; font-weight: 500; }
.learn-md-link:hover { text-decoration: underline; }
.learn-md-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.88em;
  padding: 2px 6px; border-radius: 5px;
  background: var(--bg-sunk, var(--bg-elev)); color: var(--ink-1, var(--ink)); border: 1px solid var(--line);
}
.learn-md-hr { border: none; border-top: 1px solid var(--line); margin: 36px 0; }
.learn-md-callout {
  margin: 0 0 24px; padding: 16px 20px; border-radius: 12px;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 9%, transparent));
  border: 1px solid color-mix(in srgb, var(--indigo) 28%, transparent);
  border-left: 3px solid var(--indigo);
}
.learn-md-callout-p { margin: 0 0 10px; font-size: 15.5px; line-height: 1.6; color: var(--ink-2); }
.learn-md-callout-p:last-child { margin-bottom: 0; }
.learn-md-table-wrap { overflow-x: auto; margin: 0 0 24px; }
.learn-md-table { width: 100%; border-collapse: collapse; font-size: 15px; }
.learn-md-th { text-align: left; font-weight: 700; color: var(--ink); padding: 10px 14px; border-bottom: 2px solid var(--line); background: var(--bg-sunk, var(--bg-elev)); }
.learn-md-td { padding: 10px 14px; border-bottom: 1px solid var(--line); color: var(--ink-2); }

/* Article footer + related */
.learn-article-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px;
  margin-top: 44px; padding-top: 28px; border-top: 1px solid var(--line);
}
.learn-article-back { font-size: 14.5px; font-weight: 600; color: var(--ink-3); text-decoration: none; }
.learn-article-back:hover { color: var(--indigo); }
.learn-article-cta { font-size: 14px; padding: 9px 20px; }
.learn-related { margin-top: 48px; }
.learn-related-head { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-4); margin-bottom: 18px; }

@media (max-width: 900px) { .learn-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) {
  .learn-grid { grid-template-columns: 1fr; }
  .learn-article-title { font-size: clamp(24px, 7vw, 32px); }
  .learn-article-lede { font-size: 16px; }
  .learn-md { font-size: 16px; }
  .learn-md-h2 { font-size: 21px; }
}

/* ── About page (/#about) ───────────────────────────────────────────────────── */
/* About hero — balanced headline + tidy sub, scoped to #about-top so the shared
   secpage-* hero on other pages (security, integrations) is left untouched. */
#about-top .secpage-headline { text-wrap: balance; }
#about-top .secpage-sub { text-wrap: pretty; }
.about-section-eyebrow {
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--indigo); margin-bottom: 14px;
}
/* One consistent content column + even vertical rhythm for the whole About body,
   so every section's left edge and eyebrows line up. */
.about-col { max-width: 760px; margin: 0 auto; }
.about-col > * + * { margin-top: 48px; }
.about-founder {
  display: grid; grid-template-columns: auto 1fr; gap: 28px; align-items: start;
  padding-bottom: 36px; border-bottom: 1px solid var(--line);
}
.about-avatar {
  width: 84px; height: 84px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 26px; font-weight: 700; letter-spacing: 0.02em;
  background: var(--indigo); color: #fff;
  object-fit: cover; /* when rendered as <img> (founder photo), fill the circle */
}
.about-founder-copy { min-width: 0; }
.about-founder-name { font-size: 19px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.about-founder-role { font-size: 13px; color: var(--ink-4); margin-bottom: 12px; }
.about-founder-copy p { font-size: 14.5px; line-height: 1.65; color: var(--ink-3); margin: 0; max-width: 60ch; text-wrap: pretty; }
.about-founder-link { color: var(--ink-1, var(--ink)); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.about-founder-link:hover { color: var(--accent, var(--ink-1)); }
.about-quote {
  margin: 16px 0 0; padding: 12px 18px;
  border-left: 3px solid var(--indigo);
  font-size: 16px; font-style: italic; line-height: 1.5; color: var(--ink-2, var(--ink));
}
.about-mission { text-align: center; }
.about-mission .about-section-eyebrow { margin-bottom: 12px; }
.about-mission-text {
  font-family: var(--f-sans); font-style: normal; font-weight: 500;
  font-size: clamp(20px, 2.6vw, 28px); line-height: 1.35; letter-spacing: -0.015em;
  color: var(--ink); margin: 0 auto; max-width: 32ch; text-wrap: balance;
}
.about-values { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.about-value {
  border: 1px solid var(--line); border-radius: 14px; padding: 20px;
  background: var(--bg, var(--bg-card));
  opacity: 0; transform: translateY(16px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.about-values.is-on .about-value { opacity: 1; transform: translateY(0); }
.about-value-title { font-size: 14.5px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 6px; line-height: 1.3; text-wrap: balance; }
.about-value-body { font-size: 13px; line-height: 1.55; color: var(--ink-3); text-wrap: pretty; }
.about-next { /* vertical gap comes from .about-col > * + *; don't zero it here */ }
.about-roadmap { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.about-roadmap-item {
  display: flex; align-items: flex-start; gap: 9px;
  font-size: 14px; line-height: 1.5; color: var(--ink-2, var(--ink));
}
.about-roadmap-item svg { flex-shrink: 0; margin-top: 2px; color: var(--indigo); }
.about-contact {
  /* top gap comes from .about-col > * + * (48px) — don't reset margin here */
  padding: 24px;
  border-radius: 14px; border: 1px solid var(--line); background: var(--bg-card);
  text-align: center;
}
/* Freely-spinning About sphere — no card, sits in the grid's right column. */
.ab-sphere { width: 100%; max-width: 360px; margin: 0 auto; color: var(--ink); }
.ab-sphere svg { width: 100%; height: auto; display: block; overflow: visible; }
.ab-sphere-labels text { font-family: var(--f-sans); font-weight: 500; letter-spacing: -0.01em; fill: var(--ink-3); }
.about-contact-title { font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 6px; text-wrap: balance; }
.about-contact-body { font-size: 14px; line-height: 1.6; color: var(--ink-3); margin: 0; max-width: 46ch; margin-inline: auto; text-wrap: pretty; }

@media (prefers-reduced-motion: reduce) {
  .about-value { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 768px) {
  .about-founder { grid-template-columns: 1fr; gap: 16px; }
  .about-values { grid-template-columns: 1fr; }
}

/* ── Roadmap page (/#roadmap) — Now / Next / Later / Considering board ──────── */
.rm-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; align-items: start; }
.rm-col {
  opacity: 0; transform: translateY(16px);
  transition:
    opacity 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.rm-grid.is-on .rm-col { opacity: 1; transform: translateY(0); }
.rm-col-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 0 2px 10px; margin-bottom: 12px;
  border-bottom: 2px solid var(--line);
}
.rm-col-now    .rm-col-head { border-bottom-color: var(--ok, #1a7f4b); }
.rm-col-next   .rm-col-head { border-bottom-color: var(--indigo); }
.rm-col-later  .rm-col-head { border-bottom-color: var(--ink-4); }
.rm-col-considering .rm-col-head { border-bottom-color: var(--line); }
.rm-col-label { font-size: 14px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.rm-col-meta { font-size: 11px; font-weight: 600; color: var(--ink-4); white-space: nowrap; }
.rm-cards { display: flex; flex-direction: column; gap: 10px; }
.rm-card {
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 13px;
  background: var(--bg, var(--bg-card));
}
.rm-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.rm-card-title { font-size: 13.5px; font-weight: 700; color: var(--ink-1, var(--ink)); line-height: 1.3; }
.rm-card-desc { font-size: 12px; line-height: 1.45; color: var(--ink-3); margin-top: 4px; }
.rm-when {
  flex-shrink: 0; font-size: 9.5px; font-weight: 700; letter-spacing: 0.02em;
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
  color: var(--ink-4); background: var(--bg-sunk, var(--bg-elev));
}
.rm-when-now { color: var(--ok, #1a7f4b); background: color-mix(in srgb, var(--ok, #1a7f4b) 14%, transparent); }
.rm-when-next { color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.rm-foot { text-align: center; margin-top: 36px; font-size: 14px; color: var(--ink-3); }

@media (prefers-reduced-motion: reduce) {
  .rm-col { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 1023px) { .rm-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .rm-grid { grid-template-columns: 1fr; } }

/* ── Studio Review walkthrough (the landing centerpiece) ────────────────────── */
/* ── Studio Review demo embed (.srx-*, <StudioReviewEmbed>) ─────────────────── */
.srx-shell { max-width: 1100px; margin: 44px auto 0; }
.srx-frame {
  position: relative; border-radius: 14px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 24px 70px color-mix(in srgb, var(--ink) 18%, transparent), 0 4px 14px rgba(0,0,0,0.06);
}
.srx-chrome {
  display: flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 14px;
  background: var(--bg-elev); border-bottom: 1px solid var(--line);
}
.srx-light { width: 10px; height: 10px; border-radius: 50%; background: var(--line); flex-shrink: 0; }
.srx-light:nth-child(1) { background: #ff5f57; } .srx-light:nth-child(2) { background: #febc2e; } .srx-light:nth-child(3) { background: #28c840; }
.srx-url {
  display: flex; align-items: center; gap: 6px; margin: 0 auto;
  font-size: 11.5px; color: var(--ink-4); font-family: var(--f-sans);
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px;
  padding: 4px 14px; max-width: 60%;
}
.srx-url svg { color: var(--ok, #1a7f4b); flex-shrink: 0; }
.srx-body { position: relative; aspect-ratio: 16 / 10; background: var(--bg-sunk, var(--bg-elev)); }
/* ── Studio Review demo — real anonymized screenshot + SVG animation overlay ──────
   The card BACKGROUND is the real workspace screenshot (anonymized to
   demo-assets/sr-workspace.png). The only live layer is one SVG overlay whose
   viewBox is the image's native 3420×1896, so every child coordinate is a real
   screenshot pixel and the overlay tracks the background at any card width. A ~12s
   loop runs the markup workflow; prefers-reduced-motion holds the final state. */
.srd-shell { max-width: 1100px; margin: 44px auto 0; }
.srd-frame {
  position: relative; aspect-ratio: 3420 / 1896; border-radius: 14px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.09);
  box-shadow: 0 24px 70px rgba(0,0,0,0.45), 0 4px 14px rgba(0,0,0,0.3);
  background: #0E0E10 url("/demo-assets/sr-workspace.png") center center / 100% 100% no-repeat;
}
.srd-overlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.srd-overlay text { font-family: var(--f-sans); }
/* populated-row cells (drawn on the #222427 cover over the empty state) */
.srd-rcell  { font-size: 30px; fill: #d8dbe2; }
.srd-rmute  { fill: #8b8f99; }
.srd-rchip  { fill: #ffcb73; font-weight: 600; text-anchor: middle; }
.srd-rcount { font-size: 28px; fill: #c2c6cf; }
/* orange text-box markup label (dark amber on the light orange fill over the plan) */
.srd-mk-tx  { font-size: 34px; font-weight: 600; fill: #7a4d05; }

/* base = final populated composition (reduced-motion lands here):
   markup box + arrow + table row shown; cursor hidden; arrow fully drawn */
.srd-cursor     { transform-box: view-box; transform-origin: 0 0; opacity: 0; }
.srd-arrow-line { stroke-dasharray: 360; stroke-dashoffset: 0; }

@media (prefers-reduced-motion: no-preference) {
  .srd-cursor     { animation: srd-cursor     12s ease-in-out infinite; }
  .srd-mk-box     { animation: srd-fade-box   12s ease-in-out infinite; }
  .srd-mk-arrow   { animation: srd-fade-arrow 12s ease-in-out infinite; }
  .srd-arrow-line { animation: srd-draw       12s ease-in-out infinite; }
  .srd-mk-row     { animation: srd-fade-row   12s ease-in-out infinite; }
  .srd-mk-count   { animation: srd-fade-row   12s ease-in-out infinite; }
}
@keyframes srd-cursor {
  0%   { opacity: 0; transform: translate(1700px, 1280px); }
  5%   { opacity: 1; transform: translate(1700px, 1280px); }
  20%  { opacity: 1; transform: translate(2120px, 640px); }
  44%  { opacity: 1; transform: translate(1900px, 760px); }
  64%  { opacity: 1; transform: translate(2300px, 1500px); }
  84%, 100% { opacity: 0; transform: translate(2300px, 1500px); }
}
@keyframes srd-fade-box   { 0%, 22% { opacity: 0; } 30%, 92% { opacity: 1; } 97%, 100% { opacity: 0; } }
@keyframes srd-fade-arrow { 0%, 44% { opacity: 0; } 50%, 92% { opacity: 1; } 97%, 100% { opacity: 0; } }
@keyframes srd-draw       { 0%, 44% { stroke-dashoffset: 360; } 58%, 100% { stroke-dashoffset: 0; } }
@keyframes srd-fade-row   { 0%, 72% { opacity: 0; } 80%, 94% { opacity: 1; } 98%, 100% { opacity: 0; } }

@media (max-width: 768px) {
  /* full-bleed on phones; aspect-ratio keeps the screenshot proportional */
  .srd-shell { margin-top: 28px; width: 100vw; margin-left: 50%; transform: translateX(-50%); }
  .srd-frame { border-radius: 0; border-left: none; border-right: none; box-shadow: 0 12px 30px rgba(0,0,0,0.4); }
}

/* ── Projects portfolio-gantt demo (.prd-* / .prx-*, <ProjectsAnimation>) ──────
   Row-expansion built from ONE screenshot sliced into three stacked strips. The
   frame is content-driven (no fixed aspect): when the middle strip collapses the
   frame shrinks so the lower projects sit directly under the Hudson Yards row;
   when it expands the lower rows slide down in normal flow. Slice math (native
   2437×1790): strip heights are sliceHeight/2437 as padding-bottom; each <img>
   is the full image shifted up by sliceStartY/1790 so only its slice shows.
     A (above)     0–592   → pb 24.292%, img translateY  0
     B (expansion) 592–1235 → pb 26.385%, img translateY -33.073%
     C (below)     1235–1790 → pb 22.774%, img translateY -68.994%
   prefers-reduced-motion holds the expanded state. */
.prd-shell { max-width: 1100px; margin: 44px auto 0; }
.prd-frame {
  position: relative; border-radius: 14px; overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: 0 24px 70px rgba(0,0,0,0.18), 0 4px 14px rgba(0,0,0,0.08);
  background: #FBFAF7;
}
.prx-stack { position: relative; width: 100%; line-height: 0; font-size: 0; }
.prx-strip { position: relative; width: 100%; height: 0; overflow: hidden; }
.prx-strip > img { position: absolute; left: 0; top: 0; width: 100%; height: auto; display: block; }
.prx-top { padding-bottom: 24.292%; }
.prx-mid { padding-bottom: 26.385%; }   /* default = expanded (reduced-motion rest) */
.prx-bot { padding-bottom: 22.774%; }
.prx-mid > img { transform: translateY(-33.073%); }
.prx-bot > img { transform: translateY(-68.994%); }

/* Cue over the Hudson Yards row (bottom of strip A): soft indigo band + chevron
   that pulses just before the block reveals, chevron rotates from ▸ to ▾. */
.prx-cue {
  position: absolute; left: 0; right: 0; top: 83.6%; height: 16%;
  display: flex; align-items: center; opacity: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(124,140,255,0.18), rgba(124,140,255,0.04) 70%, rgba(124,140,255,0));
}
.prx-chev { margin-left: 3.2%; transform-origin: 50% 50%; }

@media (prefers-reduced-motion: no-preference) {
  .prx-mid { animation: prx-expand 7s ease-in-out infinite; }
  .prx-cue { animation: prx-cue 7s ease-in-out infinite; }
  .prx-chev { animation: prx-chev 7s ease-in-out infinite; }
}
@keyframes prx-expand {
  0%, 12%   { padding-bottom: 0; }
  36%, 82%  { padding-bottom: 26.385%; }
  96%, 100% { padding-bottom: 0; }
}
@keyframes prx-cue {
  0%, 4%    { opacity: 0; }
  10%, 22%  { opacity: 1; }
  34%, 100% { opacity: 0; }
}
@keyframes prx-chev {
  0%, 12%   { transform: rotate(0deg); }
  36%, 82%  { transform: rotate(90deg); }
  96%, 100% { transform: rotate(0deg); }
}

@media (max-width: 768px) {
  .prd-shell { margin-top: 28px; width: 100vw; margin-left: 50%; transform: translateX(-50%); }
  .prd-frame { border-radius: 0; border-left: none; border-right: none; box-shadow: 0 12px 30px rgba(0,0,0,0.4); }
}
/* ── "See it in action" cycling card (.lia-*, <LandingInAction>) ─────────────── */
.lia-shell { max-width: 920px; margin: 36px auto 0; }
.lia-frame {
  position: relative; border-radius: 14px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 24px 70px color-mix(in srgb, var(--ink) 16%, transparent), 0 4px 14px rgba(0,0,0,0.06);
}
.lia-chrome {
  display: flex; align-items: center; gap: 7px; height: 38px; padding: 0 14px;
  background: var(--bg-elev); border-bottom: 1px solid var(--line);
}
.lia-light { width: 10px; height: 10px; border-radius: 50%; background: var(--line); flex-shrink: 0; }
.lia-light:nth-child(1) { background: #ff5f57; } .lia-light:nth-child(2) { background: #febc2e; } .lia-light:nth-child(3) { background: #28c840; }
.lia-url {
  display: flex; align-items: center; gap: 6px; margin: 0 auto;
  font-size: 11.5px; color: var(--ink-4); font-family: var(--f-sans);
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px;
  padding: 4px 14px; max-width: 60%;
}
.lia-url svg { color: var(--ok, #1a7f4b); flex-shrink: 0; }
/* Stage holds the cross-fading slides */
.lia-stage { position: relative; aspect-ratio: 16 / 10; background: var(--bg-sunk, var(--bg-elev)); }
.lia-slide {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  transition: opacity 600ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)), visibility 0s linear 600ms;
}
.lia-slide.is-active { opacity: 1; visibility: visible; transition: opacity 600ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)); }
.lia-poster { position: absolute; inset: 0; display: flex; flex-direction: column; }
/* Command Center poster */
.lia-cc { padding: 18px 20px; gap: 12px; background: var(--bg-elev); }
.lia-pill {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo); background: color-mix(in srgb, var(--indigo) 12%, transparent);
  border-radius: 999px; padding: 2px 8px; flex-shrink: 0;
}
.lia-cc-brief { display: flex; align-items: center; gap: 9px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; }
.lia-cc-brief-txt { font-size: 11.5px; color: var(--ink-3); line-height: 1.4; min-width: 0; }
.lia-cc-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.lia-metric { background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px; }
.lia-metric-v { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--ink); }
.lia-metric-l { font-size: 10px; color: var(--ink-4); margin-top: 2px; }
.lia-cc-field { background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 11px 12px; flex: 1; display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.lia-cc-field-head { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-4); }
.lia-cc-row { display: flex; align-items: center; gap: 10px; }
.lia-cc-row-name { width: 112px; flex-shrink: 0; font-size: 11px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lia-cc-track { flex: 1; height: 10px; background: var(--bg-sunk, var(--bg-elev)); border-radius: 6px; position: relative; }
.lia-cc-bar { position: absolute; top: 0; height: 100%; border-radius: 6px; }
/* Studio Review poster */
.lia-sr { background: var(--bg-sunk, var(--bg-elev)); align-items: center; justify-content: center; padding: 18px; }
.lia-sr svg { width: 100%; height: 100%; max-height: 100%; }
/* Timesheets poster */
.lia-ts { padding: 18px 20px; gap: 12px; background: var(--bg-elev); }
.lia-ts-head { display: flex; align-items: center; justify-content: space-between; }
.lia-ts-title { font-size: 13px; font-weight: 700; color: var(--ink); }
.lia-ts-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; flex: 1; min-height: 0; }
.lia-ts-col { display: flex; flex-direction: column; gap: 6px; min-height: 0; }
.lia-ts-day { font-size: 10px; font-weight: 600; color: var(--ink-4); text-align: center; }
.lia-ts-track { position: relative; flex: 1; background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px; min-height: 0; }
.lia-ts-blk {
  position: absolute; left: 4px; right: 4px; border-radius: 5px;
  font-size: 8.5px; font-weight: 600; color: #fff; padding: 3px 5px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* Edge arrows */
.lia-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 1px solid var(--line); color: var(--ink-2);
  cursor: pointer; opacity: 0; transition: opacity 200ms ease, background 120ms ease;
  box-shadow: 0 2px 10px rgba(0,0,0,0.12);
}
.lia-frame:hover .lia-arrow { opacity: 1; }
.lia-arrow:hover { background: var(--bg-elev); color: var(--ink); }
.lia-arrow-prev { left: 12px; } .lia-arrow-next { right: 12px; }
/* Caption + dots */
.lia-caption { text-align: center; margin-top: 18px; }
.lia-cap-label { display: block; font-size: 15px; font-weight: 700; color: var(--ink); }
.lia-cap-sub { display: block; font-size: 13px; color: var(--ink-3); margin-top: 3px; max-width: 460px; margin-left: auto; margin-right: auto; line-height: 1.5; }
.lia-dots { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }
.lia-dot { width: 7px; height: 7px; border-radius: 50%; border: none; background: var(--line); cursor: pointer; padding: 0; transition: background 200ms ease, width 200ms ease; }
.lia-dot.active { width: 22px; border-radius: 4px; background: var(--indigo); }
@media (prefers-reduced-motion: reduce) {
  .lia-slide { transition: none; }
}
@media (max-width: 600px) {
  .lia-shell { margin-top: 24px; }
  .lia-arrow { opacity: 1; width: 30px; height: 30px; }
  .lia-cc-metrics { gap: 6px; }
  .lia-metric-v { font-size: 18px; }
  .lia-cc-row-name { width: 78px; }
  .lia-url { max-width: 76%; }
}
/* (.srd-* freezes on its final populated state automatically — its animations are
   wrapped in `@media (prefers-reduced-motion: no-preference)`, so no explicit
   reduce-block is needed.) */
@media (max-width: 768px) {
  /* Full-bleed: break out of the landing container's horizontal padding so the
     dense replica gets every available pixel. Everything inside scales via cqw
     against .srd-frame's width, so the whole workspace stays proportional. */
  .srd-shell { margin-top: 28px; width: 100vw; margin-left: 50%; transform: translateX(-50%); }
  .srd-frame { border-radius: 0; border-left: none; border-right: none;
    box-shadow: 0 12px 30px rgba(0,0,0,0.4); }
}

.srw-section { background: var(--bg-card); }
.srw-shell { max-width: 1040px; margin: 44px auto 0; }
.srw-frame {
  position: relative; border-radius: 14px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 24px 70px color-mix(in srgb, var(--ink) 18%, transparent), 0 4px 14px rgba(0,0,0,0.06);
}
/* browser chrome */
.srw-chrome {
  display: flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 14px;
  background: var(--bg-elev); border-bottom: 1px solid var(--line);
}
.srw-light { width: 10px; height: 10px; border-radius: 50%; background: var(--line); flex-shrink: 0; }
.srw-light:nth-child(1) { background: #ff5f57; } .srw-light:nth-child(2) { background: #febc2e; } .srw-light:nth-child(3) { background: #28c840; }
.srw-url {
  display: flex; align-items: center; gap: 6px; margin: 0 auto;
  font-size: 11.5px; color: var(--ink-4); font-family: var(--f-sans);
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px;
  padding: 4px 14px; max-width: 60%;
}
.srw-url svg { color: var(--ok, #1a7f4b); flex-shrink: 0; }
/* app body */
.srw-app { position: relative; display: flex; height: 480px; background: var(--bg-sunk, var(--bg-elev)); }
/* left sidebar (scene 0) */
.srw-sidebar { width: 210px; flex-shrink: 0; border-right: 1px solid var(--line); background: var(--bg-card); padding: 14px; display: flex; flex-direction: column; }
.srw-sidebar-head { font-size: 12px; font-weight: 700; color: var(--ink-2); letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 12px; }
.srw-sidebar-empty { font-size: 12px; color: var(--ink-5); padding: 10px 0; }
.srw-newbtn { margin-top: auto; font-size: 12.5px; font-weight: 600; color: #fff; background: var(--indigo); border: none; border-radius: var(--radius-btn-icon); padding: 9px; cursor: default; }
/* left tool rail */
.srw-rail { width: 46px; flex-shrink: 0; border-right: 1px solid var(--line); background: var(--bg-card); display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 0; }
.srw-tool { width: 30px; height: 30px; border-radius: 7px; display: flex; align-items: center; justify-content: center; color: var(--ink-4); }
.srw-tool.active { background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); color: var(--indigo); box-shadow: inset 0 0 0 1.5px var(--indigo); }
/* main */
.srw-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.srw-main-top { display: flex; align-items: center; gap: 10px; padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--bg-card); }
.srw-session-title { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.srw-approved-pill { margin-left: auto; font-size: 11px; font-weight: 700; color: var(--ok, #1a7f4b); background: color-mix(in srgb, var(--ok, #1a7f4b) 14%, transparent); border-radius: 999px; padding: 3px 10px; animation: srw-fade 0.3s ease both; }
.srw-dash-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; }
.srw-dash-illus { width: 60px; height: 60px; border-radius: 14px; border: 2px dashed var(--line); }
.srw-dash-text { font-size: 13px; color: var(--ink-4); }
/* canvas */
.srw-canvas { position: relative; flex: 1; margin: 0; padding: 22px; display: flex; align-items: center; justify-content: center; overflow: hidden;
  background-image: radial-gradient(color-mix(in srgb, var(--ink) 7%, transparent) 1px, transparent 1px); background-size: 22px 22px; }
.srw-canvas-empty { background-image: none; }
.srw-upload { display: flex; flex-direction: column; align-items: center; gap: 7px; color: var(--ink-4); border: 2px dashed var(--line); border-radius: 14px; padding: 40px 60px; font-size: 14px; font-weight: 600; }
.srw-upload-sub { font-size: 11.5px; font-weight: 400; color: var(--ink-5); }
.srw-page-badge { position: absolute; top: 14px; left: 16px; z-index: 4; font-size: 10.5px; font-weight: 700; color: var(--indigo); background: var(--bg-card); border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 30%, var(--line))); border-radius: 6px; padding: 3px 8px; font-family: var(--f-mono, monospace); animation: srw-fade 0.3s ease both; }
.srw-watermark { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 5; pointer-events: none; font-size: 30px; font-weight: 800; letter-spacing: 0.1em; color: color-mix(in srgb, var(--ok, #1a7f4b) 22%, transparent); transform: rotate(-16deg); }
.srw-sheet { width: 100%; max-width: 560px; height: auto; max-height: 100%; background: var(--bg-card); border: 1px solid var(--line); box-shadow: 0 6px 22px rgba(0,0,0,0.08); border-radius: 2px; }
.srw-sheet-edge { fill: var(--bg-card); stroke: var(--line); stroke-width: 1; }
.srw-grid { stroke: var(--line); stroke-width: 0.6; stroke-dasharray: 3 3; }
.srw-bub { fill: var(--bg-card); stroke: var(--ink-4); stroke-width: 0.9; }
.srw-bub-tx { fill: var(--ink-3); font-size: 9px; font-weight: 700; text-anchor: middle; }
.srw-wall { stroke: var(--ink-3, var(--ink)); stroke-width: 2; fill: none; stroke-linejoin: round; }
.srw-door { stroke: var(--ink-4); stroke-width: 1.2; fill: none; }
.srw-tblock rect { fill: var(--bg-card); stroke: var(--ink-4); stroke-width: 0.9; }
.srw-tblock line { stroke: var(--ink-4); stroke-width: 0.7; }
.srw-tb-tx { fill: var(--ink-3); font-size: 8px; font-weight: 600; }
/* markups */
.srw-cloud { fill: none; stroke: var(--bad); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; animation: srw-draw 0.7s var(--ease-out, ease) forwards; }
.srw-cloud.grouped { stroke-dashoffset: 0; }
.srw-dim { animation: srw-fade 0.3s ease both; }
.srw-dim line, .srw-dim path { stroke: var(--indigo); stroke-width: 1.5; stroke-linecap: round; }
.srw-dim-lbl-bg { fill: var(--bg-card); stroke: var(--indigo); stroke-width: 0.8; }
.srw-dim-lbl { fill: var(--indigo); font-size: 9px; font-weight: 700; text-anchor: middle; font-family: var(--f-mono, monospace); }
.srw-group-box { fill: none; stroke: var(--indigo); stroke-width: 1.4; stroke-dasharray: 5 4; animation: srw-fade 0.25s ease both; }
.srw-pin { position: absolute; z-index: 6; transform: translate(-50%, -100%); animation: srw-drop 0.4s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)) both; }
/* comment thread */
.srw-thread { position: absolute; right: 18px; top: 40px; z-index: 7; width: 220px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px; padding: 11px 12px; box-shadow: 0 8px 26px rgba(0,0,0,0.12); animation: srw-pop 0.3s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)) both; }
.srw-thread-head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.srw-thread-avatar { width: 20px; height: 20px; border-radius: 50%; background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); color: var(--indigo); font-size: 9px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.srw-thread-name { font-size: 11.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.srw-thread-ago { font-size: 10px; color: var(--ink-5); margin-left: auto; }
.srw-thread-text { font-size: 12px; line-height: 1.45; color: var(--ink-2, var(--ink)); }
.srw-mention { color: var(--indigo); font-weight: 700; background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); border-radius: 4px; padding: 0 3px; }
.srw-thread-reply { margin-top: 8px; font-size: 11px; color: var(--ink-5); border-top: 1px solid var(--line); padding-top: 7px; }
/* signature pad */
.srw-sign { position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 8; width: 300px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; padding: 13px 14px; box-shadow: 0 14px 40px rgba(0,0,0,0.18); animation: srw-slide-up 0.34s var(--ease-out, ease) both; }
.srw-sign-head { font-size: 12px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 8px; }
.srw-sign-pad { border: 1px dashed var(--line); border-radius: 8px; background: var(--bg-elev); height: 56px; display: flex; align-items: center; justify-content: center; }
.srw-sign-pad svg { width: 80%; height: 70%; }
.srw-sign-stroke { fill: none; stroke: var(--ink-1, var(--ink)); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 400; stroke-dashoffset: 400; animation: srw-sign-draw 1.1s var(--ease-out, ease) 0.2s forwards; }
.srw-sign-row { display: flex; align-items: center; justify-content: space-between; margin-top: 9px; }
.srw-sign-by { font-size: 12px; color: var(--ink-3); font-style: italic; }
.srw-sign-btn { font-size: 11.5px; font-weight: 700; color: #fff; background: var(--indigo); border-radius: var(--radius-btn); padding: 6px 12px; }
/* right dock (properties / layers) */
.srw-dock { width: 188px; flex-shrink: 0; border-left: 1px solid var(--line); background: var(--bg-card); padding: 12px; animation: srw-fade 0.3s ease both; overflow-y: auto; }
.srw-dock-head { font-size: 12px; font-weight: 700; color: var(--ink-2); letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 12px; }
.srw-dock-grp { margin-bottom: 13px; }
.srw-dock-lbl { font-size: 10px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-5); margin-bottom: 6px; }
.srw-swatches { display: flex; gap: 6px; }
.srw-swatch { width: 18px; height: 18px; border-radius: 5px; border: 2px solid transparent; }
.srw-swatch.on { border-color: var(--ink); box-shadow: 0 0 0 1px var(--bg-card) inset; }
.srw-dock-seg { display: inline-flex; background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius-btn); overflow: hidden; }
.srw-dock-seg span { font-size: 11px; padding: 4px 11px; color: var(--ink-4); }
.srw-dock-seg span.on { background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); color: var(--indigo); font-weight: 600; }
.srw-slider { position: relative; height: 5px; border-radius: 3px; background: var(--line); }
.srw-slider-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 3px; background: var(--indigo); }
.srw-slider-knob { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid var(--indigo); transform: translate(-50%, -50%); }
.srw-layer { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--ink-2); padding: 7px 8px; border-radius: 7px; margin-bottom: 3px; }
.srw-layer.selected { background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 10%, transparent)); box-shadow: inset 0 0 0 1px var(--indigo-line, color-mix(in srgb, var(--indigo) 28%, transparent)); }
.srw-layer-ic { font-size: 13px; flex-shrink: 0; }
.srw-layer-pg { margin-left: auto; font-size: 9.5px; color: var(--ink-5); }
.srw-group-btn { width: 100%; margin-top: 8px; font-size: 11.5px; font-weight: 700; color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 28%, transparent)); border-radius: var(--radius-btn-icon); padding: 8px; cursor: default; }
/* new-session modal */
.srw-modal-wrap { position: absolute; inset: 0; z-index: 9; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--ink) 28%, transparent); animation: srw-fade 0.25s ease both; }
.srw-modal { width: 340px; background: var(--bg-card); border-radius: 14px; padding: 20px; box-shadow: 0 24px 60px rgba(0,0,0,0.28); animation: srw-pop 0.3s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)) both; }
.srw-modal-title { font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink)); margin-bottom: 16px; }
.srw-modal-lbl { font-size: 11px; font-weight: 600; color: var(--ink-4); }
.srw-modal-input { margin-top: 6px; font-size: 13px; color: var(--ink-1, var(--ink)); border: 1px solid var(--indigo); border-radius: 8px; padding: 9px 11px; background: var(--bg); box-shadow: 0 0 0 3px var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.srw-caret { display: inline-block; width: 1.5px; height: 14px; background: var(--indigo); vertical-align: middle; margin-left: 1px; animation: land-blink 0.85s step-end infinite; }
.srw-modal-row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.srw-modal-cancel { font-size: 12.5px; color: var(--ink-4); padding: 8px 14px; }
.srw-modal-create { font-size: 12.5px; font-weight: 700; color: #fff; background: var(--indigo); border-radius: 8px; padding: 8px 14px; }
/* simulated cursor */
.srw-cursor { position: absolute; z-index: 20; pointer-events: none; transform: translate(-2px, -2px); filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3)); }
.srw-cursor-pulse { position: absolute; left: 2px; top: 2px; width: 8px; height: 8px; border-radius: 50%; border: 2px solid var(--indigo); transform: translate(-50%, -50%); animation: srw-click 0.7s var(--ease-out, ease) 0.35s 1 both; }
/* edge arrows */
.srw-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 22; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--bg-card); border: 1px solid var(--line); color: var(--ink-2); cursor: pointer; opacity: 0; transition: opacity 0.2s var(--ease-out, ease), color 0.15s ease, border-color 0.15s ease; box-shadow: 0 4px 14px rgba(0,0,0,0.12); }
.srw-arrow-prev { left: 12px; } .srw-arrow-next { right: 12px; }
.srw-frame:hover .srw-arrow { opacity: 1; }
.srw-arrow:hover { color: var(--indigo); border-color: var(--indigo); }
/* caption + dots */
.srw-caption { text-align: center; font-size: 14px; color: var(--ink-3); margin-top: 18px; min-height: 20px; }
.srw-dots { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 12px; }
.srw-dot { width: 8px; height: 8px; border-radius: 50%; border: none; padding: 0; background: var(--line); cursor: pointer; transition: background 0.25s var(--ease-out, ease), transform 0.25s var(--ease-out, ease); }
.srw-dot:hover { background: var(--ink-4); }
.srw-dot.active { background: var(--indigo); transform: scale(1.3); }

@keyframes srw-draw { to { stroke-dashoffset: 0; } }
@keyframes srw-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes srw-pop { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: scale(1); } }
@keyframes srw-slide-up { from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes srw-drop { 0% { opacity: 0; transform: translate(-50%, -130%); } 60% { opacity: 1; } 100% { opacity: 1; transform: translate(-50%, -100%); } }
@keyframes srw-click { 0% { opacity: 0.9; transform: translate(-50%,-50%) scale(0.6); } 100% { opacity: 0; transform: translate(-50%,-50%) scale(3.4); } }
@keyframes srw-sign-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .srw-cloud, .srw-dim, .srw-group-box, .srw-pin, .srw-thread, .srw-sign,
  .srw-dock, .srw-modal-wrap, .srw-modal, .srw-page-badge, .srw-approved-pill { animation: none; opacity: 1; }
  .srw-cloud { stroke-dashoffset: 0; } .srw-sign-stroke { stroke-dashoffset: 0; animation: none; }
  .srw-caret { animation: none; }
}
@media (max-width: 768px) {
  .srw-shell { margin-top: 28px; }
  .srw-app { height: 360px; }
  .srw-sidebar { width: 150px; }
  .srw-dock { width: 150px; }
  .srw-thread { width: 170px; right: 10px; }
  .srw-sign { width: 88%; }
  .srw-watermark { font-size: 20px; }
  .srw-caption { font-size: 13px; }
}

/* ── Command Center walkthrough (.ccw-*, reuses .srw-frame chrome) ──────────── */
.ccw-app { position: relative; flex-direction: column; background: var(--bg); padding: 0; }
.ccw-topbar { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--bg-card); flex-shrink: 0; }
.ccw-date { font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.ccw-topbar-actions { display: flex; gap: 7px; }
.ccw-chip { font-size: 10.5px; font-weight: 600; color: var(--ink-3); background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 4px 9px; }
.ccw-chip-primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }
.ccw-body { flex: 1; min-height: 0; overflow: hidden; padding: 14px 16px; display: flex; flex-direction: column; gap: 9px; }
.ccw-eyebrow { font-size: 9px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--indigo); }
/* briefing */
.ccw-brief { display: flex; flex-direction: column; gap: 3px; background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 8%, transparent)); border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 22%, transparent)); border-radius: 9px; padding: 9px 12px; animation: srw-fade 0.3s ease both; }
.ccw-brief-text { font-size: 11px; line-height: 1.45; color: var(--ink-2); }
/* alert */
.ccw-alert { display: flex; align-items: flex-start; gap: 8px; background: color-mix(in srgb, var(--bad) 9%, var(--bg-card)); border-left: 3px solid var(--bad); border-radius: 6px; padding: 8px 11px; animation: srw-fade 0.3s ease both; }
.ccw-alert-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--bad); margin-top: 3px; flex-shrink: 0; animation: land-pulse-dot 1.3s ease infinite; }
.ccw-alert-body { display: flex; flex-direction: column; gap: 1px; }
.ccw-alert-title { font-size: 11.5px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.ccw-alert-sub { font-size: 10.5px; color: var(--ink-4); }
/* metrics */
.ccw-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; animation: srw-fade 0.3s ease both; }
.ccw-metric { background: var(--bg-card); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; }
.ccw-metric-lbl { font-size: 8.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-5); }
.ccw-metric-val { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; }
.ccw-metric-suf { font-size: 9.5px; font-weight: 500; color: var(--ink-4); margin-left: 3px; }
.ccw-metric-bar { height: 3px; border-radius: 2px; }
.ccw-ok { background: var(--ok, #1a7f4b); } .ccw-bad { background: var(--bad); } .ccw-warn { background: var(--warn); }
.ccw-metric .ccw-bad, .ccw-metric .ccw-ok, .ccw-metric .ccw-warn { opacity: 0.8; }
/* gantt */
.ccw-gantt { background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; animation: srw-fade 0.3s ease both; }
.ccw-gantt-head { margin-bottom: 7px; }
.ccw-gantt-row { display: flex; align-items: center; gap: 9px; padding: 3px 0; }
.ccw-gantt-name { font-size: 11px; font-weight: 500; color: var(--ink-2); width: 116px; flex-shrink: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ccw-gantt-phase { font-size: 8.5px; font-weight: 700; color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); border-radius: 3px; padding: 1px 5px; flex-shrink: 0; }
.ccw-gantt-track { position: relative; flex: 1; height: 10px; background: var(--bg-elev); border-radius: 4px; }
.ccw-gantt-bar { position: absolute; top: 0; height: 100%; border-radius: 4px; }
.ccw-gantt-bar.ccw-bad { background: var(--bad); } .ccw-gantt-bar.ccw-ok { background: var(--indigo); } .ccw-gantt-bar.ccw-warn { background: var(--warn); }
/* bottom 2-col */
.ccw-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.ccw-panel { background: var(--bg-card); border: 1px solid var(--line); border-radius: 9px; padding: 9px 11px; animation: srw-fade 0.3s ease both; }
.ccw-pulse-row { display: flex; justify-content: space-between; font-size: 11px; color: var(--ink-3); padding: 3px 0; }
.ccw-pulse-row strong { color: var(--ink-1, var(--ink)); font-weight: 700; }
.ccw-pulse-row:first-of-type { margin-top: 6px; }
.ccw-decision { font-size: 11px; color: var(--ink-2); padding: 6px 8px; border-radius: 6px; background: var(--bg-elev); margin-top: 6px; }
.ccw-decision.is-new { background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 10%, transparent)); box-shadow: inset 0 0 0 1px var(--indigo-line, color-mix(in srgb, var(--indigo) 28%, transparent)); display: flex; align-items: center; gap: 6px; animation: srw-pop 0.32s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)) both; }
.ccw-decision-tag { font-size: 8px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: #fff; background: var(--indigo); border-radius: 4px; padding: 1px 5px; flex-shrink: 0; }
/* Ask Aecos command bar */
.ccw-cmd-wrap { position: absolute; inset: 0; z-index: 9; background: color-mix(in srgb, var(--ink) 14%, transparent); animation: srw-fade 0.22s ease both; }
.ccw-cmd { position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%); width: 76%; max-width: 520px; background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 18px 50px rgba(0,0,0,0.24); overflow: hidden; animation: ccw-cmd-in 0.3s var(--ease-out, ease) both; }
@keyframes ccw-cmd-in { from { opacity: 0; transform: translate(-50%, 16px); } to { opacity: 1; transform: translate(-50%, 0); } }
.ccw-cmd-input { display: flex; align-items: center; gap: 8px; padding: 12px 14px; font-size: 13px; color: var(--ink-1, var(--ink)); border-bottom: 1px solid var(--line); }
.ccw-cmd-input svg { color: var(--ink-4); flex-shrink: 0; }
.ccw-cmd-answer { display: flex; gap: 8px; padding: 12px 14px; font-size: 12px; line-height: 1.5; color: var(--ink-2, var(--ink)); }
.ccw-cmd-answer strong { color: var(--ink-1, var(--ink)); font-weight: 700; }
.ccw-cmd-badge { flex-shrink: 0; height: fit-content; font-size: 9px; font-weight: 700; color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent)); border-radius: 5px; padding: 2px 7px; }

@media (prefers-reduced-motion: reduce) {
  .ccw-brief, .ccw-alert, .ccw-metrics, .ccw-gantt, .ccw-panel, .ccw-decision.is-new,
  .ccw-cmd-wrap, .ccw-cmd { animation: none; opacity: 1; }
  .ccw-alert-dot { animation: none; }
}
@media (max-width: 768px) {
  .ccw-grid2 { grid-template-columns: 1fr; }
  .ccw-gantt-name { width: 90px; }
  .ccw-cmd { width: 90%; }
}

/* ── Coming-soon placeholder pages (/#blog, /#docs) ─────────────────────────── */
.cs-hero { text-align: center; min-height: 52vh; display: flex; flex-direction: column; justify-content: center; }
.cs-soon {
  display: inline-block; margin: 4px auto 0;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 12%, transparent));
  border: 1px solid color-mix(in srgb, var(--indigo) 30%, transparent);
  border-radius: 999px; padding: 4px 12px;
}
.cs-cta { margin-top: 24px; }
.cs-cta .btn { text-decoration: none; }

/* Mobile: animations are enabled (not static) — trim entrance/reveal durations
   ~25% so they feel brisk on phones. All are transform/opacity transitions, so
   this stays GPU-cheap. prefers-reduced-motion still wins (handled separately). */
@media (max-width: 768px) {
  .sr-reveal { transition-duration: 0.34s; }
  .fc-cc-mock, .fc-proj-mock, .fc-sr-mock, .fc-ts-mock, .fc-fin-mock, .fc-mo-mock,
  .ls-proof-col, .ls-tmon-card, .ls-sec-layer, .about-value,
  .intg-card, .rm-col, .ls-prob-panel, .ls-sol-node, .ls-sol-line { transition-duration: 0.3s; }
}

/* ── SR walkthrough — real Studio Review shell embedded in the browser frame ── */
.srw-sr-embed { flex: 1 1 0; min-width: 0; height: 100%; }
.srw-sr-canvas { width: 100%; height: 100%; display: block; }
.srw-sr-watermark {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  z-index: 5; pointer-events: none; font-size: 34px; font-weight: 800; letter-spacing: 0.12em;
  color: color-mix(in srgb, var(--ok, #1a7f4b) 20%, transparent); transform: rotate(-15deg);
}
.srw-sr-approved {
  position: absolute; top: 10px; right: 12px; z-index: 6;
  font-size: 11px; font-weight: 700; color: var(--ok, #1a7f4b);
  background: color-mix(in srgb, var(--ok, #1a7f4b) 14%, transparent);
  border-radius: 999px; padding: 4px 11px; animation: srw-fade 0.3s ease both;
}
.srw-sr-comment {
  position: absolute; right: 16px; top: 44px; z-index: 7; width: 224px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 12px; box-shadow: 0 8px 26px rgba(0,0,0,0.16);
  animation: srw-pop 0.3s var(--ease-spring, cubic-bezier(0.34,1.56,0.64,1)) both;
}
.srw-sr-comment-head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; font-size: 11.5px; color: var(--ink-1, var(--ink)); }
.srw-sr-comment-av { width: 20px; height: 20px; border-radius: 50%; background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); color: var(--indigo); font-size: 9px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.srw-sr-comment-ago { margin-left: auto; font-size: 10px; color: var(--ink-5); }
.srw-sr-comment-body { font-size: 12px; line-height: 1.45; color: var(--ink-2, var(--ink)); }
.srw-sr-mention { color: var(--indigo); font-weight: 700; background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); border-radius: 4px; padding: 0 3px; }

/* ── Landing section 1: Problem (scattered tools → one project record) ─────── */
.ls-prob-stage {
  position: relative;
  max-width: 460px; margin: 40px auto 0;
  padding: 22px;
  border-radius: 16px;
  border: 1px solid transparent;
  transition: border-color var(--duration-base, 180ms) var(--ease-out, ease), background var(--duration-base, 180ms) var(--ease-out, ease), box-shadow var(--duration-base, 180ms) var(--ease-out, ease);
}
.ls-prob-stage.is-docked {
  border-color: var(--line);
  background: var(--bg-card);
  box-shadow: 0 8px 30px rgba(0,0,0,0.06);
}
.ls-prob-card-label {
  font-size: 12px; font-weight: 700; color: var(--indigo);
  text-align: center; margin-bottom: 14px;
  opacity: 0; transform: translateY(-4px);
  transition: opacity 300ms var(--ease-out, ease) 0.35s, transform 300ms var(--ease-out, ease) 0.35s;
}
.ls-prob-stage.is-docked .ls-prob-card-label { opacity: 1; transform: translateY(0); }
.ls-prob-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
}
.ls-prob-panel {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 14px 8px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--line);
  color: var(--ink-3, var(--ink-4));
  /* scattered until docked */
  /* --tx/--ty/--rot are per-panel scatter offsets that were meant to be set
     inline by the (never-shipped) JSX for this stage; no consumer of
     .ls-prob-panel exists today. Without fallbacks the WHOLE transform is
     invalid at computed-value time, so the property silently did nothing.
     Fallbacks make the undocked state honest and keep this out of the
     undefined-token sweep. */
  transform: translate(var(--tx, 0px), var(--ty, 0px)) rotate(var(--rot, 0deg));
  box-shadow: 0 6px 18px rgba(0,0,0,0.07);
  transition: transform 700ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)), color 500ms var(--ease-out, ease), box-shadow 500ms var(--ease-out, ease);
}
.ls-prob-stage.is-docked .ls-prob-panel {
  transform: none; color: var(--indigo); box-shadow: none;
}
.ls-prob-label { font-size: 10.5px; font-weight: 600; }

/* ── Landing section 2: Solution (hub-and-spoke coordination field) ────────── */
.ls-sol-stage {
  position: relative;
  max-width: 560px; margin: 44px auto 0;
  aspect-ratio: 100 / 70;
}
.ls-sol-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ls-sol-line {
  stroke: var(--indigo); stroke-width: 0.5; stroke-linecap: round;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 600ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-sol-stage.is-on .ls-sol-line { stroke-dashoffset: 0; }
.ls-sol-node {
  position: absolute; transform: translate(-50%, -50%);
  font-size: 11px; font-weight: 600; white-space: nowrap;
  padding: 6px 12px; border-radius: 999px;
  background: var(--bg-card); border: 1px solid var(--line);
  color: var(--ink-2, var(--ink));
  opacity: 0;
  transition: opacity 360ms var(--ease-out, ease), border-color 360ms var(--ease-out, ease), color 360ms var(--ease-out, ease);
}
.ls-sol-stage.is-on .ls-sol-node { opacity: 1; border-color: var(--indigo); color: var(--indigo); }
.ls-sol-hub {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; white-space: nowrap;
  padding: 11px 18px; border-radius: 12px;
  background: var(--indigo); color: #fff;
  box-shadow: 0 8px 24px color-mix(in srgb, var(--indigo) 35%, transparent);
}
.ls-sol-hub-dot { width: 7px; height: 7px; border-radius: 50%; background: #fff; opacity: 0.9; }

/* ── Constellation: AEC people → one geodesic operating field (scroll-driven) ─
   Replaces the old #problem + #solution sections. Tall section with a sticky
   viewport stage; tiny gradient-coloured dots scatter (full-bleed) → label →
   compact into a rotating geodesic sphere, centred on screen, while a CENTRED
   scroll-driven typewriter narrates the Problem (top) → Solution (below) story.
   Depth from low-alpha ink + a soft blur on rear nodes (see LsConstellation). */
/* Scrollytelling pin. The tall section gives the sticky child room to pin while the
   scatter→sphere scrubs. svh (small-viewport height) is used on purpose: on iOS
   Safari the dynamic toolbar makes `vh` jump as it shows/hides, which reflows the
   pin and stutters the scrub — svh is stable, so the section height and the sticky
   height stay locked while you scroll. (vh fallback first for old engines.) */
/* The hero animation is a SELF-RUNNING, time-based animation (see LsConstellation):
   it is NOT scrubbed by scroll, so the section is a normal one-viewport block — no
   tall pinned scroll region, no position:sticky pin, no scroll-snap. This keeps the
   whole page scrolling smoothly/naturally; the animation self-plays (and reverses)
   via a light scroll-into-view trigger in JS. */
.lsc { position: relative; width: 100%; }
.lsc-sticky {
  position: relative;
  height: 100vh; height: 100svh;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
/* Legibility scrim — a full-bleed gradient at the TOP of the animation: the page
   background colour (theme token --bg) at the top fading to transparent toward the
   sphere, so the problem/solution copy reads cleanly over the particles. The top is
   exactly var(--bg) so it blends seamlessly into the page background (no hard edge);
   it sits ABOVE the particles (z-index:1) but BELOW the story text (z-index:2), and
   fades out before the centred sphere so it doesn't dim the animation. The end stop
   is var(--bg) at ~6% alpha (via color-mix) rather than the `transparent` keyword,
   which would fade through grey on light themes and show a visible band. */
.lsc-sticky::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: clamp(260px, 42vh, 480px);
  z-index: 1; pointer-events: none;
  background: linear-gradient(
    to bottom,
    var(--bg) 0%,
    var(--bg) 40%,
    color-mix(in srgb, var(--bg), transparent 94%) 100%
  );
}
/* particle field — nudged DOWN (margin, not transform, so the fixed nav's
   backdrop-filter can still sample the particles) so the sphere clears the title
   instead of overlapping it. Slightly smaller so the downward shift doesn't clip. */
.lsc-wrap {
  width: min(820px, 88vw, 66vh);
  margin-top: clamp(72px, 14vh, 160px);
  color: var(--ink, #15161A);
}
.lsc-wrap svg { width: 100%; height: auto; display: block; overflow: visible; }
.lsc-labels text { font-family: var(--f-sans); font-weight: 340; letter-spacing: -0.01em; }

/* centred story — anchored at the top centre. The problem types in first; the
   solution then REPLACES it in the SAME spot (both blocks share one overlapping
   position and crossfade), not stacked below. */
.lsc-story {
  /* top clears the fixed nav bar comfortably (nav ≈ 64px). */
  position: absolute; top: clamp(92px, 13vh, 150px); left: 50%;
  transform: translateX(-50%); z-index: 2;
  width: min(700px, 92vw); text-align: center;
  pointer-events: none;
}
.lsc-story-block {
  position: absolute; top: 0; left: 0; right: 0; width: 100%;
  text-align: center; will-change: opacity;
}
.lsc-story-title {
  font-family: var(--f-sans);
  font-size: clamp(22px, 2.5vw, 36px); font-weight: 600;
  letter-spacing: -0.02em; line-height: 1.16; color: var(--ink);
  margin: 10px 0 12px; min-height: 1.16em;
}
.lsc-story-body {
  font-size: clamp(14px, 1.15vw, 17px); line-height: 1.5; color: var(--ink-3);
  margin: 0;
}
.lsc-caret {
  display: inline-block; width: 2px; height: 0.92em; margin-left: 2px;
  vertical-align: -0.08em; background: var(--indigo, #5B5DDF);
  animation: lsc-blink 1s steps(1) infinite;
}
@keyframes lsc-blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }

/* Narrow / mobile: tighter centred column. */
@media (max-width: 860px) {
  /* Clear the fixed nav (~60px tall at top:0) PLUS the notch safe-area so the
     problem/solution title is never hidden behind the bar. z-index keeps it above
     the scrim + particles. */
  .lsc-story { width: auto; left: 0; right: 0; transform: none; z-index: 3;
    top: calc(env(safe-area-inset-top, 0px) + clamp(82px, 12vh, 104px));
    padding: 0 clamp(20px, 6vw, 40px); }
  /* The half-sphere was a node-distribution bug (now fixed); there's plenty of room,
     so scale the sphere UP. It sits below the title; the shorter scrim (below) clears
     it so the full circle shows. */
  .lsc-wrap { width: min(96vw, 62vh); margin-top: clamp(200px, 31vh, 300px); }
  /* Shorter scrim on mobile — it only needs to cover the title, and must NOT reach
     down over the (now larger) sphere. */
  .lsc-sticky::before { height: clamp(190px, 29vh, 280px); }
}
@media (prefers-reduced-motion: reduce) {
  .lsc-caret { animation: none; display: none; }
}

/* Reduced motion: no tall scroll / no sticky — the organised sphere with the
   Solution copy shown above it (the end state), centred. */
.lsc--static { height: auto; }
.lsc--static .lsc-sticky {
  position: static; height: auto; min-height: 0;
  flex-direction: column-reverse; gap: clamp(28px, 5vh, 56px);
  padding: clamp(56px, 11vh, 120px) 0;
}
.lsc--static .lsc-story {
  position: static; transform: none; height: auto; width: min(680px, 90vw);
  text-align: center; margin: 0 auto;
}
.lsc--static .lsc-story-block { position: static; text-align: center; }
.lsc--static .lsc-story-block:first-child { display: none; } /* static shows the Solution */

/* NOTE: desktop and mobile share ONE model — a normal one-viewport .lsc section whose
   animation self-plays on a timer (no scroll-scrub, no pin, no scroll-snap). The page
   scrolls naturally; a light scroll-into-view trigger in JS starts the forward/reverse
   play. The old `.lsc--flow` / discrete-step / scroll-snap paths are all retired. */

/* ── Landing section 4: Built by architects (floor plan draws itself) ──────── */
.ls-built-inner {
  display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center;
}
.ls-built-copy { max-width: 440px; }
.ls-built-sheet {
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card); padding: 20px;
  box-shadow: 0 8px 30px rgba(0,0,0,0.05);
}
.ls-built-sheet svg { width: 100%; height: auto; display: block; }
/* drafting grid */
.ls-built-grid line {
  stroke: var(--line); stroke-width: 0.5;
  opacity: 0; transition: opacity 700ms var(--ease-out, ease);
}
.ls-built-sheet.is-drawn .ls-built-grid line { opacity: 0.4; }
/* drafting centerline axes (dash-dot) */
.ls-built-axis {
  stroke: var(--indigo); stroke-width: 0.8; stroke-dasharray: 6 3 1 3;
  opacity: 0; transition: opacity 800ms var(--ease-out, ease) 0.2s;
}
.ls-built-sheet.is-drawn .ls-built-axis { opacity: 0.3; }
/* dimension line + ticks + reference bubbles — draw in */
.ls-built-draft path, .ls-built-draft circle {
  fill: none; stroke: var(--ink-4); stroke-width: 1; stroke-linecap: round;
  opacity: 0.55;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 900ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) 0.45s;
}
.ls-built-sheet.is-drawn .ls-built-draft path,
.ls-built-sheet.is-drawn .ls-built-draft circle { stroke-dashoffset: 0; }
/* spokes from core to project-layer nodes */
.ls-built-spoke {
  stroke: var(--indigo); stroke-width: 1; opacity: 0.5;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 700ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-built-sheet.is-drawn .ls-built-spoke { stroke-dashoffset: 0; }
/* project-layer nodes */
.ls-built-node {
  fill: var(--bg-card); stroke: var(--indigo); stroke-width: 2;
  opacity: 0; transform: scale(0.3); transform-box: fill-box; transform-origin: center;
  transition: opacity 500ms var(--ease-out, ease),
              transform 500ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.ls-built-sheet.is-drawn .ls-built-node { opacity: 1; transform: scale(1); }
/* node labels */
.ls-built-label {
  fill: var(--ink-3); font-family: var(--f-sans);
  font-size: 12px; font-weight: 500; letter-spacing: 0.02em;
  opacity: 0; transition: opacity 600ms var(--ease-out, ease);
}
.ls-built-sheet.is-drawn .ls-built-label { opacity: 0.9; }
/* central Aecos mark — scales/fades in last */
.ls-built-core {
  opacity: 0; transform: scale(0.86);
  transform-box: view-box; transform-origin: 210px 160px;
  transition: opacity 700ms var(--ease-out, ease) 1.5s,
              transform 700ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)) 1.5s;
}
.ls-built-sheet.is-drawn .ls-built-core { opacity: 1; transform: scale(1); }
.ls-built-mark { fill: none; stroke: var(--indigo); stroke-width: 2.2; stroke-linecap: round; }
.ls-built-coredot { fill: var(--indigo); }

/* ── Landing section 5: Security (nested FIRM → PROJECT → ROLE → RECORD) ───── */
.ls-sec-stack { max-width: 560px; margin: 40px auto 0; }
.ls-sec-layer {
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-card); padding: 16px; margin-top: 12px;
  opacity: 0; transform: translateY(8px);
  box-shadow: 0 0 0 0 transparent;
  transition:
    opacity 500ms var(--ease-out, ease),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 500ms var(--ease-out, ease),
    box-shadow 500ms var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.ls-sec-stack > .ls-sec-layer { margin-top: 0; }
.ls-sec-stack.is-on .ls-sec-layer {
  opacity: 1; transform: translateY(0);
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 16%, transparent);
}
.ls-sec-layer-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 4px;
}
.ls-sec-label {
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--indigo);
}
.ls-sec-desc { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }

/* Security / trust — 3-column section shown right before pricing */
.ls-sectrust-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
  max-width: 920px; margin: 40px auto 0;
}
.ls-sectrust-col {
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card); padding: 22px 20px;
  opacity: 0; transform: translateY(10px);
  transition:
    opacity 500ms var(--ease-out, ease),
    transform 500ms var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.ls-sectrust-grid.is-on .ls-sectrust-col { opacity: 1; transform: translateY(0); }
.ls-sectrust-icon {
  width: 44px; height: 44px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  margin-bottom: 14px;
}
.ls-sectrust-title {
  font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink));
  line-height: 1.3; margin-bottom: 7px;
}
.ls-sectrust-desc { font-size: 13px; color: var(--ink-3); line-height: 1.55; }
.ls-sectrust-foot { text-align: center; margin-top: 26px; }
.landing-ai-trust-badge {
  display: flex; align-items: center; gap: 6px;
  width: fit-content; margin: 16px auto 0;
  padding: 5px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 24%, transparent);
}
.landing-ai-trust-badge svg { flex-shrink: 0; }
@media (max-width: 768px) {
  .ls-sectrust-grid { grid-template-columns: 1fr; gap: 14px; max-width: 440px; }
}
@media (prefers-reduced-motion: reduce) {
  .ls-sectrust-col { opacity: 1; transform: none; transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ls-prob-panel { transform: none; transition: none; }
  .ls-prob-card-label { opacity: 1; transform: none; transition: none; }
  .ls-sol-line { stroke-dashoffset: 0; transition: none; }
  .ls-sol-node { opacity: 1; transition: none; }
  .ls-built-grid line { opacity: 0.4; transition: none; }
  .ls-built-axis { opacity: 0.3; transition: none; }
  .ls-built-draft path, .ls-built-draft circle { stroke-dashoffset: 0; transition: none; }
  .ls-built-spoke { stroke-dashoffset: 0; transition: none; }
  .ls-built-node { opacity: 1; transform: scale(1); transition: none; }
  .ls-built-label { opacity: 0.9; transition: none; }
  .ls-built-core { opacity: 1; transform: scale(1); transition: none; }
  .ls-sec-layer { opacity: 1; transform: none; transition: none; }
}

@media (max-width: 900px) {
  .ls-built-inner { grid-template-columns: 1fr; gap: 28px; }
}

/* ── Projects demo ── */
.lfc-proj-wrap { display: flex; flex-direction: column; gap: 12px; height: 100%; overflow-y: auto; }
.lfc-proj-chips { display: flex; gap: 6px; flex-shrink: 0; }
.lfc-proj-chip {
  font-size: 12px; font-weight: 500; padding: 4px 10px; border-radius: 20px;
  background: var(--bg-elev); border: 1px solid var(--line); color: var(--ink-3);
  cursor: default; transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.lfc-proj-chip.active {
  background: var(--indigo-soft); color: var(--indigo-ink); border-color: var(--indigo-line);
}
.lfc-proj-table { display: flex; flex-direction: column; gap: 2px; }
.lfc-proj-thead {
  display: grid; grid-template-columns: 2fr 0.6fr 0.6fr 1fr 1.2fr;
  gap: 10px; padding: 0 12px 6px;
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--ink-5);
}
.lfc-proj-row {
  display: grid; grid-template-columns: 2fr 0.6fr 0.6fr 1fr 1.2fr;
  gap: 10px; padding: 9px 12px; align-items: center;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 8px;
  animation: lfc-fade-in 0.3s ease both;
}
.lfc-proj-name  { font-size: 12.5px; font-weight: 500; color: var(--ink); }
.lfc-office-pill {
  font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px;
  display: inline-block; text-align: center;
}
.lfc-phase-pill {
  font-size: 10px; font-weight: 700; color: var(--indigo); letter-spacing: 0.05em;
  background: var(--indigo-soft); padding: 2px 6px; border-radius: 4px; display: inline-block;
}
.lfc-risk-pill {
  font-size: 11px; font-weight: 500; padding: 2px 8px; border-radius: 4px;
  display: inline-block; transition: color 0.4s, background 0.4s;
}
.lfc-proj-fee-wrap {
  position: relative; height: 5px; background: var(--line); border-radius: 3px; overflow: visible;
  display: flex; align-items: center; gap: 6px;
}
.lfc-proj-fee-bar  { height: 100%; border-radius: 3px; transition: background 0.4s; }
.lfc-proj-fee-pct  { font-size: 10px; color: var(--ink-4); white-space: nowrap; margin-left: 4px; flex-shrink: 0; }

/* ── Studio Review demo ── */
.lfc-sr-wrap { display: flex; flex-direction: column; height: 100%; position: relative; }
.lfc-sr-bg {
  position: absolute; inset: 0; border-radius: 10px;
  background-image:
    linear-gradient(color-mix(in srgb, var(--indigo) 8%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--indigo) 8%, transparent) 1px, transparent 1px);
  background-size: 24px 24px;
  pointer-events: none;
}
.lfc-sr-svg {
  position: relative; flex: 1; width: 100%; max-height: 280px;
}
.lfc-sr-callout { animation: lfc-fade-in 0.4s ease both; }
.lfc-sr-comment  { animation: lfc-sr-slide-in 0.4s cubic-bezier(0.2, 0, 0.1, 1) both; }
@keyframes lfc-sr-slide-in { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
.lfc-sr-statusbar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 0 0; font-size: 11.5px; color: var(--ink-4);
  flex-shrink: 0;
}
.lfc-sr-status-item { display: flex; align-items: center; gap: 4px; }
.lfc-sr-status-sep  { opacity: 0.35; }

/* ── Timesheets demo ── */
.lfc-ts-wrap { display: flex; flex-direction: column; gap: 0; height: 100%; }
.lfc-ts-grid { display: flex; flex: 1; gap: 0; overflow: hidden; }
.lfc-ts-yaxis {
  position: relative; width: 36px; flex-shrink: 0; margin-top: 26px;
}
.lfc-ts-hour-label {
  position: absolute; right: 4px; font-size: 9px; color: var(--ink-5);
  transform: translateY(-50%); white-space: nowrap;
}
.lfc-ts-days { display: flex; flex: 1; gap: 4px; }
.lfc-ts-day-col { flex: 1; display: flex; flex-direction: column; }
.lfc-ts-day-label {
  font-size: 10.5px; font-weight: 600; color: var(--ink-4);
  text-align: center; padding-bottom: 6px; flex-shrink: 0;
}
.lfc-ts-col-inner { flex: 1; position: relative; }
.lfc-ts-gridline {
  position: absolute; left: 0; right: 0; height: 1px;
  background: var(--line); opacity: 0.4;
}
.lfc-ts-block {
  position: absolute; left: 2px; right: 2px;
  border-radius: 5px; padding: 4px 5px;
  overflow: hidden; animation: lfc-fade-in 0.3s ease both;
}
.lfc-ts-ghost-block {
  position: absolute; left: 2px; right: 2px;
  border-radius: 5px; padding: 4px 5px;
  border: 1.5px dashed var(--indigo);
  background: color-mix(in srgb, var(--indigo) 6%, transparent);
  animation: lfc-fade-in 0.4s ease both; overflow: hidden;
}
.lfc-ts-block-label {
  font-size: 9px; font-weight: 600; color: #fff; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lfc-ts-ghost-block .lfc-ts-block-label { color: var(--indigo); }
.lfc-ts-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding-top: 10px; flex-shrink: 0;
  animation: lfc-fade-in 0.3s ease both;
}
.lfc-ts-ai-label {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--indigo);
}
.lfc-ts-accept-btn {
  font-size: 12px; font-weight: 500; padding: 5px 12px; border-radius: 6px;
  background: var(--indigo); color: #fff; border: none; cursor: default;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.lfc-ts-accept-btn.pulse {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--indigo) 30%, transparent);
  transform: scale(1.03);
}

/* ── Financial demo ── */
.lfc-fin-wrap { display: flex; flex-direction: column; gap: 0; height: 100%; overflow-y: auto; }
.lfc-fin-section-title {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-5); margin-bottom: 10px;
}
.lfc-fin-invoice-list { display: flex; flex-direction: column; gap: 4px; }
.lfc-fin-invoice-row {
  display: grid; grid-template-columns: 1fr auto auto 80px;
  align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: 8px;
  animation: lfc-fade-in 0.3s ease both;
}
.lfc-fin-inv-client { font-size: 13px; font-weight: 500; color: var(--ink); }
.lfc-fin-inv-date   { font-size: 11px; color: var(--ink-4); }
.lfc-fin-inv-amount { font-size: 13px; font-weight: 600; color: var(--ink); text-align: right; }
.lfc-fin-inv-status { font-size: 12px; font-weight: 500; text-align: right; }
.lfc-fin-budget-wrap { display: flex; flex-direction: column; gap: 8px; }
.lfc-fin-budget-labels {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--ink-3);
}
.lfc-fin-budget-bar-bg {
  position: relative; height: 10px; background: var(--line); border-radius: 5px; overflow: hidden;
}
.lfc-fin-budget-bar {
  height: 100%; border-radius: 5px; transition: width 1s ease, background 0.5s ease;
}
.lfc-fin-budget-threshold {
  position: absolute; left: 80%; top: -2px; bottom: -2px;
  width: 2px; background: var(--bad); opacity: 0.6; border-radius: 1px;
}
.lfc-fin-budget-sub { font-size: 11px; color: var(--ink-5); }

/* ── Multi-office demo ── */
.lfc-mo-wrap { display: flex; flex-direction: column; gap: 20px; height: 100%; }
.lfc-mo-cards { display: flex; gap: 20px; flex: 1; }
.lfc-mo-card {
  flex: 1; padding: 20px; border-radius: 12px;
  background: var(--bg-elev); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 16px;
  transition: border-color 0.4s ease, box-shadow 0.4s ease;
}
.lfc-mo-card.active {
  border-color: var(--indigo-line);
  box-shadow: 0 4px 20px color-mix(in srgb, var(--indigo) 12%, transparent);
}
.lfc-mo-card-top { display: flex; align-items: center; gap: 12px; }
.lfc-mo-flag { font-size: 24px; line-height: 1; }
.lfc-mo-name { font-size: 14px; font-weight: 600; color: var(--ink); }
.lfc-mo-staff { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.lfc-mo-clock-row { display: flex; align-items: center; gap: 14px; }
.lfc-mo-time { font-size: 18px; font-weight: 600; color: var(--ink); letter-spacing: -0.02em; }
.lfc-mo-currency { font-size: 11px; color: var(--ink-4); margin-top: 2px; }
.lfc-mo-active-chip {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--indigo);
  background: var(--indigo-soft); border: 1px solid var(--indigo-line);
  border-radius: 20px; padding: 3px 10px; align-self: flex-start;
  animation: lfc-fade-in 0.3s ease both;
}
.lfc-mo-footer {
  display: flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--ink-5); flex-shrink: 0;
}

/* AI section */
.landing-ai-section { background: var(--bg-card); }
.landing-ai-inner {
  display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center;
}
.landing-ai-prompts {
  display: flex; flex-direction: column; gap: 10px;
}
.landing-ai-prompts-label {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-4); margin-bottom: 4px;
}
.landing-ai-bubble {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 12px 12px 12px 4px;
  padding: 12px 16px; font-size: 14px; color: var(--ink-2);
  line-height: 1.5;
}

/* ───────────────────────────────────────────────────────────────────────────
   Pricing (claude.com-style) — card row + Enterprise band + grouped matrix
   Built for the redesigned landing #pricing-teaser section (LandingPricing).
   Theme-safe: every colour is a token, so light / mid / dark all resolve.
   ─────────────────────────────────────────────────────────────────────────── */

/* Monthly / annual segmented toggle */
.lp2-toggle-row {
  display: inline-flex; align-items: center; gap: 4px;
  margin: 30px auto 0; padding: 4px;
  background: var(--bg-sunk); border: 1px solid var(--line);
  border-radius: 999px;
}
.lp2-toggle-opt {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--f-sans); font-size: 13px; font-weight: 600;
  color: var(--ink-4); background: transparent; border: 0;
  border-radius: 999px; padding: 7px 18px; cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
}
.lp2-toggle-opt:hover { color: var(--ink-2); }
.lp2-toggle-opt.is-on {
  color: var(--ink); background: var(--bg-card);
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.lp2-toggle-save {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
  color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent);
  border-radius: 999px; padding: 2px 7px;
}

/* Card row — four self-serve tiers */
.lp2-cards {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 18px; margin-top: 40px; align-items: stretch;
  text-align: left;
  opacity: 1; transform: none;
}
.lp2-cards:not(.is-on) { opacity: 0; transform: translateY(18px); }
.lp2-cards.is-on { opacity: 1; transform: none; transition: opacity 0.6s ease, transform 0.6s ease; }

.lp2-card {
  position: relative;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 18px; padding: 26px 22px 24px;
  display: flex; flex-direction: column; gap: 14px;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.lp2-card:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(0,0,0,0.07); }
/* (No `.lp2-card-featured` / `.lp2-badge` rules — every pricing tier is rendered with
   the same neutral .lp2-card treatment; no single plan is highlighted on the landing.) */
.lp2-card-head { display: flex; flex-direction: column; gap: 8px; }
.lp2-card-name {
  font-size: 14px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em;
}
.lp2-card-price { display: flex; align-items: baseline; gap: 3px; }
.lp2-amount {
  font-family: var(--f-sans);
  font-size: 42px; font-weight: 700; color: var(--ink); letter-spacing: -0.035em; line-height: 1;
}
.lp2-per { font-size: 14px; font-weight: 500; color: var(--ink-4); }
.lp2-billing-note { font-size: 12px; color: var(--ink-4); line-height: 1.4; min-height: 16px; }
.lp2-usage {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 600; color: var(--indigo-ink, var(--indigo));
  line-height: 1.35;
  background: var(--indigo-soft); border: 1px solid var(--indigo-line);
  border-radius: 10px; padding: 8px 11px;
}
.lp2-usage-x { font-size: 16px; font-weight: 800; letter-spacing: -0.02em; flex-shrink: 0; }
.lp2-card-desc {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.5; margin: 0; min-height: 38px;
}
/* margin-top:auto pins the CTA to the card bottom; pt gives breathing room
   above it so a feature-heavy card's button never crowds the last feature. */
.lp2-card-cta { width: 100%; font-size: 14px; justify-content: center; margin-top: auto; padding: 10px 20px; min-height: 42px; }
.lp2-feat-list { margin-bottom: 16px; }
.lp2-feat-list {
  list-style: none; padding: 0; margin: 4px 0 0;
  display: flex; flex-direction: column; gap: 9px;
  border-top: 1px solid var(--line-soft); padding-top: 16px;
}
.lp2-feat-row {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 12.5px; color: var(--ink-3); line-height: 1.45;
}
.lp2-feat-row svg { flex-shrink: 0; margin-top: 2px; color: var(--indigo); }

/* Enterprise callout band */
.lp2-ent {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  margin-top: 22px; padding: 26px 30px;
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 18px; text-align: left;
}
.lp2-ent-name { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 5px; }
.lp2-ent-desc { font-size: 13px; color: var(--ink-3); line-height: 1.55; margin: 0; max-width: 720px; }
.lp2-ent-cta { flex-shrink: 0; white-space: nowrap; }

/* Grouped comparison matrix */
.lp2-compare-head { margin-top: 56px; }
.lp2-compare-title {
  font-family: var(--f-sans);
  font-size: 22px; font-weight: 600; color: var(--ink); letter-spacing: -0.02em; margin: 0;
}
.lp2-matrix-wrap { margin-top: 24px; overflow-x: auto; }
.lp2-matrix {
  width: 100%; min-width: 760px; border-collapse: collapse; text-align: left;
}
.lp2-mx-corner { width: 30%; }
.lp2-mx-ph {
  font-size: 13px; font-weight: 600; color: var(--ink); text-align: center;
  padding: 0 8px 14px; border-bottom: 1px solid var(--line-strong); vertical-align: bottom;
}
.lp2-mx-ph-feat { color: var(--indigo-ink, var(--indigo)); }
.lp2-mx-group th {
  font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-4); background: var(--bg-sunk);
  padding: 9px 12px; border-bottom: 1px solid var(--line);
}
.lp2-mx-row { border-bottom: 1px solid var(--line-soft); }
.lp2-mx-rowlabel {
  font-size: 13px; font-weight: 500; color: var(--ink-2);
  padding: 12px 12px 12px 0; vertical-align: middle;
}
.lp2-mx-cell {
  font-size: 13px; color: var(--ink-3); text-align: center; padding: 12px 8px; vertical-align: middle;
}
.lp2-mx-cell-feat { background: color-mix(in srgb, var(--indigo) 4%, transparent); }
.lp2-cell-val { font-weight: 500; color: var(--ink-2); }
.lp2-mark { display: inline-flex; align-items: center; justify-content: center; }
.lp2-mark-yes { color: var(--indigo); }
.lp2-mark-no { color: var(--ink-5); font-size: 15px; }

/* Footer CTA */
.lp2-foot { margin-top: 52px; }
.lp2-foot-line { font-size: 17px; font-weight: 500; color: var(--ink); margin: 0 0 18px; }
.lp2-foot-ctas { display: inline-flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.lp2-foot-secondary {
  display: inline-flex; align-items: center;
  border: 1px solid var(--line-strong); background: var(--bg-card); color: var(--ink-2);
  text-decoration: none;
}
.lp2-foot-secondary:hover { border-color: var(--ink-4); color: var(--ink); }
.lp2-foot-fine { font-size: 12.5px; color: var(--ink-4); margin: 16px 0 0; }

/* Tablet — two-up cards */
@media (max-width: 1080px) {
  .lp2-cards { grid-template-columns: repeat(2, 1fr); max-width: 680px; margin-left: auto; margin-right: auto; }
}
/* Mobile — stack cards, scroll the matrix */
@media (max-width: 700px) {
  .lp2-cards { grid-template-columns: 1fr; max-width: 420px; gap: 14px; }
  .lp2-card:hover { transform: none; }
  .lp2-ent { flex-direction: column; align-items: flex-start; padding: 22px; }
  .lp2-ent-cta { width: 100%; justify-content: center; }
  .lp2-foot-ctas { display: flex; }
  .lp2-foot-ctas .btn { flex: 1; justify-content: center; }
}

/* Founder */
/* Audience section */
.landing-audience-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 20px; margin-top: 40px;
}
.landing-audience-card {
  padding: 24px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-card);
}
.landing-audience-card-roadmap {
  opacity: 0.7;
  background: var(--bg-sunk);
}
/* Learn hub — audience cards rendered as clickable resource links. */
.learn-card {
  display: flex; flex-direction: column; text-decoration: none; cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.learn-card:hover {
  border-color: var(--indigo-line); transform: translateY(-2px);
  box-shadow: 0 12px 30px -16px rgba(20, 22, 50, 0.22);
}
.learn-card-cta { margin-top: 14px; font-size: 13px; font-weight: 600; color: var(--indigo); }
.landing-audience-header {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
}
.landing-audience-label {
  font-size: 14px; font-weight: 600; color: var(--ink);
}
.landing-audience-badge {
  font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-4); background: var(--bg-elev);
  border: 1px solid var(--line); border-radius: 4px; padding: 2px 6px;
}
.landing-audience-body {
  font-size: 13px; line-height: 1.6; color: var(--ink-3); margin: 0;
}

/* Social proof */
.landing-social-proof {
  background: var(--bg-card);
  border-top: none;
  border-bottom: none;
}
.landing-sp-headline {
  font-size: clamp(18px, 2.5vw, 24px); font-weight: 600;
  color: var(--ink); margin: 0 0 20px; text-align: center;
}
.landing-sp-list {
  max-width: 640px; margin: 0 auto;
  padding: 0 0 0 20px; display: flex; flex-direction: column; gap: 10px;
}
.landing-sp-list li {
  font-size: 14px; line-height: 1.65; color: var(--ink-3);
}

/* Founder */
.landing-founder-section { background: var(--bg-card); }
.landing-founder-inner {
  display: grid; grid-template-columns: auto 1fr; gap: 48px; align-items: center;
}
.landing-founder-avatar {
  width: 80px; height: 80px; border-radius: 50%;
  background: var(--indigo); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; font-weight: 600; letter-spacing: 0.02em;
  flex-shrink: 0;
}
.landing-founder-copy { max-width: 580px; }
.landing-founder-quote {
  margin: 20px 0 0; padding: 16px 20px;
  border-left: 3px solid var(--indigo);
  background: var(--bg-elev); border-radius: 0 8px 8px 0;
  font-size: 14px; line-height: 1.65; color: var(--ink-2);
  font-style: italic;
}
.landing-founder-quote cite {
  display: block; margin-top: 8px;
  font-size: 12px; font-weight: 600; font-style: normal;
  color: var(--ink-4); letter-spacing: 0.02em;
}

/* Security */
.landing-security-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 24px; margin-top: 40px;
}
.landing-security-item {
  display: flex; flex-direction: column; gap: 10px;
}
.landing-security-icon {
  width: 40px; height: 40px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-3);
}
.landing-security-title {
  font-size: 14px; font-weight: 600; color: var(--ink);
}
.landing-security-body {
  font-size: 13px; line-height: 1.6; color: var(--ink-3);
}

/* Final CTA */
.landing-final-cta {
  background: var(--indigo-soft);
  text-align: center;
}
.landing-final-cta-inner { display: flex; flex-direction: column; align-items: center; }
.landing-final-cta-note {
  margin-top: 16px; font-size: 13px; color: var(--ink-4);
}
/* One-line trust strip — replaces the full security section on the home;
   the depth lives on the Security page. */
.landing-trust-line {
  display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; justify-content: center;
  margin: 26px auto 0; max-width: 640px;
  font-size: 12.5px; color: var(--ink-4); line-height: 1.5;
}
.landing-trust-line svg { color: var(--indigo); flex-shrink: 0; }
.landing-link { color: var(--indigo); text-decoration: none; }
.landing-link:hover { text-decoration: underline; }

/* Footer */
.landing-footer {
  background: var(--bg-card);
  border-top: none;
  padding: 56px 0 32px;
}
.landing-footer-inner {
  display: grid; grid-template-columns: 1fr auto; gap: 64px;
  margin-bottom: 40px;
}
.landing-footer-brand { display: flex; flex-direction: column; gap: 8px; max-width: 300px; }
.landing-footer-tagline { font-size: 13px; color: var(--ink-4); }
/* subscribe-to-changelog form */
.landing-foot-sub { margin-top: 14px; display: flex; flex-direction: column; gap: 7px; }
.landing-foot-sub-lbl { font-size: 12px; color: var(--ink-4); line-height: 1.4; }
.landing-foot-sub-row { display: flex; gap: 7px; max-width: 300px; }
.landing-foot-sub-input {
  flex: 1; min-width: 0; font-size: 12.5px; font-family: var(--f-sans);
  color: var(--ink); background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius-btn); padding: 8px 14px;
}
.landing-foot-sub-input:focus { outline: none; border-color: var(--indigo); box-shadow: 0 0 0 3px var(--indigo-soft, color-mix(in srgb, var(--indigo) 14%, transparent)); }
.landing-foot-sub-btn {
  flex-shrink: 0; font-size: 12.5px; font-weight: 600; color: #fff;
  background: var(--indigo); border: none; border-radius: var(--radius-btn); padding: 8px 14px;
  cursor: pointer; transition: opacity 0.15s var(--ease-out, ease);
}
.landing-foot-sub-btn:hover { opacity: 0.88; }
.landing-footer-cols { display: flex; gap: 44px; flex-wrap: wrap; }
.landing-footer-col { display: flex; flex-direction: column; gap: 10px; }
.landing-footer-col-head {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-4); margin-bottom: 2px;
}
.landing-footer-link {
  font-size: 13px; color: var(--ink-3); text-decoration: none;
  transition: color 0.15s;
}
.landing-footer-link:hover { color: var(--ink); }
.landing-footer-cta {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center; padding: 8px 0 32px; margin-bottom: 24px;
  border-top: none; padding-top: 32px;
}
.landing-footer-cta-line { font-size: 16px; font-weight: 600; color: var(--ink-1, var(--ink)); letter-spacing: -0.01em; }
.landing-footer-cta-note { font-size: 12px; color: var(--ink-5); }
.landing-footer-bottom {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
  font-size: 12px; color: var(--ink-5);
  border-top: none; padding-top: 24px;
}
.landing-footer-legal { display: flex; gap: 18px; }
.landing-footer-legal .landing-footer-link { font-size: 12px; }

/* ============================================================================
   PricingPage — standalone hash-routed page (#pricing).
   Reuses landing-wrap, landing-container, landing-nav, landing-section, etc.
   ============================================================================ */
.pricing-page-wrap .landing-section { padding: 72px 0; }

/* Annual toggle */
/* Proposed-pricing disclaimer — per-seat $ figures are placeholders pending
   founder confirmation. Theme-aware muted pill. */
.pricing-proposed-note {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 auto 26px; padding: 6px 14px; border-radius: 999px;
  font-size: 12.5px; color: var(--ink-3);
  background: var(--bg-sunk); border: 1px solid var(--line);
}
.pricing-proposed-note strong { color: var(--ink); font-weight: 700; }
.pricing-toggle-row {
  display: flex; align-items: center; gap: 10px; justify-content: center;
}
.pricing-toggle-label { font-size: 13.5px; color: var(--ink-3); }
.pricing-toggle-label.active { color: var(--ink); font-weight: 500; }
.pricing-toggle {
  width: 44px; height: 24px; border-radius: 12px;
  background: var(--line); border: none; cursor: pointer; position: relative;
  transition: background 0.2s;
}
.pricing-toggle.annual { background: var(--indigo); }
.pricing-toggle-thumb {
  position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; transition: transform 0.2s ease;
  display: block;
}
.pricing-toggle.annual .pricing-toggle-thumb { transform: translateX(20px); }
.pricing-toggle-badge {
  font-size: 11px; font-weight: 600; padding: "2px 8px";
  color: var(--good); background: color-mix(in srgb, var(--good) 12%, var(--bg-card));
  border-radius: 99px; padding: 2px 8px;
}

/* Tier grid — full width 5-col on pricing page */
/* ── Tooltip primitive (ui.jsx <Tooltip>) ───────────────────────────────────── */
.ui-tooltip {
  position: relative;
  display: inline-flex;
  outline: none;
}
.ui-tooltip-bubble {
  position: absolute;
  z-index: 60;
  width: max-content;
  max-width: 240px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--ink, #16181d);
  color: #fff;
  font-size: 11.5px;
  font-weight: 450;
  line-height: 1.4;
  text-align: left;
  white-space: normal;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  opacity: 0;
  visibility: hidden;
  transform: translateY(2px);
  transition: opacity 0.13s ease, transform 0.13s ease, visibility 0s linear 0.13s;
  pointer-events: none;
}
.ui-tooltip:hover .ui-tooltip-bubble,
.ui-tooltip:focus .ui-tooltip-bubble,
.ui-tooltip:focus-within .ui-tooltip-bubble {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity 0.13s ease, transform 0.13s ease, visibility 0s;
}
/* Caret */
.ui-tooltip-bubble::after {
  content: "";
  position: absolute;
  width: 7px; height: 7px;
  background: var(--ink, #16181d);
  transform: rotate(45deg);
}
/* Placement */
.ui-tooltip-top .ui-tooltip-bubble    { bottom: calc(100% + 8px); left: 50%; margin-left: -120px; }
.ui-tooltip-top .ui-tooltip-bubble::after    { top: 100%; left: 50%; margin-left: -3.5px; margin-top: -3.5px; }
.ui-tooltip-bottom .ui-tooltip-bubble { top: calc(100% + 8px); left: 50%; margin-left: -120px; }
.ui-tooltip-bottom .ui-tooltip-bubble::after { bottom: 100%; left: 50%; margin-left: -3.5px; margin-bottom: -3.5px; }
.ui-tooltip-left .ui-tooltip-bubble   { right: calc(100% + 8px); top: 50%; transform: translateY(-50%) translateX(2px); }
.ui-tooltip-left:hover .ui-tooltip-bubble,
.ui-tooltip-left:focus-within .ui-tooltip-bubble { transform: translateY(-50%) translateX(0); }
.ui-tooltip-left .ui-tooltip-bubble::after    { left: 100%; top: 50%; margin-top: -3.5px; margin-left: -3.5px; }
.ui-tooltip-right .ui-tooltip-bubble  { left: calc(100% + 8px); top: 50%; transform: translateY(-50%) translateX(-2px); }
.ui-tooltip-right:hover .ui-tooltip-bubble,
.ui-tooltip-right:focus-within .ui-tooltip-bubble { transform: translateY(-50%) translateX(0); }
.ui-tooltip-right .ui-tooltip-bubble::after   { right: 100%; top: 50%; margin-top: -3.5px; margin-right: -3.5px; }
/* The top/bottom bubbles use a fixed left offset for centering; clamp so edge
   cards don't push the bubble off-screen. */
@media (prefers-reduced-motion: reduce) {
  .ui-tooltip-bubble { transition: opacity 0.13s ease, visibility 0s linear 0.13s; transform: none; }
  .ui-tooltip:hover .ui-tooltip-bubble,
  .ui-tooltip:focus-within .ui-tooltip-bubble { transform: none; }
}

.pricing-tier-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
}
.pricing-tier-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 16px; padding: 24px 20px;
  display: flex; flex-direction: column; gap: 10px;
  position: relative;
  transition: border-color 0.15s;
}
.pricing-tier-featured {
  border-color: var(--indigo);
  box-shadow: 0 0 0 1px var(--indigo), 0 8px 32px color-mix(in srgb, var(--indigo) 10%, transparent);
}
.pricing-tier-badge {
  position: absolute; top: -12px; left: 50%; transform: translateX(-50%);
  background: var(--indigo); color: #fff;
  font-size: 11px; font-weight: 600; padding: 3px 12px; border-radius: 99px;
  white-space: nowrap;
}
.pricing-tier-name { font-size: 14px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.pricing-tier-price { display: flex; align-items: baseline; gap: 2px; }
.pricing-tier-amount { font-family: var(--f-sans); font-size: 28px; font-weight: 700; color: var(--ink); letter-spacing: -0.03em; }
.pricing-tier-per { font-size: 12px; color: var(--ink-4); }
.pricing-tier-billed { font-size: 10px; color: var(--ink-5); margin-left: 2px; }
.pricing-tier-custom { font-size: 22px; color: var(--ink-3); font-weight: 600; }
.pricing-tier-desc { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }
.pricing-tier-divider { border: none; border-top: 1px solid var(--line); margin: 4px 0; }
.pricing-tier-limits { display: flex; flex-direction: column; gap: 6px; }
.pricing-tier-limit-row {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 11.5px; color: var(--ink-3); line-height: 1.45;
}
.pricing-tier-limit-row svg { flex-shrink: 0; margin-top: 1px; color: var(--ink-4); }
.pricing-tier-features { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.pricing-tier-feature-row { display: flex; align-items: flex-start; gap: 7px; font-size: 11.5px; color: var(--ink-3); line-height: 1.45; }
.pricing-tier-feature-row svg { flex-shrink: 0; margin-top: 1px; color: var(--good); }
.pricing-feat-label { flex: 1; }
/* Info trigger that opens the per-feature tooltip. Pushed to the row's right
   edge; muted until hover/focus so it stays quiet but discoverable. */
.pricing-tier-feature-row .ui-tooltip { margin-left: auto; flex-shrink: 0; line-height: 0; margin-top: 1px; }
.pricing-tier-feature-row .pricing-feat-info { color: var(--ink-5); opacity: 0.55; transition: opacity 0.12s, color 0.12s; cursor: help; }
.pricing-tier-feature-row .ui-tooltip:hover .pricing-feat-info,
.pricing-tier-feature-row .ui-tooltip:focus .pricing-feat-info { color: var(--indigo); opacity: 1; }

/* FAQ */
.pricing-faq-section { background: var(--bg-card); }
/* Centered to match the landing's centered-section treatment: the FAQ block is
   centered as a column and its heading is centered; the accordion rows keep their
   left-aligned question/answer reading flow. */
.pricing-faq-inner { max-width: 720px; margin-left: auto; margin-right: auto; }
.pricing-faq-section .landing-section-title { text-align: center; }
.pricing-faq-list { display: flex; flex-direction: column; }
.pricing-faq-item { border-bottom: 1px solid var(--line); }
.pricing-faq-item:first-child { border-top: 1px solid var(--line); }
.pricing-faq-q {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 18px 0; background: none; border: none; cursor: pointer;
  font-size: 14.5px; font-weight: 500; color: var(--ink); text-align: left;
  font-family: var(--f-sans); line-height: 1.4;
}
.pricing-faq-q:hover { color: var(--indigo); }
.pricing-faq-a {
  font-size: 14px; color: var(--ink-3); line-height: 1.7;
  padding: 0 0 20px; max-width: 64ch;
}

/* Hero section on pricing page */
.pricing-hero { background: var(--bg-elev); }

/* Trial card */
.pricing-tier-free { background: var(--bg-elev); }
.pricing-tier-free-note {
  display: inline-block; font-size: 11px; font-weight: 600;
  color: var(--good); background: color-mix(in srgb, var(--good) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 25%, transparent);
  border-radius: 99px; padding: 2px 9px; letter-spacing: 0.02em;
}
/* AI credit badge on paid plan cards */
.pricing-tier-ai-credit {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; color: var(--indigo); font-weight: 500;
}
.pricing-tier-ai-credit svg { flex-shrink: 0; }
.pricing-tier-usage-note {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--ink-2, var(--ink));
  line-height: 1.4; margin-top: 6px;
}
.pricing-tier-usage-icon { color: var(--indigo); font-size: 11px; flex-shrink: 0; }
/* CTA button loading state */
.pricing-tier-cta-btn { transition: opacity 0.15s ease; }
.pricing-tier-cta-loading { opacity: 0.6; cursor: not-allowed; }
/* Custom-quote tier card */
.pricing-tier-quote { border-style: dashed; }
.pricing-tier-quote-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-elev); border: 1px solid var(--line); color: var(--ink-1, var(--ink));
  transition: border-color 0.15s var(--ease-out, ease), color 0.15s var(--ease-out, ease);
}
.pricing-tier-quote-btn:hover { border-color: var(--indigo); color: var(--indigo); }
/* Compare link row */
.pricing-compare-row { margin-top: 20px; text-align: center; }
.pricing-compare-link {
  font-size: 13px; color: var(--ink-4);
  text-decoration: none; border-bottom: 1px solid var(--line);
  padding-bottom: 1px; transition: color 0.15s, border-color 0.15s;
}
.pricing-compare-link:hover { color: var(--indigo); border-color: var(--indigo); }
/* Mobile: stack pricing cards */
@media (max-width: 900px) {
  .pricing-tier-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 540px) {
  .pricing-tier-grid { grid-template-columns: 1fr; }
}
/* Onboarding: in-wizard plan picker step */
.ob-plan-picker-screen { gap: 20px; }
.ob-plan-toggle-row { justify-content: center; margin-bottom: 4px; }
.ob-plan-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
}
.ob-plan-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 12px; padding: 16px 14px 14px;
  display: flex; flex-direction: column; gap: 8px; position: relative;
  transition: border-color 0.15s;
}
.ob-plan-card-featured {
  border-color: var(--indigo);
  box-shadow: 0 0 0 1px var(--indigo), 0 4px 20px color-mix(in srgb, var(--indigo) 10%, transparent);
}
.ob-plan-card-free { background: var(--bg-elev); }
.ob-plan-card-badge {
  position: absolute; top: -10px; left: 50%; transform: translateX(-50%);
  background: var(--indigo); color: #fff;
  font-size: 10px; font-weight: 600; padding: 2px 10px; border-radius: 99px;
  white-space: nowrap;
}
.ob-plan-card-name { font-size: 13px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.ob-plan-card-price { display: flex; align-items: baseline; gap: 2px; }
.ob-plan-price-num { font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.03em; }
.ob-plan-price-per { font-size: 10.5px; color: var(--ink-4); }
.ob-plan-features {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 5px; flex: 1;
}
.ob-plan-feature-row {
  display: flex; align-items: flex-start; gap: 6px;
  font-size: 10.5px; color: var(--ink-3); line-height: 1.4;
}
.ob-plan-feature-row svg { flex-shrink: 0; margin-top: 1px; color: var(--good); }
.ob-plan-cta {
  width: 100%; margin-top: auto; font-size: 12px; padding: 7px 10px;
}
.ob-plan-enterprise-link {
  font-size: 12px; color: var(--ink-4); background: none; border: none;
  cursor: pointer; padding: 0; text-decoration: underline; text-underline-offset: 2px;
  transition: color 0.15s;
}
.ob-plan-enterprise-link:hover { color: var(--indigo); }
@media (max-width: 760px) {
  .ob-plan-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .ob-plan-grid { grid-template-columns: 1fr; }
}
/* Onboarding: Stripe subscription confirming overlay */
.ob-sub-confirming {
  display: flex; align-items: center; justify-content: center;
}
.ob-sub-confirming-inner {
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; max-width: 320px; text-align: center;
}
.ob-sub-confirming-spinner {
  width: 36px; height: 36px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--indigo);
  animation: ob-spin 0.8s linear infinite;
}
@keyframes ob-spin { to { transform: rotate(360deg); } }
.ob-sub-confirming-msg {
  font-size: 17px; font-weight: 600; color: var(--ink); margin: 0;
}
.ob-sub-confirming-sub { font-size: 13.5px; color: var(--ink-3); margin: 0; }

/* ============================================================================
   Settings → Billing tab — Phase 5
   ============================================================================ */

/* Trial countdown banner */
.billing-trial-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px; border-radius: 10px;
  background: color-mix(in srgb, var(--warn) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  color: var(--warn); font-size: 13.5px; line-height: 1.5;
}
.billing-banner-dismiss {
  flex-shrink: 0; background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 2px; border-radius: 4px;
  display: flex; align-items: center; transition: color 0.15s;
}
.billing-banner-dismiss:hover { color: var(--ink); }

/* Subscription summary card */
.billing-sub-card {
  padding: 20px 22px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-card);
  display: flex; flex-direction: column; gap: 16px;
}
.billing-sub-card-top {
  display: flex; align-items: flex-start;
  justify-content: space-between; gap: 16px;
}
.billing-sub-card-eyebrow {
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--ink-4); margin-bottom: 6px;
}
.billing-sub-card-headline {
  font-size: 18px; font-weight: 600;
  color: var(--ink); letter-spacing: -0.01em;
}
.billing-sub-card-actions {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding-top: 4px; border-top: 1px solid var(--line);
}

/* Trial countdown badge */
.billing-trial-badge {
  display: inline-flex; align-items: baseline; gap: 4px;
  margin-top: 10px; padding: 6px 10px; border-radius: 8px;
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 30%, transparent);
}
.billing-days-num {
  font-size: 22px; font-weight: 700; line-height: 1;
  color: var(--indigo); font-variant-numeric: tabular-nums;
}
.billing-days-label {
  font-size: 12px; color: var(--indigo); font-weight: 500;
}

/* Next billing row */
.billing-next-billing {
  font-size: 12px; color: var(--ink-3); margin-top: 8px; line-height: 1.5;
}

/* Upgrade plan modal */
.bup-overlay {
  position: fixed; inset: 0; z-index: 1100;
  background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.bup-modal {
  background: var(--bg-card); border-radius: 16px;
  border: 1px solid var(--line);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  width: min(820px, 100%); max-height: 90vh;
  overflow-y: auto; padding: 28px 28px 24px;
  display: flex; flex-direction: column; gap: 20px;
}
.bup-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.bup-title {
  font-size: 20px; font-weight: 700;
  color: var(--ink); letter-spacing: -0.02em;
}
.bup-close {
  background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 6px; border-radius: 6px;
  display: flex; align-items: center; transition: color 0.15s, background 0.15s;
}
.bup-close:hover { color: var(--ink); background: var(--bg-sunk); }
.bup-toggle {
  justify-content: center; padding: 0;
}
.bup-plan-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.bup-plan-card {
  position: relative;
  padding: 18px 18px 16px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-elev);
  display: flex; flex-direction: column; gap: 10px;
  transition: border-color 0.15s;
}
.bup-plan-card:hover { border-color: var(--ink-5); }
.bup-plan-featured {
  border-color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 5%, var(--bg-elev));
}
.bup-plan-featured:hover { border-color: var(--indigo); }
@media (max-width: 680px) {
  .bup-plan-grid { grid-template-columns: 1fr; }
}

/* ============================================================================
   Subscription lockout screen — shown full-screen when 402 fires
   ============================================================================ */
.sub-lockout-overlay {
  position: fixed; inset: 0; z-index: 2100;
  background: var(--bg); overflow-y: auto;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 40px 24px 80px;
}
.sub-lockout-scroll {
  width: min(1000px, 100%);
  display: flex; flex-direction: column; align-items: center;
}
.sub-lockout-brand {
  display: flex; align-items: center; gap: 10px;
  align-self: flex-start; margin-bottom: 52px;
}
.sub-lockout-headline {
  font-size: 38px; font-weight: 700; color: var(--ink);
  letter-spacing: -0.03em; text-align: center; margin: 0 0 12px;
}
.sub-lockout-sub {
  font-size: 16px; color: var(--ink-3); text-align: center;
  max-width: 500px; line-height: 1.55; margin: 0 0 32px;
}
.sub-lockout-toggle {
  margin-bottom: 24px;
}
.sub-lockout-plans {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 14px; width: 100%; margin-bottom: 20px;
}
.sub-lockout-plan-card {
  /* inherits ob-plan-card; no extra styles needed */
}
.sub-lockout-err {
  font-size: 13px; color: var(--bad);
  text-align: center; margin-bottom: 16px;
}
.sub-lockout-actions {
  display: flex; gap: 10px; align-items: center;
  flex-wrap: wrap; justify-content: center;
  margin-bottom: 36px;
}
.sub-lockout-footer {
  font-size: 12px; color: var(--ink-4); text-align: center;
}
.sub-lockout-signout {
  background: none; border: none; cursor: pointer;
  color: var(--ink-3); font-size: 12px;
  text-decoration: underline; text-underline-offset: 2px; padding: 0;
  transition: color 0.15s;
}
.sub-lockout-signout:hover { color: var(--ink); }
@media (max-width: 820px) {
  .sub-lockout-plans { grid-template-columns: 1fr 1fr; }
  .sub-lockout-headline { font-size: 30px; }
}
@media (max-width: 520px) {
  .sub-lockout-plans { grid-template-columns: 1fr; }
  .sub-lockout-headline { font-size: 26px; }
}

/* ============================================================================
   PricingComparePage — full feature-matrix at #pricing/compare
   ============================================================================ */
.pcc-wrap { min-height: 100vh; }
.pcc-page-inner { padding-top: 40px; padding-bottom: 80px; }

/* Back link */
.pcc-back {
  background: none; border: none; cursor: pointer;
  font-size: 13px; color: var(--ink-4);
  padding: 0; margin-bottom: 32px; display: inline-flex;
  align-items: center; gap: 4px; transition: color 0.15s;
}
.pcc-back:hover { color: var(--ink); }

/* Hero */
.pcc-hero { text-align: center; margin-bottom: 52px; }
.pcc-headline { font-size: clamp(28px, 4vw, 48px); margin-bottom: 12px; }
.pcc-sub { max-width: 440px; margin: 0 auto 28px; }

/* Table scroll container */
.pcc-table-scroll {
  width: 100%; overflow-x: auto;
  border-radius: 12px;
  border: 1px solid var(--line);
}

/* Mobile accordion (shown ≤768px instead of the wide matrix) */
.pcc-mobile { display: none; }
.pcc-m-card { border: 1px solid var(--line); border-radius: 12px; margin-bottom: 12px; overflow: hidden; background: var(--bg-card); }
.pcc-m-card.featured { border-color: var(--indigo); box-shadow: 0 0 0 1px var(--indigo); }
.pcc-m-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; background: none; border: none; cursor: pointer; text-align: left;
}
.pcc-m-head-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pcc-m-name { font-size: 15px; font-weight: 700; color: var(--ink-1, var(--ink)); display: flex; align-items: center; gap: 8px; }
.pcc-m-badge { font-size: 9px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: #fff; background: var(--indigo); border-radius: 999px; padding: 2px 7px; }
.pcc-m-price { font-size: 13px; font-weight: 600; color: var(--ink-2, var(--ink)); }
.pcc-m-per { font-size: 11px; font-weight: 400; color: var(--ink-4); margin-left: 2px; }
.pcc-m-chevron { flex-shrink: 0; color: var(--ink-4); }
.pcc-m-body { padding: 4px 16px 16px; border-top: 1px solid var(--line); }
.pcc-m-cat { margin-top: 12px; }
.pcc-m-cat-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--indigo); margin-bottom: 4px; }
.pcc-m-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 7px 0; border-top: 1px solid var(--line); }
.pcc-m-cat .pcc-m-row:first-of-type { border-top: none; }
.pcc-m-row-label { font-size: 12.5px; color: var(--ink-3); }
.pcc-m-row-val { flex-shrink: 0; text-align: right; }
.pcc-m-cta { width: 100%; margin-top: 16px; }

@media (max-width: 768px) {
  .pcc-table-scroll { display: none; }
  .pcc-mobile { display: block; }
}

/* Table */
.pcc-table {
  width: 100%; min-width: 760px;
  border-collapse: collapse; table-layout: fixed;
}
.pcc-table colgroup { display: table-column-group; }

/* Sticky plan header row */
.pcc-thead-row th {
  position: sticky; top: 60px; /* account for landing-nav height */
  z-index: 10; background: var(--bg-elev);
  border-bottom: 2px solid var(--line);
}

/* Feature label column */
.pcc-th-label { width: 220px; min-width: 180px; padding: 18px 20px; }
.pcc-feat-label {
  padding: 11px 20px; font-size: 13px; color: var(--ink-2);
  text-align: left; white-space: nowrap; border-right: 1px solid var(--line);
}

/* Plan columns */
.pcc-th-plan {
  padding: 16px 12px 20px; text-align: center;
  width: 130px; border-right: 1px solid var(--line); vertical-align: top;
}
.pcc-th-plan:last-child { border-right: none; }
.pcc-th-featured {
  background: color-mix(in srgb, var(--indigo) 5%, var(--bg-elev));
  border-left: 1px solid color-mix(in srgb, var(--indigo) 25%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--indigo) 25%, transparent);
}
.pcc-rec-badge {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--indigo);
  margin-bottom: 6px;
}
.pcc-th-name {
  font-size: 14px; font-weight: 600; color: var(--ink);
  margin-bottom: 6px; letter-spacing: -0.01em;
}
.pcc-th-price {
  font-size: 12px; color: var(--ink-4); margin-bottom: 12px;
}
.pcc-price-num { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; }
.pcc-price-per { font-size: 11px; color: var(--ink-4); margin-left: 2px; }
.pcc-price-custom { font-size: 14px; font-weight: 600; color: var(--ink); }
.pcc-cta-btn {
  width: 100%; font-size: 12px; padding: 7px 10px;
}

/* Category header rows */
.pcc-cat-row td {
  background: var(--bg-sunk); border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.pcc-cat-label {
  padding: 8px 20px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-4);
}

/* Feature rows */
.pcc-row { border-bottom: 1px solid var(--line); }
.pcc-row:last-child { border-bottom: none; }
.pcc-row-alt { background: color-mix(in srgb, var(--bg-sunk) 40%, transparent); }

/* Data cells */
.pcc-cell {
  padding: 10px 12px; text-align: center;
  border-right: 1px solid var(--line); vertical-align: middle;
}
.pcc-cell:last-child { border-right: none; }
.pcc-cell-featured {
  background: color-mix(in srgb, var(--indigo) 4%, transparent);
  border-left: 1px solid color-mix(in srgb, var(--indigo) 18%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--indigo) 18%, transparent);
}
.pcc-dash { font-size: 16px; color: var(--ink-5); line-height: 1; }
.pcc-val  { font-size: 12.5px; color: var(--ink-2); font-weight: 500; }

/* Bottom CTA */
.pcc-bottom-cta {
  text-align: center; margin-top: 60px;
}
.pcc-bottom-sub { font-size: 15px; color: var(--ink-3); margin-bottom: 16px; }
.pcc-bottom-actions { display: flex; gap: 10px; justify-content: center; }

/* ============================================================================
   HeroAnimation — scattered AEC fragments → organised category lanes
   ============================================================================ */
/* ============================================================================
   LandingHeroProductDemo — "Riverside Towers" product animation
   Positioned absolute on the right side of the hero section.
   Shows: Projects list → AI panel slides in → typing → streaming → cards → export.
   ============================================================================ */
/* ── Command Center hero demo ─────────────────────────────────────────────── */
.hcc-wrap {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: 62%; pointer-events: none; overflow: hidden;
  display: flex; align-items: center;
}
/* Hero edge-fade gradient removed per design — the framed demo sits flat on
   the page background (its own border + shadow define the edge). */
.hcc-wrap::after { display: none; }
/* Hero film mount (window.AecosDemo, hero variant). The wrap centers a true
   16:9 framed panel; the frame gives the rounded/shadowed treatment and clips
   the film's edge-cropped (cover) Stage. pointer-events:none keeps it ambient —
   the hero film renders no controls. */
/* Stacked-hero film: a normal-flow block below the hero text, centered and
   wide (was absolutely anchored to the viewport's right edge). */
.hcc-film-wrap {
  position: relative; z-index: 5;
  width: 100%; max-width: min(1080px, 110vh); margin: 0 auto;
  display: flex; justify-content: center;
  pointer-events: none;
}
.hcc-film-frame {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #0E0E0E; border: 1px solid var(--line);
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 30px 80px rgba(20, 22, 50, 0.18), 0 4px 12px rgba(20, 22, 50, 0.08);
  animation: hcc-enter 0.9s 0.1s cubic-bezier(0.22, 1, 0.36, 1) both;
}
/* When the film floats on the hero aurora band, match the product-showcase
   card's stronger soft drop shadow (same as .lft-window). */
.hero-film-stage .hcc-film-frame {
  box-shadow: 0 44px 110px -30px rgba(20, 22, 50, 0.55), 0 14px 40px -16px rgba(20, 22, 50, 0.32);
}
.hcc-frame {
  position: relative; margin: 0 5% 0 2%; width: 93%; height: 78%;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 10px; overflow: hidden;
  box-shadow: 0 14px 48px rgba(0,0,0,0.22), 0 2px 6px rgba(0,0,0,0.08);
  display: flex; flex-direction: column;
  animation: hcc-enter 0.9s 0.1s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes hcc-enter {
  from { opacity: 0; transform: translateY(20px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Titlebar */
.hcc-titlebar {
  height: 26px; background: var(--bg-elev); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; padding: 0 10px; gap: 5px; flex-shrink: 0;
}
.hcc-tb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); flex-shrink: 0; }
.hcc-tb-label { font-size: 9.5px; color: var(--ink-5); font-weight: 500; margin-left: 5px; }
/* Two-column layout */
.hcc-content { display: flex; flex: 1; overflow: hidden; }
/* AI sidebar */
.hcc-ai-col {
  width: 190px; flex-shrink: 0; border-right: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
  transition: width 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
.hcc-ai-col-wide { width: 246px; }
.hcc-ai-header {
  height: 30px; display: flex; align-items: center; gap: 7px;
  padding: 0 11px; border-bottom: 1px solid var(--line); flex-shrink: 0;
  color: var(--ink-3);
}
.hcc-ai-name { font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--indigo); }
.hcc-ai-body {
  flex: 1; padding: 9px 10px; display: flex; flex-direction: column;
  gap: 6px; overflow: hidden;
}
.hcc-ai-empty {
  font-size: 10px; color: var(--ink-4); margin-top: 10px; line-height: 1.4;
}
.hcc-prompt-bubble {
  align-self: flex-end; max-width: 95%;
  background: var(--indigo); color: #fff;
  border-radius: 9px 9px 2px 9px; padding: 5px 9px;
  font-size: 9.5px; font-weight: 500; line-height: 1.45; word-break: break-word;
  animation: hcc-bubble-in 0.26s ease both;
}
.hcc-prompt-bubble-2 { animation-name: hcc-bubble-in; }
@keyframes hcc-bubble-in {
  from { opacity: 0; transform: scale(0.92) translateY(4px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.hcc-cursor {
  display: inline-block; width: 1.5px; height: 0.82em;
  margin-left: 1px; background: currentColor; vertical-align: text-bottom;
  animation: hcc-blink 0.9s step-end infinite;
}
@keyframes hcc-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
.hcc-thinking { display: flex; align-items: center; gap: 3px; padding: 1px 0; }
.hcc-think-dot {
  width: 5px; height: 5px; border-radius: 50%; background: var(--indigo);
  animation: hcc-dot-bounce 1.2s ease-in-out infinite;
}
.hcc-think-dot:nth-child(2) { animation-delay: 0.18s; }
.hcc-think-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes hcc-dot-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.3; }
  40%  { transform: translateY(-4px); opacity: 1; }
}
.hcc-think-lbl { font-size: 9.5px; color: var(--ink-4); margin-left: 4px; }
.hcc-ai-reply {
  font-size: 9.5px; color: var(--ink-3); line-height: 1.5;
  animation: hcc-fadein 0.3s ease both;
}
@keyframes hcc-fadein { from { opacity: 0; } to { opacity: 1; } }
.hcc-sec-card {
  border-radius: 5px; padding: 4px 7px; flex-shrink: 0;
  animation: hcc-sec-in 0.32s ease both;
}
@keyframes hcc-sec-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hcc-sec-ok  { background: color-mix(in srgb, var(--good) 12%, var(--bg-elev));   border-left: 2px solid var(--good); }
.hcc-sec-att { background: color-mix(in srgb, var(--warn) 12%, var(--bg-elev));   border-left: 2px solid var(--warn); }
.hcc-sec-inf { background: color-mix(in srgb, var(--indigo) 10%, var(--bg-elev)); border-left: 2px solid var(--indigo); }
.hcc-sec-label  { display: block; font-size: 8.5px; font-weight: 700; color: var(--ink-3); margin-bottom: 1px; }
.hcc-sec-detail { display: block; font-size: 8.5px; color: var(--ink-4); line-height: 1.4; }
.hcc-export-row { display: flex; gap: 4px; flex-wrap: wrap; padding-top: 2px; animation: hcc-fadein 0.4s ease both; }
.hcc-export-btn {
  font-size: 8.5px; font-weight: 600; padding: 3px 7px; border-radius: 4px;
  border: 1px solid var(--line); background: var(--bg-elev); color: var(--ink-3); cursor: default;
}
.hcc-export-btn.primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }
.hcc-input-bar {
  height: 28px; margin: 6px 8px 8px; flex-shrink: 0;
  border: 1px solid var(--line); border-radius: 6px;
  display: flex; align-items: center; padding: 0 9px;
  background: var(--bg-sunk);
}
.hcc-input-ph { font-size: 9px; color: var(--ink-5); }
/* Main content column */
.hcc-main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.hcc-topbar {
  height: 24px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 12px; border-bottom: 1px solid var(--line);
  background: var(--bg-elev); flex-shrink: 0;
}
.hcc-topbar-date { font-size: 9px; color: var(--ink-4); font-weight: 500; }
.hcc-topbar-right { display: flex; gap: 4px; align-items: center; }
.hcc-topbar-btn {
  font-size: 8.5px; font-weight: 600; padding: 2px 7px; border-radius: 4px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-4); cursor: default;
}
.hcc-topbar-primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }
/* Scrollable main body */
.hcc-scroll {
  flex: 1; overflow-y: auto; overflow-x: hidden; scrollbar-width: none;
  padding: 10px 12px; display: flex; flex-direction: column; gap: 8px;
}
.hcc-scroll::-webkit-scrollbar { display: none; }
/* ── Scale real app classes down inside the demo frame ───────────────────── */
.hcc-frame .briefing-card { padding: 7px 10px; border-radius: 7px; margin-bottom: 0; }
.hcc-frame .grid-metrics { grid-template-columns: repeat(3, 1fr); gap: 6px; }
.hcc-frame .metric-card { padding: 7px 9px 6px; border-radius: 7px; box-shadow: none; }
.hcc-frame .metric-label { font-size: 8px; letter-spacing: 0.11em; }
.hcc-frame .metric-value-row { margin-top: 5px; }
.hcc-frame .numstat-lg .numstat-value { font-size: 18px; line-height: 1; letter-spacing: -0.01em; }
.hcc-frame .numstat-prefix, .hcc-frame .numstat-suffix { font-size: 10px; }
.hcc-frame .metric-foot { margin-top: 4px; font-size: 8.5px; }
.hcc-frame .metric-accent { width: 5px; height: 5px; }
.hcc-frame .card { border-radius: 7px; }
.hcc-frame .card-padded { padding: 7px 10px; }
.hcc-frame .eyebrow { font-size: 7.5px; letter-spacing: 0.12em; }
.hcc-frame .section-title { font-size: 9.5px; margin-top: 1px; }
.hcc-frame .section-meta { font-size: 8px; margin-top: 1px; }
.hcc-frame .pf-head { padding: 7px 10px; }
.hcc-frame .pf-controls { gap: 7px; }
.hcc-frame .pf-legend { font-size: 8px; gap: 6px; }
.hcc-frame .lg-sw { width: 12px; height: 4px; }
.hcc-frame .diamond { width: 6px; height: 6px; }
.hcc-frame .seg { padding: 1.5px; border-radius: var(--radius-btn); }
.hcc-frame .seg-btn { font-size: 7.5px; padding: 2px 6px; border-radius: var(--radius-btn); border: none; background: none; cursor: default; color: var(--ink-4); }
.hcc-frame .seg-btn.on { background: var(--bg-card); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,0.1); }
.hcc-frame .pf-grid { grid-template-columns: 104px 1fr; }
.hcc-frame .pf-side-head, .hcc-frame .pf-axis {
  height: 22px; font-size: 7.5px; padding: 0 8px; letter-spacing: 0.1em;
}
.hcc-frame .pf-axis { min-width: auto; display: flex; align-items: center; justify-content: space-around; }
.hcc-frame .pf-today-cap { display: none; }
.hcc-frame .tbl thead th { font-size: 7px; padding: 4px 8px; letter-spacing: 0.08em; }
.hcc-frame .tbl tbody td { padding: 5px 8px; font-size: 8px; }
.hcc-frame .grid-2 { gap: 8px; }
/* Real PF classes scaled down inside demo frame */
.hcc-frame .pf-rows { min-width: auto; }
.hcc-frame .pf-row { height: 34px; transition: background 0.45s ease; }
.hcc-frame .pf-row.hcc-grow-hl   { background: color-mix(in srgb, var(--indigo) 8%, transparent); }
.hcc-frame .pf-row.hcc-grow-warn { background: color-mix(in srgb, var(--warn)   8%, transparent); }
.hcc-frame .pf-phase { height: 100%; top: 0; transform: none; }
.hcc-frame .pf-phase-bar { height: 14px; border-radius: 8px; }
.hcc-frame .pf-phase-money { border-radius: 8px; }
.hcc-frame .pf-ms-dot { width: 10px; height: 10px; border-width: 2px; }
/* Project group header rows in demo Gantt */
.hcc-proj-sep {
  height: 20px; display: flex; align-items: center;
  padding: 0 8px 0 6px; font-size: 7.5px; font-weight: 700; color: var(--ink-3);
  border-bottom: 1px solid var(--line-soft); border-left: 2.5px solid transparent;
  background: var(--bg-sunk); letter-spacing: 0.02em;
}
.hcc-proj-spacer {
  height: 20px; border-bottom: 1px solid var(--line-soft);
  background: var(--bg-sunk);
}
/* Input bar typing + send button */
.hcc-input-bar { gap: 6px; }
.hcc-input-typed {
  flex: 1; font-size: 9px; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hcc-cursor-input { background: var(--ink-2); }
.hcc-send-btn {
  width: 18px; height: 18px; border-radius: 4px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--line); color: var(--ink-5);
  transition: background 0.15s ease, color 0.15s ease;
}
.hcc-send-ready {
  background: var(--indigo); color: #fff;
  animation: hcc-send-pulse 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes hcc-send-pulse {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.3); }
  100% { transform: scale(1); }
}
/* Gantt rows */
.hcc-pf-side-row {
  height: 34px; display: flex; align-items: center;
  padding: 0 8px; font-size: 8px; color: var(--ink-3); font-weight: 500;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: background 0.45s ease;
  animation: hcc-row-in 0.35s ease both;
}
@keyframes hcc-row-in {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}
.hcc-pf-side-row.hcc-grow-hl   { background: color-mix(in srgb, var(--indigo) 8%, transparent); }
.hcc-pf-side-row.hcc-grow-warn { background: color-mix(in srgb, var(--warn)   8%, transparent); }
.hcc-pf-track-row {
  height: 34px; position: relative; border-bottom: 1px solid var(--line-soft);
  transition: background 0.45s ease;
  animation: hcc-row-in 0.35s ease both;
}
.hcc-pf-track-row.hcc-grow-hl   { background: color-mix(in srgb, var(--indigo) 8%, transparent); }
.hcc-pf-track-row.hcc-grow-warn { background: color-mix(in srgb, var(--warn)   8%, transparent); }
.hcc-gbar {
  position: absolute; top: calc(50% - 4px); height: 8px; border-radius: 4px;
  background: var(--indigo-soft); border: 1px solid var(--indigo-line);
}
.hcc-gbar-over {
  background: repeating-linear-gradient(
    135deg,
    color-mix(in srgb, var(--warn) 55%, transparent) 0 3px,
    color-mix(in srgb, var(--warn) 18%, transparent) 3px 6px
  );
  border-color: color-mix(in srgb, var(--warn) 50%, transparent);
}
.hcc-gantt-empty {
  height: 60px; display: flex; align-items: center; justify-content: center;
  font-size: 8px; color: var(--ink-5); text-align: center; padding: 0 10px;
}
.landing-hero-note { font-size: 12px; color: var(--ink-5); margin-top: 14px; }
/* Rescued from the retired proof strip — a single quantified line under the hero. */
.landing-hero-proof {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 12px; font-size: 12.5px; color: var(--ink-3);
}
.landing-hero-proof svg { color: var(--indigo); flex-shrink: 0; }

/* ============================================================================
   LandingAiDemo v2 — extract-project / summarize / plan-day
   ============================================================================ */
.demo-file-row { display: flex; align-items: center; animation: land-stream-in 0.22s ease both; }
.demo-file-pill {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--indigo-soft); border: 1px solid var(--line);
  border-radius: 20px; padding: 7px 14px;
  font-size: 12.5px; color: var(--indigo-ink); font-weight: 500;
}
.demo-stream-text { font-size: 13px; color: var(--ink-2); line-height: 1.5; animation: land-stream-in 0.22s ease both; }
.demo-extract-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; display: flex; flex-direction: column; gap: 6px;
  animation: land-stream-in 0.35s 0.2s ease both;
}
.demo-extract-title { font-size: 13.5px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.demo-extract-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.demo-extract-key { font-size: 11.5px; color: var(--ink-4); }
.demo-extract-val { font-size: 11.5px; color: var(--ink-2); font-weight: 500; }
.demo-extract-tag { font-size: 11px; color: var(--indigo); font-weight: 600; padding-top: 6px; border-top: 1px solid var(--line); margin-top: 2px; }
.demo-proj-list { display: flex; flex-direction: column; gap: 5px; }
.demo-proj-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 7px;
  animation: land-stream-in 0.22s ease both;
}
.demo-proj-phase { font-size: 10px; font-weight: 700; color: var(--indigo); background: var(--indigo-soft); padding: 2px 5px; border-radius: 4px; flex-shrink: 0; }
.demo-proj-name  { flex: 1; font-size: 12px; color: var(--ink-2); font-weight: 500; }
.demo-proj-meta  { font-size: 10.5px; color: var(--ink-4); }
.demo-day-plan   { display: flex; flex-direction: column; gap: 4px; }
.demo-day-block {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px 6px 9px;
  border-radius: 6px; background: var(--bg-card);
  border: 1px solid var(--line); border-left: 3px solid var(--line);
  animation: land-stream-in 0.22s ease both;
}
.demo-day-meet   { border-left-color: var(--indigo); }
.demo-day-focus  { border-left-color: var(--good); }
.demo-day-buffer { border-left-color: var(--warn); }
.demo-day-break  { opacity: 0.55; }
.demo-day-time  { font-size: 10.5px; color: var(--ink-4); width: 32px; flex-shrink: 0; }
.demo-day-label { flex: 1; font-size: 12px; color: var(--ink-2); }
.demo-day-proj  { font-size: 10px; color: var(--ink-4); background: var(--bg-elev); border-radius: 4px; padding: 1px 6px; }

/* ============================================================================
   Landing — animations, scroll-reveal, hover polish (Commit 2, 2026-05-22)
   ============================================================================ */
@keyframes land-fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes land-blueprint-drift {
  0%, 100% { transform: translate(0, 0); }
  50%       { transform: translate(-2px, -1.5px); }
}
@keyframes land-blink {
  0%, 100% { opacity: 1; } 50% { opacity: 0; }
}
@keyframes land-stream-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes land-pulse-dot {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
  40%           { transform: scale(1.1); opacity: 1; }
}

/* Hero content reveal */
.landing-hero-content, .landing-hero-text { animation: land-fade-up 0.65s ease both; animation-delay: 0.05s; }
/* Blueprint grid slow drift */
.landing-hero-svg { animation: land-blueprint-drift 12s ease-in-out infinite; }

/* CTA button hover lift */
.landing-cta-primary {
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.landing-cta-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.landing-cta-primary:active { transform: translateY(0); }

/* Feature card lift + indigo ring on hover (expand hint) */
.landing-feature-card {
  transition: transform 0.18s ease, border-color 0.18s, box-shadow 0.18s ease;
}
.landing-feature-card:hover {
  transform: translateY(-2px);
  border-color: var(--indigo-line);
  box-shadow: 0 4px 18px color-mix(in srgb, var(--indigo) 10%, transparent);
}
.landing-feature-icon { overflow: hidden; }
.landing-feature-icon svg { transition: transform 0.2s ease; }
.landing-feature-card:hover .landing-feature-icon svg { transform: scale(1.1); }

/* ── Scroll-reveal ── */
.sr-reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.45s ease, transform 0.45s ease;
  transition-delay: var(--sr-delay, 0s);
}
.sr-reveal.sr-visible { opacity: 1; transform: translateY(0); }

/* ── AI Demo component ── */
.landing-demo-section { background: var(--bg-card); }
.landing-demo-copy-row {
  text-align: center; margin-bottom: 36px;
}
/* Flex column + align-items:center so the full-bleed .lft-stage band centres on
   the viewport — same mechanism as the feature showcase / product-hero-demo. */
.lai-stage-wrap {
  display: flex; flex-direction: column; align-items: center; width: 100%;
}
/* The Intelligence demo card floats centred on the aurora band, capped so the
   moving gradient shows on all four sides (matches .lft-window). */
.lai-stage-wrap .landing-demo-wrap {
  position: relative; z-index: 1;
  max-width: 760px;
  box-shadow: 0 44px 110px -30px rgba(20, 22, 50, 0.55), 0 14px 40px -16px rgba(20, 22, 50, 0.32);
}
.landing-demo-wrap {
  background: var(--bg-card);
  border-radius: 14px;
  border: 1px solid var(--line);
  box-shadow: 0 2px 20px color-mix(in srgb, var(--ink) 7%, transparent);
  overflow: hidden;
  width: 100%;
}
.landing-demo-topbar {
  display: flex; align-items: center; gap: 6px;
  padding: 11px 20px; background: var(--bg-elev);
  border-bottom: 1px solid var(--line);
  user-select: none;
}
.landing-demo-topbar-label {
  font-size: 12px; color: var(--ink-4); font-weight: 500;
}
.landing-demo-topbar-sep {
  font-size: 12px; color: var(--ink-5); opacity: 0.5;
}
.landing-demo-body {
  padding: 32px 38px 28px;
  min-height: 400px;
  display: flex; flex-direction: column; gap: 14px;
}
.landing-demo-topbar-scene { color: var(--indigo); font-weight: 600; }
.landing-demo-resp { display: flex; flex-direction: column; gap: 9px; }
.landing-demo-prompt-bubble {
  align-self: flex-end;
  background: var(--indigo); color: #fff;
  font-size: 13px; padding: 9px 14px; border-radius: 14px 14px 4px 14px;
  max-width: 480px; line-height: 1.5;
  animation: land-stream-in 0.22s ease both;
}
.landing-demo-thinking {
  display: flex; align-items: center; gap: 5px;
  color: var(--ink-4); font-size: 12.5px;
}
.landing-demo-thinking-dot {
  width: 5px; height: 5px; border-radius: 50%; background: var(--ink-4);
  animation: land-pulse-dot 1.1s ease infinite;
}
.landing-demo-thinking-dot:nth-child(2) { animation-delay: 0.18s; }
.landing-demo-thinking-dot:nth-child(3) { animation-delay: 0.36s; }
.landing-demo-project-card {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 16px;
  display: flex; flex-direction: column; gap: 5px;
  background: var(--bg-card);
  animation: land-stream-in 0.22s ease both;
}
.landing-demo-project-title { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.landing-demo-project-meta { font-size: 11.5px; color: var(--ink-4); }
.landing-demo-risk-cards { display: flex; flex-direction: column; gap: 7px; }
.landing-demo-risk-card {
  border-radius: 8px; padding: 9px 13px;
  font-size: 12.5px; line-height: 1.45;
  animation: land-stream-in 0.22s ease both;
}
.landing-demo-risk-card.red  { background: color-mix(in srgb, var(--bad) 10%, var(--bg-card)); border-left: 3px solid var(--bad); }
.landing-demo-risk-card.amber { background: color-mix(in srgb, var(--warn) 10%, var(--bg-card)); border-left: 3px solid var(--warn); }
.landing-demo-risk-title { font-size: 12px; font-weight: 600; color: var(--ink-2); margin-bottom: 2px; }
.landing-demo-risk-body { font-size: 11.5px; color: var(--ink-4); }
.landing-demo-draft {
  font-size: 12.5px; color: var(--ink-2); line-height: 1.65;
  white-space: pre-wrap; background: var(--bg-card);
  border-radius: 8px; padding: 12px 14px;
  animation: land-stream-in 0.22s ease both;
}
.landing-demo-cursor {
  display: inline-block; width: 1.5px; height: 13px;
  background: var(--indigo); vertical-align: middle; margin-left: 1px;
  animation: land-blink 0.85s step-end infinite;
}
.landing-demo-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
  animation: land-stream-in 0.22s ease both;
}
.landing-demo-action-btn {
  font-size: 12px; padding: 6px 12px; border-radius: 6px;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-3); cursor: default; font-family: var(--f-sans);
  user-select: none;
}
button.landing-demo-action-btn {
  cursor: pointer; appearance: none; line-height: 1.2;
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
button.landing-demo-action-btn:hover {
  border-color: var(--indigo); color: var(--indigo-ink, var(--indigo));
}
/* Bottom control bar: prev · dots · next */
.landing-demo-controls {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 12px 16px 16px; border-top: 1px solid var(--line);
  background: var(--bg-elev);
}
.landing-demo-scenes { display: flex; align-items: center; gap: 8px; }
.landing-demo-scene-dot {
  width: 8px; height: 8px; border-radius: 50%; padding: 0; border: none;
  background: var(--line); cursor: pointer;
  transition: background 0.25s var(--ease-out, ease), transform 0.25s var(--ease-out, ease);
}
.landing-demo-scene-dot:hover { background: var(--ink-4); }
.landing-demo-scene-dot.active { background: var(--indigo); transform: scale(1.3); }
.landing-demo-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; padding: 0;
  background: var(--bg-card); border: 1px solid var(--line); color: var(--ink-3);
  cursor: pointer; transition: color 0.15s var(--ease-out, ease), border-color 0.15s var(--ease-out, ease), background 0.15s var(--ease-out, ease);
}
.landing-demo-arrow:hover { color: var(--indigo); border-color: var(--indigo); background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 10%, transparent)); }

/* Weekly report card */
.landing-demo-report {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px;
  background: var(--bg-card); animation: land-stream-in 0.22s ease both;
}
.landing-demo-report-head { font-size: 12.5px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }
.landing-demo-report-row {
  display: flex; justify-content: space-between; gap: 12px; padding: 5px 0;
  border-top: 1px solid var(--line); animation: land-stream-in 0.22s ease both;
}
.landing-demo-report-row:nth-child(2) { border-top: none; }
.landing-demo-report-key { font-size: 11.5px; color: var(--ink-4); flex-shrink: 0; }
.landing-demo-report-val { font-size: 11.5px; color: var(--ink-2); font-weight: 500; text-align: right; }

/* Plan-my-day blocks */
.landing-demo-day { display: flex; flex-direction: column; gap: 6px; }
.landing-demo-day-row { display: flex; align-items: stretch; gap: 10px; animation: land-stream-in 0.22s ease both; }
.landing-demo-day-time { font-size: 11px; color: var(--ink-4); width: 40px; flex-shrink: 0; padding-top: 8px; font-variant-numeric: tabular-nums; }
.landing-demo-day-block {
  flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--indigo-soft, color-mix(in srgb, var(--indigo) 9%, transparent));
  border-left: 3px solid var(--indigo); border-radius: 6px; padding: 7px 11px;
}
.landing-demo-day-title { font-size: 12px; font-weight: 600; color: var(--ink-2, var(--ink)); }
.landing-demo-day-tag { font-size: 10px; color: var(--indigo); white-space: nowrap; }

/* ── prefers-reduced-motion: strip all landing animations ── */
@media (prefers-reduced-motion: reduce) {
  .landing-hero-content, .landing-hero-text { animation: none; opacity: 1; transform: none; }
  /* Keep the Aecos-colour gradient but hold it still (no drift). */
  .aecos-sheen-text { animation: none; }
  .landing-cta-primary  { transition: none; }
  .landing-feature-card, .landing-feature-icon svg { transition: none; }
  .lp2-card, .lp2-cards { transition: none; }
  .lp2-cards:not(.is-on) { opacity: 1; transform: none; }
  .sr-reveal { opacity: 1; transform: none; transition: none; }
  /* Hero product demo — no motion, show final state */
  .hero-prod-frame, .hero-prod-row, .hero-prod-right,
  .hero-prod-prompt-bubble, .hero-prod-sec-card, .hero-prod-rfi-chip,
  .hero-prod-export-row, .hero-prod-stream, .hero-prod-chip-in { animation: none; opacity: 1; transform: none; }
  .hero-prod-cursor { animation: none; }
  .hero-prod-dot { animation: none; opacity: 0.5; }
  /* Intelligence demo */
  .landing-demo-prompt-bubble,
  .demo-file-row, .demo-stream-text, .demo-extract-card,
  .landing-demo-report, .landing-demo-report-row, .landing-demo-day-row,
  .landing-demo-risk-card, .landing-demo-actions { animation: none; opacity: 1; transform: none; }
  .landing-demo-thinking-dot { animation: none; opacity: 0.5; }
  .landing-demo-cursor { animation: none; opacity: 1; }
}

/* ============================================================================
   ContactSalesModal — enterprise / custom pricing inquiry form.
   Reuses ts-modal-overlay/ts-modal/ts-modal-head/ts-modal-foot/ts-field/
   ts-input/ts-select/ts-textarea/ts-toggle-row from the timesheets section.
   ============================================================================ */
.cs-modal { width: 560px; max-width: calc(100vw - 32px); }
.cs-modal-body { max-height: 68vh; overflow-y: auto; }
.cs-field-err {
  color: var(--bad); font-weight: 400;
  text-transform: none; letter-spacing: 0; font-size: 11px;
}
.cs-err-input { border-color: var(--bad) !important; }
.cs-optional-divider {
  display: flex; align-items: center; gap: 10px;
  color: var(--ink-5); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.1em;
  margin: 4px 0;
}
.cs-optional-divider::before,
.cs-optional-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--line-soft);
}
.cs-radio-group { display: flex; gap: 20px; margin-top: 4px; }
.cs-radio-label {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; color: var(--ink); cursor: pointer; user-select: none;
}
.cs-radio-label input[type=radio] { accent-color: var(--indigo); cursor: pointer; }
/* Success screen */
.cs-success {
  padding: 52px 40px;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
  text-align: center;
}
.cs-success-title { font-size: 18px; font-weight: 600; color: var(--ink); }
.cs-success-body { font-size: 13px; color: var(--ink-3); line-height: 1.65; max-width: 380px; }
/* Inline link-style button (no <a href=mailto:> needed for calls to event) */
.landing-link-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--indigo); font: inherit; font-size: inherit;
  text-decoration: none;
}
.landing-link-btn:hover { text-decoration: underline; }

/* ============================================================================
   OnboardingWizard — full-screen adaptive wizard shown post-auth.
   ============================================================================ */
.ob-wrap {
  display: flex; min-height: 100vh;
  background: var(--bg-elev); font-family: var(--f-sans);
}

/* ── Side rail ── */
.ob-rail {
  width: 224px; flex-shrink: 0;
  background: var(--bg-card); border-right: 1px solid var(--line);
  padding: 32px 20px;
  display: flex; flex-direction: column; gap: 40px;
}
.ob-rail-logo { display: flex; align-items: center; gap: 8px; color: var(--ink); }
.ob-rail-brand { font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink); }
.ob-rail-steps { display: flex; flex-direction: column; gap: 2px; }
.ob-step {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 8px; border-radius: 8px;
  color: var(--ink-5); font-size: 12.5px; transition: background 0.15s;
}
.ob-step-active { background: var(--indigo-soft); color: var(--indigo); font-weight: 500; }
.ob-step-done   { color: var(--ink-4); }
.ob-step-num {
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
  background: var(--bg-elev); border: 1.5px solid var(--line); color: var(--ink-4);
}
.ob-step-active .ob-step-num { background: var(--indigo); border-color: var(--indigo); color: #fff; }
.ob-step-done   .ob-step-num { background: var(--good);   border-color: var(--good);   color: #fff; }
.ob-step-label { line-height: 1; }

/* ── Main content ── */
.ob-main {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 60px 48px; overflow-y: auto;
}
.ob-main-inner {
  width: 100%; max-width: 640px;
  display: flex; flex-direction: column; gap: 36px;
  position: relative; min-height: 400px;
}

/* Skip link */
.ob-skip-btn {
  position: absolute; top: -44px; right: 0;
  font-size: 12.5px; color: var(--ink-4); background: none; border: none;
  cursor: pointer; padding: 4px 0; font-family: var(--f-sans);
}
.ob-skip-btn:hover { color: var(--ink); text-decoration: underline; }

/* Screen layout */
.ob-screen { display: flex; flex-direction: column; gap: 28px; }
.ob-screen-head { display: flex; flex-direction: column; gap: 8px; }
.ob-heading { font-size: clamp(22px, 2.8vw, 34px); font-weight: 700; letter-spacing: -0.025em; color: var(--ink); margin: 0; line-height: 1.15; }
.ob-subhead { font-size: 15px; color: var(--ink-3); margin: 0; line-height: 1.6; }

/* Entry cards — 2-col grid */
.ob-entry-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ob-entry-card {
  background: var(--bg-card); border: 1.5px solid var(--line); border-radius: 12px; padding: 18px;
  display: flex; flex-direction: column; gap: 7px; align-items: flex-start;
  cursor: pointer; text-align: left; font-family: var(--f-sans);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.ob-entry-card:hover { border-color: var(--indigo); }
.ob-entry-card-selected { border-color: var(--indigo); background: var(--indigo-soft); box-shadow: 0 0 0 1px var(--indigo); }
.ob-entry-icon  { color: var(--indigo); }
.ob-entry-label { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.ob-entry-desc  { font-size: 12px; color: var(--ink-3); line-height: 1.5; }

/* Company type — 3-col */
.ob-type-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.ob-type-card {
  background: var(--bg-card); border: 1.5px solid var(--line); border-radius: 10px; padding: 14px;
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  cursor: pointer; text-align: left; font-family: var(--f-sans);
  transition: border-color 0.15s;
}
.ob-type-card:hover { border-color: var(--indigo); }
.ob-type-card-selected { border-color: var(--indigo); background: var(--indigo-soft); box-shadow: 0 0 0 1px var(--indigo); }
.ob-type-icon  { color: var(--indigo); }
.ob-type-label { font-size: 13px; font-weight: 600; color: var(--ink); }
.ob-type-desc  { font-size: 11.5px; color: var(--ink-3); line-height: 1.4; }

/* Workflow chips */
.ob-workflow-grid { display: flex; flex-wrap: wrap; gap: 9px; }
.ob-workflow-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 9px 16px; border-radius: 99px;
  border: 1.5px solid var(--line); background: var(--bg-card);
  font-size: 13px; color: var(--ink-3); cursor: pointer; font-family: var(--f-sans);
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.ob-workflow-chip:hover { border-color: var(--indigo); color: var(--ink); }
.ob-workflow-chip-selected { border-color: var(--indigo); background: var(--indigo-soft); color: var(--indigo-ink); font-weight: 500; }

/* Form fields */
.ob-field-group { display: flex; flex-direction: column; gap: 6px; }
.ob-field-row   { display: flex; gap: 14px; }
.ob-label { font-size: 12.5px; font-weight: 500; color: var(--ink-3); }
.ob-opt   { font-weight: 400; color: var(--ink-5); }
.ob-input {
  width: 100%; padding: 10px 13px; box-sizing: border-box;
  background: var(--bg-card); border: 1.5px solid var(--line); border-radius: 8px;
  font-size: 14px; color: var(--ink); font-family: var(--f-sans); outline: none;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.ob-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 12%, transparent); }
.ob-select {
  width: 100%; padding: 10px 13px; box-sizing: border-box;
  background: var(--bg-card); border: 1.5px solid var(--line); border-radius: var(--radius-btn);
  font-size: 13.5px; color: var(--ink-2); font-family: var(--f-sans); outline: none; cursor: pointer;
}
.ob-select:focus { border-color: var(--indigo); }

/* Invite rows */
.ob-invite-rows { display: flex; flex-direction: column; gap: 10px; }
.ob-invite-row  { display: flex; gap: 10px; align-items: center; }
.ob-invite-email { flex: 1; }
.ob-invite-role  { width: 164px; flex-shrink: 0; }

/* Connect-email step — provider buttons + connected-sender picker */
.ob-connect-actions { display: flex; flex-direction: column; gap: 10px; }
.ob-connect-btn {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 16px; border-radius: var(--radius-btn-icon);
  border: 1.5px solid var(--line); background: var(--bg-card);
  cursor: pointer; text-align: left; font-family: var(--f-sans);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.ob-connect-btn:hover:not(:disabled) { border-color: var(--indigo); box-shadow: 0 0 0 1px var(--indigo); }
.ob-connect-btn:disabled { opacity: 0.6; cursor: default; }
.ob-connect-ic {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 36px; height: 36px; border-radius: 9px; color: var(--indigo);
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
}
.ob-connect-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ob-connect-txt strong { font-size: 14px; font-weight: 600; color: var(--ink); }
.ob-connect-sub { font-size: 12px; color: var(--ink-3); }
.ob-connect-list { display: flex; flex-direction: column; gap: 8px; }
.ob-connect-list-head { font-size: 12px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; }
.ob-connect-acct {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 14px; border-radius: 9px;
  border: 1.5px solid var(--line); background: var(--bg-card);
  cursor: pointer; text-align: left; font-family: var(--f-sans);
  transition: border-color 0.12s, background 0.12s;
}
.ob-connect-acct:hover:not(:disabled) { border-color: var(--indigo); }
.ob-connect-acct-default { border-color: var(--indigo); background: var(--indigo-soft); cursor: default; }
.ob-connect-radio { flex: 0 0 auto; color: var(--indigo); font-size: 13px; line-height: 1; }
.ob-connect-acct-email { flex: 1; min-width: 0; font-size: 13.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ob-connect-acct-provider { flex: 0 0 auto; font-size: 11px; color: var(--ink-4); text-transform: capitalize; }
.ob-connect-acct-badge { flex: 0 0 auto; font-size: 11px; font-weight: 600; color: var(--indigo-ink); }
.ob-connect-empty { font-size: 13px; color: var(--ink-4); margin: 0; }

/* Token input */
.ob-token-input { font-family: monospace; font-size: 13px; letter-spacing: 0.03em; }
.ob-token-ok {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; color: var(--good); font-weight: 500;
}

/* Error */
.ob-error {
  font-size: 13px; color: var(--bad);
  background: color-mix(in srgb, var(--bad) 8%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--bad) 22%, var(--line));
  border-radius: 7px; padding: 10px 14px; line-height: 1.5;
}

/* Done screen */
.ob-done-screen { align-items: center; gap: 16px; padding-top: 24px; }
.ob-done-icon   { color: var(--good); }
.ob-done-cta    { font-size: 14.5px; padding: 12px 32px; margin-top: 12px; }

/* Nav row */
.ob-nav-row {
  display: flex; align-items: center; justify-content: space-between;
  padding-top: 8px; border-top: 1px solid var(--line); margin-top: auto;
}
.ob-back-btn { color: var(--ink-3); background: none; font-size: 13.5px; }
.ob-back-btn:hover { color: var(--ink); }
.ob-next-btn { font-size: 14px; padding: 10px 28px; }
.ob-next-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ============================================================================
   RFIsPage
   ============================================================================ */

/* Header stats */
.rfi-stats-row {
  display: flex; align-items: center; gap: 18px;
  margin-top: 7px; font-size: 13px; color: var(--ink-3);
}
.rfi-stat-num { font-weight: 600; color: var(--ink); }
.rfi-stat-bad { color: var(--bad); display: flex; align-items: center; gap: 5px; }
.rfi-stat-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--bad); flex-shrink: 0;
}

/* Filter row */
.rfi-filter-row {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.rfi-status-chips { display: flex; gap: 4px; }
.rfi-chip {
  padding: 5px 11px; border-radius: var(--radius-btn);
  border: 1px solid var(--line);
  background: var(--bg-card); color: var(--ink-3);
  font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer;
  display: flex; align-items: center; gap: 5px;
  transition: background 0.12s, color 0.12s;
}
.rfi-chip:hover { background: var(--bg-hover); color: var(--ink); }
.rfi-chip.active {
  background: var(--indigo-soft); color: var(--indigo-ink);
  border-color: var(--indigo-line);
}
.rfi-chip-count {
  font-size: 11px; font-weight: 600;
  background: var(--bg-sunk); color: var(--ink-4);
  border-radius: 99px; padding: 0 5px; min-width: 16px; text-align: center;
}
.rfi-chip.active .rfi-chip-count {
  background: color-mix(in srgb, var(--indigo) 14%, var(--bg-elev));
  color: var(--indigo-ink);
}
.rfi-filter-selects { display: flex; gap: 8px; align-items: center; flex: 1; min-width: 0; }
.rfi-filter-select { width: 154px; flex-shrink: 0; font-size: 12.5px; padding: 5px 8px; border-radius: var(--radius-btn); }
.rfi-search-wrap {
  display: flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); border-radius: 6px;
  padding: 5px 10px; background: var(--bg-elev);
  flex: 1; min-width: 140px;
}
.rfi-search-input {
  flex: 1; border: 0; background: none; outline: none;
  font: inherit; font-size: 13px; color: var(--ink);
}
.rfi-search-input::placeholder { color: var(--ink-5); }

/* Recent Activity reuses the RFI filter toolbar but has ~10 chips + a
   project dropdown + search. Let the chips wrap and give the selects a
   sensible min so the search box never clips past the card edge. Scoped to
   .ra-feed so the RFI page toolbar is unaffected. */
.ra-feed .rfi-status-chips { flex-wrap: wrap; row-gap: 6px; }
.ra-feed .rfi-filter-selects { flex: 1 1 240px; min-width: 240px; }

/* Table bits */
.rfi-overdue-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--bad); flex-shrink: 0; display: inline-block;
}
.rfi-overdue-text { color: var(--bad) !important; }
.rfi-empty {
  display: flex; flex-direction: column; align-items: center;
  padding: 56px 0; font-size: 13px; color: var(--ink-4);
}

/* Detail panel */
.rfi-panel-backdrop {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(0,0,0,0.22);
}
.rfi-panel {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: 520px; max-width: 90vw;
  background: var(--bg-card); border-left: 1px solid var(--line);
  box-shadow: -12px 0 48px rgba(0,0,0,0.14);
  display: flex; flex-direction: column;
  animation: rfi-panel-slide 0.2s cubic-bezier(0.25,0.46,0.45,0.94);
}
@keyframes rfi-panel-slide {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.rfi-panel-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 20px 20px 16px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.rfi-panel-number {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-4); margin-bottom: 4px;
}
.rfi-panel-subject {
  font-size: 16px; font-weight: 650; color: var(--ink);
  letter-spacing: -0.01em; line-height: 1.3;
}
.rfi-panel-meta { font-size: 12px; color: var(--ink-4); margin-top: 6px; }
.rfi-panel-body {
  flex: 1; overflow-y: auto; padding: 18px 20px;
  display: flex; flex-direction: column; gap: 22px;
}
.rfi-panel-section { display: flex; flex-direction: column; gap: 8px; }
.rfi-panel-section-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-4);
}
.rfi-panel-question {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.65; white-space: pre-wrap;
}
.rfi-no-responses { font-size: 13px; color: var(--ink-4); }
.rfi-thread { display: flex; flex-direction: column; gap: 10px; }
.rfi-thread-item {
  padding: 12px 14px; border-radius: 8px;
  background: var(--bg-elev); border: 1px solid var(--line);
}
.rfi-thread-meta {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.rfi-thread-author { font-size: 12px; font-weight: 600; color: var(--ink); }
.rfi-thread-date   { font-size: 11px; color: var(--ink-4); }
.rfi-thread-body   { font-size: 13px; color: var(--ink-2); line-height: 1.55; white-space: pre-wrap; }

/* New RFI modal */
.rfi-new-modal {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,.2);
  width: 560px; max-width: calc(100vw - 32px);
  max-height: 90vh; overflow: hidden;
  display: flex; flex-direction: column;
}
.rfi-new-modal-body {
  padding: 20px 24px; display: flex; flex-direction: column; gap: 14px;
  overflow-y: auto; flex: 1;
}
.rfi-new-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 24px 18px; border-top: 1px solid var(--line-soft); flex-shrink: 0;
}
.rfi-form-row { display: flex; flex-direction: column; gap: 5px; }
.rfi-form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.rfi-form-label { font-size: 12px; font-weight: 500; color: var(--ink-3); }
.rfi-form-optional { font-weight: 400; color: var(--ink-5); }

/* Schema setup card */
.rfi-setup-card {
  display: flex; flex-direction: column; align-items: center;
  gap: 14px; padding: 52px 36px; text-align: center;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card); max-width: 440px; margin: 40px auto;
}
.rfi-setup-icon { color: var(--ink-4); }
.rfi-setup-title { font-size: 16px; font-weight: 650; color: var(--ink); letter-spacing: -0.01em; }
.rfi-setup-body  {
  font-size: 13px; color: var(--ink-3); line-height: 1.65;
  max-width: 36ch;
}
.rfi-setup-body code {
  background: var(--bg-elev); border: 1px solid var(--line);
  padding: 1px 5px; border-radius: 4px; font-size: 12px;
}
.rfi-setup-steps { display: flex; flex-direction: column; gap: 9px; margin-top: 6px; text-align: left; width: 100%; max-width: 320px; }
.rfi-setup-step  { display: flex; align-items: baseline; gap: 10px; font-size: 13px; color: var(--ink-2); }
.rfi-setup-num {
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
  background: var(--indigo-soft); color: var(--indigo-ink); border: 1px solid var(--indigo-line);
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700;
}
.rfi-setup-step code {
  background: var(--bg-elev); border: 1px solid var(--line);
  padding: 1px 4px; border-radius: 4px; font-size: 11.5px;
}

/* ============================================================================
   LeadsPage — Kanban CRM
   ============================================================================ */

/* View toggle */
.lead-view-toggle {
  display: flex; border: 1px solid var(--line); border-radius: 7px;
  overflow: hidden;
}
.lead-view-btn {
  padding: 6px 10px; background: none; border: 0; cursor: pointer;
  color: var(--ink-4); transition: background 0.1s, color 0.1s;
  display: flex; align-items: center;
}
.lead-view-btn:hover { background: var(--bg-hover); color: var(--ink); }
.lead-view-btn.active { background: var(--bg-card); color: var(--ink); }
.lead-view-btn + .lead-view-btn { border-left: 1px solid var(--line); }

/* Kanban board */
.lead-board {
  display: flex; gap: 14px; overflow-x: auto;
  padding-bottom: 12px; align-items: flex-start;
}
.lead-lane {
  flex: 0 0 250px; display: flex; flex-direction: column; gap: 8px;
  border-radius: 10px; padding: 8px; background: rgba(128, 128, 128, 0.045);
  transition: background var(--duration-fast, 120ms) var(--ease-out, ease-out);
}
/* Toggled while a lead card is dragged over this lane (kanban DnD) — was
   missing entirely, so dropping felt like it did nothing. */
.lead-lane-drag-over {
  background: var(--indigo-soft);
  box-shadow: inset 0 0 0 1px var(--indigo-line);
}
@media (prefers-reduced-motion: reduce) {
  .lead-lane { transition: none; }
}
.lead-lane-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 2px;
}
.lead-lane-label {
  font-size: 11.5px; font-weight: 600; color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lead-lane-count {
  font-size: 11px; font-weight: 700;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-4); border-radius: 99px;
  padding: 0 5px; min-width: 18px; text-align: center;
}
.lead-lane-val {
  font-size: 10.5px; color: var(--ink-4); font-weight: 500;
  padding: 0 2px; margin-top: -2px;
}
.lead-lane-body { display: flex; flex-direction: column; gap: 6px; }
.lead-lane-empty {
  font-size: 12px; color: var(--ink-5);
  text-align: center; padding: 12px 0;
}

/* Lead card */
.lead-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 11px;
  cursor: pointer; transition: border-color 0.12s, box-shadow 0.12s;
  display: flex; flex-direction: column; gap: 5px;
}
.lead-card:hover {
  border-color: var(--indigo-line);
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.lead-card:focus-visible {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 25%, transparent);
}
.lead-card-name   { font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.lead-card-client { font-size: 11.5px; color: var(--ink-4); }
.lead-card-foot   { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.lead-card-val    { font-size: 12px; font-weight: 600; color: var(--indigo); }
.lead-card-val-empty { font-weight: 400; color: var(--ink-5); }
.lead-card-date   { font-size: 11px; color: var(--ink-5); }

/* Lead detail panel extras */
.lead-info-grid   { display: flex; flex-direction: column; gap: 7px; }
.lead-info-row    { display: flex; align-items: baseline; gap: 10px; font-size: 13px; }
.lead-info-label  { font-size: 11.5px; font-weight: 500; color: var(--ink-4); min-width: 54px; }

/* Editable details form inside the lead panel (2026-08-14). Two columns of
   ordinary .rfi-form-row fields; .lead-edit-full spans both for the long ones
   (lead name, site address, notes). */
.lead-edit-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; align-items: start;
}
.lead-edit-grid > .rfi-form-row { margin-bottom: 0; }
.lead-edit-full { grid-column: 1 / -1; }
@media (max-width: 640px) { .lead-edit-grid { grid-template-columns: 1fr; } }

/* Manage-columns modal — the firm-defined extra lead fields */
.lead-col-row {
  display: grid; grid-template-columns: 1fr 132px 28px; gap: 8px; align-items: center;
  padding: 7px 0; border-bottom: 1px solid var(--line-soft);
}
.lead-col-row:last-child { border-bottom: 0; }
.lead-col-key { font-size: 11px; color: var(--ink-5); font-family: var(--font-mono, monospace); }

/* Activity feed */
.lead-activity-feed { display: flex; flex-direction: column; gap: 0; }
.lead-activity-item {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 7px 0; border-bottom: 1px solid var(--line-soft);
}
.lead-activity-item:last-child { border-bottom: 0; }
.lead-activity-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--indigo); flex-shrink: 0; margin-top: 5px;
}
.lead-activity-body {
  display: flex; flex-direction: column; gap: 1px; flex: 1;
}
.lead-activity-note { font-size: 13px; color: var(--ink-2); line-height: 1.4; }
.lead-activity-date { font-size: 11px; color: var(--ink-5); }

/* ============================================================================
   SubmittalsPage — reuses most rfi-* classes; only additions here
   ============================================================================ */
.sub-attachment-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--ink-3);
}
.sub-attach-drop {
  display: flex; align-items: center; gap: 8px;
  border: 1px dashed var(--line); border-radius: 8px;
  padding: 14px 16px; cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.sub-attach-drop:hover { border-color: var(--indigo-line); background: var(--bg-hover); }

/* ============================================================================
   OutOfCreditsModal
   ============================================================================ */
.ooc-backdrop {
  position: fixed; inset: 0; z-index: 600;
  background: rgba(0,0,0,0.45); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
}
.ooc-modal {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: 0 24px 60px rgba(0,0,0,0.22);
  width: 420px; max-width: calc(100vw - 32px);
  padding: 32px 28px 24px;
  display: flex; flex-direction: column; gap: 16px; align-items: center;
  text-align: center;
}
.ooc-icon {
  width: 48px; height: 48px; border-radius: 12px;
  background: color-mix(in srgb, var(--warn) 12%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--warn) 28%, var(--line));
  display: flex; align-items: center; justify-content: center;
}
.ooc-title { font-size: 17px; font-weight: 650; letter-spacing: -0.01em; color: var(--ink); }
.ooc-body  { font-size: 13.5px; color: var(--ink-3); line-height: 1.55; max-width: 34ch; }
.ooc-highlight { font-weight: 600; color: var(--ink); }
.ooc-actions { display: flex; gap: 10px; justify-content: center; margin-top: 4px; }
.ooc-footer  { font-size: 12px; color: var(--ink-4); }

/* ============================================================================
   BuyAICreditsTab
   ============================================================================ */
.bac-section { display: flex; flex-direction: column; gap: 12px; }
.bac-section-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-4);
}
.bac-usage-hero { display: flex; flex-direction: column; gap: 6px; }
.bac-usage-big  { display: flex; align-items: baseline; gap: 0; flex-wrap: wrap; }
.bac-usage-used { font-size: 32px; font-weight: 700; letter-spacing: -0.02em; color: var(--ink); }
.bac-usage-denom { font-size: 15px; color: var(--ink-4); margin-left: 6px; }
.bac-usage-bar-wrap {
  height: 6px; border-radius: 3px; background: var(--bg-hover); overflow: hidden; margin-top: 8px;
}
.bac-usage-bar-fill { height: 100%; border-radius: 3px; background: var(--indigo); transition: width 0.4s ease; }
.bac-purchased-row {
  display: flex; align-items: center; gap: 10px;
  font-size: 13.5px; color: var(--ink-2);
  padding: 10px 14px; border-radius: 8px;
  background: color-mix(in srgb, var(--good) 8%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--good) 22%, var(--line));
}
/* Pack picker */
.bac-packs-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.bac-pack-card {
  position: relative;
  display: flex; flex-direction: column; gap: 8px;
  padding: 18px 16px 14px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--bg-card);
  transition: border-color 0.15s;
}
.bac-pack-card:hover       { border-color: var(--indigo); }
.bac-pack-card.popular     { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 5%, var(--bg-card)); }
.bac-pack-badge {
  position: absolute; top: -10px; left: 50%; transform: translateX(-50%);
  font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 2px 10px; border-radius: 99px;
  background: var(--indigo); color: #fff;
  white-space: nowrap;
}
.bac-pack-name    { font-size: 12px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; }
.bac-pack-credits { font-size: 22px; font-weight: 700; letter-spacing: -0.015em; color: var(--ink); }
.bac-pack-price   { font-size: 18px; font-weight: 600; color: var(--indigo); }
.bac-pack-cpa     { font-size: 11px; color: var(--ink-5); }
.bac-pack-btn     { margin-top: 4px; width: 100%; justify-content: center; }
/* Auto-reload */
.bac-autoreload-card {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 16px 18px; background: var(--bg-card);
  display: flex; flex-direction: column; gap: 14px;
}
.bac-autoreload-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.bac-autoreload-config { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.bac-config-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.bac-config-label { font-size: 13px; color: var(--ink-3); min-width: 170px; }
.bac-config-sel { width: auto; min-width: 180px; font-size: 13px; }
/* History */
.bac-history-table { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.bac-hist-head {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: 0 16px; padding: 8px 14px;
  background: var(--bg-elev); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-4);
}
.bac-hist-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: 0 16px; padding: 10px 14px;
  font-size: 13px; color: var(--ink-2);
  border-top: 1px solid var(--line);
}
.bac-hist-row:nth-child(even) { background: color-mix(in srgb, var(--bg-elev) 50%, transparent); }

/* ============================================================================
   Transition utility classes
   All new modals, popovers, panels, and inline expands must use these.
   Toggle .is-open to animate; AnimatedModal (ui.jsx) handles mount/unmount
   timing automatically so you don't need to manage that yourself.
   ============================================================================ */

/* Backdrop */
.modal-overlay {
  /* 7000 — floor of the dialog band (was 300). AnimatedModal's backdrop moves
     with Modal, otherwise every AnimatedModal-based dialog stays invisible
     inside a z-5000 full-screen editor. Canonical ladder + rationale: the
     "⭐⭐ THE DIALOG LAYER" block above .modal-backdrop.
     ⚠️ This class has exactly ONE consumer — AnimatedModal in ui.jsx. The many
     `*-modal-overlay` names elsewhere (.ts-/.sr-/.mfa-/.doc-/.upgrade-/
     .feedback-) are SEPARATE classes and are deliberately NOT moved.
     ⚠️ THIS WHOLE "Transition utility classes" BLOCK IS DUPLICATED VERBATIM in
     styles.css (two `.modal-overlay` rules). The LAST one wins the cascade, so
     both are kept in step — and any reader (or guard) that stops at the first
     match is reading a value the browser never applies. */
  position: fixed; inset: 0; z-index: 7000;
  background: rgba(0,0,0,0.35); backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-in-out);
}
.modal-overlay.is-open { opacity: 1; }

/* Centered card */
.modal-card {
  opacity: 0; transform: translateY(8px) scale(0.98);
  transition:
    opacity   var(--duration-base) var(--ease-in-out),
    transform var(--duration-base) var(--ease-out);
}
.modal-card.is-open { opacity: 1; transform: translateY(0) scale(1); }

/* Small dropdowns / tooltip-style popovers */
.popover {
  opacity: 0; transform: translateY(4px);
  transition:
    opacity   var(--duration-fast) var(--ease-in-out),
    transform var(--duration-fast) var(--ease-out);
  pointer-events: none;
}
.popover.is-open { opacity: 1; transform: translateY(0); pointer-events: auto; }

/* Side panels — RFI/Submittal detail, etc. */
.panel-slide-right {
  transform: translateX(100%);
  transition: transform var(--duration-slow) var(--ease-out);
}
.panel-slide-right.is-open { transform: translateX(0); }

/* Accordions / collapsible sections */
.inline-expand {
  overflow: hidden;
  transition:
    max-height var(--duration-base) var(--ease-in-out),
    opacity    var(--duration-fast) var(--ease-in-out);
}

/* Honor reduced-motion at the system level */
@media (prefers-reduced-motion: reduce) {
  .modal-overlay,
  .modal-card,
  .popover,
  .panel-slide-right,
  .inline-expand {
    transition: none !important;
    transform: none !important;
    animation: none !important;
  }
}

/* ============================================================================
   Pricing page primitives — BillingToggle, PriceCard, FeatureBullet,
   FreeTierCallout, IncludedCredit
   ============================================================================ */

.billing-toggle {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--bg-sunk); border: 1px solid var(--line); border-radius: 999px;
  padding: 3px;
}
.billing-toggle-opt {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 500; color: var(--ink-4);
  padding: 5px 14px; border-radius: 999px; border: none;
  background: transparent; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.billing-toggle-opt.active {
  background: var(--bg-card); color: var(--ink);
  box-shadow: 0 1px 3px rgba(0,0,0,0.10);
}
.billing-toggle-save {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  padding: 1px 6px; border-radius: 999px;
}

.price-card {
  flex: 1 1 220px; min-width: 200px; max-width: 280px;
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-card);
  position: relative; overflow: hidden;
  transition: box-shadow 0.18s, transform 0.18s;
}
.price-card:hover { box-shadow: 0 6px 24px rgba(0,0,0,0.09); transform: translateY(-1px); }
.price-card.highlighted {
  border-color: var(--indigo); box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo) 18%, transparent);
}
.price-card.full-width { max-width: 100%; flex: 1 1 100%; }
.price-card.is-current { border-color: var(--ok); }
.price-card-ribbon {
  background: var(--indigo); color: #fff;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  text-align: center; padding: 4px 0; width: 100%;
}
.price-card-inner {
  display: flex; flex-direction: column; flex: 1 1 0;
  padding: 20px;
}
.price-card-top { margin-bottom: 16px; }
.price-card-price {
  display: flex; align-items: baseline; gap: 2px;
  margin: 10px 0 4px;
}
.price-card-currency { font-size: 20px; font-weight: 600; color: var(--ink-3); align-self: flex-start; margin-top: 4px; }
.price-card-num      { font-size: 44px; font-weight: 700; color: var(--ink); letter-spacing: -0.04em; line-height: 1; }
.price-card-per      { font-size: 14px; color: var(--ink-4); margin-left: 2px; }
.price-card-billed-note { font-size: 11.5px; color: var(--ink-5); margin-bottom: 8px; }
.price-card-desc { font-size: 13px; color: var(--ink-4); line-height: 1.5; margin: 6px 0 10px; }
.price-card-features {
  list-style: none; margin: 0 0 20px; padding: 0;
  display: flex; flex-direction: column; gap: 7px;
  flex: 1 1 0;
}
.price-card-action { margin-top: auto; }
.price-card-btn {
  width: 100%; padding: 9px 0; border-radius: var(--radius-btn-icon); border: none;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}
.price-card-btn.upgrade  { background: var(--indigo); color: #fff; }
.price-card-btn.upgrade:hover { opacity: 0.88; }
.price-card-btn.free     { background: var(--bg-elev); color: var(--ink); border: 1px solid var(--line); }
.price-card-btn.free:hover { background: var(--bg-sunk); }
.price-card-btn.current  { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok); cursor: default; }

.feature-bullet {
  display: flex; align-items: flex-start; gap: 7px;
  font-size: 13px; color: var(--ink);
}
.feature-bullet.muted { color: var(--ink-4); }
.feature-bullet.soon  { color: var(--ink-4); }
.feature-bullet-icon {
  flex-shrink: 0; margin-top: 1px;
  color: var(--ok);
}
.feature-bullet.muted .feature-bullet-icon,
.feature-bullet.soon  .feature-bullet-icon { color: var(--ink-5); }
.feature-bullet-text { flex: 1 1 0; line-height: 1.4; }
.feature-bullet-soon-chip {
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--ink-5); background: var(--bg-sunk);
  border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 5px; white-space: nowrap; flex-shrink: 0;
}

.free-tier-callout {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-5); text-align: center; padding: 6px 0;
}

.included-credit {
  display: flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--ink-4);
  background: color-mix(in srgb, var(--indigo) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 18%, transparent);
  border-radius: 6px; padding: 5px 9px; margin-top: 8px;
}
.included-credit > svg { flex-shrink: 0; color: var(--indigo); }

@media (prefers-reduced-motion: reduce) {
  .price-card, .billing-toggle-opt { transition: none; }
}

/* ============================================================================
   Mobile gate — show a static "use desktop" notice on phones / tablets.
   The rest of the app is hidden on these viewports. Added 2026-05-20.
   ============================================================================ */
@media (max-width: 1023px) {
  /* Keep the hero a normal vertical stack (text above the film band) at every
     width — column-reverse here was for the old side-by-side hero and now drops
     the aurora film band on top of the text. */
  .landing-hero { flex-direction: column; padding: 60px 0 0; min-height: auto; gap: clamp(32px, 5vw, 52px); }
  .hcc-wrap { position: relative; width: 100%; height: 400px; top: auto; bottom: auto; right: auto; }
  .hcc-wrap::after { display: none; }
  .hcc-frame { margin: 10px 16px; width: calc(100% - 32px); height: 340px; }
  .landing-hero-text { width: auto; max-width: 540px; margin: 0 auto; padding: 40px 24px 0; text-align: center; }
  /* Split hero collapses to a single centered column below desktop. */
  .landing-hero-split { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0; max-width: 540px; }
  .landing-hero-lead, .landing-hero-aside { align-items: center; padding-bottom: 0; }
  .landing-hero-split .landing-headline { font-size: clamp(36px, 9vw, 64px); }
  .landing-hero-split .landing-sub { max-width: 52ch; margin-top: 22px; }
  .landing-hero-split .landing-ctas { justify-content: center; }
  /* Below desktop, let the headline + subtitle wrap so they never overflow. */
  .landing-headline { white-space: normal; }
  .landing-sub { white-space: normal; max-width: 52ch; }
  .landing-ctas { justify-content: center; }
  .landing-hero-note { text-align: center; }
  /* Tablet: feature cards drop to two columns. */
  .landing-feature-grid { grid-template-columns: repeat(2, 1fr); }
}
#mobile-gate { display: none; }

/* R6: landscape phones (coarse pointer + ≤500px height) gate like portrait —
   keep in sync with mobile.css + window.AECOS_MOBILE.isPhone(). */
@media (max-width: 768px), ((pointer: coarse) and (max-height: 500px)) {
  /* Operational app routes stay desktop-only behind the gate… */
  body:not(.is-landing) { height: 100%; background: #fff; }
  body:not(.is-landing) #root { display: none; }
  body:not(.is-landing) #mobile-gate {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 100vh; padding: 32px 24px;
    text-align: center; color: #15161a;
    font-family: var(--f-sans);
  }
  body:not(.is-landing) #mobile-gate svg { width: 64px; height: 64px; margin-bottom: 24px; color: #000; }
  body:not(.is-landing) #mobile-gate h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 12px; }
  body:not(.is-landing) #mobile-gate p {
    font-size: 14.5px; line-height: 1.55; color: #4a4c55;
    margin: 0 0 10px; max-width: 32ch;
  }
  body:not(.is-landing) #mobile-gate .mg-note { font-size: 12.5px; color: #76787f; margin-top: 16px; }

  /* …but marketing pages render the responsive site and scroll as a normal
     document. The app shell locks html/body/#root to height:100% + overflow:hidden
     (base rules ~line 142). Unlock them on mobile so the landing scrolls.

     IMPORTANT: do NOT gate the <html> unlock on :has(body.is-landing). Several
     mobile browsers (notably older iOS Safari) don't support :has(), so that rule
     was a no-op there — <html> kept overflow:hidden and scrolling was dead. Unlock
     <html> directly and let the document scroll the natural way (overflow:visible,
     height:auto — no nested scroll container, no iOS momentum quirks). The app-gate
     route keeps itself non-scrolling via its own fixed, single-screen layout. */
  html { height: auto; overflow: visible; }
  /* …but the html unlock above (specificity 0,0,1) is SILENTLY BEATEN on phones by
     `html:has(body.is-landing){ overflow-y:auto }` (~line 13715) — a DESKTOP rule
     that is un-media-gated and higher-specificity (0,1,2). On phone Chrome that
     turned <html> back into a nested scroll container (overflow-y:auto + height:auto
     = a content-sized box with zero scrollable overflow) → TOUCH scrolling was dead
     even though programmatic/desktop scroll still worked, so the public landing
     "couldn't scroll" on mobile. Re-force natural document scroll here with a rule
     that MATCHES that desktop rule's specificity (0,1,2) and wins on source order.
     Only overflow-Y is set — leave overflow-x:clip (line ~20499) intact so the
     document still can't pan sideways. html.is-landing (set in Aecos.html) covers
     browsers without :has(). Mobile-only (this @media block); desktop keeps its
     `.landing-wrap`-scrolls behavior untouched. */
  html.is-landing, html:has(body.is-landing) { overflow-y: visible; }
  body.is-landing { height: auto; min-height: 100%; overflow: visible; }
  body.is-landing #root { height: auto; overflow: visible; display: block; }

  /* ── LANDING MOBILE SCROLL — AUTHORITATIVE UNLOCK (regression guard) ─────────
     ROOT CAUSE OF THE RECURRING "landing won't scroll on mobile" REGRESSION:
     the app-shell scroll-lock is the un-scoped base `html, body, #root {
     height:100%; overflow:hidden }` (top of this file) plus the ≤768 mobile gate.
     The landing unlock above (and its twin in the gate block ~line 13929) win
     ONLY by source order + specificity — none of it is !important. So ANY later
     ≤768 rule that touches html/body/#root height or overflow WITHOUT a
     `:not(.is-landing)` guard silently re-locks the public landing and it stops
     scrolling — exactly the bug that keeps coming back after each "fix".

     These !important rules make the landing unlock AUTHORITATIVE: no non-!important
     lock (present or future) can re-trap it. They deliberately mirror the tested
     approach directly above — BOTH axes stay `visible` on the html/body viewport
     root (NEVER clip/hidden here: on iOS WebKit clip/hidden on the root coerces
     overflow-y to `auto`, turning the page into a content-sized box that won't
     TOUCH-scroll; horizontal drift is contained on the inner .landing-wrap /
     .landing-container / .landing-section instead, which already clip). Scoped to
     body.is-landing / html.is-landing and inside this ≤768 (+ coarse/short) block,
     so the desktop `html:has(body.is-landing){overflow-y:auto}` scroller and the
     app-route mobile gate are both untouched. DO NOT remove or scope-widen. */
  html.is-landing, html:has(body.is-landing) { height: auto !important; overflow: visible !important; }
  body.is-landing { position: static !important; height: auto !important; min-height: 100% !important; overflow: visible !important; }
  body.is-landing #root { display: block !important; height: auto !important; overflow: visible !important; }

  /* ── COLD-LOAD BACKSTOP (the Chrome-mobile first-paint race) — DO NOT remove.
     html.is-landing is set PRE-PAINT by the <head> script; body.is-landing
     historically arrived only at DOMContentLoaded (after the multi-MB bundle
     parsed), so the FIRST paint of a cold mobile load was body:not(.is-landing)
     = app-shell locked. Chrome for Android latches "document not scrollable" at
     that first paint and does NOT re-latch when the unlock lands → the landing
     wouldn't touch-scroll until a route change forced a re-render (iOS/desktop
     re-evaluate fine). The primary fix is the body-open script in
     Aecos.html/app.html (id="aecos-body-boot-script") mirroring html.is-landing
     onto body BEFORE first paint; these rules are the CSS backstop in case that
     inline script is ever merge-dropped (has happened to Aecos.html inline
     logic before): keyed on html.is-landing ALONE, they keep the unlock in
     force even while body still lacks the class. (mobile.css's preview lock is
     separately guarded with html.aecos-mobile-preview:not(.is-landing) — keep
     that guard too, since its selector out-specifies these.) */
  html.is-landing body { position: static !important; height: auto !important; min-height: 100% !important; overflow: visible !important; }
  html.is-landing #root { display: block !important; height: auto !important; overflow: visible !important; }
}

/* ── LANDING TOUCH SCROLL — WIDE touch viewports (the >768px hole) ─────────────
   The authoritative unlock above only matches ≤768px (or coarse+short landscape).
   A touch device that lays out WIDER than 768 CSS px never enters it: an iPad /
   Android tablet, a fold phone's inner screen, or — the sneaky one — a PHONE with
   Chrome's "Desktop site" toggled (Chrome REMEMBERS that per-site, so one long-ago
   tap keeps aecos.studio on a ~980px layout viewport forever; plausible here since
   the mobile gate used to tell phone visitors "Aecos is built for desktop").
   Those devices fall through to the DESKTOP landing scroller
   `html:has(body.is-landing){ height:auto; overflow-y:auto }` (see the
   "DESKTOP ONLY (min-width:769px)" block ~line 13970) — a CONTENT-SIZED
   overflow:auto root (verified live: html computes height≈content, overflow-y:auto
   at ≥769px). Mouse-wheel scrolling tolerates that box, but BOTH mobile engines
   refuse to TOUCH-scroll it (Blink: frozen until a reflow; iOS WebKit coerces the
   root the same way — the exact gotchas documented on that desktop block and on
   the overflow-x rules below). Net symptom: "the landing won't scroll on my
   phone/tablet" while every ≤768 rule checks out healthy — this bug's recurring
   disguise. Fix: on any PRIMARY-touch device (pointer:coarse — touchscreen
   laptops report `fine` and keep the styled desktop root scrollbar), force the
   same natural-document-scroll pattern as the phone unlock, at ANY width.
   !important for the same reason as the block above: no later non-!important
   app-shell lock may silently re-trap it. DO NOT remove or scope-widen. */
@media (pointer: coarse) and (min-width: 769px) {
  html.is-landing, html:has(body.is-landing) { height: auto !important; overflow: visible !important; }
  body.is-landing { position: static !important; height: auto !important; min-height: 100% !important; overflow: visible !important; }
  body.is-landing #root { display: block !important; height: auto !important; overflow: visible !important; }
  /* Cold-load backstop — same first-paint race as the ≤768 block above (see the
     "COLD-LOAD BACKSTOP" comment there): keep the unlock in force off
     html.is-landing alone while body.is-landing hasn't landed yet (e.g. a phone
     with Chrome's "Desktop site" remembered). DO NOT remove. */
  html.is-landing body { position: static !important; height: auto !important; min-height: 100% !important; overflow: visible !important; }
  html.is-landing #root { display: block !important; height: auto !important; overflow: visible !important; }
  /* The root must stay overflow:visible to touch-scroll, so horizontal
     containment rides the inner wrapper instead (clip ≠ scroll container). */
  body.is-landing .landing-wrap { overflow-x: clip; max-width: 100vw; }
}

/* ── Hero demo — phone static stack (rendered by RiversideReportDemo on mobile) ─
   Not viewport-gated: the JS only renders .hcc-mobile when the screen is ≤768. */
.hcc-mobile {
  display: flex; flex-direction: column; gap: 12px;
  width: 100%; font-family: var(--f-sans);
}
.hcc-m-prompt {
  align-self: flex-end; max-width: 85%;
  background: var(--indigo); color: #fff;
  font-size: 13px; line-height: 1.4; font-weight: 500;
  padding: 9px 13px; border-radius: 14px 14px 4px 14px;
}
.hcc-m-ai {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.hcc-m-ai-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 700; color: var(--ink-2, var(--ink));
}
.hcc-m-sec { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 8px; }
.hcc-m-sec-label  { font-size: 12px; font-weight: 700; color: var(--ink-1, var(--ink)); }
.hcc-m-sec-detail { font-size: 12px; line-height: 1.4; color: var(--ink-2, var(--ink-3)); }
.hcc-m-report {
  background: var(--bg-card); border: 1px solid color-mix(in srgb, var(--indigo) 30%, var(--line));
  border-radius: 14px; padding: 14px;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--indigo) 12%, transparent);
}
.hcc-m-report-title { font-size: 13.5px; font-weight: 700; color: var(--ink); margin-bottom: 10px; }
.hcc-m-report-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.hcc-m-stat { display: flex; flex-direction: column; gap: 2px; }
.hcc-m-stat-v { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.02em; }
.hcc-m-stat-l { font-size: 10px; color: var(--ink-4); line-height: 1.25; }
.hcc-m-exports { display: flex; gap: 8px; }
.hcc-m-exports .hcc-export-btn {
  flex: 1; text-align: center; padding: 9px 0; border-radius: 8px;
  font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-2, var(--ink));
}
.hcc-m-exports .hcc-export-btn.primary { background: var(--indigo); color: #fff; border-color: var(--indigo); }

/* Fullscreen demo on phones: vertical scroll, comfortable padding, no ESC hint. */
.fc-rr-mobile { padding: 14px 16px 28px; overflow-y: auto; }
.fc-rr-mobile .fc-rr-stage { display: block; }

/* ── AppShell mobile widgets — desktop-default hidden ─────────────────────────
   These need to be at TOP LEVEL (outside the @media block below) so they're
   actually hidden on desktop. Previously they were nested inside the mobile
   @media → on desktop NEITHER rule applied → button fell back to its native
   <button> display:inline-block and showed up as a stray hamburger in the
   workspace top-left. */
.mobile-nav-trigger { display: none; }
.mobile-nav-scrim   { display: none; }
.settings-mobile-select { display: none; }
.projects-mobile-list   { display: none; }
.nav-item-mobile-only { display: none !important; }  /* "Today" + "Projects-mobile" sidebar items */

/* ── Landing — phone layout (marketing pages only; the app stays gated) ──────── */
@media (max-width: 768px) {
  .landing-container { padding: 0 20px; }
  .landing-section { padding: 56px 0; }
  .landing-solution { padding: 44px 0; }

  /* Hero text full-width, punchier headline, stacked full-width CTAs.
     The hero has no inner container, so it carries the side padding itself. */
  /* Headline FIRST, demo BELOW — explicit column order (not column-reverse) so
     stacking can't depend on DOM order, and the demo is forced into normal flow
     (position:static) so its desktop absolute positioning can never overlap the
     headline on a phone. */
  .landing-hero {
    display: flex; flex-direction: column; min-height: auto;
    /* overflow-x: clip (NOT visible) — the hero is not a .landing-section, so it
       was the one hero-level element still letting wide content (the feature-tab
       row, the demo band) spill past the viewport. On mobile body/html keep
       overflow-x:visible for iOS touch-scroll, so nothing upstream clips it →
       the page grew wider than the screen and iOS then froze vertical scrolling
       (and the tab pills fell off both edges). clip contains it here without
       becoming a scroll container; overflow-y stays visible. */
    padding: 28px 20px 0; overflow-x: clip; overflow-y: visible;
  }
}
/* ── Projects page — saved filter views ────────────────────────────────── */
.saved-views-row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-bottom: 10px;
}
.saved-views-empty {
  font-size: 12px; color: var(--ink-5);
}
.saved-view-chip {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 99px;
  font-size: 12.5px; color: var(--ink-2);
  transition: border-color var(--duration-fast),
              background var(--duration-fast),
              color var(--duration-fast);
}
.saved-view-chip:hover { border-color: var(--indigo-line); }
.saved-view-chip.active {
  background: var(--indigo-soft); color: var(--indigo); border-color: var(--indigo);
}
.saved-view-apply {
  background: none; border: none; cursor: pointer;
  font: inherit; color: inherit;
  padding: 4px 4px 4px 10px; line-height: 1.4;
}
.saved-view-del {
  background: none; border: none; cursor: pointer;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-5); font-size: 13px; line-height: 1;
  margin: 0 2px 0 0;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.saved-view-del:hover { background: var(--bg-hover); color: var(--bad); }
.saved-view-save {
  display: inline-flex; align-items: center; gap: 6px;
}
.saved-view-save .field-input {
  width: 220px; font-size: 12.5px; padding: 4px 8px; height: 28px;
}
@media (max-width: 768px) {
  .saved-view-save { flex: 1 1 100%; }
  .saved-view-save .field-input { flex: 1; width: auto; }
}

/* ── Members page — bulk select + bulk role change ─────────────────────── */
.members-bulk-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 16px;
  background: var(--indigo-soft); color: var(--indigo);
  border-bottom: 1px solid color-mix(in oklch, var(--indigo) 25%, var(--line-soft));
  font-size: 13px;
}
.members-bulk-bar-count { font-weight: 650; }
.members-bulk-bar-actions {
  display: flex; align-items: center; gap: 8px; margin-left: auto;
}
.members-bulk-bar-select {
  font-size: 12.5px; padding: 4px 8px; height: 28px;
  border: 1px solid color-mix(in oklch, var(--indigo) 40%, var(--line));
  border-radius: 6px;
  background: var(--bg-card); color: var(--ink);
  appearance: auto; -webkit-appearance: menulist;
}
.members-select-cell {
  flex: 0 0 32px;
  display: flex; align-items: center; justify-content: center;
}
.members-select-cell input[type="checkbox"] {
  cursor: pointer; width: 14px; height: 14px;
  accent-color: var(--indigo);
}
.members-list-row.selected {
  background: color-mix(in oklch, var(--indigo) 6%, var(--bg-card));
}
.members-list-row.selected:hover {
  background: color-mix(in oklch, var(--indigo) 9%, var(--bg-card));
}
@media (max-width: 768px) {
  .members-bulk-bar { padding: 8px 12px; gap: 6px; font-size: 12.5px; }
  .members-bulk-bar-actions { width: 100%; margin-left: 0; justify-content: flex-end; }
}

/* ── Offices page — "Set as primary" radio per office card ─────────────── */
.office-primary-pill {
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase;
  background: var(--indigo-soft); color: var(--indigo);
  padding: 2px 7px; border-radius: 4px; line-height: 1.4;
  margin-left: 4px;
}
.office-primary-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--ink-4);
  cursor: pointer;
  padding: 4px 8px; border-radius: 6px;
  user-select: none;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.office-primary-toggle:hover { background: var(--bg-hover); color: var(--ink-2); }
.office-primary-toggle.active {
  color: var(--indigo); font-weight: 600;
}
.office-primary-toggle input[type="radio"] {
  cursor: pointer; accent-color: var(--indigo); margin: 0;
  width: 13px; height: 13px;
}

/* ── Projects page — kanban board ──────────────────────────────────────── */
.proj-board {
  display: flex; gap: 12px;
  overflow-x: auto; padding-bottom: 12px;
  -webkit-overflow-scrolling: touch;
}
.proj-lane {
  flex: 0 0 240px; display: flex; flex-direction: column; gap: 6px;
  padding: 6px;
  border-radius: 10px;
  outline: 2px dashed transparent; outline-offset: -3px;
  transition: background var(--duration-fast), outline-color var(--duration-fast);
}
.proj-lane-drag-over {
  background: var(--indigo-soft);
  outline-color: var(--indigo);
}
.proj-lane-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 4px;
}
.proj-lane-label {
  font-size: 11.5px; font-weight: 600; color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.proj-lane-count {
  font-size: 11px; font-weight: 700;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-4); border-radius: 99px;
  padding: 0 5px; min-width: 18px; text-align: center;
}
.proj-lane-val {
  font-size: 10.5px; color: var(--ink-4); font-weight: 500;
  padding: 0 4px; margin-top: -2px;
}
.proj-lane-body { display: flex; flex-direction: column; gap: 6px; min-height: 60px; }
.proj-lane-empty {
  font-size: 12px; color: var(--ink-5);
  text-align: center; padding: 14px 0;
}
.proj-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 11px;
  cursor: grab;
  transition: border-color 0.12s, box-shadow 0.12s,
              transform 100ms ease, opacity 100ms ease;
  display: flex; flex-direction: column; gap: 5px;
}
.proj-card:hover {
  border-color: var(--indigo-line);
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.proj-card:active { cursor: grabbing; }
.proj-card.is-dragging {
  opacity: 0.45; transform: scale(0.97);
  box-shadow: 0 6px 20px rgba(0,0,0,0.14);
  border-color: var(--indigo);
}
.proj-card-name {
  font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.3;
}
.proj-card-client { font-size: 11.5px; color: var(--ink-4); }
.proj-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
}
.proj-card-val { font-size: 12px; font-weight: 600; color: var(--indigo); }

@media (max-width: 768px) {
  .proj-lane { flex: 0 0 220px; }
}

/* ── Project Detail — Activity tab (chronological timeline) ─────────────── */
.pa-timeline { display: flex; flex-direction: column; gap: 0; }
.pa-day-label {
  font-size: 10.5px; font-weight: 650; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-5);
  padding: 16px 0 6px;
  position: sticky; top: 0; background: var(--bg-card); z-index: 1;
}
.pa-day-label:first-child { padding-top: 4px; }
/* Mirrors the global Recent Activity feed row (.ra-row): colored type dot,
   title, then a meta line with the colored uppercase type tag + time. */
.pa-entry {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 6px;
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s;
}
.pa-entry:last-child { border-bottom: none; }
.pa-entry:hover { background: var(--bg-hover, var(--bg-sunk)); }
.pa-entry-dot {
  flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%;
  margin-top: 6px;
}
.pa-entry-body { flex: 1; min-width: 0; }
.pa-entry-title {
  font-size: 13px; color: var(--ink); line-height: 1.45;
}
.pa-entry-actor { color: var(--ink-4); font-weight: 500; }
.pa-entry-detail { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; line-height: 1.4; }
.pa-entry-meta  { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
.pa-entry-type  { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }
.pa-entry-dotsep { color: var(--ink-5); font-size: 11px; }
.pa-entry-time  { font-size: 11px; color: var(--ink-5); }

/* ── Office Detail — Health card (4-stat grid) ─────────────────────────── */
.oh-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 20px; margin-top: 12px;
}
.oh-stat {
  display: flex; flex-direction: column; gap: 3px;
}
.oh-stat-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-5); font-weight: 500;
}
.oh-stat-value {
  font-size: 22px; font-weight: 650; color: var(--ink);
  font-feature-settings: "tnum"; letter-spacing: -0.01em;
  line-height: 1.2;
}
.oh-stat-value[data-accent="ok"]   { color: var(--ok); }
.oh-stat-value[data-accent="warn"] { color: var(--warn); }
.oh-stat-value[data-accent="bad"]  { color: var(--bad); }
.oh-stat-footer { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }

@media (max-width: 768px) {
  .oh-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
}

/* ── ProjectDetail Finances — Financial snapshot card (4-stat grid) ─────── */
.pfs-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 20px; margin-top: 12px;
}
.pfs-stat { display: flex; flex-direction: column; gap: 3px; }
.pfs-stat-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-5); font-weight: 500;
}
.pfs-stat-value {
  font-size: 22px; font-weight: 650; color: var(--ink);
  font-feature-settings: "tnum"; letter-spacing: -0.01em;
  line-height: 1.2;
}
.pfs-stat-value[data-accent="ok"]   { color: var(--ok); }
.pfs-stat-value[data-accent="warn"] { color: var(--warn); }
.pfs-stat-value[data-accent="bad"]  { color: var(--bad); }
.pfs-stat-footer { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }

@media (max-width: 768px) {
  .pfs-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
}

/* ── Settings → Integrations — Connected integrations rows ──────────────── */
.ci-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: 8px;
  border: 1px solid var(--line-soft); background: var(--bg-card);
  transition: border-color var(--duration-fast), background var(--duration-fast), opacity var(--duration-fast);
}
.ci-row:hover { border-color: var(--line); }
.ci-row.disabled { opacity: 0.55; }
.ci-icon {
  flex-shrink: 0; width: 32px; height: 32px; border-radius: 7px;
  background: var(--bg-sunk);
  display: flex; align-items: center; justify-content: center;
}
.ci-info { flex: 1; min-width: 0; }
.ci-name {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
}
.ci-provider {
  font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px;
  text-transform: uppercase; letter-spacing: 0.04em;
  background: var(--bg-sunk); color: var(--ink-4);
}
.ci-config-preview {
  font-size: 12px; color: var(--ink-4); margin-top: 2px;
  font-family: var(--f-mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ci-actions {
  display: flex; gap: 4px; flex-shrink: 0;
  opacity: 0; transition: opacity var(--duration-fast);
}
.ci-row:hover .ci-actions { opacity: 1; }

/* ── OnboardingWizard — 4-phase Stepper at the top of ob-main ──────────── */
.ob-stepper {
  display: flex; align-items: flex-start;
  width: 100%; max-width: 480px; margin: 0 auto 24px;
  padding: 0 8px;
}
.ob-stepper-step {
  display: flex; flex-direction: column; align-items: center;
  gap: 6px; flex-shrink: 0; min-width: 56px;
}
.ob-stepper-circle {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--bg-sunk); color: var(--ink-4);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600;
  border: 1.5px solid var(--line);
  transition: background var(--duration-fast) var(--ease-in-out),
              color var(--duration-fast) var(--ease-in-out),
              border-color var(--duration-fast) var(--ease-in-out);
}
.ob-stepper-step.active .ob-stepper-circle {
  background: var(--indigo); color: #fff; border-color: var(--indigo);
  box-shadow: 0 0 0 4px color-mix(in oklch, var(--indigo) 18%, transparent);
}
.ob-stepper-step.done .ob-stepper-circle {
  background: var(--ok); color: #fff; border-color: var(--ok);
}
.ob-stepper-label {
  font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-4); font-weight: 500;
  white-space: nowrap;
}
.ob-stepper-step.active .ob-stepper-label { color: var(--ink); font-weight: 600; }
.ob-stepper-step.done .ob-stepper-label   { color: var(--ink-2); }
.ob-stepper-line {
  flex: 1; height: 2px; min-width: 18px;
  background: var(--line); margin-top: 12px;
  transition: background var(--duration-fast) var(--ease-in-out);
}
.ob-stepper-line.done { background: var(--ok); }

@media (max-width: 768px) {
  .ob-stepper { max-width: 100%; padding: 0 4px; margin-bottom: 18px; }
  .ob-stepper-step { min-width: 40px; }
  .ob-stepper-circle { width: 22px; height: 22px; font-size: 11px; }
  .ob-stepper-label { font-size: 9.5px; letter-spacing: 0.04em; }
  .ob-stepper-line { min-width: 10px; margin-top: 10px; }
}

/* ============================================================================
   Mobile polish wave — gate lifted, app is now reachable on phone (≤768px).
   ============================================================================
   Layout swaps cover the most-trafficked pages. The sweeping CSS-only changes
   (form font-size, page padding, modal full-screen, topbar) cover every page
   for free. Pages that need parallel mobile JSX (ProjectsPage card list,
   SettingsPage select dropdown) flip via display: none/block here.

   The desktop-only mobile gate (#root display:none + #mobile-gate flex) is
   intentionally NOT re-applied — the app now renders on phone. The gate
   markup stays in HTML as a no-op fallback. */

/* (Hamburger/scrim/mobile-widget desktop defaults are at top level above —
   see line 16744. They were here originally but never applied on desktop
   because they were nested inside the parent mobile @media.) */

@media (max-width: 768px) {
  /* ── Lift the desktop gate. ────────────────────────────────────────────── */
  /* These two rules sit later in the file than the original gate rules and
     override them. Keeping the gate markup itself untouched in HTML so any
     future fallback is just a class flip away. */
  #root { display: block !important; }
  #mobile-gate { display: none !important; }

  /* ── AppShell: hamburger nav drawer ────────────────────────────────────── */
  .app-root { padding-top: 0; }
  .sidebar-collapse-btn { display: none; }
  .mobile-nav-trigger {
    display: flex; align-items: center; justify-content: center;
    position: fixed; top: 10px; left: 10px; z-index: 950;
    width: 40px; height: 40px; border-radius: 8px;
    background: var(--bg-card); border: 1px solid var(--line);
    color: var(--ink-2); cursor: pointer; padding: 0;
    box-shadow: 0 1px 2px rgba(0,0,0,0.04);
  }
  /* Show mobile-only sidebar nav items (Today + Projects-mobile) on phones */
  .nav-item-mobile-only { display: flex !important; }
  .landing-hero-text { order: 0; padding: 28px 0 0; max-width: 100%; }
  .hcc-wrap, .hcc-mobile {
    order: 1; position: static;
    width: 100%; right: auto; top: auto; bottom: auto; height: auto;
  }
  .hcc-frame { margin: 18px 0 0; width: 100%; height: 360px; }
  .landing-headline { font-size: clamp(36px, 9vw, 64px); line-height: 1.1; margin-bottom: 16px; }
  .landing-sub { font-size: 15.5px; margin-bottom: 26px; }
  .landing-ctas { flex-direction: column; align-items: stretch; gap: 10px; }
  .landing-ctas .btn,
  .landing-cta-primary,
  .landing-cta-secondary { width: 100%; text-align: center; justify-content: center; }

  /* Typography */
  .landing-section-title { font-size: clamp(24px, 6.5vw, 34px); }
  .landing-body-copy, .landing-body-copy-center { font-size: 15px; }
  .landing-body-copy-center { margin-bottom: 32px; }

  /* Single-column stacking everywhere */
  .landing-feature-grid { grid-template-columns: 1fr; gap: 14px; margin-top: 32px; }
  .landing-feature-card { padding: 20px; }
  .landing-audience-grid { grid-template-columns: 1fr; }
  .ls-built-inner { grid-template-columns: 1fr; gap: 24px; }

  /* Feature mini-demos (FeatureCardCommandCenter/Projects/SR/Timesheets/Financial/
     Multi-office) — clamp every card type to viewport width. The inner demo
     visuals are designed for desktop columns and can overflow the .lfc-wrap
     parent on narrow phones; this constraints + min-width:0 lets flex children
     shrink instead of pushing past the right edge. */
  .lfc-wrap,
  .landing-feature-card,
  .fc-cc-card, .fc-pr-card, .fc-sr-card, .fc-ts-card, .fc-fn-card, .fc-mo-card {
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
    box-sizing: border-box;
  }
  /* Any inline-style fixed-width children inside the mini-demos */
  .fc-cc-card *, .fc-pr-card *, .fc-sr-card *, .fc-ts-card *, .fc-fn-card *, .fc-mo-card * {
    max-width: 100%;
    box-sizing: border-box;
  }
  /* SVG visuals already use viewBox — keep them fluid */
  .fc-cc-card svg, .fc-pr-card svg, .fc-sr-card svg, .fc-ts-card svg, .fc-fn-card svg, .fc-mo-card svg {
    width: 100%; height: auto; max-width: 100%;
  }

  /* Safety net: any rogue child anywhere in the landing tree cannot push
     past the viewport. The section-level overflow:hidden contains any
     stragglers (absolute-positioned animation layers, fixed-pixel widths
     baked into mini-demo internals, table-like rows with min-content).
     #landing-wrap already prevents horizontal scroll on the page itself;
     this enforces it section-by-section so debugging stays straightforward. */
  /* Do NOT put overflow-x: clip/hidden on the <html>/<body> viewport root. On iOS
     WebKit — which is what "Chrome" on an iPhone actually runs — clip/hidden on the
     ROOT still coerces overflow-y to `auto`, turning the page into a content-sized
     box that won't TOUCH-scroll (desktop Blink handles clip correctly, iOS does not
     → the page scrolled with a mouse wheel but was frozen on a phone). Keep the root
     overflow: visible so the viewport is the single natural scroller on every engine;
     horizontal drift is contained on the inner .landing-wrap / .landing-container /
     .landing-section below (they already clip + max-width:100vw) plus max-width here. */
  body.is-landing,
  html.is-landing { overflow-x: visible; max-width: 100vw; }
  .landing-section,
  .landing-container { overflow-x: hidden; max-width: 100vw; }
  /* clip (not hidden) so .landing-wrap never becomes a scroll container either. */
  .landing-wrap { overflow-x: clip; max-width: 100vw; }
  .landing-section > * { max-width: 100%; }

  /* Animated section visuals fit the viewport (they show static end-states on
     touch via the coarse-pointer guard in JS). */
  .ls-prob-stage { max-width: 100%; padding: 16px; }
  .ls-prob-grid { gap: 8px; }
  /* Solution diagram: the edge node pills (x=11%/89%) overhang the stage box by
     half their width, so a full-width stage spills past the viewport. Shrink the
     stage + pills so the whole diagram — overhang included — fits the content
     column with no horizontal scroll. */
  .ls-sol-stage { max-width: 280px; }
  .ls-sol-node { font-size: 10px; padding: 4px 8px; }
  .ls-sol-hub { font-size: 12px; padding: 9px 14px; }

  /* Footer columns stack */
  .landing-footer-cols { flex-direction: column; gap: 28px; }

  /* ── Mobile navbar: hamburger pattern ──────────────────────────────────
     Layout: [Aecos logomark · wordmark]   flex-grow   [hamburger button]
     The full nav set (Product/Pricing/Security/Sign in/Start free/theme)
     lives in a slide-in panel that opens from the right when the hamburger
     is tapped. Eliminates the cramming problem on small viewports. */
  .landing-nav-links { display: none !important; }  /* desktop nav hides on mobile */
  .landing-nav-hamburger {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0; margin: 0;
    background: transparent; border: 1px solid transparent;
    border-radius: 10px; cursor: pointer; flex-shrink: 0;
    transition: background 0.15s ease, border-color 0.15s ease;
  }
  .landing-nav-hamburger:hover,
  .landing-nav-hamburger:focus-visible { background: color-mix(in srgb, var(--ink) 5%, transparent); border-color: var(--line); }
  .lp-burger {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 20px; height: 14px; position: relative;
  }
  .lp-burger > span {
    display: block; width: 100%; height: 1.6px;
    background: var(--ink); border-radius: 1px;
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.18s ease;
  }
  .lp-burger.is-open > span:nth-child(1) { transform: translateY(6.6px) rotate(45deg); }
  .lp-burger.is-open > span:nth-child(2) { opacity: 0; }
  .lp-burger.is-open > span:nth-child(3) { transform: translateY(-6.6px) rotate(-45deg); }

  /* ── Mobile slide-in menu ────────────────────────────────────────────── */
  .landing-mobile-scrim {
    position: fixed; inset: 0; z-index: 9090;
    background: rgba(0, 0, 0, 0.42);
    backdrop-filter: blur(2px);
    animation: lm-scrim-in 0.22s ease both;
  }
  @keyframes lm-scrim-in { from { opacity: 0; } to { opacity: 1; } }
  .landing-mobile-menu {
    position: fixed; top: 0; right: 0; bottom: 0;
    width: min(86vw, 340px); z-index: 9091;
    background: var(--bg-card); border-left: 1px solid var(--line);
    box-shadow: -16px 0 32px rgba(0, 0, 0, 0.18);
    display: flex; flex-direction: column;
    padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px));
    animation: lm-slide-in 0.26s cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  @keyframes lm-slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
  .landing-mobile-menu-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 22px;
  }
  .landing-mobile-menu-brand {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 16px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink);
  }
  .landing-mobile-menu-close {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; padding: 0; margin: 0;
    background: transparent; border: 1px solid var(--line); border-radius: 8px;
    color: var(--ink); cursor: pointer;
  }
  .landing-mobile-menu-close:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); }
  .landing-mobile-menu-links {
    display: flex; flex-direction: column; gap: 2px;
    margin-bottom: 18px; padding-bottom: 18px;
    border-bottom: 1px solid var(--line-soft);
    flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
  .landing-mobile-menu-links a {
    display: block; padding: 14px 12px;
    font-size: 16px; font-weight: 500; color: var(--ink); text-decoration: none;
    border-radius: 10px; transition: background 0.12s ease;
  }
  .landing-mobile-menu-links a:hover,
  .landing-mobile-menu-links a:focus-visible { background: color-mix(in srgb, var(--ink) 5%, transparent); }
  /* Grouped sections in the mobile menu (mirrors the desktop dropdowns). */
  .lmm-group { margin-top: 6px; }
  .lmm-group-label {
    font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-4); padding: 10px 12px 4px;
  }
  .landing-mobile-menu-links .lmm-item { font-size: 15px; font-weight: 500; padding: 11px 12px 11px 16px; color: var(--ink-2); }
  .landing-mobile-menu-links .lmm-toplink { font-weight: 600; }
  .landing-mobile-menu-actions {
    display: flex; flex-direction: column; gap: 10px;
    margin-top: auto;
  }
  .landing-mobile-menu-signin {
    width: 100%; padding: 12px 14px;
    background: transparent; border: 1px solid var(--line); border-radius: 10px;
    font-size: 15px; font-weight: 500; color: var(--ink); cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
  }
  .landing-mobile-menu-signin:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); border-color: var(--ink-4); }
  .landing-mobile-menu-signup {
    width: 100%; padding: 12px 14px !important;
    font-size: 15px !important; border-radius: 10px;
    min-height: 44px;
  }
  .landing-mobile-menu-foot {
    display: flex; align-items: center; gap: 10px;
    margin-top: 16px; padding-top: 14px;
    border-top: 1px solid var(--line-soft);
  }
  .landing-mobile-menu-foot-label {
    font-size: 12px; color: var(--ink-4);
  }

  /* ── Mobile navbar layout polish ──────────────────────────────────────
     Logo + hamburger only — clean, never touching, always full touch targets. */
  .landing-nav-inner {
    height: 56px;
    padding: 0;                     /* container already handles horizontal padding */
    column-gap: 12px;               /* enforce min space between logo + links group */
  }
  .landing-nav-logo {
    flex-shrink: 0;                 /* logo never compresses */
    gap: 8px;                       /* logomark↔wordmark spacing */
  }
  .landing-nav-logo .landing-logo {
    font-size: 17px;                /* slightly smaller wordmark on mobile */
  }
  .landing-nav-links {
    gap: 10px;                      /* tighter for the trimmed link set */
    flex-shrink: 0;
  }
  .landing-nav-link {
    font-size: 13px;
    padding: 6px 4px;               /* invisible touch padding */
  }
  /* Drop the in-page anchor links — they don't add value on mobile single-column */
  .landing-nav-link[href="#features"],
  .landing-nav-link[href="#security"] { display: none; }

  /* Theme toggle: ≥44px touch target for accessibility */
  .landing-theme-toggle { width: 40px; height: 40px; }

  /* "Sign in" text-button + "Start free" primary CTA — pill-friendly sizing */
  .landing-nav-link.landing-nav-link-btn {
    font-size: 13px;
    padding: 7px 10px;
    border-radius: 8px;
  }
  /* Start free button (the inline-styled <button className="btn btn-primary">) */
  .landing-nav-links .btn.btn-primary {
    font-size: 13px !important;
    padding: 8px 14px !important;
    border-radius: 8px;
    min-height: 36px;
  }

  /* When morphed to floating pill — keep things from cramping inside the pill */
  .lp-nav--floating .landing-nav-inner {
    padding: 0 12px;
    column-gap: 10px;
  }
}

/* Very narrow phones (≤380px — iPhone SE, older Android): drop the Aecos
   wordmark so the logomark + action group don't compete for space. */
@media (max-width: 380px) {
  .landing-nav-logo .landing-logo { display: none; }
  .landing-nav-links { gap: 8px; }
  .landing-nav-link.landing-nav-link-btn { display: none; }  /* drop "Sign in" too — Start free covers signup */
}

/* Tightest phones: also drop the Sign in text link (Start free → auth has a
   sign-in tab) so the nav never overflows. */
@media (max-width: 400px) {
  .landing-nav-link-btn { display: none; }
  .landing-nav-links { gap: 10px; }
}

/* ============================================================================
   RESTORED: sr-mobile block — was silently dropped from styles.css in an
   earlier styles.css wipe (qa crossover audit 2026-05-25 found 0 sr-mobile
   rules). Re-imported from commit 4ffce77.
   ============================================================================ */
.sr-mobile-pills { display: none; }
.sr-mobile-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  font: inherit; font-size: 12.5px; font-weight: 500; color: var(--ink-2);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background 100ms, color 100ms;
}
.sr-mobile-pill:hover  { background: var(--bg-hover); color: var(--ink); }
.sr-mobile-pill.is-active {
  background: var(--indigo-soft);
  color: var(--indigo);
  border-color: var(--indigo-line);
}

.sr-mobile-sheet-overlay { display: none; }
.sr-mobile-sheet         { display: none; }

@media (max-width: 768px) {
  /* Pill row — fixed top-right */
  .sr-mobile-pills {
    display: flex; flex-wrap: wrap; gap: 8px;
    position: fixed; top: 16px; right: 16px; z-index: 50;
  }

  /* Backdrop behind the sheet */
  .sr-mobile-sheet-overlay {
    display: block;
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.40);
    z-index: 100;
    animation: sr-sheet-fade-in 180ms var(--ease-out, ease-out) both;
  }

  /* Bottom sheet */
  .sr-mobile-sheet {
    display: flex; flex-direction: column;
    position: fixed; bottom: 0; left: 0; right: 0;
    max-height: 70vh;
    background: var(--bg);
    color: var(--ink);
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    border-top: 1px solid var(--line);
    box-shadow: 0 -8px 32px rgba(0,0,0,0.18);
    padding: 12px 16px 16px;
    /* clear iOS home indicator */
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    z-index: 101;
    transform: translateY(0);
    transition: transform 0.25s ease;
    animation: sr-sheet-slide-up 250ms var(--ease-out, ease-out) both;
  }

  /* Drag handle pill at the top */
  .sr-mobile-sheet-handle {
    width: 36px; height: 4px;
    background: var(--ink-5);
    border-radius: 2px;
    margin: 0 auto 12px;
    opacity: 0.55;
    flex: 0 0 auto;
  }

  /* Header row inside the sheet — title + close */
  .sr-mobile-sheet-head {
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px;
    margin-bottom: 12px;
    flex: 0 0 auto;
  }
  .sr-mobile-sheet-title {
    font-size: 16px; font-weight: 600; color: var(--ink);
    letter-spacing: -0.01em;
    flex: 1; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .sr-mobile-sheet-close {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    background: none; border: none; cursor: pointer;
    color: var(--ink-4); border-radius: 8px;
    margin: -8px -8px -8px 0;
    transition: background 100ms, color 100ms;
  }
  .sr-mobile-sheet-close:hover { background: var(--bg-hover); color: var(--ink); }

  /* Scrollable body */
  .sr-mobile-sheet-body {
    flex: 1 1 0; min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
    max-height: calc(70vh - 80px);
  }
}

@keyframes sr-sheet-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes sr-sheet-slide-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
/* ============================================================================
   .mobile-bottom-nav — desktop-default hidden, shown on mobile only.
   Aecos.html:912 renders <MobileBottomNav> whenever page==="timesheets",
   with no isMobile gate. Without this default-hide, the mobile-only bottom
   nav bar leaks onto the desktop timesheets page. (qa crossover audit
   2026-05-25 HIGH #3)
   ============================================================================ */
.mobile-bottom-nav { display: none; }
@media (max-width: 768px) {
  .mobile-bottom-nav { display: flex; }
}

/* ============================================================================
   RESTORED: notif-bell + notif-popover + notif-row block — silently dropped
   from styles.css in an earlier wipe (same pattern as sr-mobile + landing CSS).
   Re-imported from commit f5e6fd3 (last known clean). User report:
   notifications bell button was unstyled white block in dark mode + opened
   into broken UI.
   ============================================================================ */

/* ── Notifications bell ────────────────────────────────────────────────────── */
.notif-bell-btn {
  position: relative;
  width: 32px; height: 32px; border-radius: var(--radius-btn);
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer;
  color: var(--ink-3);
  transition: background var(--duration-fast), color var(--duration-fast);
}
.notif-bell-btn:hover, .notif-bell-btn.active { background: var(--bg-hover); color: var(--ink); }
.notif-bell-badge {
  position: absolute; top: 3px; right: 3px;
  min-width: 14px; height: 14px; border-radius: 7px; padding: 0 3px;
  background: var(--bad); color: #fff;
  font-size: 9px; font-weight: 700; line-height: 14px;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
  animation: notif-bell-badge-pop 280ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes notif-bell-badge-pop {
  0%   { transform: scale(0.5); opacity: 0; }
  60%  { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.notif-popover-section {
  font-size: 10.5px; font-weight: 650; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-5);
  padding: 10px 16px 4px; background: var(--bg-card);
  position: sticky; top: 0; z-index: 1;
}
/* ⚠️ z-index 10, NOT 400 — AND THE SMALL NUMBER IS THE HONEST ONE.
   This popover lives INSIDE `.topbar`, whose own z-index creates a stacking
   context. Inside that context this value orders the popover against its
   topbar siblings and NOTHING MORE; the whole context then enters the page at
   the PARENT's z-index (60). So 400 never reached the page, never beat
   anything, and cost real time: it made the sliced-popover bug look impossible
   ("it's at 400, how is a header at 5 over it?") when the fix was on `.topbar`.
   ⭐ Third sighting of this shape here — see scripts/test_chrome_stacking.py,
   which fails on any descendant number that pretends it can escape. */
.notif-popover {
  position: absolute; top: calc(100% + 8px); right: 0;
  z-index: 10; width: 360px; max-height: 480px;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: 0 8px 32px rgba(0,0,0,0.12);
  display: flex; flex-direction: column; overflow: hidden;
}
.notif-popover-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px 12px; border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.notif-popover-title { font-size: 13.5px; font-weight: 650; color: var(--ink); }
.notif-popover-list { overflow-y: auto; flex: 1; }
.notif-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 16px; cursor: pointer;
  transition: background var(--duration-fast);
  border-bottom: 1px solid var(--line-soft);
}
.notif-row:last-child { border-bottom: none; }
.notif-row:hover { background: var(--bg-hover); }
.notif-row.unread { background: var(--indigo-soft); }
.notif-row.unread:hover { background: var(--indigo-line); }
.notif-row-icon {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 7px;
  background: var(--bg-sunk); display: flex; align-items: center; justify-content: center;
  color: var(--ink-4); margin-top: 1px;
}
.notif-row.unread .notif-row-icon { background: var(--indigo-soft); color: var(--indigo); }
.notif-row-body { flex: 1; min-width: 0; }
.notif-row-title { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.notif-row-desc  { font-size: 12px; color: var(--ink-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-row-time  { font-size: 11px; color: var(--ink-5); margin-top: 3px; }
.notif-row-dismiss {
  flex-shrink: 0; width: 22px; height: 22px; border-radius: 5px;
  background: none; border: none; cursor: pointer; color: var(--ink-5);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--duration-fast), background var(--duration-fast);
}
.notif-row:hover .notif-row-dismiss { opacity: 1; }
.notif-row-dismiss:hover { background: var(--bg-sunk); color: var(--ink-3); }
/* ── Recent Activity (unified feed gadget + page) ─────────────────────────── */
.ra-feed { display: flex; flex-direction: column; }
.ra-list { display: flex; flex-direction: column; }
.ra-row {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  text-align: left; background: none; border: none; cursor: pointer;
  padding: 9px 6px; border-radius: var(--radius-btn-icon);
  border-bottom: 1px solid var(--line-soft);
  transition: background 0.1s;
}
.ra-row:last-child { border-bottom: none; }
.ra-row:hover { background: var(--bg-hover); }
.ra-row-dot { flex-shrink: 0; width: 7px; height: 7px; border-radius: 50%; margin-top: 6px; }
.ra-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ra-row-title {
  font-size: 13px; color: var(--ink); line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ra-row-summary { color: var(--ink-4); font-weight: 400; }
.ra-row-meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 11px; color: var(--ink-4);
}
.ra-type-tag { font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; font-size: 9.5px; }
/* Who did it. Every row carries one, so it is weighted a little heavier than the
   rest of the meta line — it is the field people scan this feed for. */
.ra-row-actor { font-weight: 600; color: var(--ink-3); }
/* …except when there is no human author; "System" stays quiet so it reads as
   the absence of a person rather than as somebody named System. */
.ra-row-actor-system { font-weight: 400; color: var(--ink-4); font-style: italic; }
.ra-row-right { flex-shrink: 0; display: flex; align-items: center; gap: 7px; padding-top: 1px; }
.ra-unread-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--indigo, #6366f1); flex-shrink: 0; }

/* ── Card auto-header (CardHeader/CardBody/CardFooter BEM classes) ──────────
   These had NO CSS, so cards built with the Card title/actions props rendered
   with stacked title+actions and zero padding (e.g. the Recent Activity
   gadget). Style them to match the app's card language: title left, actions
   right, a subtle header divider, and proper inner padding per size context. */
.card__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.card__header-text { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.card__eyebrow { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ink-4); }
.card__title { font-size: 15px; font-weight: 650; letter-spacing: -0.01em; color: var(--ink); line-height: 1.3; }
.card__subtitle { font-size: 12.5px; color: var(--ink-4); line-height: 1.4; margin-top: 1px; }
.card__actions { flex-shrink: 0; display: flex; align-items: center; gap: 8px; }
.card__footer { display: flex; gap: 8px; align-items: center; }
.card__footer--right { justify-content: flex-end; }
.card__footer--left  { justify-content: flex-start; }
.card--pad-context-sm > .card__header { padding: 13px 14px 11px; border-bottom: 1px solid var(--line-soft); }
.card--pad-context-sm > .card__body   { padding: 12px 14px 14px; }
.card--pad-context-sm > .card__footer { padding: 10px 14px 12px; border-top: 1px solid var(--line-soft); }
.card--pad-context-md > .card__header { padding: 16px 18px 13px; border-bottom: 1px solid var(--line-soft); }
.card--pad-context-md > .card__body   { padding: 14px 18px 16px; }
.card--pad-context-md > .card__footer { padding: 12px 18px 16px; border-top: 1px solid var(--line-soft); }
.card--pad-context-lg > .card__header { padding: 20px 22px 15px; border-bottom: 1px solid var(--line-soft); }
.card--pad-context-lg > .card__body   { padding: 16px 22px 20px; }
.card--pad-context-lg > .card__footer { padding: 14px 22px 20px; border-top: 1px solid var(--line-soft); }

/* ════════════════════════════════════════════════════════════════════════
   Proposals & Contracts (docs-ui.jsx)
   ════════════════════════════════════════════════════════════════════════ */
.doc-ai-chip { display: inline-flex; align-items: center; gap: 3px; font-size: 10px; font-weight: 700; color: var(--indigo-ink, #4f46e5); background: var(--indigo-soft, #eef2ff); border: 1px solid var(--indigo-line, #e0e7ff); border-radius: 99px; padding: 1px 6px; margin-left: 6px; vertical-align: middle; }

/* List / table */
.doc-table-wrap { overflow-x: auto; }
.doc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.doc-table thead th { text-align: left; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ink-4); padding: 10px 14px; border-bottom: 1px solid var(--line); }
.doc-row { cursor: pointer; transition: background 0.1s; }
.doc-row:hover { background: var(--bg-hover, var(--bg-sunk)); }
.doc-row td { padding: 12px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
.doc-row-title { font-weight: 550; color: var(--ink); display: flex; align-items: center; gap: 7px; }
.doc-row-title-text { color: var(--ink); }
.doc-mono { font-variant-numeric: tabular-nums; }
.doc-orig-chip {
  display: inline-flex; align-items: center; gap: 3px; flex: 0 0 auto;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.4px;
  color: var(--ink-3); background: var(--bg-sunk);
  border: 1px solid var(--line-soft); padding: 1px 6px; border-radius: var(--radius-btn);
}

.doc-empty { text-align: center; padding: 48px 20px; }
.doc-empty-icon { width: 44px; height: 44px; border-radius: 12px; background: var(--bg-sunk); display: inline-flex; align-items: center; justify-content: center; color: var(--ink-4); margin-bottom: 12px; }
.doc-empty-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.doc-empty-hint { font-size: 12.5px; color: var(--ink-4); margin-top: 4px; }

/* ── Surface (project tab) — the Proposals / Contracts tabs inside a project ──
   ⚠️ .doc-surface ITSELF HAD NO RULE AT ALL until 2026-08-02 (queue c5c01eea).
   Its three CHILDREN were styled (-bar/-count/-actions, below) but the
   container they hang off did not exist in this stylesheet, so both tabs
   rendered as a bare toolbar with no vertical rhythm sitting flush under the
   tab bar — while every sibling project tab has a container of some kind
   (Overview/Finances/Discussion wrap in <Card>, Milestones uses
   .pd-milestones-tab). Exactly the silent-absence shape scripts/
   test_css_classes.py exists to catch, and it is now a hard-fail there.

   The padding deliberately MATCHES .pd-milestones-tab (padding: 16px 0) — the
   established idiom for a project tab that is a plain stack rather than a card,
   so the two read as the same surface family. No card chrome is duplicated
   here: the doc list gets its border/background from a real <Card padded={false}>
   in docs-ui.jsx, the same primitive the global Documents library page wraps
   DocList in. Restyling the table here instead would have been a second copy of
   .card, which is the drift this repo keeps paying for. */
.doc-surface { display: flex; flex-direction: column; padding: 16px 0; }
.doc-surface-bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 12px; flex-wrap: wrap; }
.doc-surface-count { font-size: 12.5px; color: var(--ink-4); font-weight: 500; }
.doc-surface-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Phase 4: import-format disclosure card (docs-ui DocImportFormatNote) ──
   Dismissible inline card near the Import controls telling users which file
   type gets which editing experience. Additive — discloses, never gates. */
.doc-import-note {
  border: 1px solid var(--line);
  background: var(--bg-sunk);
  border-radius: var(--radius-card);
  padding: 12px 14px; margin-bottom: 14px;
}
.doc-import-note-head { display: flex; align-items: center; gap: 7px; color: var(--ink-2); }
.doc-import-note-title { font-size: 12.5px; font-weight: 650; color: var(--ink-1); }
.doc-import-note-x {
  margin-left: auto; border: 0; background: none; cursor: pointer;
  color: var(--ink-4); padding: 3px; border-radius: var(--radius-btn-icon);
  display: grid; place-items: center;
}
.doc-import-note-x:hover { background: var(--line-soft); color: var(--ink-2); }
.doc-import-note-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 9px; }
.doc-import-note-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-3); line-height: 1.45;
}
.doc-import-note-tag {
  flex: 0 0 auto; font-size: 10px; font-weight: 700; letter-spacing: 0.3px;
  padding: 2px 8px; border-radius: var(--radius-btn); text-transform: none;
}
.doc-import-note-tag--word { color: var(--good); background: color-mix(in srgb, var(--good) 14%, transparent); }
.doc-import-note-tag--pdf { color: var(--warn); background: color-mix(in srgb, var(--warn) 16%, transparent); }
.doc-import-note-strong { font-weight: 650; color: var(--ink-1); }
.doc-import-note-desc { color: var(--ink-3); }
.doc-import-note-nudge { margin-top: 9px; font-size: 11.5px; color: var(--ink-4); font-style: italic; }

/* Detail / editor */
.doc-detail { display: flex; flex-direction: column; gap: 14px; }
.doc-detail-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.doc-detail-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.doc-status-select, .doc-filter-select { font-size: 12.5px; padding: 5px 8px; height: auto; }
.doc-title-input { font-size: 19px; font-weight: 650; padding: 6px 10px; width: 100%; }
.doc-detail-header { border-bottom: 1px solid var(--line-soft); padding-bottom: 12px; }
.doc-detail-title { font-size: 20px; font-weight: 650; letter-spacing: -0.01em; color: var(--ink); }
.doc-detail-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-4); margin-top: 6px; }
.doc-disclaimer { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--warn-ink, #92702a); background: var(--warn-soft, #fef6e7); border: 1px solid var(--warn-line, #f6e2b8); border-radius: 8px; padding: 6px 10px; margin-top: 10px; }
.doc-ref-box { margin-top: 10px; padding: 12px 14px; background: var(--bg-sunk); border: 1px solid var(--line-soft); border-radius: 10px; font-size: 13px; }
.doc-ref-link { font-size: 12px; color: var(--indigo, #6366f1); word-break: break-all; }
.doc-ref-caution { display: flex; align-items: flex-start; gap: 6px; font-size: 11.5px; color: var(--bad-ink, #9b2c2c); background: var(--bad-soft, #fdeaea); border: 1px solid var(--bad-line, #f5c6c6); border-radius: 8px; padding: 6px 10px; margin-top: 8px; }

.doc-detail-body { display: grid; grid-template-columns: 1fr 320px; gap: 22px; align-items: start; }
.doc-detail-main { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.doc-summary-line { font-size: 13px; color: var(--ink-3); line-height: 1.5; padding-bottom: 4px; }
.doc-section { }
.doc-section-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ink-4); margin-bottom: 6px; }
.doc-section-body { font-size: 13.5px; line-height: 1.6; color: var(--ink); white-space: pre-wrap; }
.doc-empty-body { font-size: 12.5px; color: var(--ink-5, #a0a0a0); font-style: italic; }
.doc-section-textarea { width: 100%; font-size: 13.5px; line-height: 1.55; font-family: inherit; resize: vertical; }
.doc-edit-meta { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--bg-sunk); border-radius: 10px; }
.doc-edit-label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; color: var(--ink-4); }
.doc-edit-label .field-input, .doc-edit-label textarea { font-size: 13px; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink); }

.doc-detail-side { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 12px; }
.doc-panel { border: 1px solid var(--line-soft); border-radius: 10px; overflow: hidden; }
.doc-panel-head { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ink-3); background: var(--bg-sunk); padding: 9px 12px; }
.doc-panel-head-toggle { cursor: pointer; justify-content: space-between; }
.doc-panel-body { padding: 10px 12px; font-size: 13px; }
.doc-kv { display: flex; align-items: baseline; gap: 8px; padding: 4px 0; flex-wrap: wrap; }
.doc-kv-label { font-weight: 600; color: var(--ink); font-size: 12.5px; }
.doc-kv-val { color: var(--ink-3); font-size: 12.5px; flex: 1; }
.doc-fee-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.doc-fee-table td { padding: 4px 6px 4px 0; border-bottom: 1px solid var(--line-soft); }

.doc-ai-panel { border: 1px solid var(--indigo-line, #e0e7ff); border-radius: 10px; overflow: hidden; background: var(--indigo-soft, #f5f7ff); }
.doc-ai-actions { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; }
.doc-ai-btn { display: flex; align-items: center; gap: 7px; width: 100%; text-align: left; font: inherit; font-size: 12.5px; font-weight: 500; color: var(--ink); background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-btn-icon); padding: 8px 10px; cursor: pointer; transition: border-color 0.12s, color 0.12s; }
.doc-ai-btn:hover { border-color: var(--indigo, #6366f1); color: var(--indigo-ink, #4f46e5); }
.doc-ai-note { font-size: 10.5px; color: var(--ink-4); padding: 0 12px 10px; line-height: 1.4; }

.doc-versions { display: flex; flex-direction: column; gap: 6px; }
.doc-version-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.doc-version-title { font-size: 12.5px; font-weight: 550; color: var(--ink); }

/* Library page */
.doc-lib-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 16px; flex-wrap: wrap; }
.doc-lib-tab { font: inherit; font-size: 13px; font-weight: 550; color: var(--ink-4); background: none; border: none; border-bottom: 2px solid transparent; padding: 9px 14px; cursor: pointer; margin-bottom: -1px; display: flex; align-items: center; gap: 6px; }
.doc-lib-tab:hover { color: var(--ink); }
.doc-lib-tab.active { color: var(--ink); border-bottom-color: var(--indigo, #6366f1); }
.doc-lib-count { font-size: 11px; font-weight: 600; background: var(--bg-sunk); color: var(--ink-4); border-radius: 99px; padding: 0 6px; min-width: 18px; text-align: center; }
.doc-lib-tab.active .doc-lib-count { background: var(--indigo-soft, #eef2ff); color: var(--indigo-ink, #4f46e5); }
.doc-lib-filters { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 16px; }
.doc-search { display: flex; align-items: center; gap: 7px; border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px; background: var(--bg-elev); color: var(--ink-4); flex: 1; min-width: 200px; max-width: 360px; }
.doc-search-input { flex: 1; border: 0; background: none; outline: none; font: inherit; font-size: 13px; color: var(--ink); }
.doc-chip { display: inline-flex; align-items: center; gap: 5px; font: inherit; font-size: 12.5px; font-weight: 500; color: var(--ink-3); background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 6px 11px; cursor: pointer; }
.doc-chip.active { background: var(--indigo-soft, #eef2ff); color: var(--indigo-ink, #4f46e5); border-color: var(--indigo-line, #e0e7ff); }

/* Template picker modal */
.doc-modal-overlay { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.35); backdrop-filter: blur(4px); padding: 20px; }
.doc-modal { background: var(--bg-card); border: 1px solid var(--line); border-radius: 14px; width: 560px; max-width: 100%; max-height: 80vh; display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0,0,0,0.2); }
.doc-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px; border-bottom: 1px solid var(--line-soft); }
.doc-modal-title { font-size: 15px; font-weight: 650; color: var(--ink); }
.doc-modal-body { padding: 14px 18px 18px; overflow-y: auto; }
.doc-tmpl-group-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ink-4); margin-bottom: 8px; }
.doc-tmpl-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 12px; border: 1px solid var(--line-soft); border-radius: var(--radius-menu); margin-bottom: 8px; cursor: pointer; transition: border-color 0.12s, background 0.12s; }
.doc-tmpl-item:hover { border-color: var(--indigo, #6366f1); background: var(--indigo-soft, #f5f7ff); }
.doc-tmpl-name { font-size: 13.5px; font-weight: 550; color: var(--ink); }
.doc-tmpl-blank { display: flex; align-items: center; gap: 7px; padding: 11px 12px; border: 1px dashed var(--line); border-radius: 10px; cursor: pointer; font-size: 13px; font-weight: 500; color: var(--ink-3); margin-top: 4px; }
.doc-tmpl-blank:hover { border-color: var(--indigo, #6366f1); color: var(--indigo-ink, #4f46e5); }

@container (max-width: 800px) { .doc-detail-body { grid-template-columns: 1fr; } .doc-detail-side { position: static; } }

/* ════════════════════════════════════════════════════════════════════════
   HeroCommandAnimation — landing hero workspace mockup (5-scene animation)
   Mirrors the real Command Center visual language: sidebar, topbar, morning
   briefing, KPI strip, Project Field gantt with phase bars + milestones.
   ════════════════════════════════════════════════════════════════════════ */
/* Within the landing hero (flex row, text col is 40%), the frame takes the
   remaining right column. Outside the hero (other usages), .hca-frame just
   fills its parent at 100%. */
.landing-hero > .hca-frame {
  flex: 1 1 auto; min-width: 0;
  max-width: clamp(480px, 56vw, 900px);
  margin: 0 clamp(20px, 4vw, 56px) 0 clamp(16px, 3vw, 32px);
  align-self: center;
}
.hca-frame {
  position: relative; width: 100%; aspect-ratio: 16 / 10.6;
  background: var(--bg-card, #fff); color: var(--ink, #111);
  border: 1px solid var(--line, #e5e7eb); border-radius: 14px;
  box-shadow: 0 22px 60px -16px rgba(15, 23, 42, 0.20), 0 6px 18px -4px rgba(15, 23, 42, 0.10);
  overflow: hidden; font-size: 11px; line-height: 1.35;
  opacity: 0; transform: translateY(8px);
  animation: hca-frame-in 700ms cubic-bezier(0.2, 0.7, 0.2, 1) 80ms forwards;
}
@keyframes hca-frame-in { to { opacity: 1; transform: none; } }

/* OS title bar */
.hca-titlebar {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 12px; background: #f3f4f6;
  border-bottom: 1px solid var(--line-soft, #e5e7eb);
}
.hca-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.hca-dot-r { background: #fca5a5; } .hca-dot-y { background: #fcd34d; } .hca-dot-g { background: #86efac; }
.hca-title { flex: 1; text-align: center; font-size: 10.5px; color: var(--ink-4, #6b7280); font-weight: 500; }

/* Shell: sidebar + main column */
.hca-shell { display: flex; height: calc(100% - 30px); }

/* Sidebar — recreates the real AppShell nav, simplified */
.hca-side {
  flex: 0 0 108px; background: #fafafa;
  border-right: 1px solid var(--line-soft, #e5e7eb);
  padding: 10px 7px; display: flex; flex-direction: column; gap: 1px;
  font-size: 10px;
}
.hca-side-brand { display: flex; align-items: center; gap: 5px; padding: 2px 6px 11px; font-size: 11px; font-weight: 600; color: var(--ink, #111); }
.hca-side-logo { color: var(--ink, #111); flex-shrink: 0; }
.hca-side-group { font-size: 8.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-5, #94a3b8); padding: 8px 6px 3px; }
.hca-side-item { display: flex; align-items: center; gap: 6px; padding: 4px 6px; border-radius: 5px; color: var(--ink-3, #475569); }
.hca-side-item.is-active { background: var(--indigo-soft, #eef2ff); color: var(--indigo-ink, #4f46e5); font-weight: 550; }
.hca-side-dot { width: 4px; height: 4px; border-radius: 50%; background: currentColor; opacity: 0.55; flex-shrink: 0; }
.hca-side-item.is-active .hca-side-dot { opacity: 1; }

/* Main column */
.hca-main { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }

/* Topbar */
.hca-topbar {
  display: flex; align-items: center; gap: 10px; padding: 9px 14px;
  border-bottom: 1px solid var(--line-soft, #e5e7eb); background: var(--bg-card, #fff);
}
.hca-topbar-title { font-size: 12.5px; font-weight: 600; color: var(--ink, #111); }
.hca-topbar-date { font-size: 10.5px; color: var(--ink-5, #94a3b8); }
.hca-topbar-firm { margin-left: auto; font-size: 10.5px; color: var(--ink-3, #475569); padding: 3px 8px; border: 1px solid var(--line, #e5e7eb); border-radius: 6px; background: var(--bg-card, #fff); }

/* Content */
.hca-content { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; overflow: hidden; flex: 1; }

/* Morning briefing — indigo-tinted card matching the real briefing-card */
.hca-briefing { background: #eef2ff; border: 1px solid #e0e7ff; border-radius: 9px; padding: 8px 11px; }
.hca-briefing-head { display: flex; align-items: center; gap: 5px; font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em; color: #4f46e5; text-transform: uppercase; }
.hca-briefing-body { font-size: 10.5px; color: var(--ink, #111); margin-top: 3px; line-height: 1.4; }

/* KPI strip — 6 mini metric cards */
.hca-kpis { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; }
.hca-kpi {
  background: var(--bg-card, #fff); border: 1px solid var(--line, #e5e7eb);
  border-radius: 8px; padding: 7px 9px; min-height: 52px;
  opacity: 0; transform: translateY(4px);
  animation: hca-kpi-in 420ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}
@keyframes hca-kpi-in { to { opacity: 1; transform: none; } }
.hca-kpi-label { font-size: 8.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-5, #94a3b8); line-height: 1.25; }
.hca-kpi-value { font-size: 17px; font-weight: 650; color: var(--ink, #111); margin-top: 2px; letter-spacing: -0.01em; display: flex; align-items: baseline; gap: 2px; position: relative; }
.hca-kpi-suffix { font-size: 9.5px; font-weight: 500; color: var(--ink-5, #94a3b8); }
.hca-kpi-tone { width: 6px; height: 6px; border-radius: 50%; margin-left: auto; align-self: center; }
.hca-tone-ok { background: #10b981; }
.hca-tone-bad { background: #f43f5e; }
.hca-tone-indigo { background: #6366f1; }

/* ── Project Field gantt ─────────────────────────────────────────────── */
.hca-gantt {
  flex: 1; min-height: 0; background: var(--bg-card, #fff); border: 1px solid var(--line, #e5e7eb);
  border-radius: 10px; padding: 9px 11px 6px; display: flex; flex-direction: column;
  position: relative; transition: box-shadow 280ms ease, border-color 280ms ease;
}
.hca-gantt.is-focused { border-color: #c7d2fe; box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.07); }
.hca-gantt-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; padding-bottom: 7px; }
.hca-gantt-eyebrow { font-size: 8.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-5, #94a3b8); }
.hca-gantt-title { font-size: 11.5px; font-weight: 600; color: var(--ink, #111); margin-top: 1px; }
.hca-gantt-ctrls { display: inline-flex; background: #f3f4f6; border-radius: 5px; padding: 2px; font-size: 9.5px; }
.hca-seg-btn { padding: 3px 9px; color: var(--ink-4, #6b7280); border-radius: var(--radius-btn); font-weight: 500; }
.hca-seg-btn.is-on { background: var(--bg-card, #fff); color: var(--ink, #111); box-shadow: 0 1px 2px rgba(0,0,0,0.08); }

/* Axis: project label column + month strip */
.hca-gantt-axis { display: grid; grid-template-columns: 180px 1fr; gap: 8px; padding: 5px 0 6px; border-bottom: 1px solid var(--line-soft, #e5e7eb); align-items: center; }
.hca-gantt-axis-label { font-size: 9px; font-weight: 600; color: var(--ink-5, #94a3b8); text-transform: uppercase; letter-spacing: 0.05em; padding-left: 4px; }
.hca-gantt-months { display: grid; grid-template-columns: repeat(10, 1fr); }
.hca-gantt-month { font-size: 8.5px; font-weight: 600; color: var(--ink-5, #94a3b8); letter-spacing: 0.04em; }

/* Project header row + envelope */
.hca-gantt-project-row { display: grid; grid-template-columns: 180px 1fr; gap: 8px; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--line-soft, #e5e7eb); }
.hca-gantt-project-label { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; color: var(--ink, #111); padding-left: 4px; }
.hca-gantt-chevron { color: var(--ink-5, #94a3b8); font-size: 9px; }
.hca-gantt-project-track { position: relative; height: 18px; background: var(--bg-sunk, #f9fafb); border-radius: 6px; overflow: hidden; }
.hca-gantt-envelope { position: absolute; top: 4px; bottom: 4px; background: linear-gradient(90deg, rgba(99,102,241,0.22), rgba(99,102,241,0.10)); border-radius: 5px; transition: width 600ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.hca-pill { font-size: 8.5px; font-weight: 600; padding: 1px 6px; border-radius: 99px; margin-left: auto; }
.hca-pill-warn { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }

/* Phase rows — staggered slide-in via .is-in */
.hca-gantt-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 2px; padding-top: 4px; overflow: hidden; }
.hca-gantt-row { display: grid; grid-template-columns: 180px 1fr; gap: 8px; align-items: center; min-height: 18px; opacity: 0; transform: translateY(2px); transition: opacity 300ms ease, transform 300ms ease; }
.hca-gantt-row.is-in { opacity: 1; transform: none; }
.hca-gantt-row-label { display: flex; align-items: center; gap: 6px; font-size: 10px; color: var(--ink-3, #475569); padding-left: 4px; min-width: 0; }
.hca-gantt-row-dot { width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0; }
.hca-gantt-row-name { color: var(--ink, #111); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.hca-gantt-row-meta { font-size: 9px; color: var(--ink-5, #94a3b8); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.hca-gantt-row-track { position: relative; height: 14px; }
.hca-gantt-bar {
  position: absolute; top: 3px; height: 8px; border-radius: 3px;
  transform-origin: left center;
  animation: hca-bar-grow 520ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes hca-bar-grow { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: 1; } }
.hca-gantt-milestone {
  position: absolute; top: 1px; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-bottom: 9px solid currentColor;
  animation: hca-ms-pop 360ms cubic-bezier(0.34, 1.56, 0.64, 1) 400ms both;
}
@keyframes hca-ms-pop { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.hca-gantt-empty { font-size: 10px; color: var(--ink-5, #94a3b8); font-style: italic; padding: 14px 8px; text-align: center; }

/* AI prompt overlay — Scene 3 */
.hca-prompt {
  position: absolute; bottom: 14px; left: 14px; right: 14px; z-index: 5;
  background: rgba(255, 255, 255, 0.96); backdrop-filter: blur(8px);
  border: 1px solid #c7d2fe; border-radius: 10px; padding: 9px 11px;
  box-shadow: 0 10px 24px -8px rgba(99, 102, 241, 0.30);
  animation: hca-prompt-in 320ms cubic-bezier(0.2, 0.7, 0.2, 1);
}
@keyframes hca-prompt-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.hca-prompt-bar { display: flex; align-items: center; gap: 8px; color: #4f46e5; font-size: 11.5px; }
.hca-prompt-text { color: var(--ink, #111); font-weight: 500; }
.hca-prompt-caret { color: #6366f1; animation: hca-caret-blink 0.9s steps(1) infinite; font-weight: 400; }
@keyframes hca-caret-blink { 50% { opacity: 0; } }
.hca-prompt-status { display: flex; align-items: center; gap: 7px; margin-top: 5px; font-size: 10px; color: var(--ink-4, #6b7280); padding-top: 5px; border-top: 1px solid var(--line-soft, #e5e7eb); }
.hca-spin { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid #c7d2fe; border-top-color: #6366f1; animation: hca-spin 0.7s linear infinite; flex-shrink: 0; }
@keyframes hca-spin { to { transform: rotate(360deg); } }

/* Done chip — Scene 5 */
.hca-done-chip {
  position: absolute; top: 9px; right: 11px; z-index: 4;
  display: inline-flex; align-items: center; gap: 5px;
  background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46;
  font-size: 10px; font-weight: 600; padding: 3px 8px; border-radius: 99px;
  animation: hca-done-in 360ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes hca-done-in { from { opacity: 0; transform: scale(0.85); } to { opacity: 1; transform: none; } }

/* Reduced motion — hide all animation, render final state instantly */
@media (prefers-reduced-motion: reduce) {
  .hca-frame, .hca-kpi, .hca-gantt-row, .hca-gantt-bar, .hca-gantt-milestone,
  .hca-prompt, .hca-done-chip { animation: none !important; opacity: 1 !important; transform: none !important; }
  .hca-gantt-row { opacity: 1; transform: none; }
  .hca-prompt-caret { animation: none; }
  .hca-spin { animation: none; }
}

/* Mobile — frame stays usable; reduce paddings; allow the gantt to shrink */
@media (max-width: 768px) {
  .hca-frame { aspect-ratio: 16 / 12; font-size: 10px; }
  .hca-side { flex: 0 0 90px; padding: 8px 5px; }
  .hca-side-item { font-size: 9px; padding: 3px 5px; }
  .hca-kpis { grid-template-columns: repeat(3, 1fr); }
  .hca-kpi { min-height: 44px; padding: 6px 7px; }
  .hca-kpi-value { font-size: 14px; }
  .hca-gantt-axis, .hca-gantt-project-row, .hca-gantt-row { grid-template-columns: 130px 1fr; gap: 6px; }
  .hca-gantt-row-meta { display: none; }
  .hca-content { padding: 10px; }
}

/* Hero — real screen-recorded Command Center demo GIF (replaces the prior
   CSS-recreated HeroCommandAnimation in the hero slot). Same frame language
   the rest of the landing uses: rounded card, subtle border + drop-shadow. */
.landing-hero > .hero-demo-gif {
  flex: 1 1 auto; min-width: 0;
  max-width: clamp(480px, 56vw, 900px);
  margin: 0 clamp(20px, 4vw, 56px) 0 clamp(16px, 3vw, 32px);
  align-self: center;
  width: 100%; height: auto;
  border-radius: 14px;
  border: 1px solid var(--line, #e5e7eb);
  box-shadow: 0 22px 60px -16px rgba(15, 23, 42, 0.20), 0 6px 18px -4px rgba(15, 23, 42, 0.10);
  display: block;
  background: var(--bg-card, #fff);
}
@media (max-width: 768px) {
  .landing-hero > .hero-demo-gif { max-width: 100%; margin: 0 auto; }
}

/* ── Data Intake PDF viewer modal (Google-Drive-style) ───────────────────── */
.di-pdf-modal-root {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.di-pdf-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  animation: dvOverlayIn 140ms ease-out;
}
.di-pdf-modal-frame {
  position: relative;
  width: 96vw;
  height: 94vh;
  max-width: 1600px;
  background: var(--bg-card);
  border-radius: 10px;
  border: 1px solid var(--line);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: dvOverlayIn 160ms ease-out;
}

.di-pdf-modal-topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.di-pdf-modal-topbar-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.di-pdf-modal-file-icon {
  width: 28px;
  height: 28px;
  border-radius: 5px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  color: var(--ink-3);
  flex-shrink: 0;
}
.di-pdf-modal-file-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.di-pdf-modal-topbar-center {
  display: flex;
  align-items: center;
  justify-content: center;
}
.di-pdf-modal-page-indicator {
  font-size: 12px;
  color: var(--ink-3);
  font-family: var(--f-mono);
  white-space: nowrap;
}
.di-pdf-modal-page-indicator-num {
  font-weight: 700;
  color: var(--ink-1);
}
.di-pdf-modal-topbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: flex-end;
}
.di-pdf-modal-zoom {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.di-pdf-modal-zoom-btn {
  background: transparent;
  border: none;
  color: var(--ink-3);
  font-size: 14px;
  font-weight: 600;
  width: 26px;
  height: 24px;
  border-radius: 4px;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.di-pdf-modal-zoom-btn:hover:not(:disabled) {
  background: var(--bg-elev);
  color: var(--ink-1);
}
.di-pdf-modal-zoom-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.di-pdf-modal-zoom-pct {
  background: transparent;
  border: none;
  color: var(--ink-3);
  font-family: var(--f-mono);
  font-size: 11.5px;
  min-width: 44px;
  height: 24px;
  border-radius: 4px;
  cursor: pointer;
}
.di-pdf-modal-zoom-pct:hover {
  background: var(--bg-elev);
  color: var(--ink-1);
}
.di-pdf-modal-close {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--ink-3);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.di-pdf-modal-close:hover {
  background: var(--bg-card);
  border-color: var(--line);
  color: var(--ink-1);
}

.di-pdf-modal-body {
  flex: 1;
  display: flex;
  min-height: 0;
  background: var(--bg-sunk);
}
.di-pdf-modal-status {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
  padding: 32px;
}

/* Data-intake preview panel empty/error states — markup referenced these
   classes (pages-1.jsx renderBody: "No file in storage" / "Preview failed")
   but no rules existed, so the content rendered as unstyled left-aligned
   text blocks. */
/* Data Intake per-row Project + Tags cell (project/tag association for chat retrieval) */
.di-ptcell { display: flex; flex-direction: column; gap: 5px; min-width: 150px; max-width: 210px; }
.di-proj-select { font-size: 12px; padding: 3px 6px; border: 1px solid var(--line); border-radius: 5px; background: var(--bg-elev); color: var(--ink-2); max-width: 200px; cursor: pointer; }
.di-proj-select:hover { border-color: var(--ink-5); }
.di-tags { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.di-tag { display: inline-flex; align-items: center; gap: 3px; font-size: 10.5px; background: var(--bg-hover); color: var(--ink-2); border: 1px solid var(--line); border-radius: 10px; padding: 1px 4px 1px 7px; }
.di-tag-x { background: none; border: none; cursor: pointer; color: var(--ink-4); font-size: 12px; line-height: 1; padding: 0 1px; }
.di-tag-x:hover { color: var(--bad); }
.di-addtag { background: none; border: 1px dashed var(--line); border-radius: var(--radius-btn); color: var(--ink-4); font-size: 10.5px; padding: 1px 7px; cursor: pointer; }
.di-addtag:hover { color: var(--ink-2); border-color: var(--ink-4); }
.di-tag-input { font-size: 11px; padding: 1px 6px; border: 1px solid var(--ink-5); border-radius: 10px; width: 96px; background: var(--bg-elev); color: var(--ink); }

/* ── Data Intake folder view + filter bar ──────────────────────────────────── */
.di-filterbar {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  padding: 4px 22px 14px;
}
/* Folder GRID — Google-Drive / Explorer-style tiles you click to open. */
.di-folder-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 12px; padding: 16px 22px 22px;
}
.di-folder-tile {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; text-align: left;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-btn, 12px); cursor: pointer;
  font-family: inherit; color: var(--ink);
  transition: border-color 110ms, box-shadow 110ms, background 110ms, transform 110ms;
}
.di-folder-tile:hover {
  border-color: var(--ink-5); box-shadow: var(--shadow-sm);
  background: var(--bg-hover); transform: translateY(-1px);
}
.di-folder-tile:focus-visible { outline: 2px solid var(--accent, #6366f1); outline-offset: 2px; }
.di-folder-tile-icon { flex: 0 0 auto; color: var(--indigo, #6366f1); display: inline-flex; }
.di-folder-tile-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.di-folder-tile-name { font-weight: 600; font-size: 13.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.di-folder-tile-count { font-size: 11.5px; color: var(--ink-4); }

/* Breadcrumb shown after drilling into a folder or searching. */
.di-crumbs { display: flex; align-items: center; gap: 7px; padding: 4px 22px 12px; font-size: 13px; }
.di-crumb-link { background: none; border: none; padding: 0; cursor: pointer; color: var(--ink-3); font-family: inherit; font-size: 13px; }
.di-crumb-link:hover { color: var(--ink); text-decoration: underline; }
.di-crumb-sep { color: var(--ink-5); flex: 0 0 auto; }
.di-crumb-here { font-weight: 600; color: var(--ink); display: inline-flex; align-items: center; gap: 8px; }
.di-crumb-count { font-size: 11px; font-weight: 600; color: var(--ink-4); background: var(--bg-hover); border-radius: 999px; padding: 1px 8px; }

.di-access-note { font-size: 12.5px; color: var(--ink-4); margin-top: 6px; display: flex; align-items: center; gap: 6px; }

/* Folders bar: "Folders" label + grid/list view toggle. */
.di-folders-bar { display: flex; align-items: center; justify-content: space-between; padding: 6px 22px 0; }
.di-folders-label { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); }
.di-viewtoggle { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-btn-icon, 8px); overflow: hidden; }
.di-viewtoggle-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 26px; background: var(--bg-card); border: none;
  cursor: pointer; color: var(--ink-4); transition: background 90ms, color 90ms;
}
.di-viewtoggle-btn + .di-viewtoggle-btn { border-left: 1px solid var(--line); }
.di-viewtoggle-btn:hover { background: var(--bg-hover); color: var(--ink); }
.di-viewtoggle-btn.active { background: var(--bg-hover); color: var(--indigo, #6366f1); }

/* Folder LIST view (rows) — the toggle alternative to the tile grid. */
.di-folder-list { padding: 10px 22px 4px; display: flex; flex-direction: column; gap: 2px; }
.di-folder-listrow {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 9px 12px; text-align: left; cursor: pointer;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-btn-icon, 8px);
  font-family: inherit; color: var(--ink); transition: background 90ms, border-color 90ms;
}
.di-folder-listrow:hover { background: var(--bg-hover); border-color: var(--line); }
.di-folder-listrow:focus-visible { outline: 2px solid var(--accent, #6366f1); outline-offset: -2px; }
.di-folder-listrow-icon { color: var(--indigo, #6366f1); flex: 0 0 auto; display: inline-flex; }
.di-folder-listrow-name { font-weight: 600; font-size: 13.5px; }
.di-folder-listrow-count { font-size: 12px; color: var(--ink-4); margin-left: auto; }
.di-folder-listrow-chev { color: var(--ink-5); flex: 0 0 auto; }

/* Recent files strip under the folders. */
.di-recent { border-top: 1px solid var(--line); margin-top: 14px; }
.di-recent-head { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); padding: 14px 22px 2px; }

/* "Go to folder" jump button in the recent list's action cell. */
.di-gotofolder {
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--ink-5);
  padding: 3px 5px; border-radius: var(--radius-btn-icon, 8px);
  transition: color 100ms, background 100ms;
}
.di-gotofolder:hover { color: var(--indigo, #6366f1); background: color-mix(in oklab, var(--indigo, #6366f1) 8%, transparent); }
.di-suggest { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink-3); background: color-mix(in oklab, var(--accent, #6366f1) 8%, transparent); border: 1px solid color-mix(in oklab, var(--accent, #6366f1) 22%, transparent); border-radius: 6px; padding: 2px 6px; }
.di-suggest-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 130px; }
.di-suggest-txt b { color: var(--ink); font-weight: 600; }
.di-suggest-yes { background: var(--accent, #6366f1); color: #fff; border: none; border-radius: var(--radius-btn); font-size: 10.5px; font-weight: 600; padding: 2px 8px; cursor: pointer; }
.di-suggest-yes:hover { filter: brightness(1.08); }

.di-panel-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-3);
}
.di-panel-empty-sub {
  margin-top: 6px;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--ink-4);
  max-width: 360px;
  line-height: 1.55;
}

/* Data Intake doc-viewer slide-over. The .di-panel family was rendered in JSX
   (DocPanel: backdrop + panel + header/pdf-nav/body/footer) but had NO CSS, so
   it laid out as unstyled flowing blocks with no height constraint — long notes
   (e.g. a pasted TEXT note) ran off the bottom of the viewport with no way to
   scroll. These rules make it a proper right-side slide-over whose BODY is the
   single scroll container (flex:1 + min-height:0 + overflow:auto). */
.di-panel-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.42);
  z-index: 400; animation: diPanelFade .18s ease;
}
.di-panel-backdrop.exiting { animation: diPanelFade .18s ease reverse forwards; }
@keyframes diPanelFade { from { opacity: 0; } to { opacity: 1; } }
.di-panel {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(760px, 92vw);
  background: var(--bg-card); border-left: 1px solid var(--line);
  box-shadow: -10px 0 44px rgba(0,0,0,0.28);
  z-index: 401; display: flex; flex-direction: column; min-height: 0;
  animation: diPanelSlideIn .24s cubic-bezier(0.4,0,0.2,1);
}
.di-panel.exiting { animation: diPanelSlideIn .2s ease reverse forwards; }
@keyframes diPanelSlideIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
.di-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.di-panel-pdf-nav {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 18px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.di-panel-body {
  flex: 1 1 auto; min-height: 0; overflow: auto;
  display: flex; flex-direction: column; background: var(--bg-sunk);
}
.di-panel-footer {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 18px; border-top: 1px solid var(--line); flex-shrink: 0;
}
.di-panel-action-btn {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: var(--radius-btn-icon); border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--ink-3); cursor: pointer;
  transition: background .12s, color .12s;
}
.di-panel-action-btn:hover { background: var(--bg-hover); color: var(--ink); }

/* ── CRM Contact detail pop-out ────────────────────────────────────────────
   Reuses the .di-panel right-side slide-over shell; these rules style the
   contact-specific content (avatar, detail fields, source chips, linked
   records) and narrow the panel since a contact is lighter than a document. */
.contact-panel { width: min(440px, 94vw); }
.contact-panel-avatar {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 14px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--ink-2); background: var(--bg-elev); border: 1px solid var(--line);
}
.contact-panel-name {
  font-size: 15px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.contact-panel-sub {
  font-size: 12.5px; color: var(--ink-3); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.contact-panel-body {
  background: var(--bg-card);
  padding: 18px; gap: 20px; display: flex; flex-direction: column;
}
.contact-panel-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.contact-panel-section { display: flex; flex-direction: column; gap: 10px; }
.contact-panel-section-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--ink-4);
}
.contact-panel-count {
  font-size: 10.5px; font-weight: 600; color: var(--ink-3);
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: 20px; padding: 1px 7px; letter-spacing: 0;
}
.contact-panel-fields { display: flex; flex-direction: column; gap: 12px; }
.contact-panel-field { display: flex; flex-direction: column; gap: 3px; }
.contact-panel-field-label {
  font-size: 11px; font-weight: 500; color: var(--ink-4);
}
.contact-panel-field-value {
  font-size: 13.5px; color: var(--ink-2); word-break: break-word;
}
.contact-panel-empty { color: var(--ink-5); font-style: italic; }
.contact-panel-records { display: flex; flex-direction: column; gap: 6px; }
.contact-panel-record {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg-elev);
}
.contact-panel-record.clickable { cursor: pointer; transition: background .12s, border-color .12s; }
.contact-panel-record.clickable:hover { background: var(--bg-hover); border-color: var(--line-2, var(--line)); }
.contact-panel-record-main { min-width: 0; flex: 1; }
.contact-panel-record-label {
  font-size: 13px; font-weight: 500; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.contact-panel-record-date { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.tbl tr.contact-row:hover { background: var(--bg-hover); }

/* ── Staff / guest invite slide-over ────────────────────────────────────────
   Reuses the .di-panel right-side slide-over shell (Members → Add staff /
   Invite guest / seat-purchase confirm). Narrower than the doc viewer + a
   padded card-background body since it's a compact form, not a doc canvas. */
.staff-invite-panel { width: min(460px, 94vw); }
.staff-invite-panel-title { font-size: 15px; font-weight: 650; color: var(--ink); }
.staff-invite-panel-sub { font-size: 12px; color: var(--ink-4); margin-top: 2px; }
.staff-invite-panel-body {
  background: var(--bg-card);
  padding: 18px; gap: 16px; display: flex; flex-direction: column;
}
.staff-seat-confirm { display: flex; flex-direction: column; gap: 14px; }
.staff-seat-confirm-cost { display: flex; align-items: baseline; gap: 6px; }
.staff-seat-confirm-amount { font-size: 30px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.staff-seat-confirm-per { font-size: 13px; color: var(--ink-4); }

.di-pdf-modal-thumbs {
  width: 160px;
  flex-shrink: 0;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--bg-elev);
  border-right: 1px solid var(--line);
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.di-pdf-modal-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
}
.di-pdf-modal-thumb-canvas {
  width: 100%;
  border-radius: 4px;
  border: 2px solid var(--line);
  overflow: hidden;
  background: var(--bg-card);
  display: grid;
  place-items: center;
  padding: 4px;
  box-sizing: border-box;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.di-pdf-modal-thumb-canvas canvas {
  display: block;
  max-width: 100%;
  height: auto;
}
.di-pdf-modal-thumb:hover .di-pdf-modal-thumb-canvas {
  border-color: var(--line-strong);
}
.di-pdf-modal-thumb.active .di-pdf-modal-thumb-canvas {
  border-color: var(--indigo);
  box-shadow: 0 0 0 1px var(--indigo);
}
.di-pdf-modal-thumb-label {
  font-size: 10.5px;
  font-family: var(--f-mono);
  color: var(--ink-4);
}
.di-pdf-modal-thumb.active .di-pdf-modal-thumb-label {
  color: var(--indigo);
  font-weight: 700;
}

.di-pdf-modal-scroller {
  flex: 1;
  overflow: auto;
  background: var(--bg-sunk);
}
.di-pdf-modal-pages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  padding: 28px 24px 60px;
}
.di-pdf-modal-page {
  scroll-margin-top: 16px;
}

/* ── Project → Files tab: the in-app file preview ───────────────────────────
   The lightbox chrome (root / backdrop / frame / topbar / body) is the
   .di-pdf-modal-* family above, reused wholesale so a PDF opened from a
   project looks identical to one opened from Data Intake. Only what that
   family does not already have lives here: the image body, the "this can't be
   previewed" card, and the two extra topbar actions.
   All tokens below are GLOBAL — nothing scoped like --accent, which is
   defined only under .esign-page and renders invisible anywhere else. */
/* ── Project → Files tab: upload modal ──────────────────────────────────────
   Mirrors .sr-upload-dropzone (the SR upload modal, styles.css ~6456), which
   this modal's markup was modelled on — the class had NO rule at all, so the
   dropzone rendered as bare unstyled text with a tiny click target. The JSX
   toggles "drag-over" (not SR's "is-dragover"). */
.pd-upload-dropzone {
  border: 2px dashed var(--line); border-radius: 8px; padding: 24px 16px;
  text-align: center; background: var(--bg-sunk);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  cursor: pointer; color: var(--ink-4);
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.pd-upload-dropzone:hover { border-color: var(--indigo-line); color: var(--ink-3); }
.pd-upload-dropzone.drag-over {
  border-color: var(--indigo);
  background: color-mix(in oklab, var(--indigo) 6%, var(--bg-sunk));
  color: var(--ink-2);
}
.pd-upload-file-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; font-size: 12.5px; color: var(--ink-2);
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: 6px;
}

.pd-preview-root .di-pdf-modal-backdrop { cursor: zoom-out; }
.pd-preview-act {
  width: 30px; height: 30px;
  border-radius: var(--radius-btn-icon);
  background: transparent; border: 1px solid transparent;
  color: var(--ink-3); cursor: pointer;
  display: grid; place-items: center; flex-shrink: 0;
}
.pd-preview-act:hover {
  background: var(--bg-card); border-color: var(--line); color: var(--ink-1);
}

/* .di-pdf-modal-body is display:flex, so these bodies take flex:1. */
.pd-preview-image-wrap {
  flex: 1; min-width: 0; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: auto; padding: 24px;
}
.pd-preview-image {
  max-width: 100%; max-height: 100%;
  object-fit: contain; display: block;
  border-radius: 4px; background: var(--bg-card);
  box-shadow: 0 2px 20px rgba(0, 0, 0, 0.09), 0 0 0 1px rgba(0, 0, 0, 0.05);
}
/* Only rendered when pdf.js never loaded at all — the guarded fallback. */
.pd-preview-frame { flex: 1; width: 100%; border: 0; background: var(--bg-sunk); }

.pd-preview-fallback {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 10px; padding: 40px 24px; text-align: center;
}
.pd-preview-fallback-icon {
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 12px;
  background: var(--bg-elev); border: 1px solid var(--line);
  color: var(--ink-4); margin-bottom: 2px;
}
.pd-preview-fallback-title { font-size: 14px; font-weight: 650; color: var(--ink); }
.pd-preview-fallback-desc {
  font-size: 12.5px; color: var(--ink-4); max-width: 380px; line-height: 1.55;
}
.pd-preview-fallback-actions {
  display: flex; align-items: center; gap: 8px; margin-top: 8px;
}

/* ── Landing nav account switcher (multi-account, signed-in CTA) ────────────
   Chrome-profile-style swap-in for the plain "Dashboard" button in the public
   landing nav. Scoped under .landing-nav-acct-* — distinct from the sidebar
   profile drop-up's .profile-dropup-acct-* family so each surface tunes
   independently. */
.landing-nav-acct { position: relative; flex: 0 0 auto; }
.landing-nav-acct-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  height: 34px; padding: 3px 10px 3px 4px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  font: inherit; font-size: 13px; color: var(--ink);
  transition: background var(--duration-fast), border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.landing-nav-acct-trigger:hover,
.landing-nav-acct-trigger:focus-visible {
  outline: none;
  background: var(--bg-hover);
  border-color: var(--line-strong);
}
.landing-nav-acct-trigger.is-open {
  background: var(--bg-hover);
  border-color: var(--ink-3);
}
.landing-nav-acct-trigger-avatar { pointer-events: none; flex: 0 0 auto; }
.landing-nav-acct-trigger-name {
  font-size: 13px; font-weight: 550; color: var(--ink);
  max-width: 140px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.landing-nav-acct-trigger > svg {
  color: var(--ink-4); flex: 0 0 auto;
  transition: transform var(--duration-fast), color var(--duration-fast);
}
.landing-nav-acct-trigger.is-open > svg {
  transform: rotate(180deg); color: var(--ink-2);
}

.landing-nav-acct-menu {
  position: absolute; top: calc(100% + 8px); right: 0;
  z-index: 400; width: 296px;
  background: var(--bg-card);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.14), 0 2px 8px rgba(0,0,0,0.06);
  display: flex; flex-direction: column;
  overflow: hidden;
  font-size: 13px;
  padding: 4px 0;
}

.landing-nav-acct-menu-item {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 14px;
  background: none; border: none; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--ink-2);
  text-align: left;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.landing-nav-acct-menu-item:hover { background: var(--bg-hover); color: var(--ink); }
.landing-nav-acct-menu-item--top { color: var(--ink); font-weight: 600; }
.landing-nav-acct-menu-item--danger { color: var(--ink-3); }
.landing-nav-acct-menu-item--danger:hover {
  color: var(--bad, #dc2626);
  background: color-mix(in oklab, var(--bad, #dc2626) 6%, transparent);
}
.landing-nav-acct-menu-item svg { color: currentColor; opacity: 0.85; flex: 0 0 auto; }

.landing-nav-acct-menu-divider {
  height: 1px; background: var(--line-soft);
  margin: 4px 0;
}
.landing-nav-acct-menu-section {
  font-size: 10.5px; font-weight: 650; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-5);
  padding: 6px 14px 4px;
}
.landing-nav-acct-menu-empty {
  font-size: 12px; color: var(--ink-4);
  padding: 2px 14px 8px;
}
.landing-nav-acct-menu-list {
  display: flex; flex-direction: column;
  max-height: 260px; overflow-y: auto;
  padding-bottom: 2px;
}

.landing-nav-acct-row-wrap { display: flex; flex-direction: column; }
.landing-nav-acct-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; cursor: pointer;
  transition: background var(--duration-fast);
}
.landing-nav-acct-row:hover,
.landing-nav-acct-row.is-expanded { background: var(--bg-hover); }
.landing-nav-acct-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.landing-nav-acct-row-name {
  font-size: 13px; font-weight: 550; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.landing-nav-acct-row-email {
  font-size: 11.5px; color: var(--ink-4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.landing-nav-acct-row-status {
  flex: 0 0 auto;
  font-size: 10px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--ink-4);
  background: var(--bg-sunk);
  border-radius: 4px; padding: 2px 6px;
}

.landing-nav-acct-signin-form {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 14px 8px;
  padding: 10px;
  background: var(--bg-elev);
  border: 1px solid var(--line-soft);
  border-radius: 6px;
}
.landing-nav-acct-signin-input {
  width: 100%; box-sizing: border-box;
  font: inherit; font-size: 12.5px; color: var(--ink);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 6px 8px;
  outline: none;
}
.landing-nav-acct-signin-input:focus { border-color: var(--line-strong); }
.landing-nav-acct-signin-input--ro { color: var(--ink-3); background: var(--bg-sunk); }
.landing-nav-acct-signin-err { font-size: 11.5px; color: var(--bad, #dc2626); }
.landing-nav-acct-signin-submit {
  align-self: stretch;
  font: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--bg-card); background: var(--ink);
  border: none; border-radius: 5px;
  padding: 7px 10px; cursor: pointer;
  transition: opacity var(--duration-fast);
}
.landing-nav-acct-signin-submit:disabled { opacity: 0.5; cursor: default; }
.landing-nav-acct-signin-submit:not(:disabled):hover { opacity: 0.9; }

.landing-nav-acct-add-form {
  display: flex; flex-direction: column; gap: 6px;
  margin: 4px 14px 8px;
  padding: 10px;
  background: var(--bg-elev);
  border: 1px solid var(--line-soft);
  border-radius: 6px;
}
.landing-nav-acct-add-actions {
  display: flex; gap: 6px; justify-content: flex-end;
}
.landing-nav-acct-add-cancel {
  font: inherit; font-size: 12.5px; color: var(--ink-3);
  background: none; border: none; cursor: pointer;
  padding: 7px 10px; border-radius: 5px;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.landing-nav-acct-add-cancel:hover { background: var(--bg-hover); color: var(--ink-2); }

/* ── Mobile variant — inline flat list (no popover) ────────────────────────
   Lives inside .landing-mobile-menu-actions, which is itself only mounted on
   ≤768px viewports, so these rules don't need an @media gate. */
.landing-nav-acct-mobile {
  display: flex; flex-direction: column; gap: 8px;
}
.landing-nav-acct-mobile-section {
  font-size: 10.5px; font-weight: 650; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--ink-5);
  margin-top: 4px;
}
.landing-nav-acct-mobile-active {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  background: var(--bg-elev);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}
.landing-nav-acct-active-pill {
  display: inline-block;
  font-size: 10px; font-weight: 650; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--ink-3); background: var(--bg-sunk);
  border-radius: 4px; padding: 1px 5px;
  margin-left: 6px;
}
.landing-nav-acct-mobile-action {
  display: inline-flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: inherit; font-size: 14px; color: var(--ink);
  cursor: pointer; text-align: left;
  transition: background var(--duration-fast), border-color var(--duration-fast), color var(--duration-fast);
}
.landing-nav-acct-mobile-action:hover {
  background: var(--bg-hover); border-color: var(--line-strong);
}
.landing-nav-acct-mobile-action--danger { color: var(--ink-3); }
.landing-nav-acct-mobile-action--danger:hover {
  color: var(--bad, #dc2626);
  background: color-mix(in oklab, var(--bad, #dc2626) 6%, transparent);
}
.landing-nav-acct-mobile-action svg { color: currentColor; opacity: 0.85; flex: 0 0 auto; }

/* ─── Two-factor (TOTP) — enrollment modal, Security-tab section, Profile-tab callout ─── */

/* Profile-tab yellow callout shown when no verified TOTP factor exists. */
.mfa-callout {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  margin-bottom: 18px;
  background: var(--warn-soft);
  border: 1px solid var(--warn-line);
  border-left: 3px solid var(--warn);
  border-radius: 8px;
}
.mfa-callout-icon {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 6px;
  background: color-mix(in oklab, var(--warn) 18%, transparent);
  color: var(--warn);
}
.mfa-callout-body { flex: 1 1 auto; min-width: 0; }
.mfa-callout-title { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.mfa-callout-desc { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.mfa-callout-btn { flex: 0 0 auto; }

/* Security-tab section — enrollment status + actions. */
.mfa-section {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-elev);
  display: flex; flex-direction: column; gap: 12px;
}
.mfa-section-head { display: flex; gap: 12px; align-items: flex-start; }
.mfa-section-icon {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 7px;
  background: var(--indigo-soft);
  color: var(--indigo-ink);
}
.mfa-section-text { flex: 1 1 auto; min-width: 0; }
.mfa-section-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.mfa-section-desc { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; line-height: 1.5; }
.mfa-section-status-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-top: 4px;
  border-top: 1px solid var(--line-soft);
  padding-top: 12px;
}
.mfa-section-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 500;
  padding: 4px 10px;
  border-radius: 99px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  color: var(--ink-3);
}
.mfa-section-status--ok { color: var(--ok); border-color: var(--ok-line); background: var(--ok-soft); }
.mfa-section-status--off { color: var(--ink-4); }
.mfa-section-status--muted { color: var(--ink-4); font-style: italic; }
.mfa-remove-btn { color: var(--bad); margin-left: auto; }

/* Modal — enrollment flow. */
.mfa-modal-overlay {
  position: fixed; inset: 0; z-index: 600;
  background: rgba(0,0,0,0.42);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  animation: dvOverlayIn 0.18s ease both;
}
.mfa-modal {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  width: 100%; max-width: 460px;
  max-height: 92vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 64px rgba(0,0,0,0.20);
  animation: dvPanelIn 0.22s cubic-bezier(0.34,1.2,0.64,1) both;
}
.mfa-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.mfa-modal-title { font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em; }
.mfa-modal-sub { font-size: 12px; color: var(--ink-4); margin-top: 3px; }
.mfa-modal-close {
  background: none; border: none; cursor: pointer; color: var(--ink-4);
  display: flex; align-items: center; justify-content: center;
  padding: 4px; border-radius: 5px;
  transition: background 0.1s, color 0.1s;
}
.mfa-modal-close:hover { background: var(--bg-hover); color: var(--ink); }
.mfa-modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 18px 20px;
}
.mfa-modal-footer {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px;
  border-top: 1px solid var(--line-soft);
  flex-shrink: 0;
}
.mfa-enroll-form { display: flex; flex-direction: column; gap: 8px; }
.mfa-step-label {
  font-size: 11.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-4);
  margin-top: 4px;
}
.mfa-step-help { font-size: 13px; color: var(--ink-3); line-height: 1.5; margin-bottom: 4px; }
.mfa-qr-wrap {
  display: flex; align-items: center; justify-content: center;
  padding: 12px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin: 4px 0 10px;
}
.mfa-qr {
  width: 220px; height: 220px; display: block; margin: 16px auto;
}
/* Inline SVG from Supabase's QR — force it to fill the .mfa-qr box since
   the raw <svg> won't carry width/height the way the old <img> did. */
.mfa-qr svg { width: 100%; height: 100%; display: block; }
.mfa-secret-label { font-size: 12px; color: var(--ink-4); }
.mfa-secret-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 7px;
  margin-top: 4px;
}
.mfa-secret {
  flex: 1 1 auto;
  font-family: var(--f-mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  word-break: break-all;
  background: transparent;
}
.mfa-copy-btn {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 5px;
}
.mfa-divider {
  height: 1px;
  background: var(--line-soft);
  margin: 16px 0 6px;
}
.mfa-code-input {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-elev);
  color: var(--ink);
  font-family: var(--f-mono);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-align: center;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  margin-top: 4px;
}
.mfa-code-input:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--indigo) 14%, transparent);
}
.mfa-error {
  font-size: 13px;
  color: var(--bad);
  padding: 6px 10px;
  background: var(--bad-soft);
  border: 1px solid var(--bad-line);
  border-radius: 6px;
  margin-top: 6px;
}
.mfa-loading {
  font-size: 13px; color: var(--ink-3);
  padding: 24px 0;
  text-align: center;
}
.mfa-platform-warn {
  padding: 12px 14px;
  background: var(--warn-soft);
  border: 1px solid var(--warn-line);
  border-radius: 8px;
  color: var(--ink-2);
}
.mfa-platform-warn--bad {
  background: var(--bad-soft);
  border-color: var(--bad-line);
}
.mfa-recovery-help {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  font-size: 12.5px;
  color: var(--ink-3);
}
.mfa-recovery-help summary {
  cursor: pointer;
  color: var(--ink-3);
  font-weight: 500;
  list-style: none;
  padding: 2px 0;
}
.mfa-recovery-help summary::-webkit-details-marker { display: none; }
.mfa-recovery-help summary::before {
  content: "▸";
  display: inline-block;
  width: 14px;
  color: var(--ink-4);
  transition: transform 0.15s;
}
.mfa-recovery-help[open] summary::before { transform: rotate(90deg); }
.mfa-recovery-help-body {
  padding: 8px 0 0 16px;
  line-height: 1.55;
}
.mfa-recovery-help-body a { color: var(--indigo); text-decoration: underline; }

/* ============================================================================
   Plan-prompt banner + plan-picker modal
   ---------------------------------------------------------------------------
   Top-pinned subscriber-reminder banner shown to firms that haven't picked a
   plan yet. Two visual weights:
     - .plan-prompt-banner             — full banner (~56px), shown on first
                                         load or after long absence.
     - .plan-prompt-banner.plan-prompt-banner--strip
                                       — thin condensed strip (~32px), shown
                                         on repeat sessions after dismiss.
   The banner is position:fixed at viewport top so it stays visible while the
   workspace scrolls. The body picks up `body.has-plan-banner` (and
   `body.plan-banner-strip` for the strip variant) — those classes drive the
   page padding-top AND nudge the sticky .topbar down by the banner height so
   nothing overlaps. Visual language references .announcement (soft-tint
   horizontal bar) + .billing-trial-banner (indigo-tinted subscription nudge).

   Modal: .plan-pick-overlay + .plan-pick-modal — matches existing
   .modal-backdrop / .modal-card sizing + shadow, with a card grid for the
   four plans (Free / Studio / Team / Firm). The "recommended" plan
   (.plan-pick-card-rec) gets an indigo border + "Most popular" badge.
   ============================================================================ */

/* ── Banner ─────────────────────────────────────────────────────────────── */
.plan-prompt-banner {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 20;                                /* above .topbar (z:5), below modals (350) */
  display: flex; align-items: center;
  min-height: 56px;
  padding: 10px 20px;
  background: color-mix(in srgb, var(--indigo) 10%, var(--bg-card));
  border-bottom: 1px solid color-mix(in srgb, var(--indigo) 30%, var(--line));
  color: var(--ink);
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  animation: plan-prompt-banner-in var(--duration-base, 180ms) var(--ease-out, ease-out) both;
}
.plan-prompt-banner--strip {
  min-height: 32px;
  padding: 4px 16px;
  background: color-mix(in srgb, var(--indigo) 6%, var(--bg-card));
  box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
@keyframes plan-prompt-banner-in {
  from { transform: translateY(-100%); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}

.plan-prompt-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  min-width: 0;
}

.plan-prompt-copy {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 0; flex: 1 1 auto;
}
.plan-prompt-title {
  font-size: 13.5px; font-weight: 600; color: var(--ink); letter-spacing: -0.005em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.plan-prompt-sub {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.plan-prompt-banner--strip .plan-prompt-title { font-size: 12.5px; }
.plan-prompt-banner--strip .plan-prompt-sub   { display: none; }
.plan-prompt-banner--strip .plan-prompt-copy  { flex-direction: row; align-items: baseline; gap: 8px; }

.plan-prompt-actions {
  display: flex; align-items: center; gap: 8px;
  flex: 0 0 auto;
}

.plan-prompt-cta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px;
  background: var(--indigo); color: #fff;
  border: 1px solid var(--indigo); border-radius: 7px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: background var(--duration-fast), border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.plan-prompt-cta:hover {
  background: color-mix(in srgb, var(--indigo) 88%, #000);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--indigo) 35%, transparent);
}
.plan-prompt-cta:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg-card), 0 0 0 4px var(--indigo);
}

.plan-prompt-dismiss {
  padding: 6px 10px;
  background: transparent; color: var(--ink-3);
  border: 1px solid transparent; border-radius: 7px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.plan-prompt-dismiss:hover { background: var(--bg-hover); color: var(--ink); }
.plan-prompt-banner--strip .plan-prompt-cta { padding: 4px 10px; font-size: 12px; }
.plan-prompt-banner--strip .plan-prompt-dismiss { padding: 4px 8px; font-size: 12px; }

/* ── Body offsets + sticky topbar coordination ──────────────────────────── */
/* When the banner is active, push the entire document down by exactly the
   banner height. The .topbar uses position:sticky with top:8px — bumping
   its `top` here so it sticks BELOW the fixed banner during scroll instead
   of sliding under it. (Topbar z-index 5 is below the banner's 20 anyway,
   but visual layering still matters when both are visible at rest.) */
body.has-plan-banner             { padding-top: 56px; }
body.has-plan-banner.plan-banner-strip            { padding-top: 32px; }
/* No .topbar `top` bump needed anymore: the bar is position:absolute inside
   .app-right, which the body padding-top above already displaces below the
   fixed banner — a manual offset here would double-shift it. */

@media (prefers-reduced-motion: reduce) {
  .plan-prompt-banner { animation: none; }
}

/* ── Picker modal ───────────────────────────────────────────────────────── */
.plan-pick-overlay {
  /* ⚠️ 350 NO LONGER "matches .modal-backdrop" — that moved to the 7050 dialog
     band on 2026-08-10 (see the "⭐⭐ THE DIALOG LAYER" block). This overlay is
     a BESPOKE pair with .obt-overlay (360) and is deliberately left below the
     band: neither is ever opened from inside a z-5000 full-screen editor. If
     one ever is, move BOTH into the band together — the 350/360 relationship
     between them is the thing that matters. */
  position: fixed; inset: 0; z-index: 350;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(0,0,0,0.50);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: plan-pick-overlay-in var(--duration-base, 180ms) var(--ease-in-out, ease-in-out) both;
}
@keyframes plan-pick-overlay-in {
  from { opacity: 0; } to { opacity: 1; }
}

.plan-pick-modal {
  background: var(--bg-card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 32px 64px -16px rgba(0,0,0,0.28);
  width: 100%; max-width: 920px;
  max-height: 90vh; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 24px 26px 22px;
  gap: 18px;
  animation: plan-pick-modal-in var(--duration-base, 180ms) var(--ease-out, ease-out) both;
}
@keyframes plan-pick-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}

.plan-pick-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px;
}
.plan-pick-title {
  font-size: 18px; font-weight: 600; color: var(--ink); letter-spacing: -0.015em;
  line-height: 1.25;
}
.plan-pick-sub {
  font-size: 13px; color: var(--ink-3); line-height: 1.5;
  margin-top: 4px;
}

.plan-pick-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  overflow-y: auto;
  padding: 2px;                                 /* prevent focus rings clipping */
}

.plan-pick-card {
  position: relative;
  display: flex; flex-direction: column;
  gap: 6px;
  padding: 18px 16px 16px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  min-height: 200px;
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast), transform var(--duration-fast);
}
.plan-pick-card:hover {
  border-color: var(--line-strong);
  box-shadow: 0 4px 16px rgba(0,0,0,0.06);
  transform: translateY(-1px);
}
.plan-pick-card-rec {
  border-color: var(--indigo);
  box-shadow: 0 0 0 1px var(--indigo) inset, 0 6px 20px color-mix(in srgb, var(--indigo) 16%, transparent);
}
.plan-pick-card-rec:hover {
  border-color: var(--indigo);
  box-shadow: 0 0 0 1px var(--indigo) inset, 0 10px 24px color-mix(in srgb, var(--indigo) 22%, transparent);
}

.plan-pick-badge {
  position: absolute; top: -10px; left: 14px;
  padding: 3px 8px;
  background: var(--indigo); color: #fff;
  border-radius: 999px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--indigo) 35%, transparent);
}

.plan-pick-name {
  font-size: 13px; font-weight: 600; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.plan-pick-price {
  font-size: 18px; font-weight: 600; color: var(--ink);
  letter-spacing: -0.01em; line-height: 1.2;
  margin-top: 2px;
}
.plan-pick-desc {
  font-size: 12px; color: var(--ink-3); line-height: 1.5;
  margin-top: 4px; margin-bottom: 12px;
}

@media (max-width: 768px) {
  .plan-pick-modal     { padding: 20px 18px 18px; }
  .plan-pick-cards     { grid-template-columns: 1fr; }
  .plan-prompt-inner   { gap: 10px; }
  .plan-prompt-sub     { display: none; }       /* mobile: keep banner one-line */
}

/* ── Studio Review — nav-btn active state + export spinner ──────────────────── */
.sr-nav-btn-active { background: var(--indigo-soft, oklch(92% 0.04 268)) !important; color: var(--indigo) !important; }
.sr-nav-btn-active:hover { background: var(--indigo-soft, oklch(90% 0.06 268)) !important; }

@keyframes sr-spin { to { transform: rotate(360deg); } }
.sr-export-spinner {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--indigo);
  animation: sr-spin 0.7s linear infinite; flex-shrink: 0;
}
.sr-export-spinner-overlay {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 24px 16px; color: var(--ink-3); font-size: 12px;
}
.sr-export-spinner-label { font-size: 11.5px; color: var(--ink-3); }

/* ── Studio Review — Code Check panel ─────────────────────────────────────── */
.sr-code-check-panel {
  width: 300px; flex-shrink: 0; background: var(--bg-elev);
  border-left: 1px solid var(--line);
  display: flex; flex-direction: column; overflow: hidden;
}
.sr-code-check-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 7px 10px 7px 10px; border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); flex-shrink: 0;
}
.sr-code-check-title {
  display: flex; align-items: center; font-size: 11.5px; font-weight: 600;
  color: var(--ink-2); gap: 0; letter-spacing: 0.01em;
}
.sr-code-check-jur {
  margin-left: 7px; padding: 1px 6px; border-radius: 10px;
  background: var(--indigo-soft, oklch(92% 0.04 268)); color: var(--indigo);
  font-size: 9.5px; font-weight: 600; letter-spacing: 0.03em;
}
.sr-code-check-close {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: var(--radius-btn-icon, 8px); border: none;
  background: none; cursor: pointer; color: var(--ink-4);
  transition: background var(--duration-fast), color var(--duration-fast);
}
.sr-code-check-close:hover { background: var(--bg-hover); color: var(--ink); }

.sr-code-check-advisory {
  display: flex; align-items: flex-start; gap: 6px;
  padding: 8px 10px; background: oklch(98% 0.025 85);
  border-bottom: 1px solid oklch(90% 0.04 85);
  font-size: 10px; color: oklch(42% 0.12 65); line-height: 1.45;
  flex-shrink: 0;
}
[data-theme="dark"] .sr-code-check-advisory {
  background: oklch(22% 0.04 85); border-bottom-color: oklch(30% 0.06 85);
  color: oklch(72% 0.08 80);
}

.sr-code-check-body {
  flex: 1; overflow-y: auto; padding: 8px 0;
}
.sr-code-check-loading {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 28px 16px; font-size: 11.5px; color: var(--ink-3);
}
.sr-code-check-error {
  display: flex; align-items: flex-start; gap: 6px;
  margin: 10px; padding: 8px 10px; border-radius: 5px;
  background: var(--red-soft, oklch(96% 0.02 15)); color: var(--red, #DC2626);
  font-size: 11px; border: 1px solid oklch(88% 0.04 15); line-height: 1.4;
}
.sr-code-check-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 28px 16px; gap: 6px; color: var(--ink-4); font-size: 11.5px;
  text-align: center;
}
.sr-code-check-summary {
  margin: 6px 10px 10px; padding: 8px 10px; border-radius: 5px;
  background: var(--bg-sunk); font-size: 11px; color: var(--ink-3);
  line-height: 1.5; border: 1px solid var(--line);
}
.sr-code-check-finding {
  margin: 0 8px 8px; padding: 8px 10px; border-radius: 5px;
  border: 1px solid var(--line); border-left-width: 3px;
  background: var(--bg-elev);
}
.sr-code-check-finding-header {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-bottom: 5px;
}
.sr-code-check-sev-badge {
  font-size: 9px; font-weight: 700; letter-spacing: 0.05em;
  padding: 1px 6px; border-radius: 10px; text-transform: uppercase;
}
.sr-code-check-domain {
  font-size: 9.5px; padding: 1px 6px; border-radius: 10px;
  background: var(--bg-sunk); color: var(--ink-4); border: 1px solid var(--line);
}
.sr-code-check-sheet {
  font-size: 9.5px; color: var(--ink-5); font-family: var(--f-mono);
}
.sr-code-check-concern {
  font-size: 11px; color: var(--ink-2); margin: 0 0 4px; line-height: 1.45; font-weight: 500;
}
.sr-code-check-ref {
  display: flex; align-items: center; gap: 4px;
  font-size: 10px; color: var(--ink-4); font-family: var(--f-mono);
  margin: 0 0 4px; line-height: 1.4;
}
.sr-code-check-rec {
  font-size: 10.5px; color: var(--ink-3); margin: 0; line-height: 1.45;
  padding-top: 3px; border-top: 1px solid var(--line);
}
/* Provenance banner — shown only when Maharashtra / UDCPR corpus is active */
.sr-code-check-provenance {
  display: flex; align-items: center; gap: 5px;
  padding: 5px 10px; font-size: 10px; font-weight: 600; letter-spacing: 0.02em;
  background: oklch(93% 0.06 268); color: var(--indigo); border-bottom: 1px solid oklch(85% 0.08 268);
  flex-shrink: 0;
}
[data-theme="dark"] .sr-code-check-provenance {
  background: oklch(20% 0.06 268); color: oklch(72% 0.14 268); border-bottom-color: oklch(28% 0.08 268);
}
/* Regulation number chip — prominent authoritative citation in finding header */
.sr-code-check-reg-chip {
  font-size: 10.5px; font-family: var(--f-mono); font-weight: 700;
  padding: 1px 7px; border-radius: 10px; letter-spacing: 0.02em;
  background: var(--bg-sunk); color: var(--ink-3); border: 1px solid var(--line);
}
.sr-code-check-reg-chip.grounded {
  background: oklch(93% 0.06 268); color: var(--indigo);
  border-color: oklch(85% 0.08 268);
}
[data-theme="dark"] .sr-code-check-reg-chip.grounded {
  background: oklch(20% 0.06 268); color: oklch(72% 0.14 268); border-color: oklch(28% 0.08 268);
}

/* Mode toggle (This sheet / Full set) */
.sr-cc-mode {
  display: flex; border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); flex-shrink: 0;
}
.sr-cc-mode-btn {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 5px 8px; border: none; background: none; cursor: pointer;
  font-size: 11px; color: var(--ink-4); font-weight: 500;
  border-bottom: 2px solid transparent; transition: color var(--duration-fast), border-color var(--duration-fast);
  white-space: nowrap;
}
.sr-cc-mode-btn:hover:not(:disabled) { color: var(--ink-2); }
.sr-cc-mode-btn.active { color: var(--indigo); border-bottom-color: var(--indigo); }
.sr-cc-mode-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.sr-cc-mode-cost {
  font-size: 9px; color: var(--ink-5); font-weight: 400;
}
.sr-cc-mode-hint {
  font-size: 9px; color: var(--warn); font-weight: 400;
}

/* Page range inputs */
.sr-cc-range {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px; border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); flex-shrink: 0;
}
.sr-cc-range-label {
  font-size: 10px; color: var(--ink-4); white-space: nowrap;
}
.sr-cc-range-input {
  width: 46px; font-size: 11px; color: var(--ink-2);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 4px; padding: 3px 5px; text-align: center;
}
.sr-cc-range-input:focus { outline: none; border-color: var(--indigo); }
.sr-cc-range-input:disabled { opacity: 0.5; }
.sr-cc-range-of { font-size: 9.5px; color: var(--ink-5); white-space: nowrap; }

/* Token / credit estimate */
.sr-cc-estimate {
  padding: 5px 10px; border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); flex-shrink: 0;
  font-size: 10px; color: var(--ink-4);
}
.sr-cc-est-note { font-style: italic; color: var(--ink-5); }

/* Run button row */
.sr-cc-run-row {
  padding: 7px 10px; border-bottom: 1px solid var(--line);
  background: var(--bg-sunk); flex-shrink: 0;
}
/* Run button rides on .btn.btn-primary (pill radius via --radius-btn); this
   class only adapts it to the narrow panel: full-width, centered, compact. */
.sr-cc-run-btn {
  width: 100%; padding: 6px 12px; font-size: 11.5px; font-weight: 600;
  justify-content: center; gap: 5px;
}
.sr-cc-run-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.sr-cc-jur-picker {
  padding: 7px 10px 7px; border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 4px; flex-shrink: 0;
  background: var(--bg-sunk);
}
.sr-cc-jur-label {
  font-size: 9px; font-weight: 600; color: var(--ink-4);
  letter-spacing: 0.06em; text-transform: uppercase;
}
.sr-cc-jur-select {
  width: 100%; font-size: 11.5px; color: var(--ink-2);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius-btn); padding: 4px 24px 4px 7px; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  /* Chevron stroke matches --ink-4's light value — data-URI SVGs can't
     consume CSS custom properties, so dark/mid override the image below. */
  background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2376787f' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center;
}
[data-theme="dark"] .sr-cc-jur-select {
  background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236f717b' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.sr-cc-jur-select:disabled { opacity: 0.55; cursor: not-allowed; }
.sr-cc-jur-select:focus { outline: none; border-color: var(--indigo); }
.sr-cc-jur-picker .sr-cc-jur-hint {
  font-size: 9.5px; color: var(--warn); line-height: 1.35;
}

/* Full-set stats bar */
.sr-cc-stats {
  display: flex; align-items: center; gap: 0;
  padding: 6px 10px; background: var(--bg-sunk);
  border-bottom: 1px solid var(--line); flex-shrink: 0;
  font-size: 10.5px; color: var(--ink-3);
}
.sr-cc-stat { display: flex; align-items: center; gap: 3px; padding: 0 6px; }
.sr-cc-stat strong { color: var(--ink); font-weight: 700; }
.sr-cc-stat-sep {
  width: 1px; height: 12px; background: var(--line); flex-shrink: 0;
}

/* Domain group (full-set findings grouped by discipline) */
.sr-cc-domain-group { margin-bottom: 2px; }
.sr-cc-domain-label {
  padding: 5px 10px 3px; font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-4); background: var(--bg-sunk);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  margin-bottom: 4px; position: sticky; top: 0; z-index: 1;
}

/* Sheet page chip on each finding (full-set mode) */
.sr-cc-sheet-chip {
  font-size: 9.5px; padding: 1px 6px; border-radius: 10px;
  background: var(--bg-sunk); color: var(--ink-5);
  border: 1px solid var(--line); font-family: var(--f-mono);
}

/* ============================================================================
   InvoicePreview — firm-branded invoice document (Round 1 of unified invoicing)
   ---------------------------------------------------------------------------
   Renders a clean, professional invoice document. All selectors scope
   under .inv-doc so they NEVER bleed into the invoice LIST page family
   (.inv-wrap / .inv-tbl / .inv-row / .inv-status-* etc., lines ~5400-5524) —
   the list and the doc share the .inv- prefix by feature, but have no
   overlapping bare names. A4/Letter-proportioned, white background,
   readable at preview size AND when printed.

   Per-firm accent color comes through as a CSS custom property:
       <div className="inv-doc" style={{ "--inv-accent": "#4f46e5" }}>
   Setting it on the doc root lets the accent bar + headers + grand-total
   row pick it up via var(--inv-accent) — no inline styling per element,
   so a theme change recolors the whole doc in one place.

   Print: an .inv-printing class on <body> + @media print hides every chrome
   surface and shows only .inv-doc. Callers set the class, call
   window.print(), and clear the class on the afterprint event.
   ============================================================================ */

.inv-doc {
  --inv-accent: #1c2024; /* letterhead default; JS sets --inv-accent from the resolved firm/office accent when present */
  position: relative;
  background: #fff;
  color: #111827;
  /* US Letter at ~72 dpi rendering: 8.5" × 11" → 816 × 1056. Cap width to
     match Letter at a comfortable preview density; keep min-height so the
     doc still looks like a sheet when empty. */
  width: 100%;
  max-width: 816px;
  min-height: 1056px;
  margin: 0 auto;
  padding: 56px 64px 64px;
  box-sizing: border-box;
  border: 1px solid var(--line, #e5e7eb);
  border-radius: 6px;
  box-shadow: 0 12px 36px -16px rgba(0,0,0,0.18);
  font-family: var(--f-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
  font-size: 13px;
  line-height: 1.5;
  overflow: hidden;
}

.inv-accent-bar {
  position: absolute; top: 0; left: 0; right: 0;
  height: 8px;
  background: var(--inv-accent);
}

/* ── Header: firm-left, INVOICE-meta-right ────────────────────────────── */
.inv-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 32px;
  padding-bottom: 28px;
  border-bottom: 1px solid #e5e7eb;
  margin-bottom: 28px;
}
.inv-from {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 4px;
}
.inv-logo {
  width: 56px; height: 56px;
  border-radius: 8px;
  margin-bottom: 10px;
  object-fit: contain;
  background: #fff;
}
.inv-logo-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: var(--inv-accent); color: #fff;
  font-weight: 600; font-size: 22px; letter-spacing: 0.02em;
}
.inv-from-name {
  font-size: 16px; font-weight: 600; color: #111827; letter-spacing: -0.01em;
}
.inv-from-address {
  font-size: 12px; color: #4b5563; white-space: pre-line; line-height: 1.45;
}
.inv-from-contact {
  font-size: 11.5px; color: #6b7280; margin-top: 2px;
}
.inv-sep { color: #9ca3af; }

.inv-meta {
  flex: 0 0 auto;
  text-align: right;
  min-width: 220px;
}
.inv-meta-title {
  font-size: 22px; font-weight: 700; letter-spacing: 0.18em;
  color: var(--inv-accent);
  text-transform: uppercase;
  line-height: 1;
  margin-bottom: 6px;
}
.inv-meta-num {
  font-size: 13px; font-weight: 500; color: #111827;
  font-family: var(--f-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  margin-bottom: 16px;
}
.inv-meta-grid {
  display: grid;
  grid-template-columns: auto auto;
  gap: 4px 16px;
  margin: 0;
  justify-content: end;
  font-size: 11.5px;
}
.inv-meta-grid dt { color: #6b7280; text-align: right; font-weight: 500; }
.inv-meta-grid dd { color: #111827; margin: 0; text-align: right; font-weight: 500; }

/* ── Bill To block ────────────────────────────────────────────────────── */
.inv-billto {
  margin-bottom: 24px;
}
.inv-billto-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  color: #6b7280; text-transform: uppercase;
  margin-bottom: 6px;
}
.inv-billto-name {
  font-size: 14.5px; font-weight: 600; color: #111827; line-height: 1.3;
}
.inv-billto-email {
  font-size: 12px; color: #4b5563; margin-top: 2px;
}

/* ── Line-items table ─────────────────────────────────────────────────── */
.inv-doc .inv-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 20px;
  font-size: 12.5px;
}
.inv-doc .inv-table thead th {
  background: color-mix(in srgb, var(--inv-accent) 8%, transparent);
  color: var(--inv-accent);
  font-weight: 600; font-size: 10.5px; letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 10px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--inv-accent) 30%, transparent);
  text-align: left;
}
.inv-doc .inv-table .inv-th-qty,
.inv-doc .inv-table .inv-th-rate,
.inv-doc .inv-table .inv-th-amt { text-align: right; }
.inv-doc .inv-table tbody td {
  padding: 12px;
  border-bottom: 1px solid #f1f5f9;
  vertical-align: top;
  color: #111827;
}
.inv-doc .inv-table tbody tr:last-child td { border-bottom: 1px solid #e5e7eb; }
.inv-doc .inv-table .inv-td-desc { width: auto; line-height: 1.45; }
.inv-doc .inv-table .inv-td-qty  { width: 70px;  text-align: right; font-variant-numeric: tabular-nums; }
.inv-doc .inv-table .inv-td-rate { width: 110px; text-align: right; font-variant-numeric: tabular-nums; }
.inv-doc .inv-table .inv-td-amt  { width: 130px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.inv-doc .inv-table .inv-empty-row {
  text-align: center; color: #9ca3af; font-style: italic;
  padding: 24px 12px;
}

/* ── Totals block (right-aligned) ─────────────────────────────────────── */
.inv-totals {
  display: flex; flex-direction: column;
  margin-left: auto;
  width: 280px;
  margin-bottom: 32px;
}
.inv-totals-row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 6px 0;
  font-size: 13px;
  color: #4b5563;
}
.inv-totals-row .inv-totals-value { font-variant-numeric: tabular-nums; color: #111827; }
.inv-totals-row--grand {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 2px solid var(--inv-accent);
  font-size: 15px; font-weight: 600;
  color: #111827;
}
.inv-totals-row--grand .inv-totals-label { color: #111827; }
.inv-totals-row--grand .inv-totals-value { color: var(--inv-accent); font-size: 18px; }

/* ── Footer: notes / terms / free-text footer ─────────────────────────── */
.inv-foot {
  margin-top: 16px;
  padding-top: 20px;
  border-top: 1px solid #e5e7eb;
  display: flex; flex-direction: column; gap: 16px;
}
.inv-foot-block {
  display: flex; flex-direction: column; gap: 4px;
}
.inv-foot-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  color: #6b7280; text-transform: uppercase;
}
.inv-foot-body {
  font-size: 12.5px; color: #374151; line-height: 1.55;
  white-space: pre-line;
}
.inv-foot-block--footer .inv-foot-body {
  color: #6b7280; font-size: 11.5px; font-style: italic;
  border-top: 1px dashed #e5e7eb; padding-top: 12px;
}
/* "Pay To" remittance block — key/value grid of the issuing office's payout account */
.inv-payto-grid {
  display: grid; grid-template-columns: auto 1fr;
  gap: 3px 16px; margin: 4px 0 0; max-width: 360px;
}
.inv-payto-grid dt { font-size: 12px; color: #6b7280; font-weight: 500; }
.inv-payto-grid dd { font-size: 12.5px; color: #111827; margin: 0; font-weight: 500; }

/* ── Responsive: narrow preview surfaces (modal on small viewports) ───── */
@media (max-width: 720px) {
  .inv-doc { padding: 36px 28px 40px; min-height: 0; }
  .inv-head { flex-direction: column; gap: 18px; }
  .inv-meta { text-align: left; min-width: 0; }
  .inv-meta-grid { justify-content: start; }
  .inv-meta-grid dt, .inv-meta-grid dd { text-align: left; }
  .inv-totals { width: 100%; }
}

/* ── Print: body.inv-printing → hide everything except .inv-doc ───────── */
@media print {
  body.inv-printing {
    background: #fff !important;
    padding: 0 !important; margin: 0 !important;
    /* Modal sets `document.body.style.overflow = "hidden"` inline while it's
       open (scroll lock). An inline declaration beats a plain stylesheet rule,
       so without !important the print job inherits a clipped body and stops
       after one page. */
    overflow: visible !important; height: auto !important;
  }
  /* Hide every direct child of <body> while the print class is on. The
     .inv-doc itself is whitelisted further down. */
  body.inv-printing > * { display: none !important; }
  /* The doc mounts inside a modal/portal React appended to <body>; surface it
     back by walking ancestor chains.

     ⚠ Keyed on `.inv-print-target` — the ONE preview host that doPrint marked —
     NOT on `.inv-doc`. `.inv-doc` is not unique: opening this modal from inside
     InvoiceEditor leaves the editor's "Live preview" pane mounted with its own
     `.inv-doc`, so keying on the class unhides two ancestor chains and prints
     the invoice twice. (Both chains' own overflow used to clip that into
     invisibility; releasing the clamp below to fix the one-clipped-page bug is
     precisely what would have surfaced the duplicate.) */
  body.inv-printing .inv-print-target,
  body.inv-printing .inv-print-target .inv-doc,
  body.inv-printing :has(> .inv-print-target),
  body.inv-printing :has(.inv-print-target) {
    display: block !important;
    visibility: visible !important;
    background: #fff !important;
    box-shadow: none !important;
    border: 0 !important;
    margin: 0 !important; padding: 0 !important;
    position: static !important;
    inset: auto !important;
    /* UNCLAMP the modal chrome. `.modal-backdrop .modal-card` is
       `max-height: 90vh; overflow: hidden` and `.modal-body` is
       `overflow-y: auto` — surfacing the invoice without also releasing those
       printed exactly one clipped page (measured: a 2633px invoice inside a
       422px card → 1 page; with these rules → 3 pages). This is why "Print an
       invoice" produced a cut-off document with no line items or totals. */
    max-height: none !important; height: auto !important; min-height: 0 !important;
    overflow: visible !important; max-width: none !important;
    transform: none !important; opacity: 1 !important;
    filter: none !important;
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  }
  /* Hide every branch that does NOT lead to the invoice — the modal header,
     the footer's own action buttons and the expanded email composer are all
     siblings of the preview host, so unhiding their ancestors would print them
     on the client's copy. Specificity (0,4,1) beats the unhide rule (0,2,1).
     `.inv-print-target` itself contains no nested target, so its own children
     (the .inv-doc) are never matched by this rule. */
  body.inv-printing :has(.inv-print-target) > *:not(.inv-print-target):not(:has(.inv-print-target)) {
    display: none !important;
  }
  body.inv-printing .inv-print-target .inv-doc {
    /* Restore the doc's own padding for the print page. */
    padding: 48px 56px !important;
    max-width: none !important;
    width: 100% !important;
    border-radius: 0 !important;
    page-break-after: avoid;
  }
  /* Color-accurate accents in print (most browsers honor this). */
  body.inv-printing .inv-doc,
  body.inv-printing .inv-accent-bar,
  body.inv-printing .inv-meta-title,
  body.inv-printing .inv-totals-row--grand,
  body.inv-printing .inv-table thead th {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   CONTRACTS EDITOR — premium document surface for Proposals & Contracts
   (contracts-editor.jsx). Sheet styles are explicit paper colors so the
   document reads as paper in BOTH app themes. Serif stack for body text.
   ═══════════════════════════════════════════════════════════════════════ */

.ce-root { display: flex; flex-direction: column; min-height: 0; }

/* ── command bar ─────────────────────────────────────────────────────── */
.ce-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 10px 2px 14px;
}
.ce-bar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ce-bar-title-wrap { min-width: 0; }
.ce-bar-title {
  font-size: 15px; font-weight: 650; letter-spacing: -0.01em;
  color: var(--ink-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 420px;
}
.ce-bar-meta {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-4); margin-top: 2px;
}
.ce-bar-ver { font-family: var(--mono, ui-monospace, monospace); font-size: 10.5px; }
.ce-bar-editing { display: inline-flex; align-items: center; gap: 5px; color: var(--indigo); font-weight: 600; }
.ce-bar-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ce-status-select { width: auto; min-width: 130px; height: 30px; padding: 2px 8px; font-size: 12px; }
.ce-btn-on { border-color: var(--indigo) !important; color: var(--indigo) !important; }

.ce-disclaimer-line {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--ink-4);
  padding: 0 2px 10px;
}

.ce-restore-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-2);
  background: color-mix(in srgb, var(--indigo) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 25%, transparent);
  border-radius: 10px; padding: 9px 12px; margin: 0 2px 12px;
}

/* ── Phase 4: capability chip + popover (meta-row disclosure) ─────────── */
.ce-cap-wrap { position: relative; display: inline-flex; }
.ce-cap-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 600; line-height: 1;
  padding: 3px 8px; border-radius: var(--radius-btn);
  border: 1px solid var(--line); background: var(--bg-sunk); color: var(--ink-3);
}
.ce-cap-clickable { cursor: pointer; }
.ce-cap-clickable:hover { border-color: var(--ink-4); }
.ce-cap-rich { color: var(--good); border-color: color-mix(in srgb, var(--good) 35%, var(--line)); background: color-mix(in srgb, var(--good) 9%, transparent); }
.ce-cap-positioned { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); background: color-mix(in srgb, var(--warn) 10%, transparent); }
.ce-cap-original { color: var(--ink-4); }
.ce-cap-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 90;
  width: 320px; max-width: 84vw;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-card); box-shadow: var(--shadow-md);
  padding: 12px 14px;
}
.ce-cap-pop-head { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 650; color: var(--ink-1); }
.ce-cap-pop-x {
  margin-left: auto; border: 0; background: none; cursor: pointer;
  color: var(--ink-4); padding: 3px; border-radius: var(--radius-btn-icon);
  display: grid; place-items: center;
}
.ce-cap-pop-x:hover { background: var(--line-soft); color: var(--ink-2); }
.ce-cap-pop-tip { margin-top: 7px; font-size: 12px; line-height: 1.5; color: var(--ink-3); }
.ce-cap-pop-report { margin-top: 11px; display: flex; flex-direction: column; gap: 8px; }
.ce-cap-pop-grp { border-left: 2px solid var(--line); padding-left: 9px; }
.ce-cap-pop-good { border-left-color: var(--good); }
.ce-cap-pop-amber { border-left-color: var(--warn); }
.ce-cap-pop-bad { border-left-color: var(--bad); }
.ce-cap-pop-grp-label { font-size: 10px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-4); }
.ce-cap-pop-grp-items { font-size: 11.5px; color: var(--ink-2); margin-top: 2px; line-height: 1.4; }

/* ── board a53b4c1c: the client chip is a BUTTON that opens the picker ─────
   Resets the <button> back to the inline meta-row text the read-only
   .ce-bar-dot span renders as, so turning the chip editable did not change
   how the bar reads. */
.ce-client-chip {
  display: inline-flex; align-items: center; gap: 3px;
  border: 0; background: none; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer;
  border-radius: var(--radius-btn-icon);
}
.ce-client-chip:hover { color: var(--ink-2); text-decoration: underline; text-underline-offset: 2px; }
.ce-client-chip:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.ce-client-pop { width: 300px; }
/* The picker's own AecosSelect menu portals to <body> (z 9500), so it is not
   clipped by this popover — only the inline "new client" form lives in here. */
.ce-client-pop-body { margin-top: 9px; }

/* ── Phase 4: one-time Word-vs-PDF explainer banner ──────────────────── */
.ce-disclosure-banner {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 12.5px; color: var(--ink-2); line-height: 1.5;
  background: color-mix(in srgb, var(--indigo) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 22%, transparent);
  border-radius: var(--radius-card); padding: 11px 13px; margin: 0 2px 12px;
}
.ce-disclosure-banner > svg { flex: 0 0 auto; margin-top: 1px; color: var(--indigo); }
.ce-disclosure-body { flex: 1 1 auto; min-width: 0; }
.ce-disclosure-link { margin-left: 6px; color: var(--indigo); font-weight: 600; white-space: nowrap; }
.ce-disclosure-x {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  color: var(--ink-4); padding: 3px; border-radius: var(--radius-btn-icon);
  display: grid; place-items: center;
}
.ce-disclosure-x:hover { background: var(--line-soft); color: var(--ink-2); }

/* ── native inline viewer for an uploaded original (PDF) ─────────────── */
.ce-original-inline {
  height: calc(100vh - 232px); min-height: 520px;
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  background: var(--bg-card); box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.05));
}
.ce-orig-toolbar {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 8px 12px; border-bottom: 1px solid var(--line-soft);
  background: var(--bg-sunk);
}
.ce-orig-file { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--ink-2); }
.ce-orig-file-name {
  font-size: 12.5px; font-weight: 550; color: var(--ink-1);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ce-orig-badge {
  flex: 0 0 auto; font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--indigo); background: color-mix(in oklab, var(--indigo) 12%, transparent);
  padding: 2px 7px; border-radius: var(--radius-btn);
}
.ce-orig-tools { flex: 0 0 auto; display: flex; gap: 6px; }
.ce-orig-frame { flex: 1 1 auto; min-height: 0; position: relative; background: #fff; }
/* Holding the shared AecosPdfPane (thumbnail strip + page scroller) instead of
   a browser <iframe> — the pane's two children are flex siblings, same as
   .di-pdf-modal-body. */
.ce-orig-frame--pane { display: flex; background: var(--bg-sunk); }
.ce-orig-iframe { width: 100%; height: 100%; border: none; display: block; }
/* Page indicator + zoom sit in the inline toolbar next to Open / Download. */
.ce-orig-tools { align-items: center; }
.ce-orig-tools .di-pdf-modal-page-indicator { white-space: nowrap; }
.ce-orig-state {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px; padding: 40px 24px;
  text-align: center; color: var(--ink-3); background: var(--bg-card);
}
.ce-orig-state-title { font-size: 14px; font-weight: 600; color: var(--ink-1); }
.ce-orig-state-hint { font-size: 12.5px; color: var(--ink-4); }
.ce-orig-spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2.5px solid var(--line); border-top-color: var(--indigo);
  animation: ce-orig-spin 0.7s linear infinite;
}
@keyframes ce-orig-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ce-orig-spinner { animation-duration: 1.6s; } }

/* ── layout: canvas + rails ──────────────────────────────────────────── */
.ce-body { display: flex; gap: 22px; align-items: flex-start; min-height: 0; }
.ce-canvas { flex: 1 1 auto; min-width: 0; }
.ce-meta-rail { flex: 0 0 270px; display: flex; flex-direction: column; gap: 12px; position: sticky; top: 12px; }
.ce-meta-value { font-size: 17px; font-weight: 650; color: var(--ink-1); letter-spacing: -0.01em; }
@media (max-width: 1100px) { .ce-meta-rail { display: none; } }

/* ── the sunk desk + paper sheets ────────────────────────────────────── */
.ce-doc-pages {
  display: flex; flex-direction: column; align-items: center; gap: 26px;
  background:
    radial-gradient(1200px 500px at 50% -200px, color-mix(in srgb, var(--ink-5) 7%, transparent), transparent),
    color-mix(in srgb, var(--ink-5) 9%, var(--bg-1, transparent));
  border: 1px solid color-mix(in srgb, var(--ink-5) 22%, transparent);
  border-radius: 14px;
  padding: 34px 28px 44px;
  position: relative;
  overflow: auto;
}
.ce-page {
  position: relative;
  background: #ffffff;
  color: #1c2024;
  box-shadow:
    0 1px 2px rgba(16, 18, 22, 0.10),
    0 12px 34px rgba(16, 18, 22, 0.16),
    0 0 0 1px rgba(16, 18, 22, 0.04);
  border-radius: 3px;
  box-sizing: border-box;
  font-family: "Charter", "Iowan Old Style", "Source Serif 4", Georgia, Cambria, "Times New Roman", serif;
  font-size: 14.5px; line-height: 1.62;
  flex-shrink: 0;
}
.ce-measurer {
  position: absolute; left: -10000px; top: 0; visibility: hidden;
  pointer-events: none;
  font-family: "Charter", "Iowan Old Style", "Source Serif 4", Georgia, Cambria, "Times New Roman", serif;
  font-size: 14.5px; line-height: 1.62; color: #1c2024;
}

/* ── letterhead ──────────────────────────────────────────────────────── */
.ce-letterhead {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 14px 24px; flex-wrap: wrap;
  padding-bottom: 16px; margin-bottom: 26px;
  border-bottom: 2px solid var(--ce-accent, #1c2024);
}
.ce-lh-left { display: flex; align-items: center; gap: 13px; min-width: 0; flex: 1 1 300px; }
.ce-lh-logo {
  width: 46px; height: 46px; object-fit: contain; border-radius: 6px; flex-shrink: 0;
}
.ce-lh-logo-ph {
  display: flex; align-items: center; justify-content: center;
  background: #1c2024; color: #fff; font-weight: 700; font-size: 21px;
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
}
.ce-lh-name {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 16.5px; font-weight: 700; letter-spacing: 0.01em; color: #14171a;
}
.ce-lh-tagline {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: #6a7178; margin-top: 2px;
}
.ce-lh-right {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 10.8px; line-height: 1.55; color: #5a6168; text-align: right;
  flex: 0 1 auto; margin-left: auto; padding-top: 2px;
}
.ce-lh-contact { margin-top: 3px; color: #6a7178; }
.ce-lh-editable-wrap { cursor: default; }

/* ── document typography ─────────────────────────────────────────────── */
.ce-doc-kind {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 10px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase;
  color: #8a9097; margin-bottom: 7px;
}
.ce-doc-title {
  font-size: 26px; font-weight: 700; letter-spacing: -0.012em; line-height: 1.22;
  color: #14171a; margin: 0 0 8px;
}
.ce-doc-subtitle { font-size: 12.5px; color: #6a7178; font-style: italic; }
.ce-doc-rule { height: 1px; background: #d8dce0; margin: 18px 0 6px; }

.ce-unit { padding-bottom: 13px; }
.ce-u-title { padding-bottom: 18px; }
.ce-u-sechead { padding-bottom: 6px; padding-top: 10px; }
.ce-sec-heading {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 13px; font-weight: 700; letter-spacing: 0.045em; text-transform: uppercase;
  color: #20242a; margin: 0; border-bottom: 1px solid #e6e9ec; padding-bottom: 5px;
}
.ce-sec-num { color: #9aa1a8; font-weight: 600; margin-right: 2px; }

.ce-u-block p, .ce-sec-body p { margin: 0 0 10px; }
.ce-u-block p:last-child { margin-bottom: 0; }
.ce-u-block h3, .ce-sec-body h3 {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 12px; font-weight: 700; letter-spacing: 0.02em;
  color: #2a2f35; margin: 12px 0 6px;
}
.ce-u-block ul, .ce-u-block ol, .ce-sec-body ul, .ce-sec-body ol {
  margin: 0 0 10px; padding-left: 22px;
}
.ce-u-block li, .ce-sec-body li { margin: 0 0 4px; }
.ce-u-sig p { line-height: 2.0; }
.ce-u-disclaimer {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 9.8px; line-height: 1.5; color: #9aa1a8;
  border-top: 1px solid #e6e9ec; padding-top: 10px; margin-top: 14px;
}

/* fee schedule table inside the document */
.ce-fee-table {
  width: 100%; border-collapse: collapse; margin: 4px 0 6px;
  font-size: 12.5px;
}
.ce-fee-table th {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  color: #6a7178; text-align: left; padding: 6px 10px;
  border-bottom: 1.5px solid #1c2024;
}
.ce-fee-table td { padding: 7px 10px; border-bottom: 1px solid #e6e9ec; color: #2a2f35; }
.ce-fee-table .ce-num { text-align: right; font-variant-numeric: tabular-nums; }
.ce-fee-trigger { color: #6a7178; font-style: italic; }

/* fee schedule EDITOR (edit mode) — same table dressed with inputs */
.ce-feetable-edit .ce-fee-table td { padding: 3px 4px; }
.ce-feetable-edit .ce-fee-rowtool { width: 28px; padding: 3px 0; border-bottom: 1px solid #e6e9ec; }
.ce-fee-input {
  width: 100%; box-sizing: border-box; border: 1px solid transparent; border-radius: 5px;
  background: transparent; font: inherit; color: #2a2f35; padding: 4px 6px;
}
.ce-fee-input:hover { border-color: #e6e9ec; }
.ce-fee-input:focus { outline: none; border-color: #9aa1a8; background: #fff; }
.ce-fee-input::placeholder { color: #b6bcc2; font-style: italic; }
.ce-fee-input-trigger { color: #6a7178; font-style: italic; }
.ce-fee-input-num { text-align: right; font-variant-numeric: tabular-nums; }
.ce-fee-add { margin: 4px 0 10px; }

/* ── rich block model (Phase 0): headings, nested lists, tables, images,
      page breaks — read (.ce-u-block) + edit (.ce-sec-body) ─────────────── */
.ce-u-block h1, .ce-sec-body h1, .ce-u-block h2, .ce-sec-body h2 {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  color: #1c2024; margin: 14px 0 8px; line-height: 1.25;
}
.ce-u-block h1, .ce-sec-body h1 { font-size: 17px; font-weight: 700; }
.ce-u-block h2, .ce-sec-body h2 { font-size: 14.5px; font-weight: 700; }
.ce-u-block h4, .ce-sec-body h4, .ce-u-block h5, .ce-sec-body h5, .ce-u-block h6, .ce-sec-body h6 {
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 11px; font-weight: 700; letter-spacing: 0.03em;
  color: #2a2f35; margin: 10px 0 5px;
}
.ce-u-block ul ul, .ce-u-block ol ol, .ce-u-block ul ol, .ce-u-block ol ul,
.ce-sec-body ul ul, .ce-sec-body ol ol, .ce-sec-body ul ol, .ce-sec-body ol ul {
  margin: 3px 0 0; /* nested list levels */
}
.ce-u-block table.ce-table, .ce-sec-body table.ce-table {
  width: 100%; border-collapse: collapse; margin: 6px 0 12px;
  font-size: 12.5px; table-layout: fixed;
}
.ce-u-block .ce-table td, .ce-u-block .ce-table th,
.ce-sec-body .ce-table td, .ce-sec-body .ce-table th {
  border: 1px solid #d7dbe0; padding: 6px 9px; vertical-align: top;
  color: #2a2f35; word-break: break-word;
}
.ce-u-block .ce-table p, .ce-sec-body .ce-table p { margin: 0 0 4px; }
.ce-u-block .ce-table p:last-child, .ce-sec-body .ce-table p:last-child { margin-bottom: 0; }
.ce-u-block img.ce-img, .ce-sec-body img.ce-img {
  max-width: 100%; height: auto; display: block; margin: 8px 0 12px;
  border-radius: 3px; background: #eceef1;
}
.ce-u-block hr.ce-pagebreak, .ce-sec-body hr.ce-pagebreak {
  border: none; border-top: 1.5px dashed #c3c9d1; margin: 18px 0;
  position: relative;
}
.ce-sec-body hr.ce-pagebreak::after {
  content: "Page break"; position: absolute; top: -8px; left: 50%; transform: translateX(-50%);
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 8.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: #9aa1a8; background: #fff; padding: 0 8px;
}
.ce-u-block p[data-indent="1"], .ce-sec-body p[data-indent="1"] { padding-left: 24px; }
.ce-u-block p[data-indent="2"], .ce-sec-body p[data-indent="2"] { padding-left: 48px; }
.ce-u-block p[data-indent="3"], .ce-sec-body p[data-indent="3"] { padding-left: 72px; }
.ce-u-block p[data-indent="4"], .ce-sec-body p[data-indent="4"] { padding-left: 96px; }
.ce-u-block p[data-indent="5"], .ce-sec-body p[data-indent="5"] { padding-left: 120px; }
.ce-u-block p[data-indent="6"], .ce-sec-body p[data-indent="6"] { padding-left: 144px; }
.ce-u-block p[data-indent="7"], .ce-sec-body p[data-indent="7"] { padding-left: 168px; }
.ce-u-block p[data-indent="8"], .ce-sec-body p[data-indent="8"] { padding-left: 192px; }

/* page footer */
.ce-page-footer {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 72px 26px;
  font-family: ui-sans-serif, -apple-system, "Inter", sans-serif;
  font-size: 9.5px; letter-spacing: 0.06em; color: #9aa1a8;
}
.ce-pf-num { font-variant-numeric: tabular-nums; }

/* ── edit mode ───────────────────────────────────────────────────────── */
.ce-edit-wrap { display: flex; flex-direction: column; min-width: 0; }
/* ⭐ EDIT MODE MUST NOT RESTYLE THE DOCUMENT (founder, 2026-08-19: "when you
   are in editing mode, its format shouldn't change").

   Read mode builds its sheet from the CE_PAGE_* constants as an INLINE style
   (contracts-editor.jsx `sheetStyle`), scaling every margin proportionally with
   the page: padding 60px 72px 84px on an 816px sheet, i.e. a 672px text column.
   Edit mode was declaring its own geometry here — a 56px top margin and
   `clamp(30px, 9%, 72px)` horizontal — so the two agreed only at full width and
   drifted apart the moment the desk narrowed (which is exactly what happens
   when the AI rail opens). Toggling Edit then reflowed every line.

   Matching the read constants means the text column is the same width in both
   modes, so entering and leaving edit does not move the words.

   ⚠️ This aligns the SHEET, not the pagination. Read mode splits content across
   real page sheets with footers and page numbers; edit mode is one continuous
   sheet. That difference remains — live re-pagination under contentEditable is
   a separate, much larger piece of work — and it is the one thing about edit
   mode that still does not look like the printed document. */
.ce-page-edit {
  width: 100%; max-width: 816px;
  min-height: 1056px;
  padding: 60px 72px 84px;   /* CE_MARGIN_TOP / CE_MARGIN_X / CE_MARGIN_BOTTOM */
  cursor: text;
}
.ce-mode-edit .ce-doc-pages { padding-top: 24px; }

.ce-editable { outline: none; }
.ce-editable:focus-visible { outline: none; }
.ce-sec-body { min-height: 1.4em; border-radius: 3px; }
.ce-sec-body:focus {
  box-shadow: -10px 0 0 -7px color-mix(in srgb, var(--indigo) 55%, transparent);
}
.ce-sec-body[data-sec-id]:empty::before { content: "Start writing…"; color: #b6bcc2; font-style: italic; }
.ce-doc-title.ce-editable:focus { box-shadow: -10px 0 0 -7px color-mix(in srgb, var(--indigo) 55%, transparent); border-radius: 3px; }
.ce-sec-heading-edit { display: block; }
.ce-sec-title-edit { min-width: 40px; display: inline-block; }
.ce-sec-title-edit:focus { background: color-mix(in srgb, var(--indigo) 8%, transparent); border-radius: 3px; }

.ce-article { position: relative; padding: 4px 0 10px; }
/* ⚠️ HOVER-REVEAL REACHABILITY (founder bug 2026-08-20: "delete/add buttons
   vanish when I try to go onto them"). The tools sit in the page margin at
   right:-54px; the buttons are 26px wide, which left a 28px DEAD GAP between
   the article's right edge and the buttons. Crossing that gap ends
   .ce-article:hover → display:none → the buttons vanish under the cursor.
   The padding-left below BRIDGES the gap: the (transparent, empty) padding
   area is part of the tools' hitbox, the tools are a DOM child of the
   article, so the pointer never leaves the hovered subtree on its way to the
   buttons. Bridge gaps with PADDING on the revealed element, never a margin
   or an offset the pointer must cross. */
.ce-article-tools {
  position: absolute; right: -54px; top: 2px;
  padding-left: 28px; /* bridge: box left edge lands exactly on the article's right edge */
  display: none; flex-direction: column; gap: 4px;
}
.ce-article:hover .ce-article-tools,
.ce-article:focus-within .ce-article-tools { display: flex; }
.ce-art-btn {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  background: var(--bg-card); color: var(--ink-3);
  border: 1px solid color-mix(in srgb, var(--ink-5) 35%, transparent);
  border-radius: var(--radius-btn-icon); cursor: pointer;
}
.ce-art-btn:hover { color: var(--ink-1); border-color: var(--ink-4); }
.ce-art-del:hover { color: var(--danger, #dc2626); border-color: var(--danger, #dc2626); }
@media (max-width: 980px) { .ce-article-tools { right: -8px; top: -6px; flex-direction: row; padding-left: 0; } } /* overlaps the article here — no gap to bridge, and the bridge would sit over the heading */

.ce-empty-edit { padding: 28px 0; text-align: center; }

/* ── toolbar ─────────────────────────────────────────────────────────── */
.ce-toolbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 4px;
  align-self: center;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--ink-5) 30%, transparent);
  border-radius: 12px;
  box-shadow: 0 6px 22px rgba(16, 18, 22, 0.13);
  padding: 5px 7px;
  margin-bottom: 14px;
}
.ce-tb-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  min-width: 30px; height: 30px; padding: 0 7px;
  background: transparent; color: var(--ink-2);
  border: 1px solid transparent; border-radius: var(--radius-btn-icon);
  font-size: 12.5px; cursor: pointer; white-space: nowrap;
}
.ce-tb-btn:hover { background: color-mix(in srgb, var(--ink-5) 16%, transparent); color: var(--ink-1); }
.ce-tb-btn.active { background: color-mix(in srgb, var(--indigo) 13%, transparent); color: var(--indigo); }
.ce-tb-wide { font-weight: 550; }
.ce-tb-glyph { font-size: 13px; line-height: 1; font-weight: 700; font-family: Georgia, serif; }
.ce-tb-bold { font-weight: 800; }
.ce-tb-italic { font-style: italic; font-weight: 500; }
.ce-tb-underline { text-decoration: underline; font-weight: 500; }
.ce-tb-sep { width: 1px; height: 18px; background: color-mix(in srgb, var(--ink-5) 40%, transparent); margin: 0 4px; }
.ce-tb-select {
  height: 30px; border: 1px solid transparent; border-radius: var(--radius-btn);
  background: transparent; color: var(--ink-2); font-size: 12.5px;
  padding: 0 4px; cursor: pointer;
}
.ce-tb-select:hover { background: color-mix(in srgb, var(--ink-5) 16%, transparent); }

/* ── AI rail ─────────────────────────────────────────────────────────── */
.ce-with-rail .ce-canvas { flex: 1 1 auto; }
.ce-ai-rail {
  flex: 0 0 300px; position: sticky; top: 12px;
  display: flex; flex-direction: column; gap: 12px;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--ink-5) 28%, transparent);
  border-radius: 14px; padding: 14px;
  max-height: calc(100vh - 90px); overflow-y: auto;
}
@media (max-width: 1180px) { .ce-ai-rail { flex-basis: 260px; } }
@media (max-width: 980px) { .ce-ai-rail { display: none; } }
.ce-ai-head { display: flex; align-items: center; justify-content: space-between; }
.ce-ai-head-title {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 650; color: var(--ink-1);
}
.ce-ai-close {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border: 0; background: transparent;
  color: var(--ink-4); cursor: pointer; border-radius: 6px;
}
.ce-ai-close:hover { background: color-mix(in srgb, var(--ink-5) 18%, transparent); color: var(--ink-1); }

.ce-ai-sel {
  border: 1px dashed color-mix(in srgb, var(--ink-5) 45%, transparent);
  border-radius: 10px; padding: 9px 11px; font-size: 12px;
}
.ce-ai-sel-label { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-4); margin-bottom: 4px; }
.ce-ai-sel-text { color: var(--ink-2); font-style: italic; line-height: 1.5; max-height: 88px; overflow: hidden; }
.ce-ai-sel-empty { color: var(--ink-4); line-height: 1.55; }

.ce-ai-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.ce-ai-action {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; font-size: 12px; font-weight: 550;
  background: transparent; color: var(--ink-2);
  border: 1px solid color-mix(in srgb, var(--ink-5) 35%, transparent);
  border-radius: 9px; cursor: pointer;
}
.ce-ai-action:hover:not(:disabled) { border-color: var(--indigo); color: var(--indigo); }
.ce-ai-action:disabled { opacity: 0.45; cursor: default; }

.ce-ai-instr { display: flex; flex-direction: column; gap: 8px; }
.ce-ai-instr-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  font-size: 12.5px; line-height: 1.5; color: var(--ink-1);
  background: var(--bg-1, transparent);
  border: 1px solid color-mix(in srgb, var(--ink-5) 35%, transparent);
  border-radius: 10px; padding: 9px 11px; min-height: 64px;
  font-family: inherit;
}
.ce-ai-instr-input:focus { outline: none; border-color: var(--indigo); }
.ce-ai-go { align-self: flex-end; }

.ce-ai-stream { border-top: 1px solid color-mix(in srgb, var(--ink-5) 28%, transparent); padding-top: 10px; }
.ce-ai-stream-head { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--ink-3); margin-bottom: 7px; }
.ce-ai-stop { margin-left: auto; border: 0; background: transparent; color: var(--ink-4); font-size: 11px; cursor: pointer; text-decoration: underline; }
.ce-ai-pulse {
  width: 7px; height: 7px; border-radius: 50%; background: var(--indigo);
  display: inline-block; animation: pulse 1.2s ease-in-out infinite;
}
.ce-ai-stream-body {
  font-size: 12px; line-height: 1.6; color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word;
  max-height: 240px; overflow-y: auto;
  border-left: 2px solid color-mix(in srgb, var(--indigo) 40%, transparent);
  padding-left: 10px;
}

.ce-ai-proposal { display: flex; flex-direction: column; gap: 9px; border-top: 1px solid color-mix(in srgb, var(--ink-5) 28%, transparent); padding-top: 10px; }
.ce-ai-prop-label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 650; color: var(--ink-1); }
.ce-ai-diff { font-size: 12px; line-height: 1.55; border-radius: 9px; padding: 9px 11px 9px; white-space: pre-wrap; word-break: break-word; max-height: 220px; overflow-y: auto; }
.ce-ai-diff-tag { font-size: 9.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; margin-bottom: 4px; }
.ce-ai-diff-old {
  background: color-mix(in srgb, #dc2626 6%, transparent);
  border: 1px solid color-mix(in srgb, #dc2626 22%, transparent);
  color: var(--ink-3); text-decoration: line-through; text-decoration-color: color-mix(in srgb, #dc2626 45%, transparent);
}
.ce-ai-diff-old .ce-ai-diff-tag { color: #c2410c; text-decoration: none; }
.ce-ai-diff-new {
  background: color-mix(in srgb, #16a34a 7%, transparent);
  border: 1px solid color-mix(in srgb, #16a34a 25%, transparent);
  color: var(--ink-1);
}
.ce-ai-diff-new .ce-ai-diff-tag { color: #15803d; }
.ce-ai-prop-actions { display: flex; gap: 8px; }
.ce-ai-note { font-size: 10.5px; color: var(--ink-4); line-height: 1.5; }
.ce-ai-err {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: #dc2626;
  background: color-mix(in srgb, #dc2626 7%, transparent);
  border-radius: 8px; padding: 7px 10px;
}

/* ── popovers (branding / versions) ──────────────────────────────────── */
.ce-pop-scrim { position: fixed; inset: 0; z-index: 80; background: transparent; }
.ce-branding-pop, .ce-versions-pop {
  position: fixed; top: 86px; right: 28px; z-index: 81;
  width: 330px; max-height: calc(100vh - 120px); overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--ink-5) 30%, transparent);
  border-radius: 14px;
  box-shadow: 0 18px 50px rgba(16, 18, 22, 0.22);
  padding: 14px;
}
.ce-bp-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 650; color: var(--ink-1);
  padding-bottom: 10px; margin-bottom: 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--ink-5) 24%, transparent);
}
.ce-bp-head > span { display: inline-flex; align-items: center; gap: 7px; }
.ce-bp-row { padding: 7px 0; }
.ce-bp-label { font-size: 11px; font-weight: 600; color: var(--ink-3); margin-bottom: 5px; }
.ce-bp-toggle { display: flex; align-items: center; justify-content: space-between; font-size: 12.5px; color: var(--ink-1); cursor: pointer; }
.ce-bp-logo-row { display: flex; align-items: center; gap: 12px; }
.ce-bp-logo-preview {
  width: 52px; height: 52px; object-fit: contain; border-radius: 9px;
  border: 1px solid color-mix(in srgb, var(--ink-5) 30%, transparent);
  background: #fff;
}
.ce-bp-logo-ph {
  display: flex; align-items: center; justify-content: center;
  background: var(--ink-1); color: var(--bg-card); font-weight: 700; font-size: 22px;
  border: 0;
}
.ce-bp-logo-btns { display: flex; gap: 7px; }
.ce-bp-note { font-size: 10.5px; color: var(--ink-4); line-height: 1.5; padding-top: 8px; }
.ce-bp-accent-swatch {
  width: 34px; height: 28px; padding: 0; border: 1px solid var(--line);
  border-radius: 6px; background: none; cursor: pointer; flex-shrink: 0;
}
.branding-fields { display: flex; flex-direction: column; gap: 16px; }
.branding-fields .field-input { width: 100%; max-width: 460px; }

/* Per-office invoice letterhead (Office → Finance → Invoices) */
.off-lh-card { margin-bottom: 18px; }
.off-lh-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 14px 18px; background: none; border: none; cursor: pointer;
  text-align: left; color: var(--ink-1);
}
.off-lh-head-l { display: flex; align-items: center; gap: 10px; min-width: 0; }
.off-lh-title { font-size: 14px; font-weight: 600; }
.off-lh-head-hint { font-size: 12.5px; color: var(--ink-4); flex-shrink: 0; }
.off-lh-pill {
  font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 100px;
  border: 1px solid var(--line); white-space: nowrap;
}
.off-lh-pill.default { color: var(--ink-4); background: var(--bg-elev); }
.off-lh-pill.custom { color: var(--indigo); border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 10%, transparent); }

/* Office Payments — manual vs Stripe Connect mode selector */
.off-pay-mode {
  display: flex; gap: 11px; align-items: flex-start; text-align: left;
  width: 100%; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg-elev); cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.off-pay-mode:hover { border-color: var(--ink-4); }
.off-pay-mode.is-sel { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 6%, transparent); }
.off-pay-mode.is-disabled { opacity: .6; cursor: not-allowed; }
.off-pay-mode-radio { font-size: 14px; line-height: 1.3; color: var(--indigo); flex-shrink: 0; }
.off-pay-mode-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.off-pay-mode-title { font-size: 13.5px; font-weight: 600; color: var(--ink-1); display: flex; align-items: center; gap: 7px; }
.off-pay-mode-desc { font-size: 12px; color: var(--ink-4); line-height: 1.45; }
.off-pay-mode-tag {
  font-size: 10px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;
  color: var(--indigo); border: 1px solid var(--indigo); border-radius: 100px; padding: 1px 7px;
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
}
.off-lh-body {
  display: flex; flex-direction: column; gap: 22px;
  padding: 4px 18px 18px; border-top: 1px solid var(--line);
}
.off-lh-note { font-size: 12.5px; color: var(--ink-3); margin: 12px 0 0; line-height: 1.6; }
.off-lh-preview {
  background: #fff; border-radius: 10px; border: 1px solid var(--line);
  padding: 26px 28px 18px; overflow: hidden;
}
.off-lh-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-top: 16px; border-top: 1px solid var(--line);
}
.off-lh-foot-status { font-size: 12.5px; color: var(--ink-4); }

.ce-ver-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 2px; border-bottom: 1px solid color-mix(in srgb, var(--ink-5) 18%, transparent);
}
.ce-ver-row:last-child { border-bottom: 0; }
.ce-ver-title { font-size: 12.5px; font-weight: 600; color: var(--ink-1); }
.ce-ver-meta { font-size: 11px; color: var(--ink-4); margin-top: 1px; }

/* use-template menu */
.ce-usetpl-wrap { position: relative; }
.ce-usetpl-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 81;
  min-width: 185px;
  background: var(--bg-card);
  border: 1px solid color-mix(in srgb, var(--ink-5) 30%, transparent);
  border-radius: var(--radius-menu); box-shadow: 0 14px 40px rgba(16, 18, 22, 0.20);
  padding: 5px; display: flex; flex-direction: column;
}
.ce-usetpl-menu button {
  display: flex; align-items: center; gap: 8px;
  border: 0; background: transparent; color: var(--ink-1);
  font-size: 12.5px; padding: 8px 10px; border-radius: var(--radius-btn-icon);
  cursor: pointer; text-align: left;
}
.ce-usetpl-menu button:hover { background: color-mix(in srgb, var(--ink-5) 14%, transparent); }

/* ── Phase 1A: full-screen document workspace ──────────────────────────
   ContractDocEditor portals into .app-right (the InvoiceEditor pattern —
   .app-right is a containing block + stacking context via its
   container-type: inline-size layout containment) and fills the content
   column: slim top bar, full-height document canvas, full-height side
   rail. Pages/sheets stay ≤816px wide and center on the desk (paper
   metaphor — never stretched to fill). z-index 5000 matches the
   InvoiceEditor overlay; a "Create invoice" launched from a contract
   portals in AFTER this node at the same z, so it paints above. */
.ce-workspace {
  position: absolute; inset: 0; z-index: 5000;
  background: var(--bg);
  display: flex; flex-direction: column;
}
/* fallback when the editor mounts outside the AppShell (no .app-right) */
.ce-workspace-fixed { position: fixed; }

.ce-workspace .ce-bar {
  flex: 0 0 auto;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
}
.ce-workspace .ce-disclaimer-line { flex: 0 0 auto; padding: 8px 18px 0; }
.ce-workspace .ce-restore-banner,
.ce-workspace .ce-disclosure-banner { flex: 0 0 auto; margin: 10px 18px 0; }

/* body row: canvas scrolls, rails are full-height columns */
.ce-workspace .ce-body {
  flex: 1 1 auto; min-height: 0;
  gap: 0; align-items: stretch;
  overflow: hidden;
}
.ce-workspace .ce-canvas {
  display: flex; flex-direction: column;
  min-height: 0; overflow-y: auto;
  scrollbar-gutter: stable;
}
.ce-workspace .ce-canvas > * { flex: 0 0 auto; }
/* the sunk desk becomes the whole canvas — full-bleed, pages centered */
.ce-workspace .ce-canvas > .ce-doc-pages,
.ce-workspace .ce-canvas > .ce-edit-wrap,
.ce-workspace .ce-edit-wrap > .ce-doc-pages { flex: 1 0 auto; }
.ce-workspace .ce-doc-pages {
  border: 0; border-radius: 0;
  padding: 40px 48px 64px;
}
.ce-workspace.ce-mode-edit .ce-doc-pages { padding-top: 24px; }
/* sticky formatting toolbar floats just below the canvas top edge */
.ce-workspace .ce-toolbar { top: 12px; margin-top: 14px; }

/* uploaded-original viewer fills the workspace height */
.ce-workspace .ce-original-inline {
  flex: 1 1 auto; height: auto; min-height: 520px;
  border: 0; border-radius: 0;
  box-shadow: none;
}

/* rails: attached full-height columns with their own scroll */
.ce-workspace .ce-meta-rail,
.ce-workspace .ce-ai-rail {
  position: static; top: auto;
  min-height: 0; max-height: none;
  overflow-y: auto;
  border: 0; border-left: 1px solid var(--line);
  border-radius: 0;
  background: var(--bg-card);
  padding: 16px;
}
.ce-workspace .ce-meta-rail { flex: 0 0 300px; }

/* ── print: body.ce-printing → only the document pages ─────────────────
   Visibility-based (NOT the invoice display-none/:has-unhide pattern):
   .ce-doc-pages lives deep inside the AppShell tree, so unhiding its
   ancestor chain would re-show sidebar/header siblings. visibility hides
   every box independently; ancestors keep layout but paint nothing. */
@media print {
  body.ce-printing { background: #fff !important; padding: 0 !important; margin: 0 !important; }
  body.ce-printing * { visibility: hidden !important; }
  /* ancestors must not clip/scroll the absolutely-positioned pages */
  body.ce-printing :has(.ce-doc-pages) {
    overflow: visible !important; position: static !important;
    height: auto !important; max-height: none !important;
  }
  body.ce-printing .ce-doc-pages,
  body.ce-printing .ce-doc-pages * { visibility: visible !important; }
  body.ce-printing .ce-doc-pages {
    position: absolute !important; left: 0 !important; top: 0 !important;
    width: 100% !important;
    background: #fff !important; box-shadow: none !important; border: 0 !important;
    border-radius: 0 !important; margin: 0 !important; padding: 0 !important;
    overflow: visible !important; display: block !important;
  }
  body.ce-printing .ce-measurer { display: none !important; visibility: hidden !important; }
  body.ce-printing .ce-measurer * { visibility: hidden !important; }
  body.ce-printing .ce-page {
    width: 100% !important; min-height: 0 !important;
    box-shadow: none !important; border-radius: 0 !important;
    margin: 0 auto !important;
    page-break-after: always;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  body.ce-printing .ce-page:last-child { page-break-after: avoid; }
  /* Each sheet prints at its EXACT paper box (CEReadDoc injects @page + pins
     .ce-page to the paper size), so the absolutely-positioned footer already
     sits at the true page bottom — the old `position: static` override put it
     mid-flow. */
  /* A manual page break is REALIZED by read-mode pagination (the unit closes
     its sheet and never renders), so the hr must NOT also force a break here —
     that double-break shifted every page after it. Only the pre-measurement
     single-sheet fallback frame could still paint one; keep it inert. */
  body.ce-printing hr.ce-pagebreak { border: none; margin: 0; height: 0; }
  /* the on-screen "Page break" pill label must not print */
  body.ce-printing hr.ce-pagebreak::after { content: none !important; }
  body.ce-printing .ce-table td, body.ce-printing .ce-table th {
    border: 1px solid #d7dbe0 !important;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* long tables may span pages (auto), but never split a ROW or an image;
     a heading never strands at the foot of a page */
  body.ce-printing .ce-table { page-break-inside: auto; }
  body.ce-printing .ce-table tr { page-break-inside: avoid; }
  body.ce-printing img.ce-img { page-break-inside: avoid; max-width: 100% !important; }
  body.ce-printing .ce-sec-body h1, body.ce-printing .ce-sec-body h2,
  body.ce-printing .ce-sec-body h3, body.ce-printing .ce-sec-body h4,
  body.ce-printing .ce-sec-heading { page-break-after: avoid; }

  /* positioned (reconstructed-PDF) docs: print each sheet 1:1 with the source
     page. CEPosDoc injects @page{size:<w>pt <h>pt;margin:0} while mounted;
     here the wrap is re-sized from its inline screen-scale px box to the
     source pt box (--pos-w/--pos-h set inline by CEPosPage) and the sheet's
     transform snaps to 1px→1pt (96/72 = 4/3), so the print fills the @page
     exactly regardless of the on-screen container width. */
  body.ce-printing .ce-pos-sheet-wrap {
    width: calc(var(--pos-w) * 1pt) !important;
    height: calc(var(--pos-h) * 1pt) !important;
    margin: 0 !important; box-shadow: none !important; border-radius: 0 !important;
    overflow: hidden !important;
    page-break-after: always; break-after: page;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  body.ce-printing .ce-pos-sheet-wrap:last-of-type { page-break-after: avoid; break-after: auto; }
  body.ce-printing .ce-pos-sheet { transform: scale(1.3333333) !important; }
  body.ce-printing .ce-pos-overflow { display: none !important; }
}

/* mobile: the gate hides the app ≤768px, but never let the sheet break ≤980 */
@media (max-width: 980px) {
  .ce-doc-pages { padding: 18px 10px 26px; }
  .ce-page-footer { padding: 0 28px 18px; }
}

/* Narrowest phones (<360px): the forced break after "field" orphans it on its
   own line. Drop the break so the headline wraps naturally. 360px+ keeps it. */
@media (max-width: 359px) {
  .landing-headline br { display: none; }
}

/* SR demo banner — on phones the nowrap banner is wider than the viewport and
   its text ("sign up free to save your work") gets clipped on both edges.
   Let it wrap and fit the screen. !important overrides the component's inline
   styles (which set white-space:nowrap). */
@media (max-width: 768px) {
  .sr-demo-banner {
    white-space: normal !important;
    max-width: calc(100vw - 20px) !important;
    flex-wrap: wrap !important;
    justify-content: center !important;
    text-align: center !important;
    row-gap: 2px !important;
    font-size: 11px !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   Proposal preview modal — split-screen layout + phase Gantt
   (ProposalPreviewModal in pages-1.jsx). LEFT = refine-with-Aecos chat,
   RIGHT = scrollable extracted content. Header + footer span full width
   above/below this split. Below 860px the split stacks vertically.
   ───────────────────────────────────────────────────────────────────────── */
.ppm-split {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}

/* LEFT — refinement chat column */
.ppm-chat {
  flex: 0 0 38%;
  width: 38%;
  min-width: 320px;
  max-width: 460px;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--bg-sunk);
}
.ppm-chat-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.ppm-chat-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  font-size: 12.5px;
}
.ppm-chat-empty {
  color: var(--ink-4);
  font-size: 12px;
  line-height: 1.55;
  padding: 4px 2px;
}
.ppm-chat-msg {
  max-width: 92%;
  padding: 7px 11px;
  border-radius: 9px;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}
.ppm-chat-msg.is-user {
  align-self: flex-end;
  background: var(--bg-card);
  border: 1px solid var(--line-soft);
  color: var(--ink-2);
}
.ppm-chat-msg.is-ai {
  align-self: flex-start;
  background: transparent;
  color: var(--ink-3);
}
.ppm-chat-msg-role {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 3px;
}
.ppm-chat-composer {
  flex-shrink: 0;
  display: flex;
  gap: 8px;
  /* flex-end, not center: the textarea GROWS (see .ppm-chat-input). Centred, the
     Send button drifts to the middle of a 6-row box; anchored to the bottom it
     stays on the baseline of the row you are typing. */
  align-items: flex-end;
  padding: 10px 14px 12px;
  border-top: 1px solid var(--line-soft);
  background: var(--bg-sunk);
}
/* Builder refine composer — was an <input type="text">, so it could not grow at
   all. Now a <textarea rows=1> auto-grown by the SAME
   window.AECOS_autoSizeTextarea the Aecos Intelligence composer uses, capped by
   the SAME --chat-composer-max-h token. Keeps .field-input's border/background
   (it is a bordered field here, unlike the borderless .cmd-textarea) and adds
   only what a growing textarea needs. */
.ppm-chat-input {
  flex: 1;
  min-width: 0;
  resize: none;
  overflow-y: auto;
  font-size: 12.5px;
  line-height: 1.55;
  padding: 8px 12px;
  max-height: var(--chat-composer-max-h);
}

/* RIGHT — extracted content column (replaces the old inline-styled body) */
.ppm-content {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: auto;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

/* Stack the split vertically on narrow viewports — chat on top, content below */
@media (max-width: 860px) {
  .ppm-split { flex-direction: column; overflow: auto; }
  .ppm-chat {
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
    min-width: 0;
    max-height: 42vh;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .ppm-content { flex: 1 0 auto; }
}

/* ─── Invoice email composer: AI draft + per-invoice payment methods ───────── */
.inv-ai-ctx { display: flex; gap: 10px; flex-wrap: wrap; }
.inv-ai-ctx-card {
  flex: 1 1 200px; min-width: 0;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--bg-sunk); padding: 10px 12px;
}
.inv-ai-ctx-h {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4); margin-bottom: 4px;
}
.inv-ai-ctx-name { font-size: 13px; font-weight: 600; color: var(--ink-2); margin-bottom: 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inv-ai-ctx-rows { display: flex; flex-direction: column; gap: 3px; }
.inv-ai-ctx-rows > div { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; }
.inv-ai-ctx-rows > div > span { color: var(--ink-4); }
.inv-ai-ctx-rows > div > b { color: var(--ink-2); font-weight: 600; }
.inv-ai-warn { color: var(--bad, #d9534f) !important; }

.inv-ai-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.inv-ai-bar-label { display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--ink-3); }
.inv-ai-tone { display: inline-flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
.inv-ai-tone-btn {
  border: 0; background: transparent; padding: 4px 10px; font-size: 12px;
  color: var(--ink-3); cursor: pointer; border-right: 1px solid var(--line);
}
.inv-ai-tone-btn:last-child { border-right: 0; }
.inv-ai-tone-btn.is-active { background: var(--ink-2); color: var(--bg-card, #fff); font-weight: 600; }
.inv-ai-tone-btn:disabled { opacity: 0.5; cursor: default; }

.inv-pay-methods {
  border: 1px solid var(--line); border-radius: 9px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 6px; background: var(--bg-card);
}
.inv-pay-row { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.inv-pay-row.is-disabled { cursor: default; opacity: 0.55; }
.inv-pay-name { flex: 1; color: var(--ink-2); }
.inv-pay-note { color: var(--ink-4); font-style: italic; font-size: 11px; }
.inv-pay-fee { color: var(--ink-4); font-size: 12px; white-space: nowrap; }
/* ═══ Specifications (FF&E) — specifications.jsx ═══════════════════════════ */
.spec-tab { display: flex; flex-direction: column; gap: 14px; }

/* Package selector bar */
.spec-pkg-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.spec-pkg-tabs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.spec-pkg-tab { display: inline-flex; align-items: center; gap: 5px; padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--radius-btn); background: var(--bg-card); color: var(--ink-2); font-size: 13px; cursor: pointer; transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-pkg-tab:hover { border-color: var(--line-strong); color: var(--ink); }
.spec-pkg-tab.active { border-color: var(--ink); color: var(--ink); background: var(--bg-sunk); font-weight: 600; }
.spec-pkg-rev { font-size: 10px; padding: 1px 5px; border-radius: 5px; background: var(--bg-sunk); color: var(--ink-4); }
.spec-pkg-tab.active .spec-pkg-rev { background: var(--bg-card); color: var(--ink-3); }
.spec-pkg-add { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 1px dashed var(--line-strong); border-radius: var(--radius-btn-icon); background: none; color: var(--ink-3); cursor: pointer; transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-pkg-add:hover { border-color: var(--ink); color: var(--ink); background: var(--bg-hover); }
.spec-pkg-actions { display: flex; align-items: center; gap: 6px; }

/* Buttons + chips */
.spec-btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border: 1px solid var(--line); border-radius: var(--radius-btn); background: var(--bg-card); color: var(--ink-2); font-size: 13px; font-weight: 500; cursor: pointer; transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-btn:hover { background: var(--bg-hover); border-color: var(--line-strong); color: var(--ink); }
.spec-btn:active { background: var(--bg-sunk); }
.spec-btn-sm { padding: 5px 10px; font-size: 12px; }
.spec-btn-primary { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.spec-btn-primary:hover { background: var(--ink-2); border-color: var(--ink-2); color: var(--bg); }
.spec-btn-danger { color: var(--bad); border-color: var(--bad-line); background: var(--bg-card); }
.spec-btn-danger:hover { color: var(--bad); border-color: var(--bad); background: var(--bad-soft); }
.spec-btn:disabled { opacity: 0.5; cursor: default; }
.spec-btn:disabled:hover { background: var(--bg-card); border-color: var(--line); color: var(--ink-2); }
.spec-chip { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg-card); color: var(--ink-3); font-size: 12px; cursor: pointer; transition: background var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-chip:hover { border-color: var(--line-strong); color: var(--ink-2); }
.spec-chip-on { border-color: var(--ink); color: var(--ink); background: var(--bg-sunk); font-weight: 500; }
.spec-icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 1px solid transparent; border-radius: var(--radius-btn-icon); background: none; color: var(--ink-4); cursor: pointer; transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-icon-btn:hover { background: var(--bg-hover); color: var(--ink-2); }
.spec-icon-btn.active { background: var(--indigo-soft); color: var(--indigo-ink); }
.spec-icon-btn:disabled { opacity: 0.3; cursor: default; }
.spec-icon-btn:disabled:hover { background: none; color: var(--ink-4); }
.spec-icon-danger:hover { color: var(--bad); background: var(--bad-soft); }

/* Package header + budget */
.spec-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.spec-head-left { flex: 1; min-width: 220px; }
.spec-name-input { font-size: 18px; font-weight: 600; color: var(--ink); border: none; background: none; width: 100%; outline: none; padding: 2px 0; }
.spec-head-meta { display: flex; gap: 18px; margin-top: 8px; flex-wrap: wrap; }
.spec-head-meta label { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--ink-4); }
.spec-mini-input { width: 64px; padding: 4px 6px; border: 1px solid var(--line); border-radius: 6px; font-size: 13px; color: var(--ink); background: var(--bg-card); outline: none; transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out); }
.spec-mini-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 2px var(--indigo-soft); }
.spec-name-input:focus { box-shadow: inset 0 -1px 0 var(--indigo); }
.spec-mini-wide { width: 120px; }
.spec-head-rollup { display: flex; gap: 18px; }
.spec-roll { text-align: right; }
.spec-roll span { display: block; font-size: 11px; color: var(--ink-4); }
.spec-roll strong { font-size: 17px; color: var(--ink); font-variant-numeric: tabular-nums; }
.spec-budget-bar { position: relative; height: 22px; border-radius: 7px; background: var(--line-soft, #eef0f2); margin: 12px 0 4px; overflow: hidden; }
.spec-budget-fill { position: absolute; inset: 0 auto 0 0; background: linear-gradient(90deg, #21ce56, #17a544); }
.spec-budget-bar.over .spec-budget-fill { background: linear-gradient(90deg, #e8896f, #c0392b); }
.spec-budget-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; color: var(--ink); }

/* Table */
.spec-table-wrap { margin-top: 14px; }
.spec-table-toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.spec-table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; }
.spec-table { width: 100%; border-collapse: collapse; font-size: 12.5px; min-width: 1040px; }
/* Column-width scheme (auto layout — these are proportioning hints backed by
   per-cell min-widths below). Qty narrow; Item + Link get the most room. */
.spec-col-code    { width: 88px; }
.spec-col-item    { width: 240px; }
.spec-col-cat     { width: 112px; }
.spec-col-qty     { width: 46px; }
.spec-col-money   { width: 84px; }
.spec-col-markup  { width: 70px; }
.spec-col-vendor  { width: 132px; }
.spec-col-link    { width: 190px; }
.spec-col-lead    { width: 112px; }
.spec-col-quote   { width: 56px; }
.spec-col-status  { width: 120px; }
.spec-col-actions { width: 132px; }
.spec-table th { text-align: left; padding: 8px 8px; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-4); border-bottom: 1px solid var(--line); white-space: nowrap; background: var(--bg-card); position: sticky; top: 0; z-index: 1; }
.spec-th-num { text-align: right; }
.spec-th-center { text-align: center; }
/* Drag-to-resize columns: fixed layout so the <col> widths are honored exactly
   (scoped to the resizable schedule table — the on-hold table keeps auto layout).
   The handle is a thin grabbable zone on each header's right edge; the sticky th
   is a positioned box, so the absolute handle anchors to it. */
.spec-table-resizable { table-layout: fixed; }
.spec-table-resizable th.spec-th-resz { position: sticky; overflow: hidden; text-overflow: ellipsis; }
.spec-col-resizer { position: absolute; top: 0; right: -1px; bottom: 0; width: 11px; cursor: col-resize; user-select: none; touch-action: none; z-index: 3; }
.spec-col-resizer::after { content: ""; position: absolute; top: 5px; bottom: 5px; right: 4px; width: 2px; border-radius: 1px; background: transparent; transition: background 0.12s ease; }
.spec-table-resizable th.spec-th-resz:hover .spec-col-resizer::after,
.spec-col-resizer:hover::after { background: var(--brand, #5e5ce6); }
body.spec-col-resizing { cursor: col-resize !important; user-select: none !important; }
body.spec-col-resizing * { cursor: col-resize !important; user-select: none !important; }
/* ~2× taller rows so the product-image thumbnail reads at a glance */
.spec-td { padding: 8px 6px; height: 64px; border-bottom: 1px solid var(--line-soft, #f1f3f5); vertical-align: middle; }
.spec-td-num { text-align: right; }
.spec-td-center { text-align: center; }
.spec-td-actions { white-space: nowrap; }

/* Per-row product-image control (in the Item cell) */
.spec-td-item { min-width: 230px; }
.spec-item-cell { display: flex; align-items: center; gap: 8px; }
.spec-item-cell .spec-input { flex: 1; min-width: 60px; }
.spec-item-img { flex: 0 0 auto; position: relative; }

/* ── "From your computer" / "From Aecos" source menu ─────────────────────────
   Founder (queue 9990b0ad): the spec image button went straight to the OS file
   dialog, so an image already IN Aecos could only be used by finding it on disk
   again. The picker already supported kind:"image"; this is the chooser in
   front of it.

   ⚠️ NO TRANSITION ON ANY var()-VALUED PROPERTY. A transitioned var() sticks at
   its from-value in Chrome — that shipped once tonight and made two folder rows
   both look selected. scripts/test_css_classes.py hard-fails on it now.

   z-index sits above the spec row's own stacking but well below the shared
   Modal backdrop (350), because this menu belongs to the row, not the page. */
.spec-img-srcmenu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 60;
  min-width: 178px; padding: 4px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-md);
  display: flex; flex-direction: column; gap: 1px;
}
.spec-img-srcmenu-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 7px 9px;
  border: 0; background: none; cursor: pointer;
  font-size: 12.5px; font-weight: 500; color: var(--ink-2);
  border-radius: 7px; text-align: left; white-space: nowrap;
}
.spec-img-srcmenu-item > svg { color: var(--ink-4); flex-shrink: 0; }
.spec-img-srcmenu-item:hover { background: var(--bg-hover); color: var(--ink); }
.spec-img-srcmenu-item:hover > svg { color: var(--indigo); }
.spec-img-srcmenu-item:focus-visible { outline: 2px solid var(--indigo); outline-offset: -1px; }
/* The row is only ~52px tall and can sit near the foot of a long spec table —
   flip the menu above the button when there is not room below it. */
@media (max-height: 620px) {
  .spec-img-srcmenu { top: auto; bottom: calc(100% + 4px); }
}
.spec-item-thumb-wrap { position: relative; width: 52px; height: 52px; }
.spec-item-thumb { width: 52px; height: 52px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); cursor: pointer; display: block; background: var(--bg-sunk); transition: box-shadow var(--duration-fast) var(--ease-out); }
.spec-item-thumb:hover { box-shadow: 0 0 0 2px var(--indigo-soft); }
.spec-item-thumb-x { position: absolute; top: -6px; right: -6px; width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-3); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; line-height: 0; }
.spec-item-thumb-x:hover { color: var(--bad, #c0392b); border-color: var(--bad, #c0392b); }
.spec-item-thumb-busy { position: absolute; inset: 0; border-radius: 8px; background: rgba(0,0,0,0.35); backdrop-filter: blur(1px); }
.spec-item-thumb-cap { position: absolute; bottom: -6px; right: -6px; width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-3); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; line-height: 0; }
.spec-item-thumb-cap:hover { color: var(--indigo-ink); border-color: var(--indigo); }

/* ── Spec screen-capture + drag-crop tool ── */
.spec-scap-guide { display: flex; flex-direction: column; gap: 12px; }
.spec-scap-actions { display: flex; gap: 8px; }
.spec-scap-note2 { margin: 0; font-size: 12px; color: var(--ink-4); line-height: 1.45; }
.spec-scap-diagram { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; }
.spec-scap-step { flex: 1 1 150px; min-width: 140px; display: flex; flex-direction: column; gap: 6px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg-sunk); }
.spec-scap-step-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.spec-scap-step-n { width: 20px; height: 20px; border-radius: 999px; background: var(--indigo, #6366f1); color: #fff; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.spec-scap-step-ic { color: var(--indigo, #6366f1); flex: 0 0 auto; }
.spec-scap-step-t { font-size: 13px; font-weight: 700; color: var(--ink); }
.spec-scap-step-d { font-size: 12px; line-height: 1.45; color: var(--ink-4); }
.spec-scap-step-arrow { display: flex; align-items: center; justify-content: center; color: var(--ink-4); flex: 0 0 auto; }
.spec-scap-perm { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); }
.spec-scap-perm-ic { color: var(--ink-3); flex: 0 0 auto; margin-top: 1px; }
.spec-scap-perm-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.spec-scap-perm-h { font-size: 12.5px; font-weight: 700; color: var(--ink); }
.spec-scap-perm-p { margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-4); }
.spec-scap-setuplink { align-self: flex-start; margin-top: 2px; background: none; border: 0; padding: 0; font: inherit; font-size: 12px; color: var(--ink-4); cursor: pointer; text-decoration: underline; }
.spec-scap-setuplink:hover { color: var(--ink-3); }
.spec-scap-setup { display: flex; flex-direction: column; gap: 14px; }
.spec-scap-setup-why { display: flex; align-items: flex-start; gap: 10px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg-sunk); }
.spec-scap-setup-why-ic { color: var(--indigo, #6366f1); flex: 0 0 auto; margin-top: 1px; }
.spec-scap-setup-why-p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.spec-scap-setup-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.spec-scap-setup-step { display: flex; align-items: flex-start; gap: 10px; }
.spec-scap-setup-n { width: 22px; height: 22px; border-radius: 999px; background: var(--indigo, #6366f1); color: #fff; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; margin-top: 1px; }
.spec-scap-setup-body { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; line-height: 1.5; color: var(--ink); min-width: 0; }
.spec-scap-setup-ic { color: var(--indigo, #6366f1); flex: 0 0 auto; margin-top: 2px; }
@media (max-width: 520px) {
  .spec-scap-diagram { flex-direction: column; }
  .spec-scap-step-arrow { transform: rotate(90deg); }
}
.spec-scap-overlay { position: fixed; inset: 0; z-index: 6200; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; padding: 3vh 3vw; }
.spec-scap-modal { width: 80vw; height: 80vh; max-width: 1600px; max-height: 1000px; background: var(--bg-card); border-radius: 14px; border: 1px solid var(--line); box-shadow: var(--shadow-lg); display: flex; flex-direction: column; overflow: hidden; }
.spec-scap-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.spec-scap-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spec-scap-x { width: 26px; height: 26px; border-radius: var(--radius-btn-icon); border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-3); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; flex: 0 0 auto; }
.spec-scap-x:hover { color: var(--ink); border-color: var(--line-strong); background: var(--bg-hover); }
.spec-scap-stage { position: relative; flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--bg-sunk); }
.spec-scap-img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; cursor: crosshair; user-select: none; -webkit-user-select: none; touch-action: none; }
.spec-scap-selbox { position: absolute; border: 1.5px solid var(--indigo, #6366f1); box-shadow: 0 0 0 9999px rgba(0,0,0,0.5); pointer-events: none; }
.spec-scap-hint { position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%); padding: 6px 12px; border-radius: 999px; background: rgba(0,0,0,0.6); color: #fff; font-size: 12px; pointer-events: none; }
.spec-scap-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-top: 1px solid var(--line); flex: 0 0 auto; }
.spec-scap-foot-btns { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.spec-scap-linkbtn { background: none; border: 0; padding: 0; font: inherit; color: var(--indigo, #6366f1); font-weight: 600; cursor: pointer; text-decoration: underline; }
.spec-scap-linkbtn:hover { opacity: 0.82; }
.spec-item-addrow { display: flex; flex-direction: column; gap: 4px; }
.spec-item-addimg, .spec-item-fromlink { width: 52px; height: 24px; border-radius: var(--radius-btn); border: 1px dashed var(--line); background: var(--bg-sunk); color: var(--ink-4); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; transition: color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out); }
.spec-item-addrow > .spec-item-addimg:only-child { height: 52px; }
.spec-item-addimg:hover:not(:disabled), .spec-item-fromlink:hover:not(:disabled) { color: var(--indigo-ink); border-color: var(--indigo); }
.spec-item-addimg:disabled, .spec-item-fromlink:disabled { cursor: default; opacity: 0.7; }
.spec-item-fromlink { border-style: solid; }
.spec-item-addimg-spin { width: 13px; height: 13px; border-radius: 50%; border: 2px solid var(--line); border-top-color: var(--indigo); animation: spec-spin 0.7s linear infinite; }
@keyframes spec-spin { to { transform: rotate(360deg); } }
.spec-num-best { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.spec-num-total { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.spec-input { width: 100%; min-width: 60px; border: 1px solid transparent; border-radius: 6px; padding: 4px 6px; font-size: 12.5px; color: var(--ink); background: none; outline: none; transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out); }
.spec-input::placeholder { color: var(--ink-5); }
.spec-input:hover { border-color: var(--line); }
.spec-input:focus { border-color: var(--indigo); background: var(--bg-card); box-shadow: 0 0 0 2px var(--indigo-soft); }
.spec-input-num { text-align: right; min-width: 62px; font-variant-numeric: tabular-nums; }
.spec-input-qty { min-width: 38px; padding-left: 2px; padding-right: 2px; }
.spec-input-code { min-width: 74px; font-family: ui-monospace, monospace; font-size: 11.5px; }
.spec-input-url { min-width: 150px; }
.spec-select { cursor: pointer; }
.spec-td-vendor { min-width: 118px; }
/* Dedicated Link column: URL input when empty, compact link chip when set */
.spec-td-link { min-width: 170px; }
.spec-link-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }
.spec-link-chip { display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 100%; padding: 3px 8px; border: 1px solid var(--line); border-radius: 999px; background: var(--bg-sunk); color: var(--indigo-ink, var(--ink-2)); text-decoration: none; font-size: 11.5px; transition: border-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-link-chip:hover { border-color: var(--indigo); color: var(--indigo-ink, var(--ink)); }
.spec-link-host { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spec-link-clear { flex: 0 0 auto; width: 16px; height: 16px; border-radius: 50%; border: 1px solid transparent; background: none; color: var(--ink-4); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; line-height: 0; }
.spec-link-clear:hover { color: var(--bad, #c0392b); border-color: var(--line); }
.spec-status { font-size: 11.5px; border-radius: 6px; font-weight: 500; }
.spec-status-ordered, .spec-status-shipped { color: var(--indigo); }
.spec-status-delivered { color: var(--ok); }
.spec-status-on_hold, .spec-status-cancelled { color: var(--warn); }
.spec-empty-row { text-align: center; color: var(--ink-4); padding: 22px; font-size: 13px; }

/* Group rows */
.spec-floor-row td { background: var(--bg-sunk); padding: 6px 8px; border-bottom: 1px solid var(--line); }
.spec-area-row td { background: var(--bg-elev); padding: 4px 8px 4px 20px; }
.spec-group-toggle { display: inline-flex; align-items: center; gap: 6px; border: none; background: none; cursor: pointer; color: var(--ink); font-size: 12.5px; font-weight: 600; padding: 0; }
.spec-group-toggle:hover { color: var(--indigo-ink); }
.spec-area-toggle { font-weight: 500; color: var(--ink-2); }
.spec-floor-name { font-weight: 700; }
.spec-floor-total, .spec-area-sub { float: right; font-variant-numeric: tabular-nums; color: var(--ink-3); font-size: 12px; font-weight: 500; }
.spec-add-inline { float: right; margin-right: 8px; border: none; background: none; color: var(--ink-4); cursor: pointer; border-radius: var(--radius-btn-icon); width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-add-inline:hover { background: var(--bg-hover); color: var(--indigo-ink); }

/* On-hold section */
.spec-hold-section { margin-top: 14px; }
.spec-hold-head { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink-3); margin-bottom: 6px; }
.spec-hold-note { font-weight: 400; color: var(--ink-4); }

/* Notes */
.spec-notes { margin-top: 16px; }
.spec-notes-head { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink-3); margin-bottom: 6px; }
.spec-notes-area { width: 100%; min-height: 72px; resize: vertical; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font-size: 13px; color: var(--ink); background: var(--bg-card); font-family: inherit; }
.spec-danger-row { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line-soft, #f1f3f5); }

/* Empty state */
.spec-empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 48px 20px; }
.spec-empty-icon { display: inline-flex; align-items: center; justify-content: center; width: 60px; height: 60px; border-radius: 16px; background: var(--bg-sunk); border: 1px solid var(--line); color: var(--ink-4); margin-bottom: 16px; }
.spec-empty-title { font-size: 16px; font-weight: 600; color: var(--ink); }
.spec-empty-sub { font-size: 13px; color: var(--ink-4); margin: 6px auto 18px; max-width: 420px; line-height: 1.5; }

/* ── Split shell (invoice-editor pattern) ── */
.spec-split-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 22px; border-bottom: 1px solid var(--line); background: var(--bg-card); }
.spec-split-title { font-size: 16px; font-weight: 600; color: var(--ink); }
.spec-split-sub { font-size: 12px; color: var(--ink-4); font-weight: 400; }
.spec-split-actions { display: flex; align-items: center; gap: 8px; }
.spec-split-body { flex: 1; display: flex; align-items: stretch; overflow: hidden; }
.spec-split-left { flex: 1 1 560px; min-width: 0; overflow-y: auto; padding: 18px 20px; }
.spec-split-right { flex: 1 1 480px; min-width: 0; overflow-y: auto; padding: 24px; background: var(--bg-sunk); display: flex; justify-content: center; }
@media (max-width: 900px) {
  .spec-split-body { flex-direction: column; }
  .spec-split-right { border-top: 1px solid var(--line); }
}

/* ── Presentation doc (spec book) ── */
.spec-doc { background: #fff; color: #1c2024; width: 100%; max-width: 760px; padding: 40px 44px; box-shadow: 0 1px 8px rgba(0,0,0,0.08); border-radius: 4px; font-size: 13px; }
.spec-doc-cover { border-bottom: 3px solid var(--spec-accent, #1c2024); padding-bottom: 20px; margin-bottom: 22px; }
.spec-doc-logo { max-height: 48px; margin-bottom: 12px; }
.spec-doc-firm { font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--spec-accent, #1c2024); }
.spec-doc-title { font-size: 26px; font-weight: 700; margin-top: 6px; }
.spec-doc-sub { font-size: 13px; color: #555; margin-top: 4px; }
.spec-doc-firm-addr { font-size: 11px; color: #888; margin-top: 8px; white-space: pre-line; }
.spec-doc-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--spec-accent-ink, #1c2024); margin-bottom: 8px; }
.spec-doc-summary { margin-bottom: 24px; }
.spec-doc-summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.spec-doc-summary-grid > div { display: flex; flex-direction: column; gap: 3px; }
.spec-doc-summary-grid span { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: #999; }
.spec-doc-summary-grid strong { font-size: 15px; font-variant-numeric: tabular-nums; }
.spec-doc-budget-note { margin-top: 8px; font-size: 12px; font-weight: 600; color: #17a544; }
.spec-doc-budget-note.over { color: #c0392b; }
.spec-doc-floor { margin-top: 20px; page-break-inside: auto; }
.spec-doc-floor-name { font-size: 15px; font-weight: 700; border-bottom: 1px solid #e5e7eb; padding-bottom: 4px; margin-bottom: 10px; }
.spec-doc-area { margin-bottom: 14px; }
.spec-doc-area-name { font-size: 12px; font-weight: 600; color: #555; margin-bottom: 8px; }
.spec-doc-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.spec-doc-card { display: flex; gap: 10px; border: 1px solid #e5e7eb; border-radius: 8px; padding: 8px; page-break-inside: avoid; }
.spec-doc-card-img { width: 72px; height: 72px; flex-shrink: 0; border-radius: 6px; overflow: hidden; background: #f3f4f6; display: flex; align-items: center; justify-content: center; }
.spec-doc-card-img img { width: 100%; height: 100%; object-fit: cover; }
.spec-doc-card-noimg { color: #c0c4c9; }
.spec-doc-card-body { min-width: 0; flex: 1; }
.spec-doc-card-name { font-size: 13px; font-weight: 600; }
.spec-doc-card-meta { font-size: 10.5px; color: #999; margin-top: 2px; }
.spec-doc-card-facts { display: flex; flex-wrap: wrap; gap: 8px; font-size: 11px; color: #555; margin-top: 6px; font-variant-numeric: tabular-nums; }
.spec-doc-card-vendor { font-size: 10.5px; color: #888; margin-top: 4px; }
.spec-doc-notes { margin-top: 24px; }
.spec-doc-notes-body { font-size: 12px; color: #444; white-space: pre-wrap; line-height: 1.6; }

/* ── Spec BOOK: cover → chaptered index → one spec per page ──
   Each `.spec-page` is its own white sheet; the container is the sunken tray.
   `break-after: page` (inert on screen) + the print block enforce pagination;
   the per-page PDF renderer rasterizes each `.spec-page` onto its own PDF page. */
.spec-doc-book { background: transparent; box-shadow: none; padding: 0; max-width: 816px; border-radius: 0; }
.spec-page { background: #fff; color: #1c2024; border-radius: 4px; box-shadow: 0 1px 8px rgba(0,0,0,0.08); padding: 40px 44px; margin: 0 auto 20px; box-sizing: border-box; width: 100%; break-inside: avoid; page-break-inside: avoid; break-after: page; page-break-after: always; }
.spec-page:last-child { margin-bottom: 0; break-after: auto; page-break-after: auto; }

/* US Letter sheets on screen — each book page mirrors an 8.5in × 11in sheet
   (816 × 1056 px @96dpi) so the preview matches the printed page. aspect-ratio
   sets the baseline Letter height; a rare overlong page grows instead of
   clipping. Padding ≈ 0.6in margins, comfortably inside the 0.5in print @page. */
.spec-doc-book .spec-page { max-width: 816px; aspect-ratio: 8.5 / 11; padding: 56px 60px; }

/* Cover / title page */
.spec-page-cover { min-height: 640px; display: flex; flex-direction: column; }
.spec-page-cover-top { display: flex; flex-direction: column; gap: 10px; }
/* Cover letterhead — resolved office/firm branding (logo + name + tagline + address/contact). */
.spec-page-cover-brand { display: flex; align-items: center; gap: 14px; }
.spec-page-cover-brandtext { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.spec-page-cover-tagline { font-size: 12px; color: #777; }
.spec-page-cover-brandmeta { font-size: 11px; color: #888; line-height: 1.5; }
.spec-page-cover-brandaddr { white-space: pre-line; }
.spec-page-cover-brandcontact { margin-top: 2px; }
/* Light running header on the index + per-spec pages. */
.spec-page-runhead { display: flex; align-items: center; gap: 8px; padding-bottom: 12px; margin-bottom: 16px; border-bottom: 1px solid #eee; min-height: 20px; }
.spec-page-runhead img { max-height: 24px; width: auto; opacity: 0.9; }
.spec-page-runhead-name { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; color: var(--spec-accent-ink, #1c2024); }
.spec-page-cover-mid { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 30px 0; }
.spec-page-cover-kicker { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; color: var(--spec-accent-ink, #1c2024); overflow-wrap: anywhere; word-break: break-word; }
.spec-page-cover-title { font-size: 34px; font-weight: 800; line-height: 1.1; margin-top: 10px; overflow-wrap: anywhere; word-break: break-word; }
.spec-page-cover-proj { font-size: 16px; color: #444; margin-top: 10px; font-weight: 600; }
.spec-page-cover-meta { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 14px 28px; margin-top: 26px; max-width: 460px; }
.spec-page-cover-meta > div { display: flex; flex-direction: column; gap: 3px; }
.spec-page-cover-meta span { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: #999; }
.spec-page-cover-meta strong { font-size: 14px; }
.spec-page-cover-budget { border-top: 3px solid var(--spec-accent, #1c2024); padding-top: 16px; }
.spec-page-cover-addr { font-size: 11px; color: #888; margin-top: 14px; white-space: pre-line; }

/* Index / contents */
.spec-page-index-empty { color: #888; font-size: 13px; }
.spec-index-chapter { margin-bottom: 18px; }
.spec-index-chapter-name { font-size: 15px; font-weight: 700; border-bottom: 1px solid #e5e7eb; padding-bottom: 5px; margin-bottom: 8px; color: var(--spec-accent-ink, #1c2024); }
.spec-index-rows { display: flex; flex-direction: column; gap: 3px; }
.spec-index-row { display: flex; align-items: baseline; gap: 10px; font-size: 12.5px; }
.spec-index-no { flex: 0 0 auto; width: 26px; color: #999; font-variant-numeric: tabular-nums; }
.spec-index-name { flex: 1; min-width: 0; }
.spec-index-name em { color: #999; font-style: normal; font-size: 11px; }
.spec-index-page { flex: 0 0 auto; color: #aaa; font-size: 11px; font-variant-numeric: tabular-nums; }
.spec-index-notes { margin-top: 24px; }

/* One spec per page */
.spec-page-item { display: flex; flex-direction: column; }
.spec-page-item-head { display: flex; align-items: center; justify-content: space-between; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: #999; }
.spec-page-item-chapter { font-weight: 600; color: var(--spec-accent-ink, #1c2024); }
.spec-page-item-title { font-size: 24px; font-weight: 700; margin-top: 8px; line-height: 1.15; }
.spec-page-item-sub { font-size: 12px; color: #888; margin-top: 4px; font-family: ui-monospace, monospace; }
.spec-page-item-img { margin: 18px 0; width: 100%; height: 460px; background: #f5f6f7; border: 1px solid #eee; border-radius: 8px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.spec-page-item-img img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.spec-page-item-noimg { display: flex; flex-direction: column; align-items: center; gap: 8px; color: #c0c4c9; font-size: 12px; }
.spec-page-item-total { display: flex; align-items: baseline; justify-content: space-between; border-top: 2px solid var(--spec-accent, #1c2024); padding-top: 10px; }
.spec-page-item-total span { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: #999; }
.spec-page-item-total strong { font-size: 22px; font-variant-numeric: tabular-nums; }
.spec-page-facts { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px 28px; margin: 16px 0 0; }
.spec-page-fact { display: flex; flex-direction: column; gap: 2px; }
.spec-page-fact dt { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; color: #999; }
.spec-page-fact dd { margin: 0; font-size: 13.5px; }
.spec-page-proc { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.spec-page-proc-pill { font-size: 11.5px; background: #f3f4f6; border-radius: 20px; padding: 4px 12px; color: #444; }
.spec-page-proc-pill em { color: #999; font-style: normal; margin-right: 4px; }
.spec-page-item-note { margin-top: 16px; font-size: 12px; color: #555; white-space: pre-wrap; line-height: 1.6; border-left: 3px solid #eee; padding-left: 10px; }

/* ── Customizable spec-PDF format ──────────────────────────────────────────── */
/* Serif house style — a whole-doc font swap (mono item-sub keeps its own stack). */
.spec-doc-serif { font-family: Georgia, "Times New Roman", "Iowan Old Style", serif; }
/* A4 preview sheet (the PDF renderer already emits A4; this matches the on-screen sheet). */
.spec-doc-book.spec-doc-a4 .spec-page { aspect-ratio: 210 / 297; }
/* Compact-density "schedule" layout: aligned columns (№ · thumb · item · total)
   shared by a header row and every item row via one grid template, so the
   columns line up vertically down the sheet — reads as a spec index/schedule,
   not a stack of cards. `.no-thumb` drops the image column when product images
   are toggled off (header + rows stay in lock-step). */
.spec-page-list { display: flex; flex-direction: column; }
.spec-list-head,
.spec-list-row { display: grid; grid-template-columns: 24px 52px minmax(0,1fr) auto; align-items: center; column-gap: 14px; }
.spec-page-list.no-thumb .spec-list-head,
.spec-page-list.no-thumb .spec-list-row { grid-template-columns: 24px minmax(0,1fr) auto; }
.spec-list-head { padding-bottom: 7px; margin-bottom: 2px; border-bottom: 2px solid var(--spec-accent, #1c2024); font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #9aa0a6; }
.spec-list-h-no { text-align: center; }
.spec-list-h-total { text-align: right; }
.spec-list-row { padding: 11px 0; min-height: 54px; border-bottom: 1px solid #eee; break-inside: avoid; page-break-inside: avoid; }
.spec-list-row:last-child { border-bottom: none; }
.spec-list-thumb { width: 52px; height: 52px; flex: 0 0 auto; border-radius: 6px; overflow: hidden; background: #f3f4f6; display: flex; align-items: center; justify-content: center; color: #c0c4c9; }
.spec-list-thumb img { width: 100%; height: 100%; object-fit: cover; }
.spec-list-main { min-width: 0; }
.spec-list-topline { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.spec-list-no { font-size: 11px; color: #aaa; font-variant-numeric: tabular-nums; text-align: center; }
.spec-list-name { font-size: 14px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spec-list-code { flex: 0 0 auto; font-size: 10px; font-family: ui-monospace, "SF Mono", Menlo, monospace; color: #7a7f85; background: #f3f4f6; border-radius: 4px; padding: 1px 6px; letter-spacing: 0.02em; }
.spec-list-meta { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: #999; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Single-line, clipped facts so every compact row has a bounded height — each
   .spec-page rasterizes to exactly ONE PDF page, so a wrapped row that pushed the
   8th item past the sheet would be cut, not carried over. Keeping facts to one
   line makes 8 rows fit Letter AND A4 deterministically. */
.spec-list-facts { display: flex; flex-wrap: nowrap; gap: 5px 14px; font-size: 11.5px; color: #555; margin-top: 5px; font-variant-numeric: tabular-nums; overflow: hidden; max-width: 100%; }
.spec-list-facts > span { white-space: nowrap; flex: 0 0 auto; }
.spec-list-facts em { color: #999; font-style: normal; margin-right: 3px; }
.spec-list-total { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }

/* ── Spec-PDF Format editor (modal) ────────────────────────────────────────── */
.spec-fmt { display: flex; flex-direction: column; gap: 18px; }
.spec-fmt-group { display: flex; flex-direction: column; gap: 12px; }
.spec-fmt-group-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-4); border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.spec-fmt-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.spec-fmt-row-lbl { font-size: 13px; color: var(--ink-2); }
/* Even-width segmented controls — fixed track, buttons split it 50/50 so Font /
   Paper / Density all align to the same right edge in the editor. */
.spec-fmt-seg { display: inline-flex; width: 248px; flex: 0 0 auto; border: 1px solid var(--line); border-radius: var(--radius-btn); overflow: hidden; background: var(--bg-elev); }
.spec-fmt-seg-btn { flex: 1 1 0; min-width: 0; border: none; background: transparent; padding: 6px 10px; font-size: 12.5px; line-height: 1.3; color: var(--ink-3); cursor: pointer; white-space: nowrap; text-align: center; transition: background var(--duration-fast, 0.12s) ease, color var(--duration-fast, 0.12s) ease; }
.spec-fmt-seg-btn + .spec-fmt-seg-btn { border-left: 1px solid var(--line); }
.spec-fmt-seg-btn:hover:not(.active) { background: var(--bg-hover, rgba(0,0,0,0.04)); color: var(--ink-1); }
.spec-fmt-seg-btn.active { background: var(--ink-1, #1c2024); color: #fff; font-weight: 600; }
.spec-fmt-checks { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 16px; }
.spec-fmt-checks .spec-tmpl-check { display: flex; align-items: center; gap: 8px; min-height: 30px; font-size: 13px; color: var(--ink-2); cursor: pointer; }
.spec-fmt-checks .spec-tmpl-check input { width: 16px; height: 16px; flex: 0 0 auto; cursor: pointer; }
.spec-fmt-accent { display: flex; align-items: center; gap: 10px; }
.spec-fmt-hexinput { width: 150px; flex: 0 0 auto; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px; text-transform: lowercase; }
.spec-fmt-hexinput::placeholder { text-transform: none; font-family: var(--f-sans, system-ui, sans-serif); }
.spec-fmt-office { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: var(--bg-elev); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }
.spec-fmt-office-txt { font-size: 12px; color: var(--ink-3); line-height: 1.5; }
.spec-fmt-office-h { font-weight: 600; color: var(--ink-1); margin-bottom: 1px; }

/* Print isolation. The split shell mounts INSIDE #root (.app-right), so we can't
   hide #root like the invoice `inv-printing` pattern does. Instead hide every
   node via visibility, then re-show ONLY the spec-doc subtree and neutralize the
   overlay's absolute positioning + ancestor overflow so the doc flows across
   pages. (The primary export path is the html2canvas→jsPDF "Download PDF"
   button, which rasterizes the node directly and is unaffected by this.) */
@media print {
  /* US Letter paper with a 0.5in margin frame; the sheet fills the printable area. */
  @page { size: letter; margin: 0.5in; }
  body.spec-printing * { visibility: hidden !important; }
  body.spec-printing .spec-split-overlay,
  body.spec-printing .spec-split-overlay * { visibility: visible !important; }
  body.spec-printing .spec-split-header,
  body.spec-printing .spec-split-left { display: none !important; }
  body.spec-printing .spec-split-overlay { position: absolute !important; inset: auto !important; left: 0 !important; top: 0 !important; width: 100% !important; height: auto !important; overflow: visible !important; display: block !important; }
  body.spec-printing .spec-split-body { display: block !important; overflow: visible !important; }
  body.spec-printing .spec-split-right { position: static !important; overflow: visible !important; background: #fff !important; padding: 0 !important; display: block !important; }
  body.spec-printing .spec-doc { box-shadow: none !important; max-width: none !important; padding: 0 !important; }
  /* Spec book: one sheet per page. Drop the on-screen sheet chrome + Letter
     aspect-ratio (the @page margin now sets the frame) and hard-break after
     every page except the last so cover / index / each spec land on their own
     printed page; keep images within the page height. */
  body.spec-printing .spec-page,
  body.spec-printing .spec-doc-book .spec-page { box-shadow: none !important; border-radius: 0 !important; margin: 0 !important; padding: 0 !important; min-height: 0 !important; max-width: none !important; width: 100% !important; aspect-ratio: auto !important; break-after: page !important; page-break-after: always !important; break-inside: avoid !important; page-break-inside: avoid !important; }
  body.spec-printing .spec-page:last-child { break-after: auto !important; page-break-after: auto !important; }
  body.spec-printing .spec-page-item-img { height: 52vh !important; max-height: 52vh !important; }
  body.spec-printing .spec-page-cover { min-height: 92vh !important; }
}

/* ── Gantt → PDF export editor ──────────────────────────────────────────────
   Split-screen format editor (controls left, paper-accurate preview right),
   mounted inside .app-right so the nav + chat panel stay visible. Mirrors the
   invoice editor's layout conventions. All rules namespaced .gantt-export-*. */
.gantt-export-overlay {
  background: var(--bg);
  display: flex;
  flex-direction: column;
}
.gantt-export-topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 22px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
  flex-shrink: 0;
}
.gantt-export-topbar-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.gantt-export-topbar-title span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gantt-export-x {
  background: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 10px;
  cursor: pointer;
  color: var(--ink-3);
  display: flex;
  align-items: center;
}
.gantt-export-x:hover { background: var(--bg-sunk); }
.gantt-export-split {
  flex: 1;
  display: flex;
  align-items: stretch;
  overflow: hidden;
  min-height: 0;
}
.gantt-export-controls {
  flex: 0 0 320px;
  width: 320px;
  overflow-y: auto;
  padding: 18px 20px;
  border-right: 1px solid var(--line);
  background: var(--bg-card);
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.gantt-export-group { display: flex; flex-direction: column; }
.gantt-export-group-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-4);
  margin-bottom: 6px;
}
.gantt-export-seg {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.gantt-export-seg button {
  flex: 1;
  background: none;
  border: none;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--ink-3);
}
.gantt-export-seg button.on { background: var(--brand, #5e5ce6); color: #fff; font-weight: 600; }
.gantt-export-check {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 13px;
  color: var(--ink-2, var(--ink));
  cursor: pointer;
}
.gantt-export-check input { cursor: pointer; }
.gantt-export-reset {
  align-self: flex-start;
  margin-top: 8px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
  color: var(--indigo, #5e5ce6);
}
.gantt-export-reset:hover { text-decoration: underline; }
.gantt-export-actions {
  margin-top: auto;
  display: flex;
  gap: 8px;
  padding-top: 6px;
}
.gantt-export-actions .btn { flex: 1; justify-content: center; }
.gantt-export-preview {
  flex: 1;
  min-width: 0;
  overflow: auto;
  padding: 20px 24px;
  background: var(--bg-sunk);
}
.gantt-export-preview-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-4);
  margin: 0 2px 12px;
}
.gantt-export-sheet-wrap {
  position: relative;
  overflow: hidden;
}
.gantt-export-sheet {
  box-shadow: 0 6px 26px rgba(0, 0, 0, 0.18);
}

/* ════════════════════════════════════════════════════════════════════════════
   FF&E Specifications — Phases 2-5 (spec-URL capture, template editor,
   procurement panel, filter/mode bars). Appended block; reuses Phase-1 spec-*
   base classes (spec-btn, spec-input, spec-select, spec-chip, spec-roll,
   spec-icon-btn, spec-icon-danger, spec-mini-wide).
   ════════════════════════════════════════════════════════════════════════════ */

/* Theme-aware checkboxes across every spec surface */
.spec-tab input[type="checkbox"], .spec-cap input[type="checkbox"], .spec-tmpl-check input[type="checkbox"] { accent-color: var(--indigo); cursor: pointer; }

/* ── Spec-URL capture card (in a project-chat bubble) ── */
.spec-cap { display: flex; flex-direction: column; gap: 8px; min-width: 260px; }
.spec-cap-head { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13px; color: var(--ink); }
.spec-cap-head.spec-cap-err { color: var(--bad); }
.spec-cap-note { font-size: 12px; color: var(--ink-4); line-height: 1.45; }
.spec-cap-warn { color: var(--warn); }
.spec-cap-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.spec-cap-card { display: flex; gap: 10px; padding: 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-card); }
.spec-cap-img { width: 72px; height: 72px; flex: 0 0 72px; border-radius: 8px; overflow: hidden; background: var(--bg-sunk); display: flex; align-items: center; justify-content: center; }
.spec-cap-img img { width: 100%; height: 100%; object-fit: cover; }
.spec-cap-noimg { color: var(--ink-5); }
.spec-cap-fields { flex: 1; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.spec-cap-name { font-weight: 600; }
.spec-cap-row2 { display: flex; gap: 6px; }
.spec-cap-row2 > * { flex: 1; min-width: 0; }
.spec-cap-lbl { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--ink-4); }
.spec-cap-dim { font-size: 11px; color: var(--ink-4); }
.spec-cap-pkg { max-width: 180px; }
/* Inputs inside the capture card + procurement panel read as real fields */
.spec-cap .spec-input, .spec-proc .spec-input { border-color: var(--line); background: var(--bg-card); }
.spec-cap .spec-input:focus, .spec-proc .spec-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 2px var(--indigo-soft); }

/* ── Spec template editor (modal) ── */
.spec-tmpl-overlay { position: fixed; inset: 0; z-index: 6000; background: rgba(0,0,0,0.45); display: flex; align-items: center; justify-content: center; padding: 24px; }
.spec-tmpl-modal { width: min(720px, 96vw); max-height: 88vh; overflow: auto; background: var(--bg-card); border-radius: 14px; border: 1px solid var(--line); box-shadow: var(--shadow-lg); }
.spec-tmpl-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.spec-tmpl-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--ink); }
.spec-tmpl-body { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.spec-tmpl-list { display: flex; flex-direction: column; gap: 8px; }
.spec-tmpl-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-elev); transition: border-color var(--duration-fast) var(--ease-out); }
.spec-tmpl-item:hover { border-color: var(--line-strong); }
.spec-tmpl-item-name { font-weight: 600; display: flex; align-items: center; gap: 6px; color: var(--ink); }
.spec-tmpl-item-meta { font-size: 11px; color: var(--ink-4); }
.spec-tmpl-item-actions { display: flex; gap: 6px; }
.spec-tmpl-import { padding: 12px; border: 1px dashed var(--line-strong); border-radius: 10px; display: flex; flex-direction: column; gap: 8px; }
.spec-tmpl-sub { font-size: 12px; font-weight: 600; color: var(--ink-3); margin-top: 4px; }
.spec-tmpl-foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 6px; }
.spec-tmpl-check { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-2); }
.spec-tmpl-cols { display: flex; flex-direction: column; gap: 6px; }
.spec-tmpl-col { display: flex; align-items: center; gap: 6px; }
.spec-tmpl-col-key { font-size: 10px; color: var(--ink-5); min-width: 92px; font-family: ui-monospace, monospace; }
.spec-tmpl-col-label { flex: 1; }
.spec-tmpl-modal .spec-input { border-color: var(--line); background: var(--bg-card); }
.spec-tmpl-modal .spec-input:focus { border-color: var(--indigo); box-shadow: 0 0 0 2px var(--indigo-soft); }
.spec-tmpl-add-cols { display: flex; flex-wrap: wrap; gap: 6px; }
.spec-tmpl-grouping { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.spec-tmpl-hint { font-size: 11px; color: var(--ink-4); margin-top: -2px; }
.spec-tmpl-help { font-size: 11.5px; color: var(--ink-4); line-height: 1.45; margin-top: -4px; }
/* Nested confirm dialog rendered from inside the z-6000 template overlay:
   this zero-size wrapper makes an explicit stacking context above it so the
   ModalConfirm (its own fixed backdrop) paints on top of the overlay. */
.spec-confirm-layer { position: relative; z-index: 6500; }

/* ── Procurement panel (per-item) + summary (per-package) ── */
.spec-row-procopen > .spec-td { border-bottom-color: transparent; }
.spec-icon-btn.spec-icon-ordered { color: var(--ok); }
.spec-proc-row > td { background: var(--bg-sunk); padding: 0; }
.spec-proc { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; border-left: 3px solid var(--indigo); }
.spec-proc-line { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.spec-proc-line .spec-cap-lbl { min-width: 130px; }
.spec-proc-bal { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--ink-4); }
.spec-proc-bal strong { font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }
.spec-proc-approve { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-2); cursor: pointer; }
.spec-proc-flag { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--bad); font-weight: 500; }
.spec-procsum { padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; margin: 10px 0; background: var(--bg-elev); display: flex; flex-direction: column; gap: 10px; }
.spec-procsum-metrics { display: flex; flex-wrap: wrap; gap: 18px; }
.spec-procsum-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.spec-ordchip { background: var(--bg-sunk); border-color: var(--line); color: var(--ink-3); cursor: default; }
.spec-ordchip:hover { border-color: var(--line); color: var(--ink-3); }

/* ── Client-approval banner ── */
.spec-approve-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 10px; background: var(--bg-sunk); border: 1px solid var(--line); margin: 10px 0; transition: background var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out); }
.spec-approve-bar .spec-proc-approve { font-size: 13px; font-weight: 500; color: var(--ink-2); }
.spec-approve-bar.approved { background: var(--ok-soft); border-color: var(--ok-line); }
.spec-approve-bar.approved .spec-proc-approve { color: var(--ok); font-weight: 600; }
.spec-approve-note { flex: 1; min-width: 160px; border-color: var(--ok-line); background: var(--bg-card); }
.spec-approve-note:focus { border-color: var(--ok); box-shadow: 0 0 0 2px var(--ok-soft); }

/* ── Mode tabs (segmented control) + filter bar ── */
.spec-mode-tabs { display: inline-flex; gap: 4px; margin: 10px 0; padding: 3px; background: var(--bg-sunk); border: 1px solid var(--line); border-radius: var(--radius-btn); }
.spec-mode-tab { display: flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: var(--radius-btn); border: 1px solid transparent; background: none; color: var(--ink-3); font-size: 12px; font-weight: 500; cursor: pointer; transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out); }
.spec-mode-tab:hover { color: var(--ink); }
.spec-mode-tab.active { background: var(--bg-card); color: var(--ink); border-color: var(--line); box-shadow: var(--shadow-sm); }
.spec-filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0; }
.spec-filter-bar .spec-input, .spec-filter-bar .spec-select { border-color: var(--line); background: var(--bg-card); }
.spec-filter-bar .spec-input:focus, .spec-filter-bar .spec-select:focus { border-color: var(--indigo); box-shadow: 0 0 0 2px var(--indigo-soft); }
.spec-filter-search { flex: 1; min-width: 200px; }

/* ── Meeting Notes hub (.mnh-*) ──────────────────────────────────────────── */
.mnh-subtitle { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.mnh-head-tabs { display: flex; align-items: center; }
.mnh-tab-fallback { display: flex; gap: 6px; }

.mnh-setup-card { max-width: 560px; margin: 40px auto; text-align: center; padding: 32px 28px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg-card); }
.mnh-setup-icon { width: 56px; height: 56px; margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; border-radius: 14px; background: var(--bg-elev); color: var(--brand, #4f46e5); }
.mnh-setup-title { font-size: 17px; font-weight: 600; margin-bottom: 8px; color: var(--ink); }
.mnh-setup-body { font-size: 13px; color: var(--ink-3); line-height: 1.6; }
.mnh-setup-body code { background: var(--bg-elev); padding: 1px 5px; border-radius: 4px; font-size: 12px; }

/* Filters */
.mnh-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 12px 0 16px; }
.mnh-search { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 200px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg-card); color: var(--ink-3); }
.mnh-search input { border: none; outline: none; background: transparent; flex: 1; font-size: 13px; color: var(--ink); }
.mnh-select { padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-btn); background: var(--bg-card); font-size: 12.5px; color: var(--ink); max-width: 220px; }
.mnh-input { flex: 1; min-width: 180px; padding: 7px 11px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg-card); font-size: 13px; color: var(--ink); }
.mnh-file-input { font-size: 12px; }

/* Notes list */
.mnh-note-list { display: flex; flex-direction: column; gap: 8px; }
.mnh-note-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 13px 15px; border: 1px solid var(--line); border-radius: var(--radius-menu); background: var(--bg-card); cursor: pointer; }
.mnh-note-row:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS */
.mnh-note-main { flex: 1; min-width: 0; }
.mnh-note-title { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.mnh-note-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; font-size: 11.5px; color: var(--ink-3); }
.mnh-note-sub span { display: inline-flex; align-items: center; gap: 4px; }
.mnh-note-proj { color: var(--brand, #4f46e5); }
.mnh-note-unfiled { color: var(--ink-4); font-style: italic; }
.mnh-note-snippet { font-size: 12px; color: var(--ink-3); margin-top: 6px; line-height: 1.5; }
.mnh-note-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.mnh-status-chip { font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 10px; background: var(--bg-elev); color: var(--ink-3); }
.mnh-status--work { background: color-mix(in srgb, #d98c00 16%, transparent); color: #d98c00; }
.mnh-status--live { background: color-mix(in srgb, #e0463a 16%, transparent); color: #e0463a; }
.mnh-status--error { background: color-mix(in srgb, #e0463a 18%, transparent); color: #e0463a; }
.mnh-note-unfiled-wrap { display: inline-flex; }
.mnh-file-select { font-size: 11px; padding: 1px 6px; height: auto; max-width: 180px; color: var(--ink-4); font-style: italic; }

/* Export hover menu */
.mnh-export-menu { position: relative; display: inline-flex; }
.mnh-export-pop { position: absolute; top: 100%; right: 0; margin-top: 4px; min-width: 140px; background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius-menu); box-shadow: 0 6px 22px rgba(0,0,0,0.12); padding: 5px; z-index: 40; display: none; flex-direction: column; gap: 2px; }
/* ⚠️ The 4px margin-top gap ended .mnh-export-menu:hover mid-crossing and the
   pop vanished (the `.mnh-export-pop:hover` in the reveal can never help — a
   display:none element cannot be hovered). Invisible ::before bridges the gap. */
.mnh-export-pop::before { content: ""; position: absolute; bottom: 100%; left: 0; right: 0; height: 8px; }
.mnh-export-menu:hover .mnh-export-pop, .mnh-export-pop:hover { display: flex; }
.mnh-export-opt { display: flex; align-items: center; gap: 8px; padding: 6px 9px; border: none; background: transparent; border-radius: var(--radius-btn-icon); font-size: 12.5px; color: var(--ink); cursor: pointer; text-align: left; }
.mnh-export-opt:hover { background: var(--bg-elev); }
.mnh-export-opt:disabled { opacity: .55; cursor: default; }

/* Templates */
.mnh-templates { display: flex; flex-direction: column; gap: 16px; }
.mnh-upload-card { padding: 18px 18px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg-elev); }
.mnh-upload-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.mnh-upload-sub { font-size: 12px; color: var(--ink-3); margin-top: 4px; line-height: 1.5; max-width: 620px; }
.mnh-upload-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 14px; }
.mnh-file-chip { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 11.5px; color: var(--ink-3); }
.mnh-tpl-list { display: flex; flex-direction: column; gap: 8px; }
.mnh-tpl-card { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 13px 15px; border: 1px solid var(--line); border-radius: 11px; background: var(--bg-card); }
.mnh-tpl-main { flex: 1; min-width: 0; }
.mnh-tpl-name { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.mnh-tpl-spec { font-size: 12px; color: var(--ink-3); margin-top: 5px; line-height: 1.5; }
.mnh-tpl-bound { font-size: 11px; color: var(--brand, #4f46e5); margin-top: 4px; }
.mnh-tpl-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.mnh-badge { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; padding: 1px 6px; border-radius: 5px; background: var(--bg-elev); color: var(--ink-3); }
.mnh-badge-default { background: rgba(79,70,229,0.12); color: var(--brand, #4f46e5); }
.mnh-danger { color: var(--bad, #c0392b); }

/* Preview modal */
.mnh-preview { display: flex; flex-direction: column; gap: 16px; }
.mnh-preview-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; font-size: 12px; color: var(--ink-3); }
.mnh-preview-meta span { display: inline-flex; align-items: center; gap: 5px; }
.mnh-sec { display: flex; flex-direction: column; gap: 5px; }
.mnh-sec-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); }
.mnh-sec-text { font-size: 13.5px; color: var(--ink); line-height: 1.6; }
.mnh-sec-empty { font-size: 12.5px; color: var(--ink-4); }
.mnh-sec-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--ink); line-height: 1.5; }
.mnh-sec-obj { display: flex; flex-direction: column; gap: 3px; }
.mnh-kv-row, .mnh-kv { font-size: 13px; color: var(--ink); }
.mnh-kv-k { font-weight: 600; color: var(--ink-3); }
.mnh-kv { margin-right: 10px; }
.mnh-raw-pre { white-space: pre-wrap; word-break: break-word; font-size: 12.5px; color: var(--ink); background: var(--bg-elev); padding: 12px; border-radius: 8px; margin: 0; font-family: inherit; line-height: 1.55; }
.mnh-mapping { border-top: 1px solid var(--line); padding-top: 14px; }
.mnh-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; }
.mnh-table { border-collapse: collapse; width: 100%; font-size: 12px; }
.mnh-table th, .mnh-table td { border: 1px solid var(--line); padding: 6px 9px; text-align: left; color: var(--ink); }
.mnh-table th { background: var(--bg-elev); font-weight: 600; }
.mnh-modal-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; width: 100%; }
.mnh-foot-left, .mnh-foot-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mnh-foot-tpl { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); }

/* Shared states */
.mnh-loading { padding: 40px; display: flex; align-items: center; justify-content: center; color: var(--ink-3); }
.mnh-empty-block { padding: 24px 0; }
.mnh-empty-fallback { text-align: center; padding: 40px 20px; }
.mnh-empty-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.mnh-empty-body { font-size: 13px; color: var(--ink-3); margin-top: 6px; }
.mnh-error { font-size: 12.5px; color: var(--bad, #c0392b); margin-top: 8px; }
.mnh-error-block { padding: 20px; display: flex; align-items: center; gap: 10px; justify-content: center; }

/* ── Note viewer — Aecos Intelligence chat (left) + tabbed Notes/Transcript (right) ── */
.mnh-viewer { display: flex; min-height: 60vh; max-height: 72vh; }
.mnh-chatpane {
  width: 300px; flex-shrink: 0; display: flex; flex-direction: column; min-height: 0;
  border-right: 1px solid var(--line); padding-right: 16px; margin-right: 18px;
}
.mnh-chat-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.mnh-chat-head-text { min-width: 0; }
.mnh-chat-title { display: block; font-size: 13px; font-weight: 650; color: var(--ink); }
.mnh-chat-sub { display: block; font-size: 11.5px; color: var(--ink-4); line-height: 1.45; margin-top: 2px; }
/* Report-a-bug: header button (always available) + per-reply flag (on hover). */
.mnh-chat-bug {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: 11px; font-weight: 550; color: var(--ink-4); background: transparent;
  border: 1px solid var(--line); border-radius: var(--radius-btn, 999px);
  padding: 4px 9px; cursor: pointer; transition: border-color .12s, color .12s;
}
.mnh-chat-bug:hover { border-color: var(--brand, #4f46e5); color: var(--ink-2); }
.mnh-chat-bug.is-sent { color: var(--ok, #16a34a); border-color: var(--ok, #16a34a); }
/* The row inherits the bubble's old 94% cap so the reply is exactly as wide as
   it was before the flag button existed; the bubble then fills the row. */
.mnh-chat-row { display: flex; align-items: flex-start; gap: 4px; align-self: flex-start; max-width: 94%; }
.mnh-chat-row .mnh-chat-msg { max-width: 100%; }
.mnh-chat-msg-bug {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-top: 2px; color: var(--ink-5); background: transparent;
  border: none; border-radius: var(--radius-btn-icon, 8px); cursor: pointer;
  opacity: 0; transition: opacity .12s, color .12s;
}
.mnh-chat-row:hover .mnh-chat-msg-bug,
.mnh-chat-msg-bug:focus-visible,
.mnh-chat-msg-bug.is-sent { opacity: 1; }
.mnh-chat-msg-bug:hover { color: var(--ink-2); background: var(--bg-elev); }
.mnh-chat-msg-bug.is-sent { color: var(--ok, #16a34a); }
.mnh-chat-scroll { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding: 12px 2px; }
.mnh-chat-empty { display: flex; flex-direction: column; gap: 6px; font-size: 11.5px; color: var(--ink-4); margin-top: 6px; }
.mnh-chat-empty button {
  text-align: left; font-size: 12px; color: var(--ink-2); background: var(--bg-elev);
  border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.mnh-chat-empty button:hover { border-color: var(--brand, #4f46e5); color: var(--ink); }
.mnh-chat-msg { font-size: 12.5px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; border-radius: 10px; padding: 8px 10px; max-width: 94%; }
.mnh-chat-msg--user { background: var(--brand, #4f46e5); color: #fff; align-self: flex-end; border-bottom-right-radius: 4px; }
.mnh-chat-msg--aecos { background: var(--bg-elev); color: var(--ink); align-self: flex-start; border-bottom-left-radius: 4px; }
.mnh-chat-busy { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--ink-4); }
.mnh-chat-input { display: flex; gap: 6px; align-items: flex-end; padding-top: 10px; border-top: 1px solid var(--line); }
.mnh-chat-input textarea {
  flex: 1; min-width: 0; resize: none; font: inherit; font-size: 12.5px; line-height: 1.4;
  color: var(--ink); background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 9px; padding: 8px 10px; outline: none; min-height: 38px; max-height: 96px;
}
.mnh-chat-input textarea:focus { border-color: var(--brand, #4f46e5); }
.mnh-chat-send { flex-shrink: 0; }
.mnh-viewer-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; padding-right: 4px; }
.mnh-viewer-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
/* Transcript tab */
.mnh-transcript { display: flex; flex-direction: column; gap: 12px; padding-bottom: 6px; }
.mnh-turn-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
.mnh-turn-speaker { font-size: 12.5px; font-weight: 650; }
.mnh-turn-ts { font-size: 10.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.mnh-turn-text { font-size: 13px; color: var(--ink); line-height: 1.55; }
/* Narrow viewport: stack chat above the note instead of squeezing side-by-side. */
@media (max-width: 860px) {
  .mnh-viewer { flex-direction: column; max-height: none; }
  .mnh-chatpane {
    width: auto; border-right: none; padding-right: 0; margin-right: 0;
    border-bottom: 1px solid var(--line); padding-bottom: 12px; margin-bottom: 12px; max-height: 300px;
  }
}

/* ─── First-run onboarding (O-3) ──────────────────────────────────────────────
   .obt-*  = product-tour modal (window.OnboardingTour)
   .obchk-* = "Getting started" checklist card (window.OnboardingChecklist)
   Theme-aware via the app's canonical tokens (--ink / --line / --bg-card /
   --indigo / --ok). See onboarding-tour.jsx. */

/* Tour modal overlay */
.obt-overlay {
  /* 360 — above .plan-pick-overlay (350). ⚠️ This is NOT the Drawer's 7060;
     the two numbers were never related. Bespoke pair, below the dialog band —
     see the note on .plan-pick-overlay. */
  position: fixed; inset: 0; z-index: 360;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(0,0,0,0.50);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: obt-overlay-in 180ms ease both;
}
@keyframes obt-overlay-in { from { opacity: 0; } to { opacity: 1; } }

.obt-card {
  position: relative;
  width: 100%; max-width: 480px;
  background: var(--bg-card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 32px 64px -16px rgba(0,0,0,0.30);
  padding: 30px 30px 22px;
  display: flex; flex-direction: column;
  animation: obt-card-in 200ms cubic-bezier(0.2,0.7,0.3,1) both;
}
@keyframes obt-card-in {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.obt-skip {
  position: absolute; top: 14px; right: 16px;
  background: none; border: none; cursor: pointer;
  font-size: 12px; font-weight: 600; color: var(--ink-4);
  padding: 4px 6px; border-radius: 6px; letter-spacing: 0.01em;
}
.obt-skip:hover { color: var(--ink-2); background: var(--bg-hover, rgba(0,0,0,0.04)); }

.obt-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--indigo); margin-bottom: 8px;
}
.obt-title {
  font-size: 21px; font-weight: 650; letter-spacing: -0.02em; line-height: 1.2;
  color: var(--ink); margin: 0 0 10px;
}
.obt-body {
  font-size: 14px; line-height: 1.6; color: var(--ink-3); margin: 0 0 18px;
}

.obt-goto {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 6px;
  background: color-mix(in srgb, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--indigo) 35%, transparent);
  color: var(--indigo);
  font-size: 12.5px; font-weight: 650; cursor: pointer;
  padding: 7px 12px; border-radius: 8px; margin-bottom: 20px;
  transition: background 120ms ease, border-color 120ms ease;
}
.obt-goto:hover {
  background: color-mix(in srgb, var(--indigo) 16%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 55%, transparent);
}

.obt-progress { display: flex; gap: 6px; margin-bottom: 18px; }
.obt-dot {
  width: 7px; height: 7px; border-radius: 999px;
  background: var(--line-strong); transition: background 160ms ease, width 160ms ease;
}
.obt-dot.is-done { background: color-mix(in srgb, var(--indigo) 45%, var(--line-strong)); }
.obt-dot.is-active { width: 20px; background: var(--indigo); }

.obt-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.obt-count { font-size: 12px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.obt-btn {
  font-size: 13px; font-weight: 600; cursor: pointer;
  padding: 8px 16px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-2);
  transition: border-color 120ms ease, background 120ms ease, opacity 120ms ease;
}
.obt-btn:hover:not(:disabled) { border-color: var(--line-strong); color: var(--ink); }
.obt-btn:disabled { opacity: 0.4; cursor: default; }
.obt-btn-primary {
  background: var(--indigo); border-color: var(--indigo); color: #fff;
}
.obt-btn-primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--indigo) 88%, #000); border-color: color-mix(in srgb, var(--indigo) 88%, #000); color: #fff;
}

/* Getting-started checklist card */
.obchk-card {
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 18px 14px; margin-bottom: 20px;
}
.obchk-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.obchk-head-l { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.obchk-label { font-size: 13px; font-weight: 650; color: var(--ink); letter-spacing: -0.01em; }
.obchk-count { font-size: 12px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.obchk-dismiss {
  background: none; border: none; cursor: pointer; color: var(--ink-4);
  font-size: 13px; padding: 3px 6px; border-radius: 6px; flex: 0 0 auto;
}
.obchk-dismiss:hover { color: var(--ink-2); background: var(--bg-hover, rgba(0,0,0,0.04)); }

.obchk-bar { height: 4px; border-radius: 999px; background: var(--line-soft); overflow: hidden; margin-bottom: 12px; }
.obchk-bar-fill { display: block; height: 100%; background: var(--ok); border-radius: 999px; transition: width 260ms ease; }

.obchk-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.obchk-row { display: flex; align-items: center; gap: 12px; padding: 8px 4px; border-radius: 8px; }
.obchk-row:hover { background: var(--bg-hover, rgba(0,0,0,0.03)); }

.obchk-mark {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 999px;
  display: grid; place-items: center;
  border: 1.5px solid var(--line-strong); color: #fff;
  transition: background 140ms ease, border-color 140ms ease;
}
.obchk-mark.is-done { background: var(--ok); border-color: var(--ok); }
.obchk-tick { display: block; }

.obchk-txt { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.obchk-item-label { font-size: 13px; font-weight: 550; color: var(--ink); line-height: 1.3; }
.obchk-item-hint { font-size: 11.5px; color: var(--ink-4); line-height: 1.3; }
.obchk-row.is-done .obchk-item-label { color: var(--ink-3); text-decoration: line-through; text-decoration-color: var(--ink-5); }

.obchk-go {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 650; cursor: pointer;
  padding: 5px 11px; border-radius: 7px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink-2);
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.obchk-go:hover { border-color: var(--indigo); color: var(--indigo); background: color-mix(in srgb, var(--indigo) 8%, transparent); }
.obchk-done-tag { flex: 0 0 auto; font-size: 11px; font-weight: 650; color: var(--ok); letter-spacing: 0.02em; }
.obchk-skip-tag { flex: 0 0 auto; font-size: 11px; font-weight: 650; color: var(--ink-4); letter-spacing: 0.02em; }

@media (prefers-reduced-motion: reduce) {
  .obt-overlay, .obt-card { animation: none; }
  .obt-dot, .obt-btn, .obt-goto, .obchk-bar-fill, .obchk-go, .obchk-mark, .obt-skip, .obchk-dismiss { transition: none; }
}

@media (max-width: 768px) {
  .obt-card { padding: 24px 20px 18px; }
  .obt-title { font-size: 19px; }
}

/* ─── Landing · Intelligence page (.lint-) ─────────────────────────────────────
   Scoped redesign of the #product/intelligence surface. Reuses the app's theme
   tokens (--ink*, --line*, --indigo*, --bg-*) so it themes across light/mid/dark
   automatically; only the gold accent + ambient glow are defined locally (the app
   has no --gold), with overrides for the dark grounds. */
.lint-page {
  --lint-gold: #9a6b1e;
  --lint-gold-soft: rgba(154,107,30,.10);
  --lint-glow: rgba(77,84,216,.10);
  --lint-serif: "Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --lint-mono: ui-monospace,"SF Mono",Menlo,Monaco,"Cascadia Code",monospace;
  --lint-maxw: 1080px;
  color: var(--ink);
  /* isolate so the fixed bird-flock canvas (z-index:-1 below) paints above
     .landing-wrap's opaque background but below ALL page content */
  position: relative; isolation: isolate;
}
/* Full-page ambient bird-flock canvas (BirdFlockBackground, landing.jsx).
   Fixed to the viewport so the flock keeps flying while the page scrolls;
   pointer-events:none keeps everything on top clickable. */
.lint-flock-canvas {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  z-index: -1; pointer-events: none; display: block;
}
[data-theme="dark"] .lint-page,
.lint-page .lint-wrap { max-width: var(--lint-maxw); margin: 0 auto; padding: 0 28px; position: relative; }
.lint-page .lint-lbl {
  font-family: var(--lint-mono); font-size: 11.5px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--indigo); font-weight: 600;
}

/* Hero — ambient radial glow */
.lint-hero { position: relative; overflow: hidden; }
.lint-hero::before {
  content: ""; position: absolute; inset: -30% -10% auto -10%; height: 520px;
  background: radial-gradient(60% 100% at 50% 0%, var(--lint-glow), transparent 70%);
  pointer-events: none;
}
.lint-hero .lint-wrap { padding-top: 104px; padding-bottom: 88px; }
.lint-h1 {
  font-size: clamp(40px,7vw,72px); line-height: 1.03; letter-spacing: -.03em;
  font-weight: 660; margin: 22px 0 0; text-wrap: balance; max-width: 15ch;
}
.lint-h1 em { font-style: normal; color: var(--indigo); }
.lint-h1 .lint-fade { color: var(--ink-4); }
.lint-lede {
  margin: 26px 0 0; font-size: clamp(17px,2.1vw,20px); color: var(--ink-2);
  max-width: 60ch; line-height: 1.55;
}
.lint-meta {
  margin-top: 34px; display: flex; gap: 26px; flex-wrap: wrap;
  font-family: var(--lint-mono); font-size: 12px; color: var(--ink-4); letter-spacing: .02em;
}
.lint-meta b { color: var(--ink-3); font-weight: 600; }

/* Sections + section heads */
.lint-section { padding: 76px 0; }
.lint-shead { display: flex; align-items: baseline; gap: 16px; margin-bottom: 38px; flex-wrap: wrap; }
.lint-h2 { font-size: clamp(24px,3.4vw,34px); letter-spacing: -.02em; font-weight: 640; margin: 0; text-wrap: balance; }

/* ─── Intelligence articles — index grid + per-article reader ─────────────────── */
.intel-index-grid {
  margin-top: 28px;
  display: grid;
  /* min(280px, 100%) so a single card never forces horizontal overflow on a
     narrow phone (a bare 280px min would overflow a ~260px content box). */
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 16px;
}
.intel-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 22px 22px 18px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 16px;
  text-decoration: none;
}
.intel-card:hover { box-shadow: 0 0 0 1px var(--line); } /* thicken-outline convention; SNAPS — no lift, no drop shadow */
.intel-card-cat {
  font-size: 11px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase;
  color: var(--indigo);
}
.intel-card-title { font-size: 17px; font-weight: 640; line-height: 1.28; letter-spacing: -.01em; color: var(--ink); }
.intel-card-dek { font-size: 13.5px; line-height: 1.5; color: var(--ink-3); flex: 1; }
.intel-card-meta { margin-top: 4px; font-size: 12.5px; font-weight: 560; color: var(--ink-4); display: flex; align-items: center; gap: 6px; }
.intel-card-arrow { transition: transform 160ms var(--ease-out, ease); }
.intel-card:hover .intel-card-arrow { transform: translateX(3px); }

/* Blog-feed kind labels — distinguish long-form Blog posts from news/changelog
   Release/Update articles within the one chronological archive on #blog. */
.blogfeed-kind {
  display: inline-block;
  padding: 2px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  vertical-align: middle;
}
.blogfeed-kind--blog { color: var(--indigo); background: var(--indigo-tint, rgba(99,102,241,.12)); }
.blogfeed-kind--news { color: var(--ink-3); background: var(--bg-2, rgba(120,120,130,.12)); }
.blogfeed-cat-sep { color: var(--ink-4); font-weight: 600; letter-spacing: .04em; }

/* Reader */
.intel-article { padding: 0; border-bottom: 1px solid var(--line); }
.intel-article-inner { max-width: 760px; margin: 0 auto; padding: 72px 28px 88px; }
.intel-back {
  display: inline-block; margin-bottom: 30px;
  font-size: 13.5px; font-weight: 560; color: var(--ink-4); text-decoration: none;
  transition: color 140ms var(--ease-out, ease);
}
.intel-back:hover { color: var(--indigo); }
.intel-article-cat {
  font-size: 12px; font-weight: 650; letter-spacing: .07em; text-transform: uppercase;
  color: var(--indigo); margin-bottom: 14px;
}
.intel-article-title { font-size: clamp(30px, 4.4vw, 46px); font-weight: 560; letter-spacing: -.025em; line-height: 1.08; margin: 0 0 18px; color: var(--ink); text-wrap: balance; }
.intel-article-dek { font-size: clamp(17px, 2vw, 20px); line-height: 1.5; color: var(--ink-3); margin: 0 0 20px; }
.intel-article-meta { font-size: 13px; font-weight: 560; color: var(--ink-4); padding-bottom: 26px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }

.intel-article-body { font-size: 16.5px; line-height: 1.72; color: var(--ink-2); }
.intel-p { margin: 20px 0; }
.intel-h2 { font-size: clamp(22px, 2.8vw, 28px); font-weight: 620; letter-spacing: -.02em; line-height: 1.2; color: var(--ink); margin: 48px 0 4px; }
.intel-h3 { font-size: 18.5px; font-weight: 620; letter-spacing: -.01em; color: var(--ink); margin: 34px 0 2px; }
.intel-ul, .intel-ol { margin: 18px 0; padding-left: 24px; }
.intel-ul li, .intel-ol li { margin: 8px 0; padding-left: 4px; }
.intel-ul { list-style: none; padding-left: 4px; }
.intel-ul li { position: relative; padding-left: 22px; }
.intel-ul li::before { content: ""; position: absolute; left: 4px; top: 11px; width: 6px; height: 6px; border-radius: 50%; background: var(--indigo); }
.intel-code-inline {
  font-family: var(--f-mono, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: .88em; background: var(--bg-sunk); border: 1px solid var(--line-soft);
  border-radius: 5px; padding: 1px 5px; color: var(--ink-2);
}

/* Steps */
.intel-steps { list-style: none; margin: 24px 0; padding: 0; counter-reset: none; }
.intel-step { display: flex; gap: 16px; padding: 16px 0; border-top: 1px solid var(--line-soft); }
.intel-step:first-child { border-top: 0; }
.intel-step-n {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  background: var(--indigo-soft); color: var(--indigo-ink);
  border: 1px solid var(--indigo-line);
  font-size: 13px; font-weight: 680; display: flex; align-items: center; justify-content: center;
  margin-top: 2px;
}
.intel-step-body { display: flex; flex-direction: column; gap: 4px; }
.intel-step-title { font-weight: 640; color: var(--ink); font-size: 16px; }
.intel-step-text { color: var(--ink-3); font-size: 15px; line-height: 1.62; }

/* Tables */
.intel-tablewrap { margin: 28px 0; }
.intel-table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
.intel-table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 460px; }
.intel-table th, .intel-table td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: top; line-height: 1.5; }
.intel-table thead th { background: var(--bg-sunk); font-weight: 640; color: var(--ink); font-size: 12.5px; letter-spacing: .01em; }
.intel-table tbody tr:last-child td { border-bottom: 0; }
.intel-table td { color: var(--ink-3); }
.intel-figcap { margin-top: 10px; font-size: 12.5px; color: var(--ink-4); text-align: center; font-style: italic; }

/* Callouts */
.intel-callout { margin: 28px 0; padding: 18px 20px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg-elev); border-left-width: 3px; }
.intel-callout-title { display: flex; align-items: center; gap: 8px; font-weight: 650; font-size: 14.5px; color: var(--ink); margin-bottom: 6px; }
.intel-callout-title svg { flex: none; }
.intel-callout-body { margin: 0; font-size: 14.5px; line-height: 1.62; color: var(--ink-3); }
.intel-callout--security { border-left-color: var(--indigo); }
.intel-callout--security .intel-callout-title { color: var(--indigo-ink); }
.intel-callout--note { border-left-color: var(--line-strong); }
.intel-callout--limit { border-left-color: oklch(72% 0.14 62); }
.intel-callout--limit .intel-callout-title { color: oklch(58% 0.13 62); }

/* Figures / diagrams */
.intel-figure { margin: 30px 0; }
.intel-figure-nodes { display: flex; align-items: stretch; justify-content: center; flex-wrap: wrap; gap: 6px; }
.intel-figure--stack .intel-figure-nodes { flex-direction: column; align-items: center; }
.intel-node {
  flex: 0 1 auto; min-width: 120px; max-width: 200px;
  padding: 12px 14px; border-radius: 10px;
  background: var(--bg-card); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 3px; text-align: center;
}
.intel-figure--stack .intel-node { min-width: 220px; }
.intel-node-label { font-weight: 620; font-size: 13.5px; color: var(--ink); }
.intel-node-sub { font-size: 11.5px; color: var(--ink-4); line-height: 1.4; }
.intel-node-arrow { display: flex; align-items: center; color: var(--ink-5); font-size: 18px; padding: 0 2px; }
.intel-figure--stack .intel-node-arrow { justify-content: center; }

/* Code block */
.intel-codeblock {
  margin: 24px 0; padding: 16px 18px; overflow-x: auto;
  background: var(--bg-sunk); border: 1px solid var(--line); border-radius: 12px;
  font-family: var(--f-mono, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 13px; line-height: 1.6; color: var(--ink-2);
}
.intel-codeblock code { white-space: pre; }

/* Reader footer + more */
.intel-article-foot { margin-top: 44px; padding-top: 30px; border-top: 1px solid var(--line); display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.intel-link { font-size: 14px; font-weight: 560; color: var(--indigo); text-decoration: none; }
.intel-link:hover { text-decoration: underline; }
.intel-more { margin-top: 56px; }
.intel-more-h { font-size: 13px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); }

@media (max-width: 640px) {
  .intel-article-inner { padding: 48px 20px 64px; }
  .intel-figure--flow .intel-node-arrow { transform: rotate(90deg); }
  .intel-figure--flow .intel-figure-nodes { flex-direction: column; align-items: center; }
  .intel-figure--flow .intel-node { min-width: 220px; }
}
.lint-shead p { margin: 0; color: var(--ink-4); font-size: 15px; max-width: 46ch; }

/* The shift — two columns */
.lint-shift { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.lint-col { border: 1px solid var(--line); border-radius: 16px; padding: 28px; background: var(--bg-card); }
.lint-col.lint-now { background: var(--bg-sunk); }
.lint-col.lint-next { border-color: var(--indigo-line); background: linear-gradient(180deg, var(--lint-glow), transparent 60%), var(--bg-card); }
.lint-tag { font-family: var(--lint-mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-4); }
.lint-col.lint-next .lint-tag { color: var(--indigo); }
.lint-col h3 { margin: 10px 0 18px; font-size: 21px; letter-spacing: -.01em; font-weight: 620; }
.lint-col ul { list-style: none; margin: 0; padding: 0; }
.lint-col li { padding: 11px 0; border-top: 1px solid var(--line); color: var(--ink-2); font-size: 15px; display: flex; gap: 11px; align-items: flex-start; }
.lint-col li:first-child { border-top: 0; }
.lint-k { color: var(--ink-4); flex: 0 0 auto; margin-top: 2px; }
.lint-col.lint-next .lint-k { color: var(--indigo); }

/* Four pillars */
.lint-pillars { display: grid; grid-template-columns: repeat(2,1fr); gap: 20px; }
.lint-pillar { border: 1px solid var(--line); border-radius: 16px; padding: 26px 26px 24px; background: var(--bg-card); position: relative; }
.lint-pillar.lint-grow { border-color: var(--indigo-line); }
.lint-n { font-family: var(--lint-mono); font-size: 12px; color: var(--ink-4); letter-spacing: .1em; }
.lint-pillar h3 { margin: 14px 0 8px; font-size: 20px; font-weight: 630; letter-spacing: -.01em; }
.lint-pillar p { margin: 0; color: var(--ink-2); font-size: 14.5px; line-height: 1.55; }
.lint-eg {
  margin-top: 16px; padding: 12px 14px; border-radius: 10px; background: var(--bg-sunk);
  border: 1px solid var(--line); font-size: 13.5px; color: var(--ink-2);
  font-family: var(--lint-mono); line-height: 1.5;
}
.lint-eg b { color: var(--indigo); font-weight: 600; font-family: inherit; }
.lint-pillar.lint-grow .lint-eg b { color: var(--lint-gold); }

/* The experience — copy + live demo */
.lint-exp { display: grid; grid-template-columns: 1.02fr .98fr; gap: 30px; align-items: center; }
.lint-expcopy h3 { font-size: 22px; margin: 0 0 12px; font-weight: 630; letter-spacing: -.01em; }
.lint-expcopy p { color: var(--ink-2); margin: 0 0 18px; font-size: 15px; }
.lint-flist { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.lint-flist li { display: flex; gap: 12px; align-items: flex-start; color: var(--ink-2); font-size: 14.5px; }
.lint-flist b { color: var(--ink); font-weight: 620; }
.lint-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--indigo); margin-top: 8px; box-shadow: 0 0 0 4px var(--indigo-soft); }
.lint-demo { min-width: 0; }

/* Voice — 3-col cards + serif pull-quote */
.lint-voice { display: grid; grid-template-columns: repeat(3,1fr); gap: 18px; }
.lint-vcard { border: 1px solid var(--line); border-radius: 14px; padding: 22px; background: var(--bg-card); }
.lint-vcard h4 { margin: 0 0 7px; font-size: 16px; font-weight: 620; letter-spacing: -.01em; }
.lint-vcard p { margin: 0; color: var(--ink-3); font-size: 13.5px; line-height: 1.5; }
.lint-pullwrap { margin-top: 46px; border-top: 1px solid var(--line); padding-top: 40px; }
.lint-pull { font-family: var(--lint-serif); font-size: clamp(21px,3vw,29px); line-height: 1.4; color: var(--ink); max-width: 24ch; margin: 0; letter-spacing: -.01em; }
.lint-accent { color: var(--indigo); }

/* CTA */
.lint-cta { border-bottom: 0; }
.lint-ctarow { margin-top: 28px; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.lint-ctalink { font-family: var(--lint-mono); font-size: 13px; letter-spacing: .04em; color: var(--indigo); text-decoration: none; font-weight: 600; }
.lint-ctalink:hover { color: var(--indigo-ink); }

@media (max-width: 820px) {
  .lint-shift, .lint-pillars, .lint-exp, .lint-voice { grid-template-columns: 1fr; }
  .lint-exp { gap: 22px; }
  .lint-hero .lint-wrap { padding-top: 76px; padding-bottom: 60px; }
  .lint-section { padding: 56px 0; }
}
@media (prefers-reduced-motion: reduce) {
  .lint-page * { transition: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   NATIVE AECOS SELECT TREATMENT (CSS-only, cross-cutting)
   Force every <select> that isn't already themed to use appearance:none plus
   the native Aecos chevron (matches .ct-select / .txn-filter-select), so no
   browser-default arrow leaks through in light, mid, or dark.

   Chevron props use !important so they win over (a) inline `background:`
   shorthands on unclassed selects and (b) more-specific existing rules that set
   `background:` (e.g. `.spec-filter-bar .spec-select`) — which would otherwise
   reset background-image to none. Only the IMAGE layer is forced; each select
   keeps its own border / background-color / height / font.

   Data-URI SVGs can't read CSS custom props, so mid/dark override the whole
   background-image below. Already-native selects (.ct-select, .txn-filter-select,
   .ts-select, .ts-timer-select, .sr-cc-jur-select, .sr-dash-sort,
   .pagination__pagesize-select, .field__select) are intentionally NOT listed —
   they already render a chevron and must not be double-applied.
   ═══════════════════════════════════════════════════════════════════════════ */
select:not([class]),
select.field-input,
.rfi-filter-select,
.inv-filter-select,
.spec-select,
select.spec-mini-input,
.sr-form-select,
.sr-select,
.sr-snap-spacing-sel,
.mnh-select,
.ua-clearance-select,
.txn-cat-select,
.ob-select,
select.m-select,
select.form-input,
select.twk-field,
.tsm-sort-select,
.tsm-project-select,
.pf-tpl-select,
select.pf-gridcell,
.ce-tb-select,
.paste-select,
.mu-filter-select {
  appearance: none !important;
  -webkit-appearance: none !important;
  -moz-appearance: none !important;
  padding-right: 28px !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%2376787f'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 10px center !important;
}
/* Unclassed selects are commonly inline-styled with a fixed background + width:100%;
   border-box keeps the extra chevron room from overflowing their container. */
select:not([class]) { box-sizing: border-box; }

[data-theme="dark"] select:not([class]),
[data-theme="dark"] select.field-input,
[data-theme="dark"] .rfi-filter-select,
[data-theme="dark"] .inv-filter-select,
[data-theme="dark"] .spec-select,
[data-theme="dark"] select.spec-mini-input,
[data-theme="dark"] .sr-form-select,
[data-theme="dark"] .sr-select,
[data-theme="dark"] .sr-snap-spacing-sel,
[data-theme="dark"] .mnh-select,
[data-theme="dark"] .ua-clearance-select,
[data-theme="dark"] .txn-cat-select,
[data-theme="dark"] .ob-select,
[data-theme="dark"] select.m-select,
[data-theme="dark"] select.form-input,
[data-theme="dark"] select.twk-field,
[data-theme="dark"] .tsm-sort-select,
[data-theme="dark"] .tsm-project-select,
[data-theme="dark"] .pf-tpl-select,
[data-theme="dark"] select.pf-gridcell,
[data-theme="dark"] .ce-tb-select,
[data-theme="dark"] .paste-select,
[data-theme="dark"] .mu-filter-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236f717b'/%3E%3C/svg%3E") !important;
}

/* Disabled selects: dim, keep the chevron (no state change needed). */
select:disabled { opacity: 0.55; cursor: not-allowed; }

/* ── Meeting whiteboard: selection inspector + zoom controls ─────────────────── */
.wb-inspector {
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: #22262d;
  border: 1px solid #343a43;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  max-width: 92%;
  flex-wrap: wrap;
}
.wb-ins-swatches { display: flex; gap: 4px; }
.wb-ins-sw {
  width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  cursor: pointer; padding: 0; flex-shrink: 0;
}
.wb-ins-widths, .wb-ins-fills, .wb-ins-sizes { display: flex; gap: 3px; align-items: center; }
.wb-ins-w {
  width: 26px; height: 24px; border-radius: 6px;
  border: 1px solid #3a414b; background: transparent; color: #cdd3da;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.wb-ins-w.on { border-color: var(--brand); background: rgba(99, 102, 241, 0.18); color: #fff; }
.wb-ins-f, .wb-ins-sz, .wb-ins-edit, .wb-ins-del {
  min-width: 26px; height: 24px; padding: 0 7px; border-radius: 6px;
  border: 1px solid #3a414b; background: transparent; color: #cdd3da;
  cursor: pointer; font-size: 12px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.wb-ins-f.on { border-color: var(--brand); background: rgba(99, 102, 241, 0.18); color: #fff; }
.wb-ins-edit { color: #9ec7ff; }
.wb-ins-del { color: #ff7a6b; border-color: #6d3a34; }
.wb-ins-f:hover, .wb-ins-sz:hover, .wb-ins-edit:hover, .wb-ins-del:hover, .wb-ins-w:hover { border-color: var(--brand); }

.wb-zoom-ctl {
  position: absolute;
  right: 12px; bottom: 12px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: #22262d;
  border: 1px solid #343a43;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
}
.wb-zoom-ctl button {
  min-width: 30px; height: 28px; padding: 0 6px;
  border: none; background: transparent; color: #cdd3da;
  cursor: pointer; font-size: 15px; font-weight: 600; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
}
.wb-zoom-ctl button:hover { background: #2c313a; color: #fff; }
.wb-zoom-ctl .wb-zoom-pct { font-size: 12px; min-width: 46px; }
/* The board's expand-arrows "full screen" button and its rule are GONE — that
   control never entered full screen, it only repeated the reset the percentage
   button already does (founder decision 2026-08-14: remove it, don't repair it).
   scripts/test_whiteboard_geometry.js keeps both from coming back. */

/* ── Bookkeeping — expandable transaction rows (Weekly Review) ─────────────
   Clicking a queue row expands an inline detail panel (original bank
   description, account, category, AI reasoning). Row is keyboard-actionable
   (role=button + tabIndex); its own controls (checkbox/select) don't toggle.
   NOTE: no transitions on var()-valued properties (Chrome sticks at the
   from-value — see feedback-css-var-transition-stuck); the chevron rotate +
   panel entrance animate literal values only. */
.bk-txn-row { cursor: pointer; }
.bk-txn-row:hover { background: var(--bg-hover); }
.bk-txn-row:focus-visible { outline: 2px solid var(--indigo); outline-offset: -2px; }
.bk-txn-row.bk-open { background: var(--bg-hover); }
.bk-txn-row.bk-open td { border-bottom-color: transparent; }
.bk-chev {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; flex: 0 0 16px;
  color: var(--ink-4);
  transition: transform 0.16s ease;   /* literal transform values only */
}
.bk-chev.open { transform: rotate(90deg); }
.bk-expand-tr td { padding: 0 !important; background: var(--bg-hover); }
.bk-expand { overflow: hidden; }
.bk-expand-inner {
  padding: 4px 18px 16px 52px;
  border-bottom: 1px solid var(--line-soft);
  animation: bkExpandIn 0.18s ease;
}
@keyframes bkExpandIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.bk-expand-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 28px;
}
.bk-expand-field { min-width: 0; }
.bk-expand-field.bk-expand-wide { grid-column: 1 / -1; }
.bk-expand-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-4); margin-bottom: 3px;
}
.bk-expand-value { font-size: 12.5px; color: var(--ink-2); line-height: 1.55; overflow-wrap: anywhere; }
.bk-expand-mono { font-family: var(--f-mono); font-size: 12px; color: var(--ink-3); }

/* ── E-signature signer page (#sign:<token>) ────────────────────────────────
   Account-less, client-facing surface (esign-signer.jsx). Deliberately a FIXED
   LIGHT "paper" palette regardless of the firm's app theme — it's a legal
   document in front of an external client (literal colors, not theme tokens,
   so a dark workspace theme can't bleed in). The page is its own scroll
   container (position:fixed + overflow-y:auto) so it scrolls even when the
   app-shell scroll-lock (html/body overflow:hidden) is active — e.g. when a
   SIGNED-IN user opens a sign link and body.is-landing is absent.
   NOTE: no transitions on var()-valued properties (Chrome sticks at the
   from-value — feedback-css-var-transition-stuck); literal values only. */
.esign-page {
  position: fixed; inset: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  color-scheme: light;
  background: #f4f5f7; color: #1a1a1f;
  font-family: var(--f-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
  font-size: 14px; line-height: 1.5;
  --ink: #1a1a1f; --ink-4: #565663; --ink-5: #767683; --muted: #565663;
  --line: #e3e4ea; --bg-0: #ffffff; --bg-1: #ffffff; --bg-2: #f4f5f7;
  --accent: #4f46e5;
}
.esign-topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 10px;
  padding: 13px 20px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid #e3e4ea;
}
.esign-brand { font-weight: 700; letter-spacing: -0.02em; font-size: 16px; color: #1a1a1f; }
.esign-secure {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: #565663;
}
.esign-secure svg { flex-shrink: 0; color: #767683; }
.esign-wrap { max-width: 780px; margin: 0 auto; padding: 26px 18px 64px; }
.esign-title { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; margin: 0; }
.esign-sub { color: #565663; font-size: 13.5px; margin-top: 5px; }
.esign-meta { color: #8a8a94; font-size: 12px; margin-top: 3px; }
.esign-card {
  background: #fff; border: 1px solid #e3e4ea; border-radius: 12px;
  margin-bottom: 18px;
}
.esign-card-pad { padding: 16px 18px; }
.esign-card-head { font-weight: 600; font-size: 14px; margin-bottom: 4px; color: #1a1a1f; }
.esign-card-note { color: #8a8a94; font-size: 12px; margin-bottom: 10px; }

/* Signer progress chips (only shown for multi-signer requests) */
.esign-signers { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.esign-signer-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid #e3e4ea; background: #fff;
  font-size: 12px; color: #565663;
}
.esign-signer-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: #c9cad2; flex-shrink: 0; }
.esign-signer-chip.signed { border-color: #bfe3cd; background: #f2faf5; color: #1e6b40; }
.esign-signer-chip.signed .dot { background: #1e8a4c; }
.esign-signer-chip.viewed .dot { background: #4f46e5; }
.esign-signer-chip.you { font-weight: 600; }

/* Document viewer */
.esign-doc-frame {
  width: 100%; height: min(72vh, 640px);
  border: none; display: block; background: #fff;
}
.esign-doc-frame.with-sections { border-bottom: 1px solid #e3e4ea; }
/* Shared AecosPdfPane on the signer page. The signer page is deliberately
   light-only (colorScheme:light on .esign-page), while the pane's shared
   .di-pdf-modal-* rules are var-driven and theme-aware — so pin the vars to
   the signer palette locally instead of forking the pane's CSS. */
.esign-doc-pane {
  --bg-sunk: #f4f4f7; --bg-elev: #ffffff; --bg-card: #ffffff;
  --line: #e3e4ea; --line-strong: #c9cad4;
  --ink-1: #1a1a1f; --ink-2: #33333d; --ink-3: #5a5a66; --ink-4: #8a8a94;
  --indigo: #4f46e5;
  display: flex; flex-direction: column;
  height: min(72vh, 640px);
  background: #f4f4f7;
}
.esign-doc-pane.with-sections { border-bottom: 1px solid #e3e4ea; }
.esign-doc-pane-bar {
  flex: 0 0 auto; display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; min-height: 34px; padding: 5px 12px;
  background: #ffffff; border-bottom: 1px solid #e3e4ea;
}
.esign-doc-pane-body { flex: 1 1 auto; min-height: 0; display: flex; }
@media (max-width: 640px) {
  .esign-doc-pane { height: 62vh; }
  .esign-doc-pane .di-pdf-modal-thumbs { display: none; }
}
.esign-sections { padding: 22px 26px; }
.esign-section { margin-bottom: 20px; }
.esign-section:last-child { margin-bottom: 0; }
.esign-section-title { font-size: 15px; font-weight: 700; margin-bottom: 6px; color: #1a1a1f; }
.esign-section-body { font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; color: #1a1a1f; }
/* Rich (block-rendered) section body — real HTML from the shared block
   renderer, so drop pre-wrap and style the block elements. Literal light
   palette like every .esign-* rule (client-facing legal page, theme-proof). */
.esign-section-body.esign-rich { white-space: normal; }
.esign-rich p { margin: 0 0 10px; }
.esign-rich p:last-child { margin-bottom: 0; }
.esign-rich h1, .esign-rich h2, .esign-rich h3, .esign-rich h4, .esign-rich h5, .esign-rich h6 {
  margin: 14px 0 6px; color: #1a1a1f; line-height: 1.35; font-weight: 700;
}
.esign-rich h1 { font-size: 18px; } .esign-rich h2 { font-size: 16.5px; }
.esign-rich h3 { font-size: 15px; } .esign-rich h4 { font-size: 14px; }
.esign-rich h5, .esign-rich h6 { font-size: 13.5px; }
.esign-rich h1:first-child, .esign-rich h2:first-child, .esign-rich h3:first-child,
.esign-rich h4:first-child, .esign-rich h5:first-child, .esign-rich h6:first-child { margin-top: 0; }
.esign-rich ul, .esign-rich ol { margin: 0 0 10px; padding-left: 22px; }
.esign-rich li { margin: 2px 0; }
.esign-rich p[data-indent="1"] { padding-left: 24px; } .esign-rich p[data-indent="2"] { padding-left: 48px; }
.esign-rich p[data-indent="3"] { padding-left: 72px; } .esign-rich p[data-indent="4"] { padding-left: 96px; }
.esign-rich table.ce-table {
  border-collapse: collapse; width: 100%; margin: 8px 0 12px;
  font-size: 12.5px; table-layout: fixed; word-break: break-word;
}
.esign-rich table.ce-table td {
  border: 1px solid #d6d7df; padding: 5px 8px; vertical-align: top; color: #1a1a1f;
}
.esign-rich table.ce-table p { margin: 0 0 4px; }
.esign-rich table.ce-table p:last-child { margin-bottom: 0; }
.esign-rich img.ce-img {
  max-width: 100%; height: auto; display: block; margin: 8px 0 12px;
  border-radius: 3px; background: #eceef1;
}
.esign-rich hr.ce-pagebreak { border: none; border-top: 1.5px dashed #d6d7df; margin: 16px 0; }
.esign-rich a { color: #4f46e5; }
.esign-doc-empty { padding: 30px; text-align: center; color: #8a8a94; font-size: 13px; }

/* Inputs + buttons (literal light-palette; global .btn/.field-input are theme-
   token-driven so they'd flip with the app theme — these must not) */
.esign-input {
  width: 100%; padding: 9px 12px;
  border: 1px solid #d6d7df; border-radius: 8px;
  background: #fff; color: #1a1a1f; font-size: 13.5px; font-family: inherit;
}
.esign-input::placeholder { color: #9a9ba5; }
.esign-input:focus-visible { outline: 2px solid #4f46e5; outline-offset: 1px; border-color: #4f46e5; }
.esign-page button:focus-visible { outline: 2px solid #4f46e5; outline-offset: 2px; }
.esign-input-script {
  padding: 14px 18px; font-size: 30px; line-height: 1.3;
  font-family: 'Snell Roundhand', 'Segoe Script', 'Brush Script MT', cursive;
}
.esign-label { font-size: 12.5px; color: #565663; display: block; margin-bottom: 5px; }

.esign-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px; border-radius: 8px; font-size: 13px; font-weight: 500;
  border: 1px solid #d6d7df; background: #fff; color: #1a1a1f; cursor: pointer;
}
.esign-btn:hover:not(:disabled) { border-color: #b9bac4; background: #fafafb; }
.esign-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.esign-btn-link {
  background: transparent; border: none; color: #4f46e5;
  cursor: pointer; font-size: 12.5px; padding: 4px 6px; border-radius: 6px;
}
.esign-btn-link:hover { background: #eef0fb; }
.esign-sign-btn {
  width: 100%; padding: 13px; border-radius: 9px; border: none;
  font-size: 14.5px; font-weight: 600; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: #4f46e5; color: #fff;
}
.esign-sign-btn:hover:not(:disabled) { background: #4338ca; }
.esign-sign-btn:disabled { background: #e3e4ea; color: #8a8a94; cursor: not-allowed; }

/* Type/Draw tabs */
.esign-tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.esign-tab {
  padding: 7px 18px; border-radius: 8px; font-size: 13px; font-weight: 500;
  cursor: pointer; border: 1px solid #d6d7df; background: #fff; color: #1a1a1f;
}
.esign-tab:hover:not(.on) { border-color: #b9bac4; }
.esign-tab.on { border-color: #4f46e5; background: #4f46e5; color: #fff; }

/* Signature canvas */
.esign-canvas-wrap { position: relative; }
.esign-canvas {
  width: 100%; height: 150px; display: block;
  background: #fff; border: 1px dashed #c9cad2; border-radius: 8px;
  touch-action: none; cursor: crosshair;
}
.esign-canvas-hint {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  color: #b9bac4; font-size: 13px; pointer-events: none; user-select: none;
}
.esign-canvas-foot { display: flex; justify-content: flex-end; margin-top: 4px; }

/* Consent + errors */
.esign-consent {
  display: flex; gap: 9px; align-items: flex-start;
  font-size: 12.5px; line-height: 1.5; color: #1a1a1f;
  cursor: pointer; margin-bottom: 16px;
}
.esign-consent input { margin-top: 2px; flex-shrink: 0; accent-color: #4f46e5; }
.esign-err { color: #b3261e; font-size: 12.5px; margin-bottom: 12px; }

/* Comments */
.esign-comment { padding: 8px 0; border-bottom: 1px solid #eef0f3; }
.esign-comment:last-of-type { border-bottom: none; }
.esign-comment-meta { font-size: 12.5px; }
.esign-comment-meta .who { font-weight: 600; }
.esign-comment-meta .when { color: #8a8a94; margin-left: 8px; }
.esign-comment-body { font-size: 13.5px; margin-top: 3px; white-space: pre-wrap; }
.esign-comment-row { display: flex; gap: 8px; }
.esign-comment-row .esign-input { flex: 1; }

/* Change requests (negotiation round-trip) — distinct amber treatment */
.esign-comment.change { border-left: 3px solid #d97706; padding-left: 10px; background: #fffbf4; border-radius: 0 6px 6px 0; }
.esign-change-tag {
  display: inline-block; margin-left: 8px; padding: 1px 7px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.3px; text-transform: uppercase;
  color: #b45309; background: #fef3c7; border: 1px solid #fcd9a0; border-radius: 999px;
  vertical-align: middle;
}
.esign-btn-change {
  border-color: #d97706 !important; background: #d97706 !important; color: #fff !important;
}
.esign-btn-change:hover:not(:disabled) { border-color: #b45309 !important; background: #b45309 !important; }
.esign-changes-banner {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px 12px; margin-bottom: 12px;
  background: #fffbf4; border: 1px solid #fcd9a0; border-radius: 8px;
  color: #92400e; font-size: 12.5px; line-height: 1.5;
}
.esign-changes-banner svg { flex: 0 0 auto; margin-top: 1px; }

/* Loading / error / done states */
.esign-state { text-align: center; padding: 50px 22px; }
.esign-state-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.esign-state-body { color: #565663; font-size: 13.5px; max-width: 440px; margin: 0 auto; }
.esign-state-note { color: #8a8a94; font-size: 12.5px; margin-top: 14px; }
.esign-done-badge {
  width: 54px; height: 54px; border-radius: 50%;
  background: #1e8a4c; color: #fff;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 16px;
}
.esign-spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2.5px solid #e3e4ea; border-top-color: #4f46e5;
  animation: esign-spin 0.8s linear infinite;
  display: inline-block; vertical-align: middle;
}
@keyframes esign-spin { to { transform: rotate(360deg); } }
.esign-sign-btn .esign-spinner { width: 15px; height: 15px; border-width: 2px; border-color: rgba(255,255,255,0.35); border-top-color: #fff; }

.esign-foot { text-align: center; color: #8a8a94; font-size: 11.5px; margin-top: 18px; line-height: 1.6; }

/* Phone — the sign link is a public URL people open on phones; the platform
   mobile gate is lifted for #sign (see Aecos.html allow-mobile), so this page
   must stand on its own at narrow widths. */
@media (max-width: 560px) {
  .esign-wrap { padding: 18px 12px 56px; }
  .esign-title { font-size: 19px; }
  .esign-doc-frame { height: 62vh; }
  .esign-sections { padding: 16px 16px; }
  .esign-input-script { font-size: 24px; }
}
/* Bigger draw target for fingers */
@media (pointer: coarse) {
  .esign-canvas { height: 200px; }
  .esign-tab, .esign-btn { padding-top: 9px; padding-bottom: 9px; }
}
@media (prefers-reduced-motion: reduce) {
  .esign-spinner { animation-duration: 1.6s; }
}

/* Phase 2D — signer-side sign-at-fields. Same fixed LIGHT palette as every
   other .esign-* rule (client-facing legal page, theme-proof). v1 renders the
   signer's fields as a checklist of capture controls (flow "Signature block"
   and page-coordinate fields alike). */
.esign-field-panel-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.esign-field-progress {
  font-size: 12px; font-weight: 600; color: #4f46e5;
  background: #eef0fb; border: 1px solid #dfe2f7; border-radius: 999px; padding: 2px 10px; white-space: nowrap;
}
.esign-fields { display: flex; flex-direction: column; gap: 12px; margin-bottom: 16px; }
.esign-field-row {
  border: 1px solid #e3e4ea; border-radius: 10px; padding: 12px 14px; background: #fcfcfd;
}
.esign-field-row.done { border-color: #bfe3cd; background: #f6fbf8; }
.esign-field-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap;
}
.esign-field-num {
  width: 20px; height: 20px; flex-shrink: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700; color: #565663;
  background: #eceef2; border: 1px solid #dcdee5;
}
.esign-field-row.done .esign-field-num { color: #fff; background: #1e8a4c; border-color: #1e8a4c; }
.esign-field-label { font-size: 13.5px; font-weight: 600; color: #1a1a1f; }
.esign-field-req { color: #b3261e; font-weight: 700; }
.esign-field-where {
  margin-left: auto; font-size: 11.5px; color: #8a8a94;
  background: #f2f3f6; border-radius: 6px; padding: 1px 8px; white-space: nowrap;
}
.esign-field-ctl .esign-input { margin-bottom: 0; }
.esign-field-ctl .esign-tabs { margin-bottom: 8px; }

/* ── Share-for-review redlining (cr-*) — contract-review.jsx ────────────────
   Guest page rides the .esign-* light "paper" shell; these classes add the
   two-column layout, the floating redline toolbar, the text marks, and the
   annotation rail. Fixed light palette on purpose (scoped under .esign-page). */
.cr-wrap { max-width: 1080px; }
.cr-layout { display: flex; gap: 18px; align-items: flex-start; }
.cr-main { flex: 1 1 auto; min-width: 0; }
.cr-rail { flex: 0 0 300px; position: sticky; top: 14px; }
.cr-rail-card { display: flex; flex-direction: column; }
.cr-rail-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.cr-rail-count {
  margin-left: auto; font-size: 11.5px; font-weight: 700; color: #4b4b55;
  background: #f2f3f6; border-radius: 999px; padding: 2px 9px; font-variant-numeric: tabular-nums;
}
.cr-howto {
  margin-top: 12px; font-size: 13px; color: #55555e; background: #f7f7f9;
  border: 1px solid #ebebef; border-radius: 8px; padding: 9px 12px; line-height: 1.55;
}
.cr-status { font-weight: 600; color: #8a6d1a; }
.cr-status.done { color: #1e8a4c; }

/* selectable doc body */
.cr-sections { cursor: text; }
.cr-sec-body { user-select: text; -webkit-user-select: text; }

/* the four mark kinds — background/underline tints on wrapped text nodes */
.cr-mark { border-radius: 2px; cursor: pointer; padding: 0 1px; margin: 0 -1px; background: transparent; color: inherit; }
.cr-mark-highlight { background: rgba(255, 213, 79, 0.45); }
.cr-mark-strikethrough { background: rgba(229, 87, 87, 0.14); text-decoration: line-through; text-decoration-color: #c62828; text-decoration-thickness: 1.5px; }
.cr-mark-suggest { background: rgba(76, 175, 110, 0.16); box-shadow: inset 0 -2px 0 #2e9e5b; }
.cr-mark-comment { background: rgba(83, 141, 236, 0.13); box-shadow: inset 0 -2px 0 0 rgba(59, 108, 212, 0.55); }
.cr-mark-accepted { outline: 1px solid rgba(46, 158, 91, 0.5); }
.cr-mark-rejected { opacity: 0.45; }
.cr-mark-flash { animation: cr-flash 1.1s ease; }
@keyframes cr-flash {
  0% { box-shadow: 0 0 0 3px rgba(59, 108, 212, 0.45); }
  100% { box-shadow: 0 0 0 3px rgba(59, 108, 212, 0); }
}

/* floating redline toolbar over an active selection */
.cr-toolbar {
  position: fixed; z-index: 80; display: flex; align-items: center; gap: 2px;
  background: #16161a; border-radius: 9px; padding: 4px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
}
.cr-tool {
  border: 0; background: transparent; color: #f2f2f4; font-size: 12.5px; font-weight: 600;
  padding: 6px 10px; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.cr-tool:hover { background: rgba(255, 255, 255, 0.12); }
.cr-tool-highlight:hover { color: #ffd54f; }
.cr-tool-strikethrough:hover { color: #ff8a80; }
.cr-tool-suggest:hover { color: #7ee2a8; }
.cr-tool-comment:hover { color: #9db9ff; }
.cr-tool-x { padding: 6px 8px; color: #9a9aa4; font-size: 14px; line-height: 1; }

/* annotation cards in the rail */
.cr-ann-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; max-height: 52vh; overflow-y: auto; }
.cr-ann {
  border: 1px solid #ebebef; border-radius: 8px; padding: 9px 11px; background: #fff;
  cursor: pointer; transition: border-color 0.12s ease, background 0.12s ease;
}
.cr-ann:hover { border-color: #d9d9e0; }
.cr-ann.active { border-color: #3b6cd4; background: #f7faff; }
.cr-ann.rejected { opacity: 0.62; }
.cr-ann-flash { animation: cr-flash 1.1s ease; }
.cr-ann-head { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.cr-ann-chip {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em; border-radius: 5px; padding: 1px 7px;
}
.cr-chip-highlight { background: rgba(255, 213, 79, 0.4); color: #7a5d00; }
.cr-chip-strikethrough { background: rgba(229, 87, 87, 0.14); color: #a12525; }
.cr-chip-suggest { background: rgba(76, 175, 110, 0.18); color: #196a3c; }
.cr-chip-comment { background: rgba(83, 141, 236, 0.14); color: #2450a5; }
.cr-ann-where { font-size: 11px; color: #8a8a94; background: #f2f3f6; border-radius: 5px; padding: 1px 7px; }
.cr-ann-res { margin-left: auto; font-size: 10.5px; font-weight: 700; border-radius: 5px; padding: 1px 7px; }
.cr-ann-res.ok { background: #e5f5eb; color: #1e8a4c; }
.cr-ann-res.no { background: #fbeaea; color: #a12525; }
.cr-ann-x {
  margin-left: auto; border: 0; background: transparent; color: #8a8a94; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 0 2px; border-radius: 4px;
}
.cr-ann-res + .cr-ann-x, .cr-ann-where + .cr-ann-x { margin-left: 4px; }
.cr-ann-x:hover { color: #a12525; background: #fbeaea; }
.cr-ann-quote { font-size: 12px; color: #55555e; font-style: italic; line-height: 1.5; margin-bottom: 4px; }
.cr-ann-proposed { font-size: 12.5px; color: #196a3c; line-height: 1.5; margin-bottom: 4px; white-space: pre-wrap; }
.cr-ann-body { font-size: 12.5px; color: #26262c; line-height: 1.5; white-space: pre-wrap; }
.cr-ann-when { font-size: 10.5px; color: #9a9aa4; margin-top: 5px; }

/* composer / return modals over the light page */
.cr-modal-veil {
  position: fixed; inset: 0; z-index: 90; display: flex; align-items: center; justify-content: center;
  background: rgba(20, 20, 24, 0.42); padding: 18px;
}
.cr-modal { width: 100%; max-width: 480px; margin: 0; box-shadow: 0 18px 60px rgba(0, 0, 0, 0.3); }
.cr-quote-preview {
  font-size: 12.5px; color: #55555e; font-style: italic; line-height: 1.5;
  background: #f7f7f9; border: 1px solid #ebebef; border-radius: 7px; padding: 8px 11px; margin-bottom: 12px;
}
.cr-textarea { resize: vertical; min-height: 74px; line-height: 1.55; }
.cr-modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 14px; align-items: center; }
.cr-btn-return { background: #16161a; color: #fff; border-color: #16161a; }
.cr-btn-return:hover:not(:disabled) { background: #2a2a30; border-color: #2a2a30; }
.cr-return-btn { margin-top: 12px; }

/* PDF-only fallback note composer */
.cr-pdfnote-row { display: flex; gap: 8px; align-items: center; }
.cr-pdfnote-row .esign-input { margin-bottom: 0; }
.cr-pdfnote-page { flex: 0 0 76px; }

@media (max-width: 900px) {
  .cr-layout { flex-direction: column; }
  .cr-rail { position: static; flex: 1 1 auto; width: 100%; }
}

/* Owner side — send-modal signer rows (contracts-editor.jsx CEEsignModal):
   flag a non-empty-but-invalid email so "why is Send disabled?" is answerable. */
.ce-esign-row-input.invalid { border-color: var(--bad); }
.ce-esign-progress { font-size: 11.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }

/* ── E-sign Phase 2A — signature-field placement (ce-fp-*) ──────────────────
   The manual placement surface inside CEEsignModal's "fields" step: toolbar +
   inspector + scrollable page canvases with a per-page overlay of draggable
   field boxes. Each box is tinted by its signatory's accent (--fp-accent, set
   inline from CE_SIGNER_COLORS). Coordinates are stored as page FRACTIONS, so
   nothing here is size-sensitive. */
.ce-fp-wrap { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.ce-fp-toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 16px; border-bottom: 1px solid var(--line); background: var(--bg-card);
  flex: 0 0 auto;
}
.ce-fp-hint { font-size: 12px; color: var(--ink-4); margin-left: auto; }
.ce-fp-inspector {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 16px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-card) 88%, var(--line));
  flex: 0 0 auto;
}
.ce-fp-req { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-2); cursor: pointer; }
.ce-fp-scroller {
  flex: 1 1 auto; min-height: 0; overflow: auto;
  padding: 20px 24px 28px;
  background: color-mix(in srgb, var(--bg-card) 82%, var(--ink) 6%);
}
.ce-fp-pagewrap { position: relative; width: fit-content; margin: 0 auto 18px; }
.ce-fp-layer { z-index: 4; }
.ce-fp-layer.ce-fp-armed { cursor: crosshair; }
.ce-fp-field {
  position: absolute; box-sizing: border-box;
  border: 1.5px solid var(--fp-accent, #3b82f6);
  background: color-mix(in srgb, var(--fp-accent, #3b82f6) 14%, transparent);
  border-radius: 3px; cursor: grab;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; touch-action: none; user-select: none;
}
.ce-fp-field:active { cursor: grabbing; }
.ce-fp-field.selected {
  border-width: 2px; z-index: 2;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--fp-accent, #3b82f6) 35%, transparent);
}
.ce-fp-field-label {
  font-size: 10.5px; font-weight: 600; color: var(--fp-accent, #3b82f6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: 0 4px; pointer-events: none;
}
.ce-fp-resize {
  position: absolute; right: -5px; bottom: -5px; width: 11px; height: 11px;
  border-radius: 3px; background: var(--fp-accent, #3b82f6); cursor: nwse-resize; touch-action: none;
}
/* flow docs — signature-block builder (checkbox cards, one per signatory) */
.ce-fp-blocks { padding: 4px 0; }
.ce-fp-block-card {
  border: 1px solid var(--line); border-left: 3px solid var(--fp-accent, var(--line));
  border-radius: 8px; padding: 10px 14px; margin-bottom: 10px; background: var(--bg-card);
}
.ce-fp-block-name { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 6px; }
.ce-fp-block-kinds { display: flex; gap: 14px; flex-wrap: wrap; }
.ce-fp-block-kind { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-2); cursor: pointer; }
/* signers-step summary card ("N fields placed" + Place/Clear buttons) */
.ce-fp-summary {
  margin-top: 16px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: 8px; background: color-mix(in srgb, var(--bg-card) 92%, var(--line));
}
/* Phase 2B — "Suggest fields (AI)" action (accented; sits in both modes) */
.ce-fp-blockwrap { display: flex; flex-direction: column; }
.ce-fp-suggestbar { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.ce-fp-suggest {
  border-color: color-mix(in srgb, var(--accent, #6366f1) 55%, var(--line));
  color: var(--accent, #6366f1);
}
.ce-fp-suggest:disabled { opacity: 0.55; cursor: default; }

/* ── Background-chat completion toasts + in-list running spinner ─────────────
   A chat's AI request keeps running when you leave it; when it finishes while
   you're elsewhere, a bottom-right toast announces it (click → go to that
   chat). The list spinner marks a chat that's still generating in the
   background. Scoped, self-contained; uses existing theme tokens. */
.cmd-bgtoast-host {
  position: fixed; right: 18px; bottom: 18px; z-index: 100000;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none; max-width: 340px;
}
.cmd-bgtoast {
  pointer-events: auto; display: flex; align-items: center; gap: 10px;
  max-width: 320px; padding: 10px 12px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--bg-card); color: var(--ink);
  box-shadow: 0 8px 28px rgba(0,0,0,.18); cursor: pointer; text-align: left;
  font: inherit; animation: cmdBgToastIn .22s ease;
}
.cmd-bgtoast:hover { border-color: var(--line-strong); }
.cmd-bgtoast:focus-visible { outline: 2px solid var(--ok); outline-offset: 2px; }
.cmd-bgtoast-ic {
  display: flex; width: 22px; height: 22px; flex-shrink: 0;
  align-items: center; justify-content: center; border-radius: 50%;
  background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok);
}
.cmd-bgtoast-err .cmd-bgtoast-ic {
  background: color-mix(in srgb, var(--bad) 18%, transparent); color: var(--bad);
}
.cmd-bgtoast-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cmd-bgtoast-title { font-size: 11px; color: var(--ink-4); line-height: 1.3; }
.cmd-bgtoast-name {
  font-size: 13px; font-weight: 600; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cmd-bgtoast-x {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  color: var(--ink-4); padding: 3px; border-radius: 6px; cursor: pointer;
}
.cmd-bgtoast-x:hover { background: var(--bg-sunk); color: var(--ink); }
@keyframes cmdBgToastIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

.cmd-run-spinner {
  flex-shrink: 0; width: 11px; height: 11px; margin-left: auto;
  border: 2px solid color-mix(in srgb, var(--ok) 30%, transparent);
  border-top-color: var(--ok); border-radius: 50%;
  animation: cmdRunSpin .7s linear infinite;
}
@keyframes cmdRunSpin { to { transform: rotate(360deg); } }

/* ── Command Center "Calendar" gadget ───────────────────────────────────────
   Compact-but-full month calendar + day agenda rendered as a reorderable /
   toggleable CC dash-block (id "calendar"). Reads the same data the Timesheets
   calendar reads (native meetings + Aecos + synced external events). */
.cc-cal { display: flex; flex-direction: column; }
.cc-cal-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px 14px; flex-wrap: wrap; padding: 14px 18px 12px;
  border-bottom: 1px solid var(--line);
}
.cc-cal-title {
  display: inline-flex; align-items: center; gap: 8px; min-width: 0;
  font-size: 15px; font-weight: 600; color: var(--ink); letter-spacing: -0.01em;
}
.cc-cal-title > svg { flex: none; color: var(--ink-4); }
.cc-cal-count {
  font-size: 11px; font-weight: 500; color: var(--ink-4);
  font-variant-numeric: tabular-nums; white-space: nowrap;
  background: var(--bg-sunk); border: 1px solid var(--line-soft);
  border-radius: var(--radius-btn); padding: 2px 9px; margin-left: 4px;
}
.cc-cal-nav { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cc-cal-navbtn { padding-left: 8px; padding-right: 8px; }
.cc-cal-open { margin-left: 2px; white-space: nowrap; }
/* Day / Week / Month segmented toggle. NOTE: no transitions on background /
   color here — those states resolve from var() tokens and this Chrome sticks
   var-valued transitions at the from-value (see CLAUDE.md gotcha). */
.cc-cal-viewtoggle {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--bg-sunk); border: 1px solid var(--line-soft);
  border-radius: var(--radius-btn); padding: 2px; margin-right: 4px;
}
.cc-cal-viewbtn {
  border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600;
  line-height: 1.3; color: var(--ink-4); padding: 4px 13px;
  border-radius: var(--radius-btn); cursor: pointer;
}
.cc-cal-viewbtn:hover { color: var(--ink-2); }
.cc-cal-viewbtn.is-active {
  background: var(--bg-card); color: var(--ink);
  box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 0 0 1px rgba(0,0,0,.04);
}
.cc-cal-viewbtn:focus-visible { outline: 2px solid var(--indigo); outline-offset: 1px; }
/* Fixed body height so the gadget keeps ONE size across Day / Week / Month.
   The grid rows equal-share this height (grid-auto-rows: 1fr), so a 5-week
   month, a 6-week month, a single week row, and the day agenda all fill the
   same box instead of resizing the card on every view switch. */
.cc-cal-body { display: flex; gap: 0; align-items: stretch; height: 420px; }
/* Day view: the agenda takes the full width (no grid). */
.cc-cal-body--day .cc-cal-agenda { flex: 1 1 auto; max-width: none; border-left: 0; padding: 16px 18px 18px; }
.cc-cal-grid-wrap { flex: 1 1 auto; min-width: 0; padding: 12px 16px 16px; display: flex; flex-direction: column; min-height: 0; }
.cc-cal-dow {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin-bottom: 6px;
}
.cc-cal-dow-cell {
  text-align: center; font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-5);
}
.cc-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; flex: 1 1 auto; grid-auto-rows: 1fr; min-height: 0; }
.cc-cal-cell {
  display: flex; flex-direction: column; gap: 4px; align-items: stretch;
  min-height: 0; padding: 6px 6px 5px; text-align: left;
  background: var(--bg-sunk); border: 1px solid var(--line-soft);
  border-radius: var(--radius-btn-icon);
  cursor: pointer; font: inherit; color: var(--ink); overflow: hidden;
}
.cc-cal-cell:hover { border-color: var(--line-strong); background: var(--bg-hover); }
.cc-cal-cell:focus-visible { outline: 2px solid var(--indigo); outline-offset: 1px; }
.cc-cal-cell.is-out { opacity: 0.45; }
.cc-cal-cell.is-today { background: var(--indigo-soft); border-color: var(--indigo-line); }
.cc-cal-cell.is-sel { border-color: var(--indigo); background: var(--bg-card); box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.cc-cal-cell.is-today.is-sel { background: var(--indigo-soft); }
/* Fixed-size day-number box so today's filled badge doesn't shift the chips. */
.cc-cal-daynum {
  align-self: flex-start; display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; padding: 0 2px; margin: -1px 0 0 -1px;
  border-radius: 50%; font-size: 11.5px; font-weight: 600; line-height: 1;
  color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.cc-cal-cell.is-today .cc-cal-daynum { background: var(--indigo); color: var(--bg); }
.cc-cal-chips { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cc-cal-chip {
  display: inline-flex; align-items: center; gap: 5px; min-width: 0;
  font-size: 10.5px; line-height: 1.35; color: var(--ink-3);
}
.cc-cal-chip-txt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.cc-cal-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; }
.cc-cal-more { font-size: 10px; color: var(--ink-5); font-weight: 500; padding-left: 11px; }

.cc-cal-agenda {
  flex: 0 0 240px; max-width: 240px; min-width: 0;
  border-left: 1px solid var(--line); padding: 14px 16px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.cc-cal-agenda-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13px; font-weight: 600; color: var(--ink);
  padding-bottom: 8px; border-bottom: 1px solid var(--line-soft);
}
.cc-cal-agenda-today {
  font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--indigo-ink); background: var(--indigo-soft);
  border-radius: var(--radius-btn); padding: 1px 8px;
}
.cc-cal-agenda-empty {
  flex: 1 1 auto; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px;
  padding: 26px 8px; color: var(--ink-5); font-size: 12px; text-align: center;
}
.cc-cal-agenda-empty > svg { color: var(--ink-5); opacity: 0.7; }
.cc-cal-agenda-list { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.cc-cal-agenda-item {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 7px 8px; border-radius: var(--radius-btn-icon);
  border: 0; background: none; cursor: pointer;
  font: inherit; text-align: left; color: var(--ink);
}
.cc-cal-agenda-item:hover { background: var(--bg-hover); }
.cc-cal-agenda-item:focus-visible { outline: 2px solid var(--indigo); outline-offset: -1px; }
.cc-cal-agenda-item .cc-cal-dot { align-self: center; }
.cc-cal-agenda-time {
  flex: none; font-size: 11px; font-weight: 600; color: var(--ink-4);
  min-width: 52px; font-variant-numeric: tabular-nums;
}
.cc-cal-agenda-name {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--ink-2);
  display: inline-flex; align-items: center; gap: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cc-cal-agenda-name > svg { flex: none; color: var(--indigo); }

@media (max-width: 900px) {
  .cc-cal-body { flex-direction: column; height: auto; }
  .cc-cal-agenda { flex-basis: auto; max-width: none; border-left: 0; border-top: 1px solid var(--line); }
}

/* ── Lawyer Agent — reference-reuse contract drafting ──────────────────────── */
.lawyer-launch { color: var(--indigo); border-color: color-mix(in srgb, var(--indigo) 40%, var(--line)); }
.lawyer-launch:hover { background: color-mix(in srgb, var(--indigo) 10%, transparent); }
.lawyer-step { display: flex; flex-direction: column; gap: 14px; }
.lawyer-intro { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.lawyer-mode { display: flex; gap: 10px; }
.lawyer-mode-btn { flex: 1; display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg-card); color: var(--ink);
  font-size: 13px; font-weight: 500; cursor: pointer; text-align: left; }
.lawyer-mode-btn:hover { background: var(--bg-hover); }
.lawyer-mode-btn.active { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 8%, var(--bg-card)); color: var(--indigo); }
.lawyer-field { display: flex; flex-direction: column; gap: 6px; }
.lawyer-field > label { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.lawyer-hint { font-size: 11.5px; color: var(--ink-3); }
.lawyer-file-name { display: inline-flex; align-items: center; gap: 6px; margin-left: 10px; font-size: 12.5px; color: var(--ink-2); }
.lawyer-newfields { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  padding: 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg-card); }
.lawyer-review-head { font-size: 13px; line-height: 1.5; color: var(--ink); }
.lawyer-note { display: flex; align-items: flex-start; gap: 6px; margin-top: 6px; font-size: 12px;
  color: var(--ink-2); }
.lawyer-note.tone-warn { color: var(--warn); }
.lawyer-group { display: flex; flex-direction: column; gap: 6px; }
.lawyer-group-head { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-3); margin-top: 6px; }
.lawyer-var { display: flex; gap: 10px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 9px; background: var(--bg-card); }
.lawyer-var.is-off { opacity: 0.55; }
.lawyer-var.is-missing { border-color: color-mix(in srgb, var(--bad) 40%, var(--line)); }
.lawyer-var-inc { display: flex; align-items: flex-start; padding-top: 2px; }
.lawyer-var-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.lawyer-var-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lawyer-var-label { font-size: 13px; font-weight: 600; color: var(--ink); }
.lawyer-var-badge { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  padding: 1px 6px; border-radius: 999px; }
.lawyer-var-badge.tone-warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 15%, transparent); }
.lawyer-var-badge.tone-bad { color: var(--bad); background: color-mix(in srgb, var(--bad) 15%, transparent); }
.lawyer-var-occ { font-size: 11px; color: var(--ink-3); font-family: var(--mono); }
.lawyer-var-desc { font-size: 12px; color: var(--ink-3); line-height: 1.4; }
.lawyer-var-io { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.lawyer-var-from { display: flex; flex-direction: column; min-width: 0; max-width: 260px; }
.lawyer-var-from-lbl { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-4); }
.lawyer-var-from-val { font-size: 12.5px; color: var(--ink-2); font-family: var(--mono);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lawyer-var-input { flex: 1; min-width: 160px; padding: 7px 10px; border: 1px solid var(--line);
  border-radius: var(--radius-btn, 8px); background: var(--bg); color: var(--ink); font-size: 13px; }
.lawyer-var-input:focus { outline: none; border-color: var(--indigo); }
.lawyer-var-input:disabled { opacity: 0.5; }
.lawyer-legal { display: flex; align-items: flex-start; gap: 8px; margin-top: 4px; padding: 10px 12px;
  border-radius: 9px; background: var(--bg-hover); font-size: 11.5px; line-height: 1.45; color: var(--ink-3); }
.lawyer-error { display: flex; align-items: center; gap: 7px; padding: 9px 12px; border-radius: 8px;
  background: color-mix(in srgb, var(--bad) 12%, transparent); color: var(--bad); font-size: 12.5px; }
.lawyer-empty { padding: 20px; text-align: center; font-size: 13px; color: var(--ink-3);
  border: 1px dashed var(--line); border-radius: 10px; }
.lawyer-loading { align-items: center; text-align: center; padding: 34px 20px; gap: 14px; }
.lawyer-loading-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.lawyer-loading-sub { font-size: 12.5px; color: var(--ink-3); }
.lawyer-spinner { width: 30px; height: 30px; border-radius: 50%;
  border: 3px solid color-mix(in srgb, var(--indigo) 25%, transparent); border-top-color: var(--indigo);
  animation: lawyer-spin 0.8s linear infinite; }
@keyframes lawyer-spin { to { transform: rotate(360deg); } }
.lawyer-done { align-items: center; text-align: center; padding: 18px; gap: 8px; }
.lawyer-done-icon { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; background: color-mix(in srgb, var(--good) 18%, transparent); color: var(--good); }
.lawyer-done-title { font-size: 16px; font-weight: 700; color: var(--ink); }
.lawyer-done-sub { font-size: 13px; color: var(--ink-2); }
.lawyer-foot-count { font-size: 12px; color: var(--ink-3); margin-right: 10px; }
@media (max-width: 640px) { .lawyer-newfields { grid-template-columns: 1fr; } }

/* ===== SR CSS recovery (rules dropped in reformatting commit d9543a35; restored 2026-07-18) ===== */
@keyframes sr-folder-snap {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.016); }
  100% { transform: scale(1); }
}
@keyframes sr-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}
@keyframes sr-ai-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes sr-actions-item-in {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: translateX(0); }
}

.sr-zoom-indicator {
position:absolute; left:12px; z-index:10; background:var(--bg-elev); border:1px solid var(--line); border-radius:4px; padding:2px 8px; font-size:11px; color:var(--ink-2); cursor:pointer; user-select:none; font-family:var(--f-mono,monospace); transition: color 0.1s, border-color 0.1s;
}
.sr-zoom-indicator:hover {
color:var(--ink-1); border-color:var(--indigo,#6366f1);
}
.sr-minimap {
position: absolute;
  right: 12px;
  bottom: 52px;
  z-index: 10;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 14px rgba(0,0,0,0.32), 0 0 0 1px rgba(255,255,255,0.07);
  cursor: crosshair;
  user-select: none;
  background: var(--bg-card);
  opacity: 0.82;
  transition: opacity 0.15s;
}
.sr-minimap:hover {
opacity: 1;
}
.sr-dash-empty {
display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 48px 24px; color: var(--ink-4); text-align: center;
}
.sr-dash-empty-title {
font-size: 13px; color: var(--ink-2); margin: 0;
}
.sr-files-tab {
display: flex; flex-direction: column; height: 100%;
}
.sr-files-tab.dragging {
user-select: none; cursor: grabbing !important;
}
.sr-files-search {
display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-bottom: 1px solid var(--line-soft); flex-shrink: 0;
}
.sr-files-search input {
flex: 1; border: none; background: none; outline: none;
  font-size: 11.5px; color: var(--ink-2);
}
.sr-files-search input::placeholder {
color: var(--ink-5);
}
.sr-files-search-count {
font-size: 10px; color: var(--ink-5); white-space: nowrap; font-family: var(--f-mono);
}
.sr-folder-drop-line {
height: 2px; background: transparent;
  margin: 0 8px; border-radius: 1px; transition: background 0.08s;
}
.sr-folder-drop-line.active {
background: var(--indigo);
}
.sr-folder-chevron {
transition: transform 0.18s cubic-bezier(0,0,0.2,1); flex-shrink: 0;
}
.sr-folder-chevron.open {
transform: rotate(90deg);
}
.sr-folder-children {
display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.2s cubic-bezier(0,0,0.2,1);
}
.sr-folder-children.open {
grid-template-rows: 1fr;
}
.sr-folder-children-inner {
overflow: hidden; min-height: 0;
}
.sr-folder-snap {
animation: sr-folder-snap 0.22s cubic-bezier(0.34,1.56,0.64,1);
}
.sr-files-grid {
display: grid;
  grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 7px; padding: 8px 10px;
}
.sr-file-card {
border: 1px solid var(--line); border-radius: 7px; overflow: hidden;
  background: var(--bg-card); cursor: grab;
  transition: border-color 0.1s, box-shadow 0.1s;
}
.sr-file-card:hover {
border-color: var(--indigo-line); box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.sr-file-card-thumb {
height: 64px; background: var(--bg-sunk);
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid var(--line-soft);
}
.sr-file-card-body {
padding: 6px 7px 7px;
}
.sr-file-card-name {
font-size: 10.5px; font-weight: 500; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 2px;
}
.sr-file-card-meta {
font-size: 9.5px; color: var(--ink-5);
}
.sr-empty-state {
display: flex; flex-direction: column; align-items: center;
  gap: 6px; padding: 36px 20px 28px; text-align: center;
}
.sr-empty-state-title {
font-size: 13px; font-weight: 600; color: var(--ink-3);
}
.sr-empty-state-sub {
font-size: 11.5px; color: var(--ink-5); line-height: 1.5;
}
.sr-shimmer-line {
height: 11px; border-radius: 6px; margin-bottom: 7px;
  background: linear-gradient(90deg, var(--line-soft) 25%, var(--bg-hover) 50%, var(--line-soft) 75%);
  background-size: 800px 100%;
  animation: sr-shimmer 1.4s ease infinite;
}
.sr-ai-summary-card {
margin: 8px 12px 4px; flex-shrink: 0;
  background: var(--bg-elev);
  border: 1px solid var(--indigo-line);
  border-radius: 10px; padding: 11px 13px;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--indigo) 6%, transparent),
              inset 0 1px 0 color-mix(in oklab, white 6%, transparent);
  opacity: 0;
}
.sr-ai-summary-card.visible {
animation: sr-ai-fade-in 0.25s cubic-bezier(0,0,0.2,1) forwards;
}
.sr-ai-summary-card-head {
display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 600; color: var(--indigo); margin-bottom: 8px;
}
.sr-ai-badge {
font-size: 8.5px; font-weight: 700; letter-spacing: 0.05em;
  padding: 1px 5px; border-radius: 3px;
  background: color-mix(in oklab, var(--indigo) 10%, transparent);
  color: var(--indigo); text-transform: uppercase; margin-left: 2px;
}
.sr-ai-icon-btn {
background: none; border: none; cursor: pointer;
  color: var(--ink-4); padding: 2px 4px; border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 0.1s, color 0.1s;
}
.sr-ai-icon-btn:hover {
background: var(--bg-hover); color: var(--ink-2);
}
.sr-ai-icon-btn:disabled {
opacity: 0.4; cursor: wait;
}
.sr-ai-summary-text {
font-size: 12px; line-height: 1.7; color: var(--ink-2);
  max-width: 100%; hyphens: auto;
}
.sr-ai-summary-footer {
margin-top: 9px; padding-top: 7px;
  border-top: 1px solid var(--line-soft);
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; color: var(--ink-5);
}
.sr-ai-summary-collapsed {
margin: 6px 12px 0; padding: 5px 10px;
  background: color-mix(in oklab, var(--indigo) 7%, transparent);
  border: 1px solid var(--indigo-line); border-radius: 20px;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 500; color: var(--indigo);
  cursor: pointer; transition: background 0.1s;
  flex-shrink: 0; width: fit-content;
}
.sr-ai-summary-collapsed:hover {
background: color-mix(in oklab, var(--indigo) 13%, transparent);
}
.sr-ai-onboarding-tip {
margin-bottom: 9px; padding: 7px 9px;
  background: color-mix(in oklab, var(--indigo) 8%, transparent);
  border: 1px dashed var(--indigo-line); border-radius: 6px;
  font-size: 11px; color: var(--ink-3); line-height: 1.5;
  cursor: pointer; display: flex; align-items: flex-start; gap: 6px;
  transition: background 0.1s;
}
.sr-ai-onboarding-tip:hover {
background: color-mix(in oklab, var(--indigo) 12%, transparent);
}
.sr-ai-category-pill {
display: inline-flex; align-items: center;
  font-size: 9px; font-weight: 700; padding: 1px 6px;
  border-radius: 4px; cursor: pointer; flex-shrink: 0; letter-spacing: 0.02em;
  transition: filter 0.1s;
}
.sr-ai-category-pill:hover {
filter: brightness(0.92);
}
.sr-ai-cat-edited {
width: 5px; height: 5px; border-radius: 50%;
  background: var(--ink-5); flex-shrink: 0; display: inline-block;
  margin-left: 3px; vertical-align: middle;
}
.sr-ai-actions-panel {
padding: 8px 12px 10px; margin: 0 12px 4px;
  background: var(--bg-sunk); border-radius: 0 0 7px 7px;
  border: 1px solid var(--line-soft); border-top: none;
  font-size: 11px; color: var(--ink-3); line-height: 1.6;
  overflow: hidden;
}
.sr-ai-actions-item {
display: flex; gap: 7px; align-items: baseline;
  padding: 2px 0;
  animation: sr-actions-item-in 0.18s cubic-bezier(0,0,0.2,1) both;
}
.sr-ai-actions-checkbox {
width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0;
  border: 1.5px solid var(--line-strong); cursor: pointer;
  background: var(--bg-card); display: inline-flex; align-items: center;
  justify-content: center; transition: background 0.1s, border-color 0.1s;
  margin-top: 2px;
}
.sr-ai-actions-checkbox.done {
background: var(--indigo); border-color: var(--indigo);
}
.sr-ai-actions-item-text.done {
text-decoration: line-through; color: var(--ink-5);
}
.sr-hl-blend-toggle {
display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--ink-2); cursor: pointer;
}
.sr-layer-list {
display: flex; flex-direction: column; gap: 2px; padding: 6px;
}
.sr-layer-row {
display: flex; align-items: center; gap: 4px; padding: 4px 6px; border-radius: 4px; cursor: pointer; user-select: none;
}
.sr-layer-row:hover {
background: var(--bg-hover, rgba(255,255,255,0.06));
}
.sr-layer-row.sr-layer-active {
background: var(--indigo, #6366f1) !important; color: #fff;
}
.sr-layer-icon-btn {
background: none; border: none; padding: 1px; cursor: pointer; color: inherit; opacity: 0.7; display: flex; align-items: center;
}
.sr-layer-icon-btn:hover {
opacity: 1;
}
.sr-layer-color {
width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; cursor: pointer; border: 1px solid rgba(255,255,255,0.2);
}
.sr-layer-label {
flex: 1; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sr-layer-active-dot {
width: 6px; height: 6px; border-radius: 50%; background: #fff; flex-shrink: 0;
}
.sr-layer-add-btn {
margin: 4px 6px 0; padding: 4px 8px; font-size: 11px; border: 1px dashed var(--line); border-radius: 4px; background: none; cursor: pointer; color: var(--ink-2); width: calc(100% - 12px);
}
.sr-layer-add-btn:hover {
background: var(--bg-hover);
}
.sr-groups-section {
border-top: 1px solid var(--line); padding: 6px;
}
.sr-groups-header {
font-size: 10px; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.05em; padding: 2px 0 4px;
}
.sr-group-row {
border-radius: 4px; overflow: hidden; margin-bottom: 2px;
}
.sr-group-header {
display: flex; align-items: center; gap: 4px; padding: 4px 6px; cursor: pointer; font-size: 12px; background: var(--bg-elev);
}
.sr-group-header:hover {
background: var(--bg-hover);
}
.sr-group-chevron {
font-size: 10px; color: var(--ink-3); width: 10px; flex-shrink: 0;
}
.sr-group-name {
flex: 1; color: var(--ink-1);
}
.sr-group-child-row {
padding: 3px 6px 3px 22px; font-size: 11px; color: var(--ink-3); border-top: 1px solid var(--line); background: var(--bg-sunk);
}
.sr-group-child-kind {
text-transform: capitalize;
}
.sr-author-filter {
padding: 8px 10px; border-top: 1px solid var(--line);
}
.sr-layer-section-label {
font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;
}
.sr-author-filter-clear {
font-size: 9px; color: var(--indigo, #6366f1); background: none; border: none; cursor: pointer; padding: 0;
}
.sr-author-filter-clear:hover {
text-decoration: underline;
}
.sr-author-row {
display: flex; align-items: center; gap: 6px; padding: 3px 0; cursor: pointer; font-size: 11px; color: var(--ink-1);
}
.sr-author-row.dimmed {
opacity: 0.4;
}
.sr-author-name {
flex: 1;
}
.sr-author-row:hover { color: var(--ink); }
.sr-author-row input[type="checkbox"] { accent-color: var(--indigo); }

/* ── SR Approvals panel (native Aecos restyle 2026-07-18 — the .sr-approv*
   rules were lost in the d9543a35 styles.css regression; rebuilt on the
   card/pill token system rather than recovered) ─────────────────────────── */
.sr-panel-empty {
  padding: 20px 12px; text-align: center; color: var(--ink-5); font-size: 11px;
  line-height: 1.5;
}
.sr-approval-panel {
  display: flex; flex-direction: column; gap: 8px; padding: 10px;
}
.sr-approval-header {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 0 2px;
}
.sr-approval-title {
  font-size: 11px; font-weight: 700; color: var(--ink-2);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.sr-approval-badge {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.04em;
  padding: 2px 9px; border-radius: var(--radius-btn);
}
.sr-approval-badge.approved {
  background: color-mix(in srgb, var(--ok, #059669) 12%, transparent);
  color: var(--ok, #059669);
  border: 1px solid color-mix(in srgb, var(--ok, #059669) 30%, transparent);
}
.sr-approver-row {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-card, 10px); padding: 8px 10px;
  display: flex; flex-direction: column; gap: 6px;
  transition: border-color 0.12s, background 0.12s;
}
.sr-approver-row.approved { border-color: color-mix(in srgb, var(--ok, #059669) 35%, var(--line)); }
.sr-approver-row.rejected { border-color: color-mix(in srgb, var(--bad, #dc2626) 35%, var(--line)); }
.sr-approver-header {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  cursor: pointer; min-width: 0;
}
.sr-approver-row.approved .sr-approver-header,
.sr-approver-row.rejected .sr-approver-header { cursor: default; }
.sr-approver-name { font-size: 12px; font-weight: 600; color: var(--ink); }
.sr-approver-status { display: flex; align-items: center; gap: 5px; flex-shrink: 0; }
.sr-approver-date { font-size: 10px; color: var(--ink-4); font-family: var(--f-mono); }
.sr-approver-pending-label {
  font-size: 9.5px; font-weight: 600; color: var(--ink-4);
  border: 1px solid var(--line); border-radius: var(--radius-btn); padding: 1px 8px;
}
.sr-approver-rejected-label {
  font-size: 9.5px; font-weight: 700; color: var(--bad, #dc2626);
  background: color-mix(in srgb, var(--bad, #dc2626) 10%, transparent);
  border-radius: var(--radius-btn); padding: 1px 8px;
}
.sr-approver-sig-preview {
  background: var(--bg-elev); border: 1px dashed var(--line);
  border-radius: 8px; padding: 4px 8px; align-self: flex-start;
}
.sr-sig-img { max-height: 44px; max-width: 100%; display: block; }
.sr-approver-reject-reason {
  font-size: 11px; color: var(--ink-3); line-height: 1.45;
  background: color-mix(in srgb, var(--bad, #dc2626) 6%, var(--bg-elev));
  border-radius: 8px; padding: 6px 9px;
}
.sr-approver-expand {
  border-top: 1px solid var(--line-soft); padding-top: 8px;
  display: flex; flex-direction: column; gap: 6px;
}
.sr-sigpad-label { font-size: 11px; color: var(--ink-3); margin: 0; }
.sr-sigpad-wrap { display: flex; flex-direction: column; gap: 7px; }
.sr-sigpad-canvas {
  width: 100%; height: 100px; background: var(--bg-elev);
  border: 1px dashed var(--line-strong); border-radius: 8px; cursor: crosshair;
}
.sr-sigpad-actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.sr-reject-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px;
  background: var(--bg-elev); color: var(--ink); font-size: 12px;
  font-family: inherit; line-height: 1.45; outline: none;
}
.sr-reject-input:focus { border-color: var(--indigo); }
.sr-approve-session-btn {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; padding: 7px 12px; margin-top: 2px;
  border: none; border-radius: var(--radius-btn); cursor: pointer;
  background: var(--ok, #059669); color: #fff; font-size: 12px; font-weight: 600;
  transition: filter 0.12s;
}
.sr-approve-session-btn:hover { filter: brightness(1.08); }

/* ── SR Review Tools panel — armable saved presets ───────────────────────── */
.sr-review-tool-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-card, 10px); padding: 7px 10px; margin-bottom: 6px;
  cursor: pointer; text-align: left; font-family: inherit;
  transition: border-color 0.12s, background 0.12s;
}
.sr-review-tool-row:hover:not(:disabled) { background: var(--bg-hover); border-color: var(--line-strong); }
.sr-review-tool-row:disabled { opacity: 0.5; cursor: not-allowed; }
.sr-review-tool-row.armed {
  border-color: var(--indigo);
  background: var(--indigo-soft);
}
.sr-review-tool-dot {
  width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
.sr-review-tool-info { display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 1px; }
.sr-review-tool-name {
  font-size: 11.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sr-review-tool-kind { font-size: 9.5px; color: var(--ink-4); text-transform: capitalize; }
.sr-review-tool-armed {
  font-size: 9px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--indigo); background: var(--bg-card);
  border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 30%, transparent));
  border-radius: var(--radius-btn); padding: 2px 8px; flex-shrink: 0;
}

/* ── SR Measurements — sheet-scale calibration card ──────────────────────── */
.sr-scale-card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius-card, 10px); padding: 10px 11px;
  display: flex; flex-direction: column; gap: 7px;
}
.sr-scale-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sr-scale-card-title {
  font-size: 10px; font-weight: 700; color: var(--ink-3);
  letter-spacing: 0.05em; text-transform: uppercase;
}
.sr-scale-badge {
  font-size: 9.5px; font-weight: 700; padding: 2px 9px;
  border-radius: var(--radius-btn); font-family: var(--f-mono); white-space: nowrap;
}
.sr-scale-badge.set {
  color: var(--indigo);
  background: var(--indigo-soft);
  border: 1px solid var(--indigo-line, color-mix(in srgb, var(--indigo) 28%, transparent));
}
.sr-scale-badge.unset {
  color: var(--ink-4); border: 1px dashed var(--line-strong); background: none;
}
.sr-scale-card-body { font-size: 10.5px; color: var(--ink-3); line-height: 1.5; }

/* ── SR chat panel — drag-to-resize handle (right edge of docked panel) ──── */
.sr-chat-resize-handle {
  position: absolute; top: 0; right: -3px; width: 7px; height: 100%;
  cursor: col-resize; z-index: 30; touch-action: none;
}
.sr-chat-resize-handle::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 3px; width: 1px;
  background: transparent; transition: background 0.12s;
}
.sr-chat-resize-handle:hover::after,
.sr-chat-resize-handle:active::after { background: var(--indigo); }
.sr-nav-badge {
position: absolute; top: 2px; right: 2px; min-width: 14px; height: 14px; border-radius: 7px; background: var(--indigo,#6366f1); color: #fff; font-size: 8px; font-weight: 700; display: flex; align-items: center; justify-content: center; padding: 0 2px; pointer-events: none;
}
.sr-snap-controls {
display: flex; align-items: center; gap: 4px;
}
.sr-swipe-zone {
display: none;
}
.sr-files-subtabs {
display:flex; gap:0; border-bottom:1px solid var(--line); flex-shrink:0;
}
.sr-files-subtabs button {
flex:1; padding:5px; font-size:11px; border:none; background:none; cursor:pointer; color:var(--ink-3); border-bottom:2px solid transparent; transition:color 0.12s;
}
.sr-files-subtabs button.active {
color:var(--indigo,#6366f1); border-bottom-color:var(--indigo,#6366f1);
}
.sr-files-subtabs button:hover:not(.active) {
color:var(--ink-2);
}
.sr-revisions-list {
overflow-y:auto; flex:1 1 0;
}
.sr-rev-row {
display:flex; align-items:center; justify-content:space-between; padding:7px 10px; border-bottom:1px solid var(--line); gap:8px;
}
.sr-rev-row.archived {
opacity:0.65;
}
.sr-rev-info {
display:flex; flex-direction:column; gap:2px; min-width:0; flex:1;
}
.sr-rev-name {
font-size:12px; font-weight:500; color:var(--ink-1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.sr-rev-meta {
font-size:10px; color:var(--ink-3);
}
.sr-rev-actions {
display:flex; gap:4px; flex-shrink:0;
}
.sr-upload-replace-banner {
background:var(--bg-sunk); border-radius:4px; padding:8px 10px; margin-bottom:10px; font-size:12px; color:var(--ink-2);
}
.sr-upload-radio-label {
display:flex; align-items:center; gap:6px; margin-top:6px; cursor:pointer; font-size:11.5px; color:var(--ink-2);
}
.sr-upload-radio-label input[type="radio"] {
accent-color:var(--indigo); cursor:pointer;
}
.sr-diff-box {
position:absolute; border:2px solid; border-radius:2px; pointer-events:auto;
}
.sr-radio-group {
display:flex; flex-direction:column; gap:4px; margin-top:4px;
}
.sr-radio-label {
display:flex; align-items:center; gap:6px; font-size:12px; color:var(--ink-1); cursor:pointer;
}
.sr-radio-label input {
accent-color:var(--indigo,#6366f1); cursor:pointer;
}
.sr-field-label {
display:block; font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:var(--ink-4); margin-bottom:4px;
}
.sr-field-hint {
font-size:11px; color:var(--ink-4); margin:0;
}

@media (prefers-reduced-motion: reduce) {
.sr-folder-chevron {
transition: none;
}
.sr-folder-children {
transition: none;
}
.sr-folder-drop-line {
transition: none;
}
.sr-folder-snap {
animation: none;
}
.sr-shimmer-line {
animation: none; opacity: 0.5;
}
.sr-ai-summary-card.visible {
animation: none;
}
.sr-ai-actions-item {
animation: none !important; opacity: 1 !important;
}
}

/* ── Studio Review markup-entrance / label animations ─────────────────────────
   These keyframes previously lived only in the DEMO route's inline <style>
   block (studio-review.jsx), so markups/labels animated in the landing demo
   but referenced undefined animations in the real workspace. Copied here so
   they work everywhere (2026-07-18, sweep item #17). */
@keyframes srMkupEnter {
from { opacity:0; transform:scale(0.88); }
to   { opacity:1; transform:scale(1); }
}
@keyframes srLabelFadeIn {
from { opacity:0; }
to   { opacity:1; }
}
.sr-mk-label { cursor:pointer; }
.sr-mk-label:hover text {
text-decoration:underline;
text-decoration-color:currentColor;
text-underline-offset:2px;
text-decoration-thickness:1px;
}
@keyframes srDemoPulseRing {
0%, 100% { opacity:0.72; stroke-width:2.5; }
50%       { opacity:0.12; stroke-width:4.5; }
}
@media (prefers-reduced-motion: reduce) {
.sr-mk-label, [style*="srMkupEnter"], [style*="srDemoPulseRing"] { animation: none !important; }
}

/* ── AddMemberChoiceModal cards (ui.jsx .amw-choice-card) ─────────────────────
   Hover/focus affordance. The component sets border/background inline, so the
   hover overrides need !important to win over the inline shorthand. */
.amw-choice-card:hover {
border-color: var(--indigo-line, var(--indigo)) !important;
background: var(--bg-hover, var(--bg-elev)) !important;
}
.amw-choice-card:focus-visible {
outline: 2px solid var(--indigo);
outline-offset: 2px;
}

/* ── Location autocomplete (event/meeting modals) ────────────────────────────
   Suggestion list under the Location input. Absolutely positioned inside the
   field wrapper (position:relative) and above the modal body's own stacking. */
.ts-loc-suggest {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 40;
  margin-top: 4px;
  max-height: 240px;
  overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.ts-loc-suggest-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 8px 10px;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line-soft, var(--line));
  cursor: pointer;
  color: var(--ink);
}
.ts-loc-suggest-item:last-child { border-bottom: 0; }
.ts-loc-suggest-item:hover,
.ts-loc-suggest-item:focus-visible {
  background: color-mix(in srgb, var(--indigo) 8%, transparent);
}
.ts-loc-suggest-name { font-size: 13px; font-weight: 600; line-height: 1.3; }
.ts-loc-suggest-addr { font-size: 11.5px; color: var(--ink-5); line-height: 1.3; }

/* Deep-link focus pulse — window.AECOS_focusAnchor rings the exact control a
   link/action pointed at (data-nav-anchor). Theme-safe (uses --indigo). */
.nav-anchor-pulse { animation: navAnchorPulse 2.4s cubic-bezier(.25,.8,.35,1) both; border-radius: 10px; position: relative; z-index: 1; }
@keyframes navAnchorPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--indigo, #4f46e5) 55%, transparent); }
  12%  { box-shadow: 0 0 0 4px color-mix(in srgb, var(--indigo, #4f46e5) 60%, transparent), 0 0 0 9px color-mix(in srgb, var(--indigo, #4f46e5) 22%, transparent); }
  70%  { box-shadow: 0 0 0 4px color-mix(in srgb, var(--indigo, #4f46e5) 45%, transparent), 0 0 0 9px color-mix(in srgb, var(--indigo, #4f46e5) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONTRACTORS — Office → Contractors tab (contractors.jsx)
   Two families:
     .ctr-editor / .ctr-split*   the full-bleed split-pane editors (W-9, 1099).
                                 Layout copied from InvoiceEditor, which carries
                                 its geometry INLINE and leaves only a mobile
                                 hook class; here the geometry is real CSS so a
                                 rule exists for every class the JSX emits.
     .ctr-paper*                 the "paper" being filled in on the right.
                                 A FIXED LIGHT palette, like .esign-page: these
                                 are tax documents that get printed and emailed,
                                 and dark-mode paper reads as a bug.
   ═══════════════════════════════════════════════════════════════════════════ */

/* the tab shell */
.ctr-tab { display: flex; flex-direction: column; gap: 16px; }
.ctr-tab-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.ctr-tab-title { font-size: 15px; font-weight: 650; color: var(--ink-1); }
.ctr-tab-sub {
  font-size: 12.5px; color: var(--ink-3); line-height: 1.6;
  max-width: 620px; margin-top: 4px;
}
.ctr-layout {
  display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
  gap: 18px; align-items: start;
}
@media (max-width: 900px) { .ctr-layout { grid-template-columns: 1fr; } }

.ctr-list { display: flex; flex-direction: column; gap: 6px; }
.ctr-row {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 10px 12px; border: 1px solid var(--line);
  border-radius: var(--radius-btn-icon); background: var(--bg-card);
  color: inherit; font: inherit;
}
.ctr-row:hover { border-color: var(--line-strong); }
.ctr-row.on { border-color: var(--indigo); background: var(--bg-sunk); }
.ctr-row-name { font-size: 13px; font-weight: 600; color: var(--ink-1); }
.ctr-row-meta { font-size: 11.5px; color: var(--ink-4); margin-top: 2px; }
.ctr-row-tin { font-size: 11.5px; color: var(--ink-3); margin-top: 4px; }
.ctr-row-tin.missing { color: var(--warn); }

.ctr-detail { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.ctr-detail-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}
.ctr-detail-name { font-size: 16px; font-weight: 650; color: var(--ink-1); }
.ctr-detail-meta { font-size: 12px; color: var(--ink-3); margin-top: 3px; }

.ctr-panel {
  border: 1px solid var(--line); border-radius: var(--radius-card);
  background: var(--bg-card); padding: 14px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.ctr-panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 11px; font-weight: 650; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4);
}
.ctr-item {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-2);
  padding: 6px 0; border-top: 1px solid var(--line-soft);
}
.ctr-item-main { flex: 1 1 auto; min-width: 0; }
.ctr-badge {
  display: inline-block; font-size: 10.5px; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 2px 7px; border-radius: var(--radius-btn);
  background: var(--bg-sunk); color: var(--ink-3); border: 1px solid var(--line);
}
.ctr-badge--signed,
.ctr-badge--issued { color: var(--ok); border-color: var(--ok); }
.ctr-badge--sent { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.ctr-badge--draft { color: var(--ink-4); }
.ctr-badge--voided { text-decoration: line-through; }

/* Driven by a button; it must not occupy layout. */
.ctr-file-input { display: none; }

.ctr-tin-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ctr-tin-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; font-weight: 600; color: var(--ink-1);
  letter-spacing: 0.04em;
}
.ctr-tin-note { font-size: 11.5px; color: var(--ink-4); }
.ctr-tin-missing { font-size: 13px; color: var(--warn); font-weight: 600; }

.ctr-hint { font-size: 11.5px; color: var(--ink-4); line-height: 1.6; margin-top: 6px; }
.ctr-hint--box {
  padding: 8px 10px; border: 1px solid var(--line);
  border-radius: var(--radius-btn-icon); background: var(--bg-sunk);
}
/* ⚠️ `.btn-link` — used three times in office-detail.jsx — has NO rule anywhere
   in styles.css. Rather than reuse an unstyled class (or restyle three existing
   buttons as a side effect of an unrelated feature), the contractor surfaces
   carry their own. */
.ctr-linkbtn {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--indigo);
  text-decoration: underline; text-underline-offset: 2px;
}
.ctr-linkbtn:hover { text-decoration-thickness: 2px; }
.ctr-hint-btn { margin-left: 6px; font-size: 11.5px; }
.ctr-warn {
  font-size: 12px; line-height: 1.55; padding: 9px 11px;
  border: 1px solid var(--warn-line); background: var(--warn-soft);
  color: var(--warn); border-radius: var(--radius-btn-icon);
}
.ctr-err {
  font-size: 12.5px; line-height: 1.55; padding: 9px 11px;
  border: 1px solid var(--bad); color: var(--bad);
  border-radius: var(--radius-btn-icon); margin-top: 8px;
}
.ctr-check {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--ink-2); margin-top: 8px; cursor: pointer;
}
.ctr-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 8px; }
.ctr-row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-top: 8px; }
@media (max-width: 620px) {
  .ctr-row2, .ctr-row3 { grid-template-columns: 1fr; }
}
.ctr-card {
  padding: 14px 16px; border: 1px solid var(--line);
  border-radius: var(--radius-card); background: var(--bg-card);
  display: flex; flex-direction: column;
}

/* The not-filed disclaimer.
   This is the single most important piece of copy in the feature. The failure
   mode being designed against is someone believing Aecos filed a 1099 with the
   IRS when it did not, so it is loud, it repeats, and it appears ON the
   printable artifact as well as around it. */
.ctr-notfiled {
  font-size: 12px; line-height: 1.6; padding: 10px 12px;
  border: 1px solid var(--warn-line); background: var(--warn-soft);
  color: var(--ink-2); border-radius: var(--radius-btn-icon);
}
.ctr-notfiled--loud {
  display: flex; align-items: flex-start; gap: 8px;
  border-width: 2px; font-weight: 500; color: var(--ink-1);
}
.ctr-notfiled--paper {
  margin: 0 22px 14px; border-color: #d9a441; background: #fdf5e3; color: #4a3a12;
  font-size: 11px;
}

/* The split-pane editors.
   Portalled into .app-right (position:relative, container-type:inline-size), so
   inset:0 fills exactly the content column and the sidebar + chat stay live —
   the same host choice InvoiceEditor makes. `position` is set inline by the JSX
   because it depends on whether that host was found. */
.ctr-editor {
  inset: 0; z-index: 5000; background: var(--bg);
  display: flex; flex-direction: column;
}
.ctr-editor-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding: 16px 20px; border-bottom: 1px solid var(--line);
}
.ctr-editor-title { font-size: 15px; font-weight: 650; color: var(--ink-1); }
.ctr-editor-sub {
  font-size: 12px; color: var(--ink-3); line-height: 1.55;
  margin-top: 3px; max-width: 640px;
}
.ctr-editor-x {
  background: none; border: 1px solid var(--line);
  border-radius: var(--radius-btn-icon); padding: 6px 10px;
  cursor: pointer; color: var(--ink-3); flex: 0 0 auto;
}
.ctr-editor-x:disabled { opacity: 0.5; cursor: default; }
.ctr-editor-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  padding: 12px 20px; border-top: 1px solid var(--line); background: var(--bg);
}
.ctr-editor-foot-note {
  margin-right: auto; font-size: 11.5px; color: var(--warn); font-weight: 600;
}
.ctr-split {
  flex: 1; display: flex; align-items: stretch;
  overflow: hidden; background: var(--bg);
}
.ctr-split-form { flex: 1 1 560px; min-width: 0; overflow-y: auto; padding: 20px 24px; }
.ctr-split-form-inner {
  max-width: 720px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 14px;
}
.ctr-split-preview {
  flex: 1 1 480px; min-width: 380px; max-width: 720px;
  border-left: 1px solid var(--line); background: var(--bg-sunk);
  overflow-y: auto; padding: 16px 18px;
}
.ctr-split-preview-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-4); margin: 2px 2px 10px;
}
/* Narrow viewports: stack the panes rather than crushing the paper. */
@media (max-width: 1000px) {
  .ctr-split { flex-direction: column; overflow-y: auto; }
  .ctr-split-form, .ctr-split-preview { overflow-y: visible; max-width: none; min-width: 0; }
  .ctr-split-preview { border-left: none; border-top: 1px solid var(--line); }
}

/* The paper.
   FIXED LIGHT palette with literal colors, exactly like .esign-page: a tax
   document is printed and emailed, and a dark-mode W-9 reads as broken.
   color-scheme keeps any form control inside it light too. */
.ctr-paper {
  color-scheme: light;
  background: #ffffff; color: #14161a;
  border: 1px solid #dcdcd6; border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}
.ctr-paper-band { padding: 14px 22px 12px; border-bottom: 2px solid #14161a; }
.ctr-paper-band--warn { border-bottom-color: #b4761a; }
.ctr-paper-band-title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.ctr-paper-band-sub {
  font-size: 10.5px; font-weight: 650; text-transform: uppercase;
  letter-spacing: 0.09em; color: #8a6a1c; margin-top: 3px;
}
.ctr-paper-body { padding: 16px 22px 22px; display: flex; flex-direction: column; gap: 12px; }
.ctr-paper-req { font-size: 11.5px; color: #4a4c55; }
.ctr-paper-line { min-width: 0; }
.ctr-paper-label {
  font-size: 9.5px; font-weight: 650; text-transform: uppercase;
  letter-spacing: 0.07em; color: #76787f;
}
.ctr-paper-value {
  font-size: 13px; color: #14161a; margin-top: 3px;
  border-bottom: 1px solid #d9d9d2; padding-bottom: 4px; line-height: 1.5;
  word-break: break-word;
}
.ctr-paper-value.empty { color: #a8a8a2; }
.ctr-paper-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.ctr-paper-tin {
  margin-top: 4px; padding: 10px 12px;
  border: 1.5px solid #14161a; border-radius: 6px; background: #fafaf7;
}
.ctr-paper-tin-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; font-weight: 650; letter-spacing: 0.06em;
  color: #14161a; margin-top: 4px;
}
.ctr-paper-tin-val.empty {
  font-family: inherit; font-size: 12px; font-weight: 500;
  letter-spacing: 0; color: #76787f;
}
.ctr-paper-tin-note {
  display: block; font-family: inherit; font-size: 10.5px;
  font-weight: 400; letter-spacing: 0; color: #76787f; margin-top: 4px;
}
.ctr-paper-tin-inline {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; color: #4a4c55; margin-top: 3px;
}
.ctr-paper-cert { margin-top: 4px; }
.ctr-paper-cert p { font-size: 10.5px; line-height: 1.55; color: #4a4c55; margin: 4px 0 0; }
.ctr-paper-corrected {
  align-self: flex-start; font-size: 11px; font-weight: 700;
  letter-spacing: 0.1em; color: #a4321e; border: 1.5px solid #a4321e;
  padding: 3px 9px; border-radius: 4px;
}
.ctr-box-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;
}
.ctr-box { border: 1px solid #14161a; border-radius: 4px; padding: 8px 10px; min-width: 0; }
.ctr-box--lead { grid-column: 1 / -1; background: #fafaf7; }
.ctr-box-num { font-size: 10px; font-weight: 700; color: #76787f; }
.ctr-box-label { font-size: 10px; color: #4a4c55; line-height: 1.35; margin-top: 1px; }
.ctr-box-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; font-weight: 650; color: #14161a; margin-top: 5px;
}

/* The contractor's own W-9 block on the account-less signer page. Scoped inside
   .esign-page, which already pins a fixed light palette. */
.ctr-w9-guest { display: flex; flex-direction: column; gap: 12px; }
.ctr-w9-guest .ctr-hint { color: #5a5c63; }
.ctr-w9-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ctr-w9-row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
@media (max-width: 620px) {
  .ctr-w9-row2, .ctr-w9-row3 { grid-template-columns: 1fr; }
}
.ctr-w9-tin-field {
  border: 1.5px solid #14161a; border-radius: 8px;
  padding: 12px 14px; background: #fafaf7;
}
.ctr-w9-tin-lock {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: #4a4c55; margin-top: 8px;
}

/* ============================================================================
   RESTORED 2026-08-05 — 140 Timesheets classes that lost their rules in
   57cc3ce3 and have been rendering naked in production ever since.

   WHAT HAPPENED. 57cc3ce3 ("ui-kit: region markers for SHELL/AUTH/DASHBOARD/
   STUDIO REVIEW/MODALS", 2026-05-24) reads as a cosmetic commit that only
   inserts block markers. Its diff is +4883/-1039, and the 1039 removed lines
   are real rules, deleted outright — not moved, not reformatted. Checked three
   ways: no removed selector name reappears anywhere in the same commit's added
   lines; the classes are present in the parent tree and absent in the very
   next one; and the hunks show whole blocks (the TSMobileView layout, the
   timesheet shortcut overlay, the undo snackbar) replaced in place by
   unrelated new features. The commit's own message names two EARLIER
   truncations of this file — 32b32c9 and 4e7a088 — so this is the third in a
   series, and the markers it added to guard against a fourth are themselves
   already gone from this file. Only MODALS and LANDING survive.

   WHY IT MATTERS MOST. 74 of the 140 are `tsm-*`, which is the whole of
   TSMobileView. timesheets.jsx:14480 renders it unconditionally at
   `window.innerWidth <= 768` and its structural elements carry no inline
   styles, so THE MOBILE TIMESHEETS SCREEN HAS BEEN COMPLETELY UNSTYLED SINCE
   2026-05-24. The other 66 are `ts-*` desktop states that only appear on a
   secondary interaction — budget bars, the bulk-edit toolbar, drag/keyboard
   calendar states, the paste-preview modal, the shortcut overlay, the undo
   snackbar — which is why ten weeks passed without anyone reporting it.

   EVERY ONE WAS VERIFIED BEFORE RESTORING: still referenced by a static
   className in current markup (all 140 in timesheets.jsx), and with no rule in
   today's stylesheet in ANY form — bare, compound, descendant or inside an
   @media block. Zero renames, zero duplicates, zero stale entries. Nothing
   here overrides a rule that exists today.

   THREE DELIBERATE DEVIATIONS FROM A VERBATIM RESTORE:
   1. Two of the old rules were @media print comma-lists that also named
      .sidebar / .sidebar-collapse-btn / .topbar / .ts-sidebar /
      .ts-modal-overlay / .ts-cal-block-actions / .ts-cal-now — all of which
      ARE styled today. Those selectors are dropped. Re-adding an unscoped
      print-time `display:none` for the app shell would change printing across
      the whole product, and none of those classes is part of this defect.
      Today's other print rules are all body-class scoped (.inv-printing,
      .ce-printing, .spec-printing); this one would not have been.
   2. `.tsm-wrap` asked for `var(--bg-page)`. That token is declared nowhere —
      not today, and not in the old blob either, so the rule was already
      half-broken when it was written. Rewritten to `var(--bg)`, the canonical
      page background.
   3. @keyframes tsSnackIn / tsLinkedPulse / ts-today-pin-in went in the same
      deletion and are restored here too; without them the `animation:`
      shorthands below are silently inert. (ts-pulse survived and is not
      duplicated.)

   ⚠️ NOT BROWSER-VERIFIED. No screen below has been looked at. The claim being
   made is narrow and checkable: these rules were written for exactly these
   class names by the same commits that wrote the markup, and the markup still
   renders those names. Mobile Timesheets and the desktop secondary states
   listed above are the surfaces whose appearance CHANGES with this block, and
   they are the ones to put eyes on.
   ============================================================================ */

@keyframes tsSnackIn {
  from { transform: translateY(16px) translateX(-50%); opacity: 0; }
  to   { transform: translateY(0)    translateX(-50%); opacity: 1; }
}
@keyframes tsLinkedPulse {
  0%   { outline-color: var(--indigo); outline-width: 2px; }
  50%  { outline-color: var(--indigo); outline-width: 2.5px; }
  100% { outline-color: color-mix(in srgb, var(--indigo) 55%, transparent); outline-width: 2px; }
}
@keyframes ts-today-pin-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.ts-shortcut-modal {
  width: 540px;
  max-width: 90vw;
  max-height: 80vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.ts-shortcut-body {
  overflow-y: auto;
  padding: 4px 20px 20px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 24px;
}
.ts-shortcut-group { margin-top: 16px; }
.ts-shortcut-group-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--ink-4);
  margin-bottom: 6px;
}
.ts-shortcut-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  border-bottom: 1px solid var(--line);
}
.ts-shortcut-row:last-child { border-bottom: none; }
.ts-shortcut-keys {
  display: flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
  min-width: 90px;
}
.ts-shortcut-plus {
  font-size: 10px;
  color: var(--ink-4);
}
.ts-shortcut-click {
  font-size: 10px;
  color: var(--ink-4);
  font-family: var(--f-mono);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}
.ts-shortcut-desc {
  font-size: 12.5px;
  color: var(--ink-2);
}
.ts-undo-snackbar {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--ink);
  color: #fff;
  border-radius: 10px;
  padding: 10px 14px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.28);
  font-size: 13px;
  white-space: nowrap;
  animation: tsSnackIn 0.18s ease;
}
.ts-undo-label {
  flex: 1;
  color: rgba(255,255,255,0.88);
}
.ts-undo-btn {
  background: transparent;
  border: 1px solid rgba(255,255,255,0.3);
  color: #fff;
  border-radius: 6px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s;
}
.ts-undo-btn:hover { background: rgba(255,255,255,0.15); }
.ts-undo-close {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  color: rgba(255,255,255,0.5);
  display: flex;
  align-items: center;
  margin-left: 2px;
}
.ts-undo-close:hover { color: #fff; }
.ts-paste-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line-soft);
  transition: opacity .15s;
}
.ts-paste-row--dim { opacity: 0.4; }
.ts-paste-day {
  font-size: 11px;
  font-weight: 700;
  color: var(--indigo);
  min-width: 30px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.ts-paste-hours {
  width: 64px;
  flex-shrink: 0;
}
.ts-paste-project {
  flex: 2;
  min-width: 0;
}
.ts-paste-notes {
  flex: 3;
  min-width: 0;
}
.ts-entry-cb {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity .1s;
  cursor: pointer;
}
.ts-entry-row:hover .ts-entry-cb, .ts-entry-row--selected .ts-entry-cb { opacity: 1; }
.ts-entry-lock-badge {
  color: var(--ink-4);
  display: flex;
  align-items: center;
}
.ts-bulk-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin-bottom: 8px;
  background: color-mix(in srgb, var(--indigo) 8%, var(--bg-elev));
  border: 1px solid color-mix(in srgb, var(--indigo) 25%, transparent);
  border-radius: 8px;
  flex-wrap: wrap;
}
.ts-bulk-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--indigo);
  white-space: nowrap;
}
.ts-bulk-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  flex-wrap: wrap;
}
.ts-bulk-clear {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 11px;
  color: var(--ink-4);
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 4px 8px;
  border-radius: 5px;
  margin-left: auto;
  transition: color .1s;
}
.ts-bulk-clear:hover { color: var(--ink-1); }
.ts-bulk-hours {
  display: flex;
  align-items: center;
  gap: 4px;
}
.ts-bulk-hours-input {
  width: 58px;
  padding: 5px 7px;
  font-size: 12px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg-card);
  color: var(--ink);
  outline: none;
  font-family: inherit;
}
.ts-bulk-hours-input:focus { border-color: var(--indigo); }
.ts-bulk-hours-input::-webkit-inner-spin-button, .ts-bulk-hours-input::-webkit-outer-spin-button { opacity: 1; }
.ts-entry-drag-handle {
  color: var(--ink-5);
  cursor: grab;
  font-size: 14px;
  padding: 0 2px;
  flex-shrink: 0;
  user-select: none;
  opacity: 0;
  transition: opacity .1s;
}
.ts-entry-row:hover .ts-entry-drag-handle { opacity: 1; }
.ts-entry-swatch {
  width: 4px;
  height: 20px;
  border-radius: 2px;
  flex-shrink: 0;
}
.ts-entry-cal-link {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0 2px;
  color: var(--ink-4);
  display: flex;
  align-items: center;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity .1s, color .1s;
}
.ts-entry-row:hover .ts-entry-cal-link { opacity: 1; }
.ts-entry-cal-link:hover { color: var(--indigo); }
.ts-sync-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
  cursor: default;
  vertical-align: middle;
}
.ts-cal-block-name .ts-sync-dot { margin-left: 4px; }
.ts-week-summary-bill {
  font-size: 11.5px;
  padding: 1px 7px;
  border-radius: 4px;
  font-weight: 500;
}
.ts-week-summary-bar-bill {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(255,255,255,.28);
  border-radius: 0 3px 3px 0;
}
.ts-week-summary-hrs {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-2);
  text-align: right;
}
.ts-week-summary-hrs--bill {
  color: var(--indigo);
  font-size: 11px;
}
.ts-week-summary-hrs--nonbill {
  color: var(--ink-4);
  font-size: 11px;
}
.ts-entry-edit-fields {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
}
.ts-entry-edit-project {
  flex: 2;
  min-width: 0;
}
.ts-entry-edit-hours {
  width: 64px;
  flex-shrink: 0;
}
.ts-entry-edit-notes {
  flex: 3;
  min-width: 0;
}
.ts-entry-edit-bill {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  color: var(--ink-2);
}
.ts-today-pin {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 12px 6px 14px;
  margin-bottom: 8px;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--indigo) 7%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--indigo) 22%, transparent);
  border-radius: 8px;
  animation: ts-today-pin-in 0.18s ease;
}
.ts-today-pin-label {
  font-size: 12px;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ts-cal-block--linked {
  outline: 2px solid var(--indigo) !important;
  outline-offset: 1px;
  animation: tsLinkedPulse 0.9s ease-out 1;
  z-index: 3 !important;
  opacity: 1 !important;
}
/* ⚠️ THE CURSOR USED TO CHANGE MID-DRAG. This class sets pointer-events:none
   (which is also what made a click retarget to the column and the block
   unopenable), so while dragging, the cursor is resolved from the element
   UNDERNEATH the pointer — the column — not from the block. It flipped from
   grab to the grid's cursor the instant a drag began. Holding `grabbing` on
   the grid while any drag is active is the only way to keep it steady,
   because the thing being dragged is deliberately transparent to the mouse. */
.ts-cal-block--dragging {
  opacity: 0.25 !important;
  pointer-events: none;
}
.ts-cal-body:has(.ts-cal-block--dragging),
.ts-cal-body:has(.ts-cal-block--drag-ghost) {
  cursor: grabbing;
}
.ts-cal-body:has(.ts-cal-block--dragging) .ts-cal-block,
.ts-cal-body:has(.ts-cal-block--drag-ghost) .ts-cal-block {
  cursor: grabbing;
}
.ts-cal-block--drag-ghost {
  opacity: 0.92;
  box-shadow: 0 4px 20px rgba(0,0,0,.18);
  cursor: grabbing !important;
  z-index: 10;
  pointer-events: none;
}
.ts-cal-block-event-link {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  color: rgba(255,255,255,0.5);
  display: flex;
  align-items: center;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity .1s;
}
.ts-cal-block:hover .ts-cal-block-event-link { opacity: 1; }
.ts-cal-block-event-link:hover { color: rgba(255,255,255,0.9); }
.ts-timer-bar--warn {
  background: #7f1d1d;
  border-color: #991b1b;
}
.ts-timer-elapsed--warn {
  color: #fca5a5 !important;
  animation: ts-pulse 1s ease-in-out infinite;
}
.ts-float-time--warn { color: #fca5a5; }
.ts-float-btn--warn {
  background: #7f1d1d;
  border-color: #991b1b;
}
.tsm-timer-elapsed--warn { color: #ef4444 !important; }
.ts-budget-bars {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 10px 14px 8px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
  flex-shrink: 0;
}
.ts-budget-bar-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  text-align: left;
  width: 100%;
  border-radius: 4px;
  transition: background 0.1s;
}
.ts-budget-bar-row:hover { background: var(--bg-elev); }
.ts-budget-bar-name {
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-2);
  width: 140px;
  flex-shrink: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ts-budget-bar-track {
  flex: 1;
  height: 5px;
  background: var(--bg-sunk);
  border-radius: 3px;
  overflow: visible;
  position: relative;
}
.ts-budget-bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 0.3s;
}
.ts-budget-bar-overflow {
  position: absolute;
  left: 100%;
  top: 0;
  height: 100%;
  border-radius: 0 3px 3px 0;
  opacity: 0.5;
}
.ts-budget-bar-label {
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  width: 72px;
  text-align: right;
  flex-shrink: 0;
}
.ts-budget-bar-eta {
  font-size: 10px;
  color: var(--ink-4);
  width: 180px;
  flex-shrink: 0;
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ts-cal-week-day-head--focused {
  outline: 2px solid var(--indigo);
  outline-offset: -2px;
}
.ts-cdt-bill { ; }
.ts-cdt-util { letter-spacing: -0.01em; }
.ts-cal-week-col--focused { background: color-mix(in oklab, var(--indigo) 5%, var(--bg-card)); }
.ts-cal-block--kb-focus {
  outline: 2px solid var(--indigo) !important;
  outline-offset: 1px;
  z-index: 5 !important;
}
.ts-cal-month-detail-close { flex-shrink: 0; }
.tsm-wrap {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  background: var(--bg);
  overflow: hidden;
}
.tsm-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
  flex-shrink: 0;
}
.tsm-header-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-1);
}
.tsm-header-timer-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--bad-bg, color-mix(in srgb, var(--bad) 12%, transparent));
  border: 1px solid color-mix(in srgb, var(--bad) 30%, transparent);
  border-radius: 20px;
  padding: 4px 10px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--bad);
}
.tsm-header-timer-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bad);
  animation: ts-pulse 1.2s ease-in-out infinite;
}
.tsm-scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tsm-timer-card {
  margin: 16px 16px 0;
  padding: 16px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tsm-timer-running-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.tsm-timer-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--bad);
  flex-shrink: 0;
  animation: ts-pulse 1.2s ease-in-out infinite;
}
.tsm-timer-info {
  flex: 1;
  min-width: 0;
}
.tsm-timer-project {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tsm-timer-elapsed {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  color: var(--ink-1);
  margin-top: 2px;
}
.tsm-start-btn {
  width: 100%;
  height: 56px;
  border-radius: 10px;
  background: var(--indigo);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  touch-action: manipulation;
}
.tsm-start-btn:disabled { opacity: 0.45; }
.tsm-stop-btn {
  width: 100%;
  height: 56px;
  border-radius: 10px;
  background: var(--bad);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  touch-action: manipulation;
}
.tsm-search-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px 0;
}
.tsm-search-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 10px;
  height: 36px;
}
.tsm-search-input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  font-size: 13px;
  color: var(--ink-1);
  min-width: 0;
}
.tsm-search-input::placeholder { color: var(--ink-4); }
.tsm-search-clear {
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: var(--ink-4);
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.tsm-filter-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.tsm-filter-row::-webkit-scrollbar { display: none; }
.tsm-filter-chip {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  cursor: pointer;
  touch-action: manipulation;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.tsm-filter-chip--active {
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 40%, transparent);
  color: var(--indigo);
}
.tsm-entry-date-badge {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 2px;
}
.tsm-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 16px 8px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.tsm-log-btn {
  background: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--indigo);
  cursor: pointer;
  touch-action: manipulation;
}
.tsm-empty {
  padding: 24px 16px;
  font-size: 13px;
  color: var(--ink-4);
  text-align: center;
}
.tsm-entry-list {
  padding: 0 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tsm-swipe-wrap {
  position: relative;
  overflow: hidden;
  border-radius: 10px;
  /* allow vertical scroll, intercept horizontal for swipe */
  touch-action: pan-y;
  transition: max-height 0.22s ease, opacity 0.22s ease, margin-bottom 0.22s ease;
  max-height: 120px;
  opacity: 1;
}
.tsm-swipe-wrap--exit {
  max-height: 0 !important;
  opacity: 0;
  margin-bottom: -8px !important;
}
.tsm-swipe-delete {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  background: var(--bad);
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  cursor: pointer;
  user-select: none;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tsm-swipe-delete:active { filter: brightness(0.88); }
.tsm-entry-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  text-align: left;
  cursor: pointer;
  touch-action: pan-y;
  transition: background 0.12s;
  min-height: 44px;
}
.tsm-entry-row:active { background: var(--bg-elev); }
.tsm-entry-color {
  width: 4px;
  height: 36px;
  border-radius: 2px;
  flex-shrink: 0;
}
.tsm-entry-info {
  flex: 1;
  min-width: 0;
}
.tsm-entry-project {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tsm-entry-desc {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tsm-entry-meta {
  font-size: 11px;
  color: var(--ink-4);
  margin-top: 2px;
}
.tsm-entry-hours {
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-1);
  flex-shrink: 0;
}
.tsm-week { padding: 16px; }
.tsm-week-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
}
.tsm-week-total-hrs {
  font-weight: 700;
  color: var(--ink-1);
}
.tsm-week-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  min-height: 44px;
}
.tsm-week-row--today .tsm-week-label {
  color: var(--indigo);
  font-weight: 600;
}
.tsm-week-label {
  font-size: 13px;
  color: var(--ink-2);
  width: 130px;
  flex-shrink: 0;
}
.tsm-week-bar-wrap {
  flex: 1;
  height: 6px;
  background: var(--bg-sunk);
  border-radius: 3px;
  overflow: hidden;
}
.tsm-week-bar {
  height: 100%;
  background: var(--indigo);
  border-radius: 3px;
  transition: width 0.3s;
  min-width: 3px;
}
.tsm-week-hours {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  width: 36px;
  text-align: right;
  flex-shrink: 0;
}
.tsm-week-summary {
  margin: 12px 16px 0;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
}
.tsm-wsum-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
.tsm-wsum-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.tsm-wsum-total {
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink-1);
}
.tsm-wsum-bar {
  display: flex;
  height: 5px;
  border-radius: 3px;
  overflow: hidden;
  gap: 2px;
  margin-bottom: 12px;
}
.tsm-wsum-bar-seg {
  border-radius: 2px;
  min-width: 4px;
}
.tsm-wsum-projects {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.tsm-wsum-proj-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tsm-wsum-proj-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.tsm-wsum-proj-name {
  flex: 1;
  font-size: 13px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tsm-wsum-proj-hrs {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--ink-1);
  flex-shrink: 0;
}
.tsm-wsum-more {
  font-size: 12px;
  color: var(--ink-4);
}
.tsm-empty-projects {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 60px 32px 40px;
  text-align: center;
}
.tsm-empty-projects-icon {
  color: var(--ink-4);
  margin-bottom: 14px;
}
.tsm-empty-projects-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 6px;
}
.tsm-empty-projects-sub {
  font-size: 13px;
  color: var(--ink-4);
  max-width: 26ch;
  margin-bottom: 20px;
  line-height: 1.5;
}
.tsm-empty-projects-cta { font-size: 13px; }
.tsm-empty-week {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 0 4px;
  text-align: center;
}
.tsm-empty-week-icon {
  color: var(--ink-4);
  margin-bottom: 10px;
}
.tsm-empty-week-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 4px;
}
.tsm-empty-week-sub {
  font-size: 12px;
  color: var(--ink-4);
  margin-bottom: 14px;
}
.tsm-empty-week-cta { font-size: 13px; }
.tsm-plan-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 32px;
  text-align: center;
}
.tsm-plan-title {
  font-size: 17px;
  font-weight: 600;
  color: var(--ink-1);
  margin-bottom: 10px;
}
.tsm-plan-desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 28ch;
}
.tsm-fab {
  position: fixed;
  bottom: 80px;
  right: 20px;
  z-index: 100;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--indigo);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0,0,0,0.28);
  transition: transform 0.15s, box-shadow 0.15s;
}
.tsm-fab:active {
  transform: scale(0.92);
  box-shadow: 0 2px 8px rgba(0,0,0,0.22);
}
.tsm-bottom-nav {
  display: flex;
  align-items: stretch;
  border-top: 1px solid var(--line);
  background: var(--bg-card);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  flex-shrink: 0;
}
.tsm-nav-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 10px 4px 12px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 10px;
  font-weight: 500;
  color: var(--ink-4);
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.tsm-nav-btn.active { color: var(--indigo); }
.tsm-nav-btn.active svg { stroke: var(--indigo); }
@media print {
  .ts-today-pin { display: none !important; }
  .ts-cal-block-event-link, .ts-sync-dot { display: none !important; }
}

/* ─── AIWorkingFeed (.ai-feed*) — the live Intelligence working feed ─────────
   Quiet by design: the feed is small and dim so the ANSWER below it stays
   visually dominant. The running indicator is the .ai-feed-pulse class — an
   animated "…" glyph — kept in CSS (never an inline animation style) so the
   reduced-motion media query at the bottom can actually reach it and swap the
   pulse for a static glyph. */
.ai-feed { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.ai-feed-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.ai-feed-status {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--ink-4); min-height: 18px;
}
.ai-feed-status-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-feed-status-elapsed { flex: none; color: var(--ink-5); font-variant-numeric: tabular-nums; }

.ai-feed-pulse::after {
  content: "\2026"; /* … */
  display: inline-block;
  color: var(--indigo);
  font-weight: 600;
  letter-spacing: 1px;
  animation: ai-feed-pulse 1.2s ease-in-out infinite;
}
@keyframes ai-feed-pulse {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 1; }
}

.ai-feed-steps { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ai-feed-step { min-width: 0; }
.ai-feed-step-row {
  display: flex; align-items: center; gap: 7px; width: 100%; text-align: left;
  border: none; background: none; cursor: pointer;
  padding: 3px 6px;
  border-radius: var(--radius-btn-icon); /* full-width row — never the pill */
  font-size: 11.5px; color: var(--ink-3);
}
.ai-feed-step-row:hover { background: color-mix(in srgb, var(--ink-5) 12%, transparent); }
.ai-feed-step-icon { display: inline-flex; flex: none; color: var(--ink-4); }
.ai-feed-step-label {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ai-feed-step-ms { flex: none; font-size: 10.5px; color: var(--ink-5); font-variant-numeric: tabular-nums; }
.ai-feed-step-state { display: inline-flex; flex: none; align-items: center; min-width: 14px; justify-content: center; }
.ai-feed-check { color: var(--good); }
.ai-feed-x     { color: var(--bad); }
.ai-feed-step--failed .ai-feed-step-label { color: var(--bad); }

.ai-feed-detail {
  margin: 0 6px 4px 25px;
  padding: 2px 0 2px 10px;
  border-left: 2px solid color-mix(in srgb, var(--ink-5) 35%, transparent);
  font-size: 11px; line-height: 1.55; color: var(--ink-4);
  white-space: pre-wrap; word-break: break-word;
  max-height: 110px; overflow-y: auto;
}
/* ⭐ THE THINKING TRACE IS MEANT TO BE READ WHILE IT STREAMS.
   `.ai-feed-detail` is sized for a step's short detail line — 11px in a 110px
   box. The extended-thinking trace shares the element but is a different kind
   of content: hundreds of words arriving live. At 11px/110px it scrolls past
   faster than anyone can follow, which is why it read as a status indicator
   rather than as the model's reasoning.

   ⚠️ Stays dim and italic deliberately. Reasoning must remain visually
   subordinate to the answer — if it competes, people read the draft instead of
   the conclusion. Bigger and taller, not louder. */
.ai-feed-detail--thinking {
  font-style: italic;
  font-size: 12.5px;
  line-height: 1.7;
  max-height: 420px;
  margin-right: 0;
  padding: 4px 0 4px 12px;
}

.ai-feed-summary {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start;
  border: none; background: none; cursor: pointer;
  padding: 2px 6px; margin-left: -6px;
  border-radius: var(--radius-btn);
  font-size: 11px; color: var(--ink-4);
}
.ai-feed-summary:hover { color: var(--ink-2); background: color-mix(in srgb, var(--ink-5) 12%, transparent); }
.ai-feed-summary-chevron { display: inline-flex; transition: transform 0.15s ease; }
.ai-feed-summary--open .ai-feed-summary-chevron { transform: rotate(90deg); }

@media (prefers-reduced-motion: reduce) {
  .ai-feed-pulse::after { animation: none; opacity: 1; } /* static "…" glyph */
  .ai-feed-summary-chevron { transition: none; }
}

/* ─── Client / external portal (.ext-*) ─────────────────────────────────────
   The chrome for external-workspace.jsx — what an outside CLIENT or consultant
   sees instead of AppShell.

   WHY THIS BLOCK EXISTS AT ALL. That file was ~100% inline styles, and an
   inline style is unreachable by a media query. So the portal did not have
   WEAK mobile behaviour — it had NONE, by construction: not one of this
   stylesheet's ~209 @media blocks could touch it. Its fixed "14px 28px" header
   and "34px 28px 80px" main burned 56px of a 390px phone, and .btn's 7px
   padding at the portal's 12px font gave ~32px touch targets. A client opens an
   invoice or a signature request on a phone far more often than staff open the
   workspace on one, so the portal's MOST COMMON viewport was its only unstyled
   one. Moving the chrome into classes is the whole fix; the 640px block at the
   bottom is what it buys.

   COMPOSITION — these classes carry LAYOUT and RHYTHM ONLY. Tone, type scale
   and status stay owned by the shared primitives, because a hand-copied
   duplicate of a house rule is exactly the drift this portal already had
   (C5/C8 in .claude/docs/plan-client-portal-ui.md):
     · section labels → .eyebrow            ("eyebrow ext-section-head")
     · project title  → .page-header__title ("page-header__title ext-project-title")
     · secondary text → .muted
     · actions        → .btn / .btn-primary / .btn-ghost
     · status         → .pill + .pill-ok|warn|bad|indigo via invoiceTone()
   None of those is restated below. Where a size IS declared here it is one the
   portal owns and no house class expresses.

   TOKENS. Every colour, shadow and radius resolves through a global token, so
   dark/mid theme comes free and this block contains no literal colour. Radii
   are the NAMED tokens only — --radius-btn (pill) for text buttons and chips,
   --radius-btn-icon for full-width rows, --radius-lg for the project container
   (the .card value), --radius-md for the inset summary strip, --radius-sm for a
   focus ring on a text link. Font sizes are literal px because this stylesheet
   has no type-scale token; that is the convention every other family here
   follows, not an invention.

   MOTION. Nothing here is transitioned. Several of these properties are
   var()-valued and Chrome sticks a var()/color-mix() transition at its
   from-value ([[feedback-css-var-transition-stuck]]), so state changes snap.

   ⚠️ AUTHORED, NOT YET ADOPTED — and therefore NEVER RENDERED. Written
   2026-08-14 against the markup in external-workspace.jsx as Phase 2 of
   .claude/docs/plan-client-portal-ui.md; that file is single-writer and belongs
   to another phase, so no element carries these classes yet. Phase 3 applies
   them. Until then every rule below is dead code by design.
   ────────────────────────────────────────────────────────────────────────── */

/* Page root. dvh so a phone's collapsing address bar can't leave a strip of
   unpainted background below the fold. */
.ext-shell {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.ext-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 14px 28px;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
/* Left cluster: the "Aecos" wordmark (.eyebrow) stacked over the firm name. */
.ext-header-brand { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ext-firm {
  font-size: 14.5px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Right cluster: who you are signed in as, + Sign out. */
.ext-header-user { display: flex; align-items: center; gap: 12px; flex: none; min-width: 0; }
.ext-user-name {
  font-size: 13px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40vw;
}

/* ── Main column ────────────────────────────────────────────────────────── */
.ext-main { max-width: 780px; margin: 0 auto; padding: 34px 28px 80px; }
/* The one-sentence orientation line under the header. */
.ext-lede { font-size: 12.5px; line-height: 1.6; color: var(--ink-4); margin-bottom: 26px; }

/* ── Summary strip ──────────────────────────────────────────────────────────
   "1 document to sign · $4,200 due" — an inset callout, so --radius-md: not a
   card, and never a button radius. Items are scroll anchors, hence <a> states. */
.ext-summary-strip {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 11px 14px; margin-bottom: 24px;
  background: var(--bg-sunk);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  font-size: 12.5px; color: var(--ink-3);
}
.ext-summary-item {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink-2); text-decoration: none;
}
.ext-summary-item:hover { color: var(--ink); text-decoration: underline; }
.ext-summary-item:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.ext-summary-item--due { font-weight: 600; color: var(--ink); }

/* ── Sections ───────────────────────────────────────────────────────────────
   .ext-section-head is a LAYOUT wrapper + heading margin reset, so a count Pill
   can sit beside the label. It declares NO type: compose it onto the .eyebrow
   that already owns uppercase / tracking / colour —
       <h3 className="eyebrow ext-section-head">Your invoices <Pill …/></h3>
   ────────────────────────────────────────────────────────────────────────── */
.ext-section { margin-bottom: 34px; }
.ext-section-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 8px;
}

/* ── Rows (invoices, contracts, reviews, phases, milestones, files) ───────── */
.ext-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
}
.ext-row:last-child { border-bottom: none; }
/* flex-basis 180px is the wrap trigger: below it the side/action cells drop to
   their own line unaided, before the 640px block is even consulted. */
.ext-row-main    { flex: 1 1 180px; min-width: 0; }
.ext-row-title   { font-size: 13.5px; color: var(--ink); }
.ext-row-meta    { font-size: 11.5px; color: var(--ink-4); }
.ext-row-side    { flex: none; text-align: right; }
.ext-row-actions { flex: none; display: flex; align-items: center; gap: 8px; }

/* Row modifiers for the Phase-3 timeline. --sub is the sub-phase indent (the
   flat-render defect C4); --past mutes a finished phase; --current is the
   weight bump that pairs with the "In progress" Pill. */
.ext-row--sub { padding-left: 18px; }
.ext-row--past .ext-row-title    { color: var(--ink-4); }
.ext-row--current .ext-row-title { font-weight: 600; }

/* --stack marks a row whose side + action cells go FULL WIDTH on a phone:
   invoices (amount + Pay) and contracts (Review & sign). Opt-in, because a
   secondary ghost action like "Open review" reads better left inline.
   ⚠️ The modifier is DECLARED ONLY inside the 640px block — it is inert above
   it, and an empty ruleset here would be dropped by any minifier/CSSOM parse,
   so it would read as "the class does not exist" to a parse-based check. */

/* ── Project container ──────────────────────────────────────────────────────
   The grouping surface two stacked projects were missing (C9). Same recipe as
   .card — --radius-lg, --shadow-sm, 1px --line — expressed through the tokens
   rather than by composing .card onto the markup, so its padding can shrink at
   640px without dragging every .card in the app with it. */
.ext-project-card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--d-card-pad);
  margin-bottom: 22px;
}
.ext-project-card:last-child { margin-bottom: 0; }
.ext-project-head { margin-bottom: 18px; }
/* Margin ONLY — the size comes from .page-header__title, composed on:
       <h2 className="page-header__title ext-project-title">
   which also inherits that class's 26px → 22px step at 640px for free. */
.ext-project-title { margin: 4px 0 6px; }
.ext-project-meta  { font-size: 13.5px; color: var(--ink-3); }

/* ── Invoice specifics ──────────────────────────────────────────────────────
   tabular-nums so a column of amounts aligns; the portal is the one surface
   where a non-expert compares figures and decides whether to pay. */
.ext-invoice-amount      { font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }
.ext-invoice-outstanding { font-size: 11.5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.ext-invoice-lines       { margin-top: 6px; display: flex; flex-direction: column; gap: 2px; width: 100%; }
.ext-invoice-line        { display: flex; gap: 12px; font-size: 12px; color: var(--ink-3); }
.ext-invoice-line-desc   { flex: 1 1 auto; min-width: 0; }
.ext-invoice-line-amt    { flex: none; color: var(--ink-4); font-variant-numeric: tabular-nums; }
/* "Secure checkout via Stripe" — the heads-up before window.location.assign
   ships a client off-site. width:100% so it takes its own line under the row. */
.ext-invoice-note        { margin-top: 4px; font-size: 11px; color: var(--ink-5); width: 100%; }

/* ── "Who you are working with" chips ───────────────────────────────────────
   --radius-btn is the NAMED token for the pill shape the markup currently
   hardcodes as `borderRadius: 999`. */
.ext-member-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.ext-member-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-btn);
  background: var(--bg-card);
  max-width: 100%;
}
.ext-member-name  { font-size: 13.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ext-member-title { font-size: 12px; color: var(--ink-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ════════════════════════════════════════════════════════════════════════════
   V2 SHELL — the floating left nav (Phase B of plan-client-portal-v2.md)
   ════════════════════════════════════════════════════════════════════════════

   ⭐⭐ THE CENTRAL DECISION, AND THE ONE THING NOT TO UNDO. The founder asked
   for a floating nav that "looks the same as in the Aecos platform". The
   platform's floating nav is not a look — it is the `.sidebar` rule at the top
   of this file (styles.css ~295): elevated card, 12px radius, 8px inset
   margins, sticky, `--bg-elev` on a `--line` border. So the portal WEARS
   `.sidebar` / `.brand` / `.nav` / `.nav-item` / `.nav-section` /
   `.sidebar-foot` verbatim and this block adds only the deltas. Matching it by
   eye would be a second implementation, and a second implementation of a rule
   already written correctly is THE most repeated defect in this repo
   (CLAUDE.md 2026-08-14: three of that week's biggest bugs, one shape).

   ⛔ THEREFORE: nothing below re-declares the sidebar's surface —
   no background, no border, no border-radius, no box-shadow, no width. If you
   find yourself adding one of those to `.ext-sidebar`, you are forking the
   nav; change `.sidebar` instead so both wearers move together.
   `scripts/test_portal_css.py` asserts this, by property name.

   WHAT THE PORTAL DOES *NOT* WEAR, and why no rule is needed for it:
     · `.sidebar.collapsed` (the 64px rail) — the portal never sets the class.
     · `.chat-ctx-sidebar` — Aecos Intelligence is unreachable to an external.
     · `.sidebar-collapse-btn` / `.sidebar-ctl-fullscreen` — not rendered.
   Absence of markup is the mechanism; an extra `display:none` here would just
   be a second thing to keep in step.

   ⚠️ AUTHORED, NOT YET ADOPTED. external-workspace.jsx is single-writer and
   belongs to Phase E; today it renders the single-column `.ext-shell` layout
   and carries NONE of the classes in this sub-block. Until Phase E lands these
   rules are dead by design — the same status the rest of this family had
   between 2026-08-14 and Phase 3. The guard prints which classes are authored
   but unadopted rather than counting them as coverage.
   ────────────────────────────────────────────────────────────────────────── */

/* Page root, composed ON the shipped root: <div class="ext-shell ext-app">.
   `.ext-shell` already owns min-height/background/colour, so this adds the row
   axis and NOTHING else — restating the background here is how two roots start
   disagreeing about dark mode. Mirrors `.app` (styles.css ~299). */
.ext-app {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
}

/* The content column: header + main. min-width:0 is load-bearing — without it
   a long invoice description or a wide spec table makes this flex item refuse
   to shrink and pushes the nav off-screen instead of wrapping. */
.ext-content {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* ── .ext-sidebar — the deltas, and only the deltas ─────────────────────────
   1. TOP CLEARANCE. `.sidebar .nav { margin-top: 38px }` and
      `.brand { margin-top: 36px }` exist to clear the FIXED collapse and
      fullscreen controls (styles.css ~651–666). The portal renders neither, so
      inheriting that clearance would open the nav with ~74px of nothing above
      it. Reset to the padding the card already has.
   2. IT ACTUALLY FLOATS. `.sidebar` is `position: sticky; top: 0` but in the
      workspace it lives inside `.app-root`, which is `height:100%;
      overflow:hidden` — a fixed-height, inner-scrolling shell where the rail is
      full-height and sticky never fires. The portal deliberately does NOT
      depend on ancestor heights (`html,body{height:100%}` is app-shell setup we
      do not control from here), so the page is the scroller. That means the
      sidebar must opt OUT of flex stretch (`align-self`) and cap its own
      height, or `position: sticky` is inert and the nav scrolls away — the
      exact opposite of "floating". top:8px matches its own 8px margin so the
      card keeps its inset when it sticks.
   3. Its own scroller, since it no longer stretches to fit its content. */
.ext-sidebar {
  align-self: flex-start;
  top: 8px;
  height: auto;
  max-height: calc(100dvh - 16px);
  overflow-y: auto;
}
.ext-sidebar .nav   { margin-top: 4px; }
.ext-sidebar .brand { margin-top: 0; }

/* Hamburger. Lives INSIDE `.ext-header` (not `position: fixed` like AppShell's
   `.mobile-nav-trigger`, styles.css ~22776) — the portal header is not frosted
   or overlaid, so a fixed button would only buy a z-index argument. Hidden at
   every width until the phone block turns it on; declared at TOP LEVEL because
   a hidden-only-inside-@media widget falls back to its native <button>
   display on desktop and shows up as a stray glyph — the precise bug the
   comment at styles.css ~22364 records. */
.ext-nav-trigger { display: none; }
.ext-nav-scrim   { display: none; }

/* Header left cluster: [hamburger] [Aecos ▸ firm name]. `.ext-header` is
   `justify-content: space-between`, which only reads correctly with exactly
   two children — this keeps it at two once the trigger appears. */
.ext-header-lead {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}

/* ── Grouping inside a section (specifications: floor → area; meetings:
   upcoming → past) ─────────────────────────────────────────────────────────
   Layout + rhythm only. The label composes `.eyebrow`, exactly as
   `.ext-section-head` does — this block declares no type, no colour. */
.ext-group { margin-bottom: 20px; }
.ext-group:last-child { margin-bottom: 0; }
.ext-group-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line-soft);
}

/* A numeric cell inside an `.ext-row` — a spec quantity, a lead time in weeks.
   tabular-nums for the same reason `.ext-invoice-amount` has it: a column of
   figures a non-expert is comparing. flex:none so it never steals the wrap
   budget from `.ext-row-main`. */
.ext-row-num {
  flex: none;
  font-size: 12.5px; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* A meeting's start time. Own class rather than `.ext-row-meta` because it is
   the row's PRIMARY fact (a client scans "when", not "what") and takes the row
   title's weight, not the muted meta size. */
.ext-meeting-when {
  font-size: 13px; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* ── Phone (≤640px) ─────────────────────────────────────────────────────────
   The reason the whole family exists. Padding drops 28px → 16px (24px of a
   390px viewport handed back to content), touch targets rise to 40px, and an
   invoice's amount + Pay stop competing for a line they cannot both have.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .ext-header { padding: 12px 16px; gap: 10px; }
  .ext-main   { padding: 22px 16px 64px; }
  .ext-lede   { margin-bottom: 20px; }
  .ext-user-name { max-width: 50vw; }

  .ext-summary-strip { padding: 10px 12px; gap: 6px 12px; margin-bottom: 18px; }

  .ext-project-card { padding: 16px; margin-bottom: 16px; }
  .ext-project-head { margin-bottom: 14px; }
  .ext-section      { margin-bottom: 26px; }

  /* Touch targets. .btn is 7px/12px at 13px ≈ 32px tall, and the portal drops
     its buttons to 12px, so they land smaller still. Raised ONLY inside the
     portal — .btn is untouched everywhere else in the app. */
  .ext-header .btn,
  .ext-row .btn,
  .ext-row-actions .btn,
  .ext-summary-strip .btn { min-height: 40px; }

  /* A --stack row goes vertical: title block, amount left-aligned beneath it,
     then a full-width primary action. ⚠️ A FULL-WIDTH row takes
     --radius-btn-icon, NEVER --radius-btn — a 999px pill across 358px is a
     lozenge (see the token comment at the top of this file). */
  .ext-row--stack { align-items: stretch; row-gap: 8px; }
  .ext-row--stack .ext-row-side    { width: 100%; text-align: left; }
  .ext-row--stack .ext-row-actions { width: 100%; }
  .ext-row--stack .ext-row-actions .btn {
    width: 100%;
    justify-content: center;
    border-radius: var(--radius-btn-icon);
  }

  .ext-row--sub { padding-left: 12px; }

  /* ── The nav at 390px ──────────────────────────────────────────────────────
     A 216px left rail on a 390px phone is 55% of the viewport spent on
     furniture, so below 640px the nav is NOT a rail: it is a drawer behind a
     hamburger in the header — the same pattern AppShell uses (`mobileNavOpen`,
     shell.jsx ~1531), and deliberately not a bottom tab bar, because "same as
     the platform" was the instruction.

     ⭐ THE DRAWER IS `display: none`, NOT AN OFF-SCREEN TRANSFORM. A panel
     parked at translateX(-100%) is still in the layout and still focusable, and
     this repo already carries one of those ("a Drawer whose reveal fails still
     has an off-screen panel", CLAUDE.md → FOUND, NOT FIXED). display:none makes
     a failed reveal a VISIBLE nothing instead of an invisible something, and it
     is why the closed drawer provably cannot eat the viewport.

     ⚠️ No transition on the reveal, matching this family's motion policy — and
     note `.sidebar` itself transitions width/padding/margin, so anything that
     changed those on toggle would animate from the platform's rule, not this
     one. Toggling display sidesteps that entirely: it snaps. */
  .ext-app { display: block; }

  .ext-nav-trigger {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none;
    width: 40px; height: 40px; min-height: 40px; padding: 0;
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-btn-icon);
    color: var(--ink-2);
    cursor: pointer;
  }

  /* Tap-anywhere-to-close. Below the dialog band (7000+) on purpose: a modal
     opened from the portal must still cover the drawer. */
  .ext-nav-scrim {
    display: block;
    position: fixed; inset: 0;
    z-index: 940;
    background: var(--scrim);
  }

  .ext-sidebar { display: none; }
  .ext-sidebar.is-open {
    display: flex;
    position: fixed;
    top: 8px; left: 8px; bottom: 8px;
    /* ⚠️ The cap is VIEWPORT-relative, not a second fixed number. .sidebar's
       216px is comfortable at 390px but would overhang a 320px device; this
       leaves 32px of scrim visible on every phone, so "tap outside to close"
       is always reachable. */
    max-width: calc(100vw - 32px);
    height: auto;
    max-height: none;
    margin: 0;
    z-index: 941;
    overflow-y: auto;
  }
}

/* ─── PasswordField — the ONE password input's reveal toggle ──────────────────
   Component: ui.jsx `PasswordField` (search "THE reveal-toggle password
   input"). Applied to every sign-in / sign-up / set-password surface.
   Guarded by scripts/test_password_reveal.js.

   THE WRAPPER IS INTENTIONALLY THIN. Every consumer already styles its own
   input (.auth-field input, .landing-nav-acct-signin-input,
   .profile-dropup-acct-input, .dev-input) and each of those sits in a flex
   column that used to stretch the bare <input>. Wrapping it in a <span> would
   collapse that, so the wrapper is display:block/width:100% and the input keeps
   width:100%; the ONLY thing added to the input is room on the right for the
   button. Two-class selectors are used deliberately — `.auth-field input` is
   (0,1,1) and would otherwise win the padding shorthand. */
.pwfield {
  position: relative; display: block; width: 100%;
  /* ONE knob for the whole control — a compact surface shrinks the button and
     the input's right padding follows, instead of a second copy of the rule. */
  --pwfield-btn: 28px;
}
.pwfield .pwfield__input { width: 100%; padding-right: calc(var(--pwfield-btn) + 8px); }
.pwfield .pwfield__toggle {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center;
  width: var(--pwfield-btn); height: var(--pwfield-btn); padding: 0;
  /* ⚠️ Icon-only control ⇒ --radius-btn-icon (8px). Never --radius-btn (the
     999px pill), never a hardcoded number. */
  border: 0; border-radius: var(--radius-btn-icon);
  background: transparent; color: var(--ink-4); cursor: pointer;
  transition: color .12s, background .12s;
}
.pwfield .pwfield__toggle:hover { color: var(--ink-2); background: var(--bg-hover); }
.pwfield .pwfield__toggle[aria-pressed="true"] { color: var(--ink-2); }
.pwfield .pwfield__toggle:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--indigo) 45%, transparent);
  outline-offset: 1px;
}
.pwfield .pwfield__toggle:disabled { opacity: .45; cursor: not-allowed; }
/* ≥44px touch target on finger devices WITHOUT inflating the visual control:
   an invisible hit-area expander, not a bigger button. The inset is derived
   from the button size, so the compact rows below still reach a full 44px. */
@media (pointer: coarse) {
  .pwfield .pwfield__toggle::after {
    content: ""; position: absolute;
    inset: calc((44px - var(--pwfield-btn)) / -2);
  }
}
/* Compact surfaces: the account-switcher sign-in rows on the landing nav and
   in the shell's profile drop-up use 12.5px inputs with 6px padding, where a
   28px button would crowd the placeholder. */
.landing-nav-acct-signin-form .pwfield,
.landing-nav-acct-add-form .pwfield,
.profile-dropup-acct-signin .pwfield,
.profile-dropup-acct-add .pwfield { --pwfield-btn: 22px; }
/* Edge paints its OWN reveal eye inside a password input and Safari parks the
   credentials key at the right edge. Two eyes side by side is the bug this
   feature would otherwise introduce, so the native one is suppressed and the
   autofill key is moved clear of ours. */
.pwfield .pwfield__input::-ms-reveal,
.pwfield .pwfield__input::-ms-clear { display: none; }
.pwfield .pwfield__input::-webkit-credentials-auto-fill-button,
.pwfield .pwfield__input::-webkit-strong-password-auto-fill-button { margin-right: 26px; }
/* Surface fit-up: the dev console lays its edit rows out as label + control in
   a flex row and sized the bare input with `flex: 1` (dev.html). */
.dev-edit-row .pwfield { flex: 1; min-width: 0; }

/* ─── The action card's "Send from" select must not spill the chat bubble ────
   FOUNDER REPORT 2026-08-18: "the green bubble from the response … is kind of
   overlapping/falling-out of the response box."

   MEASURED IN THE LIVE PAGE, not inferred. The chain was
     .cmd-chat-bubble  scrollWidth 270 / clientWidth 259
       .cmd-action-card             269 / 257
         .cmd-send-from             257 / 233
           .aecos-select      width 256.5 in a 233px box
   The select is `display:inline-block`, so it is sized by its CONTENT — and its
   content is an email address ("joshua@eufingerstudio.com · default"). A longer
   address spills further; this is not a fixed 24px.

   ⚠️ The fix belongs on the SELECT, not on the bubble. Clipping at the bubble
   would hide the overflow while the control stayed the wrong size, and the
   founder would meet it again the first time an address got longer.
   ⚠️ Scoped to `.cmd-send-from` deliberately: AecosSelect is used across the
   product at natural widths, and a global max-width would squash every other
   one. The menu itself PORTALS TO BODY (z 9500), so truncating the trigger
   cannot clip the open list — the full address stays readable when you open it.
   VERIFIED by injecting exactly these rules into the live page: every level went
   to scrollWidth == clientWidth and the select 256.5px -> 233px. */
.cmd-send-from .aecos-select { max-width: 100%; min-width: 0; }
.cmd-send-from .aecos-select > * { max-width: 100%; min-width: 0; }
.cmd-send-from .aecos-select button,
.cmd-send-from .aecos-select [role="combobox"],
.cmd-send-from .aecos-select [role="button"] {
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── Cost to Complete report ────────────────────────────────────────────────
   The on-screen twin of the server-rendered PDF. Two rules here are not
   cosmetic:
   (1) A BLANK CELL MUST READ AS BLANK. `.ctc-num[data-blank="1"]` renders no
       glyph at all — no dash, no zero. A dash reads as zero at a glance to a
       finance reader, and several of these columns are legitimately blank
       because the underlying feature does not exist yet. The printed reason
       lives in .ctc-warnings directly above the table.
   (2) A LOSS MUST BE UNMISTAKABLE. `.ctc-neg` colours the figure AND the
       markup wraps it in parentheses, so the signal survives a black-and-white
       print of the same table — colour alone is not an accessible signal.
   ⚠️ No transitions on var()/color-mix()-valued properties anywhere in this
   block: Chrome sticks such a transition at its from-value. Hover states snap.
   ──────────────────────────────────────────────────────────────────────── */
.ctc-body { display: flex; flex-direction: column; gap: 18px; }

.ctc-runform {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-card);
  padding: 14px 16px;
}
.ctc-runform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 14px;
}
.ctc-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ctc-field--sm { flex: 1 1 180px; }
.ctc-field--wide { flex: 2 1 320px; }
.ctc-field-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.ctc-runform-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.ctc-runform-hint { font-size: 12px; color: var(--ink-4); flex: 1 1 260px; }

.ctc-error {
  border: 1px solid var(--bad-line);
  background: var(--bad-soft);
  color: var(--bad);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
}

.ctc-artifacts { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── The honesty block. Expanded, never behind a toggle. ── */
.ctc-warnings {
  border: 1px solid var(--warn-line);
  background: var(--warn-soft);
  border-radius: 12px;
  padding: 12px 14px;
}
.ctc-warnings-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--warn);
  margin-bottom: 8px;
}
.ctc-warnings-list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.ctc-warnings-list li { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); }

/* ── The table ── */
.ctc-table-scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-card);
}
.ctc-table { font-size: 12.5px; min-width: 1100px; }
.ctc-table thead th {
  white-space: nowrap;
  vertical-align: bottom;
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-card);
}
.ctc-table th.ctc-num, .ctc-table td.ctc-num { text-align: right; }
.ctc-rowhead-col { width: 190px; min-width: 190px; text-align: left; }
.ctc-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* (1) A blank cell renders NOTHING. Not a dash, not a zero. */
.ctc-num[data-blank="1"] { color: transparent; }
/* (2) A loss is coloured AND parenthesised in the markup. */
.ctc-neg { color: var(--danger); font-weight: 650; }
.ctc-strong { font-weight: 650; }

.ctc-table .ctc-pm-band th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--bg-sunk);
  padding: 9px 12px;
}
.ctc-table .ctc-project-band td {
  padding: 8px 12px 6px;
  background: var(--bg-hover);
  border-bottom: 1px solid var(--line-soft);
}
.ctc-project-label { font-weight: 600; color: var(--ink); margin-right: 8px; }
.ctc-table .ctc-rowhead {
  text-align: left;
  font-weight: 500;
  color: var(--ink-3);
  padding-left: 20px;
  white-space: nowrap;
}
.ctc-basis {
  display: inline-block;
  min-width: 34px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-4);
}
.ctc-rowhead-note { margin-left: 8px; font-size: 11.5px; color: var(--ink-4); }
.ctc-row--strong td, .ctc-row--strong th { background: var(--bg-sunk); }
.ctc-table tfoot .ctc-row--strong td, .ctc-table tfoot .ctc-row--strong th {
  border-top: 2px solid var(--line-strong);
  color: var(--ink);
}

/* ── The PM → Finance round-trip ── */
.ctc-todo {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-card);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ctc-todo-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-4);
  margin-bottom: 6px;
}
.ctc-todo-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }
.ctc-todo-steps li { font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }
.ctc-todo-disabled {
  border: 1px solid var(--warn-line);
  background: var(--warn-soft);
  border-radius: 10px;
  padding: 9px 12px;
  font-size: 12.5px;
  color: var(--ink-2);
}
.ctc-todo-row {
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ctc-todo-project { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ctc-todo-number { font-size: 12px; font-weight: 700; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.ctc-todo-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.ctc-todo-fields { display: flex; flex-wrap: wrap; gap: 10px 12px; }
.ctc-todo-close {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-btn-icon);
  background: var(--bg-sunk);
  cursor: pointer;
}
.ctc-todo-close input { margin-top: 2px; }
.ctc-todo-close-label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.ctc-todo-close-help { display: block; font-size: 12px; color: var(--ink-4); margin-top: 2px; line-height: 1.45; }
.ctc-todo-actions,
.ctc-todo-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.ctc-todo-footer { border-top: 1px solid var(--line-soft); padding-top: 12px; }
.ctc-todo-error { font-size: 12.5px; color: var(--danger); }
.ctc-todo-saved { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--ok); }

/* ── Run history ── */
.ctc-history {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-card);
  padding: 6px 14px 12px;
}
.ctc-history-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding: 10px 0 8px;
}
.ctc-history-empty { font-size: 12.5px; color: var(--ink-4); padding: 6px 0 8px; }
.ctc-history-error { font-size: 12.5px; color: var(--danger); padding: 6px 0 8px; }
.ctc-history-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-top: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.ctc-history-main { display: flex; flex-direction: column; gap: 2px; flex: 1 1 220px; min-width: 0; }
.ctc-history-period { font-size: 13px; font-weight: 600; color: var(--ink); }
.ctc-history-meta { font-size: 11.5px; color: var(--ink-4); }
.ctc-history-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* The Finance export modal's route to the report that renders a real PDF —
   the wiring that replaced its dead "PDF — Coming soon" button. */
.fin-export-pdf-note {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
  font-size: 12px;
  color: var(--ink-4);
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
}

@media (max-width: 820px) {
  .ctc-runform-grid { grid-template-columns: 1fr 1fr; }
  .ctc-todo-fields { flex-direction: column; }
}
