/* =============================================================================
   OPERATO DESIGN SYSTEM v1.0
   "Editorial Operator" — agency OS that prevents churn before it happens.
   =============================================================================

   ARCHITECTURE
   ────────────────────────────────────────────────────────────────────────────
   Three layers, in this order:
     1. PRIMITIVES — raw values (hex codes, pixels). Don't reference from
        components. Only semantic tokens reference these.
     2. SEMANTIC   — meaning tokens (--surface-base, --text-primary). This is
        what components consume. Switch a primitive, every semantic updates.
     3. COMPONENT  — instance-scoped tokens (--button-primary-bg). References
        semantic tokens. Tweak a component without touching the system.

   USAGE
   ────────────────────────────────────────────────────────────────────────────
   1. Paste this entire file inside a <style> block in index.html, OR import
      it as a separate stylesheet linked before the rest of your CSS.
   2. In all other CSS, reference SEMANTIC tokens only.
      ✅ background: var(--surface-elevated);
      ❌ background: #11151D;
      ❌ background: var(--grey-900);
   3. To switch from dark to light mode, toggle the [data-theme="light"]
      attribute on <html> or <body>. All semantic tokens re-resolve.

   GOVERNANCE
   ────────────────────────────────────────────────────────────────────────────
   - No hex codes outside this file. Ever.
   - No spacing values outside the spacing scale. Ever.
   - The yellow accent (--accent-default) appears ONLY on:
       primary CTA fill, focus rings, AI Insight left border, active nav.
     Nowhere else. If in doubt, use grey.
   ============================================================================= */


/* =============================================================================
   LAYER 1 — PRIMITIVES
   Raw values. Don't reference these from components.
   ============================================================================= */

:root {
  /* ── Greyscale (the backbone) ─────────────────────────────────────────────
     11-step scale. Tuned for dark mode primary. Each step ~10% delta.
     #0A0D14 (950) is the deepest — intentional ink, NOT pure black, because
     pure black + Inter = harsh on OLED screens at night.
     ────────────────────────────────────────────────────────────────────── */
  --grey-0:   #FFFFFF;
  --grey-50:  #F4F6FB;   /* primary text in dark mode / page bg in light */
  --grey-100: #E4E7EE;
  --grey-200: #C8CDD8;
  --grey-300: #9BA3B7;   /* secondary text in dark mode */
  --grey-400: #7A8295;
  --grey-500: #6B7384;   /* tertiary text — micro labels */
  --grey-600: #4A5060;
  --grey-700: #2F3441;
  --grey-800: #1A1F2A;   /* surface-overlay (popovers, dropdowns) */
  --grey-900: #11151D;   /* surface-elevated (cards, panels) */
  --grey-950: #0A0D14;   /* surface-base (the page) */

  /* ── Sulphur (the brand accent) ───────────────────────────────────────────
     #E8FF6B is the committed brand color. Picked because:
       (a) Not blue. The whole B2B category is blue.
       (b) Reads as "operator alert" semantically — close to amber/highlighter.
       (c) Holds well in both dark (high contrast) and light (with care).
       (d) Distinct in market: nobody else in agency-tools owns yellow.
     Used SPARINGLY. Decoration-by-default kills the signal.
     ────────────────────────────────────────────────────────────────────── */
  --sulphur-300: #F0FF94;   /* hover state — slightly brighter */
  --sulphur-400: #E8FF6B;   /* DEFAULT accent */
  --sulphur-500: #D4EB57;   /* pressed state — slightly muted */
  --sulphur-tint:  rgba(232, 255, 107, 0.14);   /* soft fills */
  --sulphur-trace: rgba(232, 255, 107, 0.06);   /* very faint backgrounds */
  /* S-01/§05: nav active-indicator underline. The Sulphur family reads ~1.1–1.5:1 on white —
     below WCAG 1.4.11 (≥3:1) for a graphical status marker. This darkened chartreuse stays in
     the accent family (hue ≈66°) but clears the bar (3.59:1 on #fff). Nav underline ONLY —
     --sulphur-deep is unchanged for its many other uses. */
  --nav-active-underline: #808F00;
  /* D-26 Step 4a: the canonical focus indicator, PROMOTED from index.html:6465 into the stylesheet.
     Two tokens — the ring references --v2-focus, so both move together. --surface (index.html's name)
     is --surface-elevated here. Indigo ~6.5:1 on white; the 2px inner ring keeps it robust on any bg. */
  --v2-focus: #4f5b93;
  --v2-focus-ring: 0 0 0 2px var(--surface-elevated), 0 0 0 4px var(--v2-focus);

  /* ── Functional colors ────────────────────────────────────────────────────
     Industry-standard hues. Don't get clever. Users expect green=good,
     amber=warning, red=error. Breaking that = cognitive tax forever.
     ────────────────────────────────────────────────────────────────────── */
  --green-400: #6FDDB1;
  --green-500: #5BD49A;   /* success — muted, NOT supermarket green */
  --green-600: #3FB87E;

  --amber-400: #FFB54A;
  --amber-500: #F5A524;   /* warning / at-risk */
  --amber-600: #DC8B0E;

  --red-400:   #FF5A66;
  --red-500:   #F23F4C;   /* error */
  --red-600:   #D8222F;

  --blue-500:  #5B8DEF;   /* info — used for info badges only, NOT brand */

  /* ── Spacing (4px grid) ───────────────────────────────────────────────────
     Every spacing decision must be on this scale. No 10px. No 18px.
     Numeric naming (1=4px, 2=8px) maps to the multiplier. After 6, naming
     stays linear (8 = 32px = 4×8) — this is intentional, helps mental math.
     ────────────────────────────────────────────────────────────────────── */
  --space-0:   0;
  --space-1:   4px;
  --space-2:   8px;
  --space-3:   12px;
  --space-4:   16px;
  --space-5:   20px;
  --space-6:   24px;
  --space-8:   32px;
  --space-10:  40px;
  --space-12:  48px;
  --space-16:  64px;
  --space-20:  80px;

  /* ── Type scale (V2 UI Freeze · Wave 1 · §1.1 · frozen Master Brief values) ─
     Seven steps, line-heights on a 4px rhythm, Inter family unchanged. Tokens
     carry the SIZE; the paired line-height / weight / tracking / case are the
     documented contract applied at each consumption site:
       --fs-1 11/16 600 +0.06em UPPERCASE  eyebrows, column headers, badges, pill labels
       --fs-2 12/16 400 0       Sentence   meta, caption, timestamps, as-of, helper
       --fs-3 14/20 400 0       Sentence   BODY DEFAULT — cells, rows, paragraphs, values
       --fs-4 16/24 600 0       Sentence   card titles, sub-section headings, emphasised body
       --fs-5 24/32 600 0       Sentence   object / panel titles — client name, drawer/modal title
       --fs-6 32/40 600 0       Sentence   page titles, KPI values
       --fs-7 40/48 700 -0.01em Sentence   the single dominant element — one per surface
     T1 (null-delta) repoints only font-size declarations whose px EXACTLY equals
     a token value, as var(--fs-N, <original literal>). 11.5 / 12.5 / 13 etc. are
     T2 residuals and remain untouched. --fs-1 and --fs-2 are 1px apart by design.
     ────────────────────────────────────────────────────────────────────── */
  --fs-1:  11px;
  --fs-2:  12px;
  --fs-3:  14px;
  --fs-4:  16px;
  --fs-5:  24px;
  --fs-6:  32px;
  --fs-7:  40px;

  /* ── Radius ───────────────────────────────────────────────────────────────
     B2B SaaS sweet spot: 4–8px. 12px is the ceiling for cards. Anything
     above 12px feels childish for an operator tool.
     ────────────────────────────────────────────────────────────────────── */
  --radius-xs:   2px;
  --radius-sm:   4px;
  --radius-md:   6px;    /* default for buttons, inputs */
  --radius-lg:   8px;    /* default for cards */
  --radius-xl:   12px;   /* large surfaces, side panels */
  --radius-pill: 9999px; /* avatars, badges, pills */

  /* ── Borders (widths) ─────────────────────────────────────────────────── */
  --border-width-1: 1px;
  --border-width-2: 2px;   /* the AI Insight stripe + active nav */

  /* ── Typography — primitives ──────────────────────────────────────────────
     Inter Variable. Includes optical sizing + tabular numbers by default
     for the entire app. This is the 5% upgrade over plain Inter.

     Self-hosted recommended (faster, more reliable than Google Fonts).
     Variable font: load ONE file, get all weights.
     Source: https://rsms.me/inter/  (free, open-source).
     ────────────────────────────────────────────────────────────────────── */
  --font-sans:
    "Inter Variable",
    "Inter",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    Helvetica,
    Arial,
    sans-serif;

  --font-mono:
    "JetBrains Mono",
    ui-monospace,
    SFMono-Regular,
    Menlo,
    Consolas,
    monospace;

  /* Font weights — only 3 weights used. More = noise. */
  --font-weight-regular:  400;
  --font-weight-medium:   500;
  --font-weight-semibold: 600;

  /* Line height ratios (unitless — multiply by font-size) */
  --line-height-tight:  1.2;   /* display sizes */
  --line-height-snug:   1.35;  /* headings */
  --line-height-normal: 1.45;  /* body */

  /* Letter spacing — used for editorial micro-labels */
  --letter-spacing-tight: -0.025em;  /* display hero */
  --letter-spacing-snug:  -0.015em;  /* h1 */
  --letter-spacing-normal: 0;
  --letter-spacing-wide:   0.06em;   /* UPPERCASE micro labels */

  /* ── Shadows ──────────────────────────────────────────────────────────────
     B2B SaaS: borders > shadows. Shadows reserved for elevated surfaces
     that genuinely lift off the page (modals, dropdowns).
     ────────────────────────────────────────────────────────────────────── */
  --shadow-overlay:
    0 4px 12px rgba(0, 0, 0, 0.32),
    0 1px 2px rgba(0, 0, 0, 0.24);
  --shadow-modal:
    0 20px 48px rgba(0, 0, 0, 0.48),
    0 4px 8px rgba(0, 0, 0, 0.24);

  /* ── Motion ───────────────────────────────────────────────────────────────
     Short transitions, ease-out feels snappy. Long transitions feel slow.
     ────────────────────────────────────────────────────────────────────── */
  --motion-duration-fast:    120ms;   /* hover, focus */
  --motion-duration-normal:  200ms;   /* panel slide-in */
  --motion-duration-slow:    320ms;   /* modal entry */
  /* F-06 ALIGN: single ease vocabulary. --ease-standard keeps the production ease-out
     curve (was --motion-easing-standard); --ease-enter/exit/expressive migrated here from
     the v2InjectStyles block so named easings have one home. --motion-easing-* removed. */
  --ease-standard:   cubic-bezier(0.2, 0, 0, 1);   /* ease-out — most transitions */
  --ease-enter:      cubic-bezier(0.0,0.0,0.2,1);  /* decelerate — elements arriving */
  --ease-exit:       cubic-bezier(0.4,0.0,1.0,1);  /* accelerate — elements leaving */
  --ease-expressive: cubic-bezier(0.2,0.0,0.0,1.3);/* emphasized — single AI-signal moment */

  /* ── Data palette (PR-01 F-04) — categorical series, data cells only, never Sulphur ──
     Muted so no single series dominates; each measured ≥3:1 on #FFFFFF (WCAG 1.4.11). */
  --data-1: #2F6F8F;   /* slate blue   5.54:1 */
  --data-2: #3F7D5F;   /* moss         4.87:1 */
  --data-3: #8A6D3B;   /* ochre        4.85:1 */
  --data-4: #6B5B95;   /* plum         5.91:1 */
  --data-5: #A15C42;   /* clay         5.09:1 */
  --data-6: #4A5D6B;   /* steel        6.84:1 */

  /* ── Health magnitude ramp (PR-01 F-05) — ONE green hue, light→dark = 0→100 ──
     Magnitude not category; each ≥3:1 on #FFFFFF; never Sulphur (§05/§06). */
  --health-0:   #5F9E82;   /* 3.13:1 */
  --health-25:  #53957A;   /* 3.53:1 */
  --health-50:  #448A6C;   /* 4.12:1 */
  --health-75:  #2F7D57;   /* 5.01:1 */
  --health-100: #1D6B49;   /* 6.46:1 */
  --health-track: #E4EBE7; /* background rail — not a data colour */

  /* ── Health BANDS (V2 UI Freeze W1 §1.2 · ratified) ──────────────────────
     The semantic 4-band model replaces the 5-stop magnitude ramp for V2 health
     rendering: Healthy 70–100 · Watch 50–69 · At risk 0–49 · Not scored (no
     numeric score — never 0, never blank). Per band: fill = pill background,
     ink = readable text ON the fill (each ≥4.5:1), solid = strong marker/dot
     (each ≥3:1 on white). The --health-0..100 ramp above stays declared
     (legacy member, out of W1 scope); V2 renders consume ONLY these band
     tokens via the v2PMHealth single source. */
  --health-healthy-fill: #E3F2E4;
  --health-healthy-ink:  #186A3B;  /* 5.71:1 on the fill */
  --health-healthy-solid:#2E7D4F;  /* 5.11:1 on white */
  --health-watch-fill:   #FDF0D5;
  --health-watch-ink:    #7A4B00;  /* 6.62:1 on the fill */
  --health-watch-solid:  #B77400;  /* 3.81:1 on white */
  --health-risk-fill:    #FBE4E4;
  --health-risk-ink:     #A11B1B;  /* 6.44:1 on the fill */
  --health-risk-solid:   #C62828;  /* 5.63:1 on white */
  --health-none-fill:    #EEF0F4;
  --health-none-ink:     #575B66;  /* 5.93:1 on the fill */
  --health-none-solid:   #7C8494;  /* 3.76:1 on white */

  /* ── Task-status pairs (V2 UI Freeze W1 §1.3 · ratified) ─────────────────
     Six canonical statuses, FIVE colour classes. Palette economy: To do reuses
     the Not-scored ramp, both Waiting states reuse the Watch ramp, Done reuses
     the Healthy ramp (aliased at the consumption layer); only these two NEW
     pairs join the colour vocabulary. */
  --status-progress-fill: #E3EDFB;
  --status-progress-ink:  #1B4F9C;  /* 6.72:1 on the fill — In progress */
  --status-review-fill:   #DDF0EF;
  --status-review-ink:    #0F5F5A;  /* 6.43:1 on the fill — In review */

  /* ── Status pairs (Storytelling §05) — strong shade for text + markers, -bg
     shade for tinted surfaces. Strong ≥4.5:1 on white AND ≥3:1 as a marker;
     strong on its own -bg ≥4.5:1 for text-inside-a-chip. Canonical §05 names;
     v2's --good/--warn/--bad are back-compat aliases pointing here (index.html).
     Replaces the shipped #1d9e75/#bd7714/#d8433d which failed the 4.5:1 text bar
     (3.39 / 3.61 / 4.38). ── */
  --status-good:    #1D7A4D;   /* 5.33:1 on #fff · 4.70:1 on --status-good-bg */
  --status-good-bg: #E7F4EC;   /* tinted surface — 1.13:1 on #fff (a fill, not a marker) */
  --status-warn:    #8F5400;   /* 6.11:1 on #fff · 5.42:1 on --status-warn-bg */
  --status-warn-bg: #FBF0DE;   /* tinted surface */
  --status-risk:    #C0392B;   /* 5.44:1 on #fff · 4.67:1 on --status-risk-bg (§05 'risk' = v2 'bad') */
  --status-risk-bg: #FBEAE8;   /* tinted surface */
  /* --info is NOT a §05 status colour; relocated here UNCHANGED (was index.html body.v2-active,
     shared line 6438 with --bad) so index.html carries no raw hex. v2-only consumers. */
  --info:      #2f7fd6;
  --info-soft: #e7f0fb;

  /* ── z-index scale ────────────────────────────────────────────────────────
     Don't use ad-hoc z-index. Ever. Otherwise you get z-index: 9999 wars.
     ────────────────────────────────────────────────────────────────────── */
  --z-base:        0;
  --z-sticky:      100;   /* sticky table headers, sticky footers */
  --z-dropdown:    200;
  --z-popover:     300;
  --z-side-panel:  400;
  --z-modal:       500;
  --z-toast:       600;
  --z-tooltip:     700;
}


/* =============================================================================
   LAYER 2 — SEMANTIC TOKENS (DARK MODE — DEFAULT)
   This is what components consume. Components NEVER reference primitives.
   ============================================================================= */

:root,
:root[data-theme="dark"] {

  /* ── Surfaces ─────────────────────────────────────────────────────────────
     base       = page background, the deepest layer
     elevated   = cards, panels, the working surfaces
     overlay    = popovers, dropdowns (one step up from cards)
     sunken     = inputs, code blocks (one step DOWN from cards — pressed-in)
     ────────────────────────────────────────────────────────────────────── */
  --surface-base:     var(--grey-950);
  --surface-elevated: var(--grey-900);
  --surface-overlay:  var(--grey-800);
  --surface-sunken:   #06080D;
  --surface-inverse:  var(--grey-50);

  /* ── Borders ──────────────────────────────────────────────────────────────
     Opacity-based — they auto-adjust as the surface beneath them changes.
     subtle  = decorative dividers between rows
     default = card outlines, input borders at rest
     strong  = active inputs, emphasis borders
     focus   = the ring that appears on keyboard focus (accent color)
     ────────────────────────────────────────────────────────────────────── */
  --border-subtle:  rgba(255, 255, 255, 0.06);
  --border-default: rgba(255, 255, 255, 0.10);
  --border-strong:  rgba(255, 255, 255, 0.16);

  /* ── Text ─────────────────────────────────────────────────────────────────
     primary   = headlines, body copy you must read
     secondary = supporting copy, descriptions
     tertiary  = micro-labels, metadata, timestamps
     disabled  = unusable controls, ghost states
     inverse   = text on accent fills (yellow CTA → dark text)
     ────────────────────────────────────────────────────────────────────── */
  --text-primary:   var(--grey-50);
  --text-secondary: var(--grey-300);
  --text-tertiary:  var(--grey-400);  /* v1.1: repointed grey-500→grey-400 for AA (~5.2:1 on --surface-base) */
  --text-disabled:  var(--grey-600);
  --text-inverse:   var(--grey-950);

  /* ── Accent (the sulphur, semantically named) ─────────────────────────────
     default = the resting color
     hover   = pointer over a CTA
     pressed = the moment of click
     subtle  = tinted backgrounds (selected row left border bg, etc.)
     trace   = barely-there backgrounds (focus background flashes)
     ────────────────────────────────────────────────────────────────────── */
  --accent-default: var(--sulphur-400);
  --accent-hover:   var(--sulphur-300);
  --accent-pressed: var(--sulphur-500);
  --accent-subtle:  var(--sulphur-tint);
  --accent-trace:   var(--sulphur-trace);

  /* ── Status (semantic functional colors) ──────────────────────────────────
     For badges, alerts, status indicators. Each has a fill + a text variant.
     The "soft" version is for tinted backgrounds (e.g., warning banners).
     ────────────────────────────────────────────────────────────────────── */
  --status-success:      var(--green-500);
  --status-success-soft: rgba(91, 212, 154, 0.12);
  --status-success-text: var(--green-400);

  --status-warning:      var(--amber-500);
  --status-warning-soft: rgba(245, 165, 36, 0.14);
  --status-warning-text: var(--amber-400);

  --status-error:        var(--red-500);
  --status-error-soft:   rgba(242, 63, 76, 0.14);
  --status-error-text:   var(--red-400);

  --status-info:         var(--blue-500);
  --status-info-soft:    rgba(91, 141, 239, 0.14);
  --status-info-text:    var(--blue-500);
  --status-info-bg:      rgba(91, 141, 239, 0.14);

  /* ── Aliases (back-compat for render code that uses shorter names) ─── */
  --surface:             var(--surface-elevated);
  --card-bg:             var(--surface-elevated);
  --text:                var(--text-primary);
  --shadow-lg:           0 10px 30px rgba(0, 0, 0, 0.45);

  /* ── Spacing semantics ────────────────────────────────────────────────────
     Use these in components instead of raw spacing primitives. If you find
     yourself reaching for --space-N directly, ask: is this a recurring
     pattern that deserves a name? If yes, add it here.
     ────────────────────────────────────────────────────────────────────── */
  --gutter:            var(--space-6);    /* 24px — page horizontal padding */
  --section-gap:       var(--space-12);   /* 48px — between major sections */
  --card-padding:      var(--space-5);    /* 20px — inside cards */
  --card-gap:          var(--space-5);    /* 20px — between cards */
  --inline-gap-tight:  var(--space-2);    /* 8px  — icon ↔ text in button */
  --inline-gap:        var(--space-3);    /* 12px — default inline */
  --stack-gap:         var(--space-4);    /* 16px — vertical between elements */
  --stack-gap-loose:   var(--space-6);    /* 24px — looser vertical */

  /* ── Radius semantics ─────────────────────────────────────────────────── */
  --radius-control: var(--radius-md);   /* 6px — buttons, inputs */
  --radius-input:   var(--radius-control);   /* 6px — alias; 130 legacy references */
  --radius-card:    var(--radius-lg);   /* 8px — cards, panels */
  --radius-overlay: var(--radius-lg);   /* 8px — popovers, dropdowns */
  --radius-modal:   var(--radius-xl);   /* 12px — modals, side panels */
  --radius-badge:   var(--radius-pill); /* 9999px — pills */

  /* ═══════════════════════════════════════════════════════════════════════
     WAVE 2 / STAGE 1 — COMPONENT-TOKEN FOUNDATION (Layer 3, additive)
     operato-wave2-stage1-ui-foundations. Every value resolves to an existing
     Layer-1/2 token or a brief-specified rgba(); no raw hex. §0.1 tertiary AA
     fix applied above at --text-tertiary.
     ═══════════════════════════════════════════════════════════════════════ */
  /* PART 0 — elevation ramp + focus system */
  --shadow-sm: 0 1px 2px rgba(10,13,20,0.30);
  --shadow-md: 0 4px 12px rgba(10,13,20,0.35), 0 1px 0 rgba(255,255,255,0.05) inset;
  --elevation-border: 0 0 0 1px var(--border-subtle);
  --focus-ring: 0 0 0 2px var(--surface-base), 0 0 0 4px var(--accent-default);
  --focus-ring-inset: inset 0 0 0 2px var(--accent-default);
  /* Canonical label colour ON the Sulphur brand fill (Deep Space). CTAs/buttons use this,
     NEVER white — Sulphur #E8FF6B on white is ~1.1:1; #06142D on Sulphur ≈ 17.5:1 (§05). */
  --text-on-brand: #06142D;
  /* BUTTON */
  --button-radius: var(--radius-control);
  --button-height-sm: 28px; --button-height-md: 36px; --button-height-lg: 44px;
  --button-padding-x: var(--space-4); --button-gap: var(--space-2); --button-font-weight: 560;
  --button-primary-bg: var(--accent-default);
  --button-primary-bg-hover: var(--accent-hover);
  --button-primary-bg-active: var(--accent-pressed);
  --button-primary-text: var(--text-on-brand);
  --button-primary-disabled-bg: var(--grey-700);
  --button-primary-disabled-text: var(--text-disabled);
  --button-secondary-bg: var(--surface-elevated);
  --button-secondary-bg-hover: var(--grey-800);
  --button-secondary-border: var(--border-strong);
  --button-secondary-text: var(--text-primary);
  --button-ghost-bg-hover: rgba(255,255,255,0.04);
  --button-destructive-bg: var(--red-600);   /* D-26 Step 6: was var(--status-error) — dark --status-error is --red-500 #F23F4C, on which the near-white --button-destructive-text is 3.47:1 (fails AA). --red-600 #D8222F clears it (white 4.64:1) and equals the value light already resolved, so light is unchanged. Fix is on the BACKGROUND, not the text primitive. */
  --button-destructive-text: var(--grey-50);
  /* LINK — §9 substitution: brief spec is var(--text-link), but in the forced light v2 theme
     --text-link (lime, --sulphur-600) is ~1.78:1 on white (fails AA). Use the theme-aware --text-primary
     (passes on both dark + white) and rely on the always-underline in .link for the affordance.
     Pre-existing light-theme link-colour gap logged in RECOMMENDED-CHANGES.md. */
  --link-text: var(--text-primary);
  --link-text-hover: var(--accent-hover);
  --link-underline-offset: 2px;
  /* INPUT */
  --input-height: 36px;
  --input-bg: var(--surface-sunken);
  --input-border: #565E70;   /* D-26 Step 5: solid per-theme literal (was var(--border-default), a 10% alpha that composited differently per surface). Dark: 3.08:1 on --surface-sunken #06080D — clears the 1.4.11 floor without overshoot. */
  --input-border-hover: #68707F;   /* D-26 Step 6: was var(--border-strong), a 16%/18% alpha that composited to ~1.5:1 — WEAKER than the Step-5 resting border (3.08:1 dark), so hovering made the boundary vanish. Solid per theme, above rest: 4.02:1 on --input-bg #06080D (dark); light overridden below. */
  --input-focus-ring: 0 0 0 3px color-mix(in srgb, var(--accent-default) 35%, transparent);  /* Micha v1.1 sulphur glow */
  --input-radius: 10px;                /* Wave2-fix: Micha v1.1 (off the 6/8/12 control scale — reconcile in Wave 4) */
  --input-padding-y: var(--space-3);   /* 12px */
  --input-padding-x: 14px;             /* Wave2-fix: Micha v1.1 horizontal (space-3 is 12px) */
  --input-text: var(--text-primary);
  --input-placeholder: var(--text-tertiary);
  --input-disabled-bg: var(--surface-sunken);   /* Wave2-fix: light & muted (was dark --grey-900 block) */
  --input-border-error: var(--status-error);
  --input-border-success: var(--status-success);
  /* TABLE */
  --table-header-height: 32px;
  --table-header-bg: var(--surface-base);
  --table-header-text: var(--text-tertiary);
  --table-header-weight: 600;
  --table-row-height: 40px;
  --table-cell-padding-x: var(--space-3);
  --table-row-border: var(--border-subtle);
  --table-row-bg-hover: rgba(255,255,255,0.02);
  --table-row-bg-selected: color-mix(in srgb, var(--accent-default) 10%, transparent);   /* Wave2-fix: very light transparent lime tint (was 18%) */
  --table-row-selected-marker: inset 2px 0 0 0 var(--accent-default);   /* restrained left marker, not a full fill */
  --table-sticky-col-shadow: 2px 0 4px rgba(10,13,20,0.25);
  /* TOOLTIP (pull-forward — health-score explainer etc.) */
  --tooltip-bg: var(--surface-overlay);
  --tooltip-text: var(--text-primary);
  --tooltip-radius: var(--radius-control);
  --tooltip-shadow: var(--shadow-overlay);
}


/* =============================================================================
   LAYER 2 — SEMANTIC TOKENS (LIGHT MODE OVERRIDE)
   Activate by setting [data-theme="light"] on <html> or <body>.
   ONLY override semantic tokens. Primitives stay the same.
   ============================================================================= */

:root[data-theme="light"],
:root:has(body.light-theme) {

  /* ── Surfaces (inverted) ──────────────────────────────────────────────── */
  --surface-base:     #FAFBFC;
  --surface-elevated: var(--grey-0);
  --surface-overlay:  var(--grey-0);
  --surface-sunken:   var(--grey-50);
  --surface-inverse:  var(--grey-950);

  /* ── Borders (light-mode opacities) ───────────────────────────────────── */
  --border-subtle:  rgba(10, 13, 20, 0.06);
  --border-default: rgba(10, 13, 20, 0.10);
  --input-border: #898E98;   /* D-26 Step 5: light solid — cool neutral, 3.04:1 on --input-bg #F4F6FB (the fill barely differs from the page, so the border is the sole identifier — 1.4.11 at 3:1). */
  --border-strong:  rgba(10, 13, 20, 0.18);

  /* ── Text (inverted hierarchy) ────────────────────────────────────────── */
  --text-primary:   #0A0D14;
  --text-secondary: #4A5060;
  --text-tertiary:  #6B7384;
  --text-disabled:  #9BA3B7;
  --text-inverse:   var(--grey-50);

  /* ── Accent (toned for light mode — pure sulphur is too bright) ──────── */
  --accent-default: #E8FF6B;   /* v1.1: Micha Sulphur brand accent (was muted #C4DD3F) */
  --accent-hover:   #D4EB57;   /* same hue, one step darker lime (≈ brightness 0.94) */
  --accent-pressed: #C0D63F;   /* same hue, darker still — no hue shift */
  --accent-subtle:  rgba(232, 255, 107, 0.18);   /* subtle tint of the new accent */
  --accent-trace:   rgba(232, 255, 107, 0.08);   /* v1.1: match Sulphur family (was olive rgba(196,221,63)) */

  /* ── Status (slightly muted for light mode) ──────────────────────────── */
  --status-success:      #1D7A4D;   /* D-26 Step 1: light-block value corrected to the compliant --status-good hex (drives .status-dot--success, --input-border-success, .sg-msg--success) */
  --status-success-soft: #E7F4EC;   /* D-26 Step 1: = --status-good-bg */
  --status-success-text: #1D7A4D;   /* D-26 Step 1: = --status-good; fixes .badge--success AND .icon--success */

  --status-warning:      #8F5400;   /* D-26 Step 1: = --status-warn (drives .status-dot--warning) */
  --status-warning-soft: #FBF0DE;   /* D-26 Step 1: = --status-warn-bg */
  --status-warning-text: #8F5400;   /* D-26 Step 1: = --status-warn; fixes .badge--warning AND .icon--warning */

  --status-error:        var(--red-600);
  --status-error-soft:   #FBEAE8;   /* D-26 Step 1: = --status-risk-bg */
  --status-error-text:   #C0392B;   /* D-26 Step 1: = --status-risk; fixes .badge--error AND .icon--error */

  --status-info:         #1d4ed8;
  --status-info-soft:    rgba(29, 78, 216, 0.10);
  --status-info-text:    #1d4ed8;
  --status-info-bg:      rgba(29, 78, 216, 0.10);

  /* ── D-26 Step 6: light-theme resting-value fixes (this block is the failing scope) ── */
  --input-placeholder:   #646C7C;   /* was var(--text-tertiary) #6B7384 = 4.40:1 on --input-bg #F4F6FB (fails the 4.5 bar). #646C7C = 4.88:1. Dark placeholder already passes, so only light is overridden. */
  --link-text-hover:     #6B7700;   /* was var(--accent-hover) #D4EB57 = 1.33:1 on white (invisible link-hover). Darkened sulphur #6B7700 = 4.93:1. Dark keeps var(--accent-hover). */
  --input-border-hover:  #757B87;   /* light half of the hover-regression fix: 3.93:1 on --input-bg #F4F6FB, above the 3.04:1 resting border. */

  /* ── Aliases (light-mode back-compat) ───────────────────────────────── */
  --surface:             var(--surface-elevated);
  --card-bg:             var(--surface-elevated);
  --text:                var(--text-primary);
  --shadow-lg:           0 10px 30px rgba(10, 13, 20, 0.10);
}


/* =============================================================================
   TYPOGRAPHY UTILITIES
   These are NOT components — they're class utilities you apply to any element.
   The whole type scale is enumerated. Don't define ad-hoc font-sizes.
   ============================================================================= */

.t-display {
  font-family: var(--font-sans);
  font-size: var(--fs-7, 40px);
  line-height: var(--line-height-tight);
  letter-spacing: var(--letter-spacing-tight);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.t-h1 {
  font-family: var(--font-sans);
  font-size: 28px;
  line-height: 36px;
  letter-spacing: var(--letter-spacing-snug);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.t-h2 {
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 28px;
  letter-spacing: -0.01em;
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.t-h3 {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 22px;
  letter-spacing: var(--letter-spacing-normal);
  font-weight: var(--font-weight-semibold);
  color: var(--text-primary);
}

.t-body {
  font-family: var(--font-sans);
  font-size: var(--fs-3, 14px);
  line-height: 20px;
  font-weight: var(--font-weight-regular);
  color: var(--text-primary);
}

.t-body-medium {
  font-family: var(--font-sans);
  font-size: var(--fs-3, 14px);
  line-height: 20px;
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
}

/* AI Insight body copy — slightly heavier than default body. */
.t-body-insight {
  font-family: var(--font-sans);
  font-size: var(--fs-4, 16px);
  line-height: 24px;
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
  max-width: 720px;
}

.t-small {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 18px;
  font-weight: var(--font-weight-regular);
  color: var(--text-secondary);
}

/* The editorial micro-label. UPPERCASE, tracked, tertiary color.
   Used for: section eyebrows ("INSIGHT · 4M AGO"), table column headers,
   stat card labels, breadcrumbs. */
.t-micro {
  font-family: var(--font-sans);
  font-size: var(--fs-1, 11px);
  line-height: 16px;
  font-weight: var(--font-weight-medium);
  letter-spacing: var(--letter-spacing-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Tabular variant — for any numeric content. Numbers don't shift width
   when values change. Critical for tables and dashboards. */
.t-tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Mono — for IDs, technical strings, code references. */
.t-mono {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 18px;
  font-weight: var(--font-weight-regular);
}


/* =============================================================================
   GLOBAL RESET + BASE
   Applies font, colors, sensible defaults to the document.
   ============================================================================= */

html {
  font-family: var(--font-sans);
  font-size: 14px; /* W1 fix-pass R1: the document rem basis (reaches frozen legacy) — reverted to the literal per Design; NOT a type-scale member */
  line-height: var(--line-height-normal);
  background: var(--surface-base);
  color: var(--text-primary);
  /* Smooth font rendering on macOS. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Tabular numbers everywhere by default — flip to proportional only when
     you explicitly need them (e.g. running prose). */
  font-variant-numeric: tabular-nums;
  /* Inter Variable optical sizing — adjusts shape based on size. */
  font-optical-sizing: auto;
}

body {
  margin: 0;
  background: var(--surface-base);
  color: var(--text-primary);
}

/* Focus ring — global default. Can be overridden per-component. */
*:focus-visible {
  outline: none;   /* D-26 Step 4a: was 2px sulphur --border-focus (1.33:1). One indicator per surface: the canonical indigo double ring. */
  box-shadow: var(--v2-focus-ring);
}

*:focus:not(:focus-visible) {
  outline: none;
}


/* =============================================================================
   LAYER 3 — COMPONENT TOKENS + STYLES
   ============================================================================= */


/* ── BUTTON ───────────────────────────────────────────────────────────────
   Variants: primary | secondary | ghost | destructive
   Sizes: sm (28px) | md (32px) | lg (36px)
   States: default, hover, active, focus, disabled, loading
   ────────────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--inline-gap-tight);
  font-family: var(--font-sans);
  font-size: var(--fs-3, 14px);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  letter-spacing: -0.005em;
  border: var(--border-width-1) solid transparent;
  border-radius: var(--radius-control);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition:
    background-color var(--motion-duration-fast) var(--ease-standard),
    border-color var(--motion-duration-fast) var(--ease-standard),
    color var(--motion-duration-fast) var(--ease-standard);
}

/* Sizes */
.btn--sm { height: 28px; padding: 0 var(--space-3); font-size: 13px; }
.btn--md { height: 32px; padding: 0 var(--space-4); }
.btn--lg { height: 36px; padding: 0 var(--space-5); }

/* Primary — sulphur fill, dark text. The signature CTA of the product. */
.btn--primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}
.btn--primary:active {
  background: var(--accent-pressed);
  border-color: var(--accent-pressed);
}

/* Secondary — outlined, primary text. */
.btn--secondary {
  background: transparent;
  color: var(--text-primary);
  border-color: var(--border-default);
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--border-strong);
}
.btn--secondary:active {
  background: rgba(255, 255, 255, 0.06);
}

/* Ghost — no border, no background. For tertiary actions in dense layouts. */
.btn--ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: transparent;
}
.btn--ghost:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-primary);
}
.btn--ghost:active {
  background: rgba(255, 255, 255, 0.06);
}

/* Destructive — red fill, used for delete/remove actions. */
.btn--destructive {
  background: var(--status-error);
  color: var(--grey-50);
  border-color: var(--status-error);
}
.btn--destructive:hover {
  background: var(--red-400);
  border-color: var(--red-400);
}

/* ═══════════════════════════════════════════════════════════════════════════
   AI APPROVAL-ACTION BUTTON SYSTEM (semantic roles; §07d trust surface).
   ONE base `.v2-ai-action` + `[data-action-role]` modifiers — Approve = GREEN success
   (NOT sulphur), Review = PURPLE informational, Open = BLUE navigation, Reject = RED
   destructive, Edit = neutral. Colour is set from the ACTION SEMANTICS by the consumer,
   NEVER from the button label or a shared `.btn*` selector. v2-scoped so legacy is
   byte-identical; global (not #v2Page) so it also reaches the #v2OverlayHost overlay.
   Runtime-measured on white: approve white-on-green 5.33:1 · review #4f5b93 6.46:1 ·
   open #1d62b8 (darkened from --info 4.10:1 → AA) · reject 5.44:1. Reuses the v2
   focus-ring + --state-disabled-* — no second focus/disabled system.
   ══════════════════════════════════════════════════════════════════════════ */
body.v2-active {
  /* WS-1A PR-4 · layer model — shell vs card, and the hover role split out of --page.
     Levels 01/02/03 are all #FFFFFF; only their border + shadow differ, so they need no bg token. */
  --layer-00:      #EEF0F4;   /* shell — page, nav rail, table headers (1.141:1 vs #fff; every ink/status token holds ≥4.5:1 on it) */
  --hover-tint:    #F6F7F9;   /* the old --page value, now in its real :hover role only */
  --layer-02-line: #D9DDE4;   /* float border — dropdown / menu / tooltip / popover (elev-2) */
  --layer-03-line: #D9DDE4;   /* overlay border — drawer / modal / command palette (elev-3) */
  /* WS-1A PR-6 · accent role tokens — one Sulphur value per role, so the accent can never be used
     as the wrong role. Referenced by claude/client-profile-onboarding-design-2026-08-12.md. */
  --accent-fill:    #E8FF6B;   /* fill only — 1.11:1 on white, never a stroke, never text */
  --accent-on-fill: #16171c;   /* 16.15:1 on --accent-fill */
  --accent-stroke:  #808F00;   /* 3.59:1 on --surface, 3.15:1 on --layer-00 */
  --accent-text:    #5F6D00;   /* 5.72:1 on --surface, 5.01:1 on --layer-00 */
  --accent-wash:    #fffdf0;   /* fill */
  --action-approve-fg:       #ffffff;
  --action-approve-bg:       var(--status-good);   /* #1D7A4D — white text = 5.33:1 */
  --action-approve-bg-hover: #15613C;              /* darker green — white text ~6.6:1 */
  --action-approve-bg-active:#114E31;
  --action-review-fg:        var(--violet);        /* #4f5b93 on --violet-soft = 5.67:1 */
  --action-review-bg:        var(--violet-soft);   /* soft lavender fill */
  --action-open-fg:          #1d62b8;              /* AA blue (--info #2f7fd6 is only 4.10:1) */
  --action-open-bg:          color-mix(in srgb, var(--info-soft) 65%, var(--surface));       /* lighter blue — less saturated beside Approve; text ~5.5:1 */
  --action-reject-fg:        var(--status-risk);   /* #C0392B — §05 strong-on-soft */
  --action-reject-bg:        color-mix(in srgb, var(--status-risk-bg) 65%, var(--surface));  /* lighter red — softer than solid Approve; text ~4.9:1 */
  --action-edit-bg:          var(--page);          /* soft neutral-grey fill */
  --action-neutral-fg:       var(--ink2);
  /* S-04 · Deep Space command palette — the ONE dark surface in v2 (frozen exception), distinct from the light search overlay. Runtime-verified on the dark panel. */
  --cmdp-bg:                 #111726;              /* Deep Space panel surface */
  --cmdp-fg:                 #eef1f8;              /* primary text on --cmdp-bg (~15:1) */
  --cmdp-muted:              #a9b2c6;              /* group labels / secondary / placeholder (~8:1, ≥4.5) */
  --cmdp-item-active:        #26324e;              /* active-option fill */
  --cmdp-accent:             #8fb6ff;              /* active-option marker + input focus (~8.9:1 on bg, ≥3) */
  --cmdp-border:             #5D6B94;              /* D-26 Step 5: resting boundary, 3.09:1 on the wrapper fill #1B202F (3.4:1 on --cmdp-bg #111726) — clears 3:1 and STAYS subordinate to --cmdp-accent #8fb6ff (7.96:1 focus), gap ~2.6x, so :focus-within still reads as a state change. */
}
/* ONE base — identical geometry for every role (height, padding, radius, weight, icon, gap). Approve is
   the only SOLID; Review/Open/Reject/Edit are TINTED secondaries (soft fill + strong text + matching
   border) reusing the §05 strong-text-on-soft pattern — softer than Approve, never a bare outline. */
body.v2-active .v2-ai-action {
  display:inline-flex; align-items:center; justify-content:center; gap:5px; white-space:nowrap;
  box-sizing:border-box; min-height:26px; min-width:62px;
  font:inherit; font-size:var(--fs-2, 12px); font-weight:550; line-height:1.15;   /* compact-button type scale — ONE size across roles; secondaries 550, approve overrides to 600 */
  padding:5px 12px; border-radius:var(--r-sm); border:1px solid var(--line);
  background:var(--surface); color:var(--action-neutral-fg); cursor:pointer;
  transition:filter var(--motion-fast) var(--ease-standard), background var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard);
}
body.v2-active .v2-ai-action .ti { font-size:13px; flex:0 0 auto; }   /* tame the icon so iconed + text-only buttons share one height */
body.v2-active .v2-ai-action:disabled, body.v2-active .v2-ai-action[aria-disabled="true"] { opacity:var(--state-disabled-opacity); cursor:var(--state-disabled-cursor); }
body.v2-active:not(.v2-pointer) .v2-ai-action:focus-visible { outline:none; box-shadow:var(--v2-focus-ring); }
body.v2-active .v2-ai-action[data-action-role="approve"] { background:var(--action-approve-bg); border-color:var(--action-approve-bg); color:var(--action-approve-fg); font-weight:600; }   /* the ONLY solid + the only semibold */
body.v2-active .v2-ai-action[data-action-role="approve"]:hover { background:var(--action-approve-bg-hover); border-color:var(--action-approve-bg-hover); }
body.v2-active .v2-ai-action[data-action-role="approve"]:active { background:var(--action-approve-bg-active); border-color:var(--action-approve-bg-active); }
/* secondaries — border is a MID-TINT of the semantic colour (lighter than the text): reinforces the role, never dominates. ~3.5:1 vs surface (≥3), text stays the strong fg. */
body.v2-active .v2-ai-action[data-action-role="review"] { background:var(--action-review-bg); color:var(--action-review-fg); border-color:color-mix(in srgb, var(--action-review-fg) 75%, var(--surface)); }
body.v2-active .v2-ai-action[data-action-role="open"]   { background:var(--action-open-bg);   color:var(--action-open-fg);   border-color:color-mix(in srgb, var(--action-open-fg) 75%, var(--surface)); }
body.v2-active .v2-ai-action[data-action-role="reject"] { background:var(--action-reject-bg); color:var(--action-reject-fg); border-color:color-mix(in srgb, var(--action-reject-fg) 75%, var(--surface)); }
body.v2-active .v2-ai-action[data-action-role="edit"]   { background:var(--action-edit-bg);   color:var(--action-neutral-fg); border-color:var(--line); }
/* hover/active — uniform subtle darken; darkening a light-fill/dark-text button preserves (slightly raises) its contrast ratio, so no per-role tuning needed. Matches the prior mini-btn hover. */
body.v2-active .v2-ai-action[data-action-role="review"]:hover, body.v2-active .v2-ai-action[data-action-role="open"]:hover, body.v2-active .v2-ai-action[data-action-role="reject"]:hover, body.v2-active .v2-ai-action[data-action-role="edit"]:hover { filter:brightness(0.97); }
body.v2-active .v2-ai-action[data-action-role="review"]:active, body.v2-active .v2-ai-action[data-action-role="open"]:active, body.v2-active .v2-ai-action[data-action-role="reject"]:active, body.v2-active .v2-ai-action[data-action-role="edit"]:active { filter:brightness(0.94); }
/* action-row containment — consistent gap, wrapping, and inset on every surface; no clipped border/ring */
body.v2-active .approve-btns, body.v2-active .agent-act, body.v2-active .ws-card-btns, body.v2-active .v2ov-actrow, body.v2-active .dr-btns { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
body.v2-active .approve-btns, body.v2-active .ws-card-btns, body.v2-active .agent-act { margin-top:10px; }
@media (prefers-reduced-motion: reduce) { body.v2-active .v2-ai-action { transition:none; } }

/* S-04 · Deep Space command palette — a Layer-3 modifier class on the Layer-1 overlay panel (added by
   v2CmdOpen to rec.panel). Re-skins the SHARED Layer-2 .v2ll markup dark WITHOUT touching Layer 1/2:
   the light search overlay (no .v2cmd-ds) is untouched. All colour via --cmdp-* tokens. */
body.v2-active .v2ov-panel.v2cmd-ds { background:var(--cmdp-bg); border-color:var(--cmdp-border); }
body.v2-active .v2cmd-ds .v2ll-top { border-bottom-color:var(--cmdp-border); }
body.v2-active .v2cmd-ds .v2ll-inwrap { background:rgba(255,255,255,.04); border-color:var(--cmdp-border); }
body.v2-active .v2cmd-ds .v2ll-inwrap:focus-within { border-color:var(--cmdp-accent); }
body.v2-active .v2cmd-ds .v2ll-in { color:var(--cmdp-fg); }
body.v2-active .v2cmd-ds .v2ll-in::placeholder { color:var(--cmdp-muted); opacity:1; }
body.v2-active .v2cmd-ds .v2ll-gh { color:var(--cmdp-muted); }
body.v2-active .v2cmd-ds .v2ll-opt-l { color:var(--cmdp-fg); }
body.v2-active .v2cmd-ds .v2ll-opt-s { color:var(--cmdp-muted); }
body.v2-active .v2cmd-ds .v2ll-opt:hover { background:rgba(255,255,255,.05); }
body.v2-active .v2cmd-ds .v2ll-opt[aria-selected="true"] { background:var(--cmdp-item-active); box-shadow:inset 3px 0 0 var(--cmdp-accent); }   /* active-option marker = the roving focus indicator (aria-activedescendant) */
body.v2-active .v2cmd-ds .v2ll-gempty, body.v2-active .v2cmd-ds .v2ll-empty { color:var(--cmdp-muted); }

/* S-02 · unified create modal — a Layer-3 skin on the shared Layer-1 .v2ov-panel (centered by the base). */
/* B5 — focused desktop width (fits the Task two-column grid); constant across tabs so there's no width jump. */
body.v2-active .v2ov-panel.v2cm-panel { width:min(620px,94vw); }
body.v2-active .v2cm-wrap { display:flex; flex-direction:column; min-height:0; max-height:92vh; }
body.v2-active .v2cm-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 18px 10px; flex:0 0 auto; }
body.v2-active .v2cm-title { font-size:17px; font-weight:660; color:var(--ink); margin:0; outline:none; }
body.v2-active .v2cm-tabs { display:flex; gap:4px; padding:0 18px; border-bottom:1px solid var(--line); flex:0 0 auto; }
body.v2-active .v2cm-tab { appearance:none; border:none; background:none; font:inherit; font-size:13.5px; font-weight:550; color:var(--ink3); padding:8px 12px 10px; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; border-radius:var(--r-sm) var(--r-sm) 0 0; }
body.v2-active .v2cm-tab:hover { color:var(--ink); }
body.v2-active .v2cm-tab.on { color:var(--ink); border-bottom-color:var(--nav-active-underline); }   /* D-26 Step 6b: underline repointed --sulphur-deep → --nav-active-underline #808F00 (3.59:1 on the light .v2cm-panel). This is a SELECTION state (outside D-26's focus scope) but it falls under the BROADER sulphur principle — sulphur is a fill, never a stroke/text on a light surface, and an underline is a stroke. Both remaining sulphur-on-light markers (this + the §Z #157 nav icon) now use the same darkened-ramp member. Resolves the §Z #160 selection-marker finding. */
body.v2-active:not(.v2-pointer) .v2cm-tab:focus-visible { outline:none; box-shadow:var(--v2-focus-ring); }
/* B5 — content-driven body: no flex-grow (never stretches to a blank block); scrolls only past max-height */
body.v2-active .v2cm-body { padding:16px 18px 18px; overflow-y:auto; min-height:0; }
body.v2-active .v2cm-field { margin-bottom:12px; }
body.v2-active .v2cm-field label { display:block; font-size:var(--fs-2, 12px); font-weight:600; color:var(--ink2); margin-bottom:5px; }
/* B6 — DS control geometry inside the modal (the base .dr-field rules are #v2drawer-scoped; mirror them so controls aren't raw HTML). */
body.v2-active .v2cm-panel .dr-field { font:inherit; font-size:13.5px; color:var(--ink); background:var(--surface2); border:1px solid var(--line); border-radius:var(--r-sm); padding:8px 10px; width:100%; box-sizing:border-box; }
body.v2-active .v2cm-panel select.dr-field { cursor:pointer; appearance:none; -webkit-appearance:none; padding-right:30px; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa0aa' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 10px center; }
body.v2-active .v2cm-panel textarea.dr-field { min-height:74px; resize:vertical; line-height:1.5; display:block; }
body.v2-active .v2cm-panel .dr-field:focus { outline:none; }   /* D-26 Step 4b */
body.v2-active:not(.v2-pointer) .v2cm-panel .dr-field:focus-visible { box-shadow:var(--v2-focus-ring); }
/* B5 — Task: balanced two-column grid; equal-height columns so the primary column's Description grows to match the planning column. */
body.v2-active .v2cm-grid2 { display:grid; grid-template-columns:1fr 1fr; gap:0 16px; }
body.v2-active .v2cm-col { display:flex; flex-direction:column; min-width:0; }
body.v2-active .v2cm-col > .v2cm-field:last-child { margin-bottom:0; }
body.v2-active .v2cm-field-grow { flex:1 1 auto; display:flex; flex-direction:column; }
body.v2-active .v2cm-field-grow textarea.dr-field { flex:1 1 auto; min-height:120px; }
body.v2-active .v2cm-note { display:flex; align-items:flex-start; gap:6px; color:var(--ink3); background:var(--page); border:1px solid var(--line); border-radius:var(--r-sm); padding:8px 10px; margin-top:12px; }
body.v2-active .v2cm-note .ti { flex:0 0 auto; margin-top:1px; }
body.v2-active #v2cmErr.dr-field-err { display:flex; align-items:center; gap:6px; margin-top:4px; }
/* B7 — footer: explicit Cancel on the left, primary split on the right */
body.v2-active .v2cm-foot { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:12px 18px 16px; border-top:1px solid var(--line); flex:0 0 auto; }
/* B5 — one-column collapse on narrow viewports */
@media (max-width:560px){ body.v2-active .v2cm-grid2 { grid-template-columns:1fr; gap:0; } body.v2-active .v2cm-field-grow textarea.dr-field { min-height:88px; } }
/* accessible split-button (main Create + caret menu) */
body.v2-active .v2split { position:relative; display:inline-flex; }
body.v2-active .v2split-main { border-top-right-radius:0; border-bottom-right-radius:0; }
body.v2-active .v2split-caret { border-top-left-radius:0; border-bottom-left-radius:0; border-left:1px solid rgba(0,0,0,.18); padding-left:8px; padding-right:8px; min-width:0; }
body.v2-active .v2split-caret .ti { font-size:15px; }
body.v2-active .v2split-menu { position:absolute; right:0; bottom:calc(100% + 6px); min-width:180px; background:var(--surface); border:1px solid var(--line); border-radius:var(--r-sm); box-shadow:var(--elev-3); padding:5px; z-index:2; }
body.v2-active .v2split-item { display:block; width:100%; text-align:left; appearance:none; border:none; background:none; font:inherit; font-size:13px; color:var(--ink); padding:8px 10px; border-radius:var(--r-sm); cursor:pointer; }
body.v2-active .v2split-item:hover { background:var(--page); }
body.v2-active:not(.v2-pointer) .v2split-item:focus-visible { outline:none; box-shadow:var(--v2-focus-ring); }
body.v2-active .v2split-main:disabled, body.v2-active .v2split-caret:disabled, body.v2-active .v2cm-tab:disabled { opacity:var(--state-disabled-opacity); cursor:var(--state-disabled-cursor); }
/* B8 — actionable create toast (reuses the toast system; container already sits at top:64px, clear of the header) */
body.v2-active .v2cm-toast { display:flex; align-items:center; gap:10px; }
body.v2-active .v2cm-toast .v2cm-toast-btn { margin-left:6px; font:inherit; font-size:var(--fs-2, 12px); font-weight:700; color:var(--v2-focus, #4f5b93); background:none; border:none; cursor:pointer; text-decoration:underline; padding:0; flex:0 0 auto; }
/* B9 — transient reveal flash on the exact new task row */
@keyframes v2wsFlash { 0%{ background:var(--sulphur-tint); } 100%{ background:transparent; } }
body.v2-active .tk-row.v2ws-flash > td { animation:v2wsFlash 1.8s ease-out; }

/* Disabled (apply to any variant) */
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}


/* ── INPUT ────────────────────────────────────────────────────────────────
   Text/email/password/number/search. Sunken background — feels pressed-in.
   ────────────────────────────────────────────────────────────────────── */

.input {
  display: block;
  width: 100%;
  height: 36px;
  padding: 0 var(--space-3);
  font-family: var(--font-sans);
  font-size: var(--fs-3, 14px);
  line-height: 20px;
  color: var(--text-primary);
  background: var(--surface-sunken);
  border: var(--border-width-1) solid var(--border-default);
  border-radius: var(--radius-control);
  transition:
    border-color var(--motion-duration-fast) var(--ease-standard),
    background-color var(--motion-duration-fast) var(--ease-standard);
}

.input::placeholder {
  color: var(--text-tertiary);
}

.input:hover {
  border-color: var(--border-strong);
}

.input:focus {
  outline: none;
  border-color: var(--accent-default);
  background: var(--surface-elevated);
}

.input[aria-invalid="true"] {
  border-color: var(--status-error);
}

.input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}


/* ── BADGE ────────────────────────────────────────────────────────────────
   Variants: neutral | success | warning | error | info
   Use for: status pills (AT RISK, ACTIVE), tags, counts.
   AT RISK uses --warning. NEVER --accent (sulphur).
   ────────────────────────────────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  height: 20px;
  padding: 0 var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--fs-1, 11px);
  font-weight: var(--font-weight-medium);
  letter-spacing: var(--letter-spacing-wide);
  text-transform: uppercase;
  border-radius: var(--radius-badge);
  border: var(--border-width-1) solid transparent;
  white-space: nowrap;
}

.badge--neutral {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-secondary);
  border-color: var(--border-subtle);
}

.badge--success {
  background: var(--status-success-soft);
  color: var(--status-success-text);
}

.badge--warning {
  background: var(--status-warning-soft);
  color: var(--status-warning-text);
}

.badge--error {
  background: var(--status-error-soft);
  color: var(--status-error-text);
}

.badge--info {
  background: var(--status-info-soft);
  color: var(--status-info-text);   /* D-26 Step 1: was the raw --blue-500 primitive; repoint to the theme-aware, already-compliant semantic token (matches .icon--info) */
}

/* Count pill — small grey number after a section header.
   "All clients (12)" — the (12) is a count badge. */
.badge--count {
  height: 18px;
  padding: 0 var(--space-2);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-tertiary);
  border-color: var(--border-subtle);
  letter-spacing: 0;
  text-transform: none;
  font-size: var(--fs-1, 11px);
  font-variant-numeric: tabular-nums;
}


/* ── CARD ─────────────────────────────────────────────────────────────────
   The workhorse surface. Cards never use shadows in Operato — only borders.
   ────────────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface-elevated);
  border: var(--border-width-1) solid var(--border-subtle);
  border-radius: var(--radius-card);
  padding: var(--card-padding);
}

/* Interactive card — for clickable cards (rows in "Needs attention" list). */
.card--interactive {
  cursor: pointer;
  transition:
    border-color var(--motion-duration-fast) var(--ease-standard),
    background-color var(--motion-duration-fast) var(--ease-standard);
}
.card--interactive:hover {
  border-color: var(--border-default);
  background: var(--surface-overlay);
}

/* Stat card — for the dashboard KPI cards. */
.card--stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Hero stat card — the larger, featured stat (3.2x ROAS in Operato). */
.card--stat-hero {
  /* Sized larger by the layout, not by the card. The card itself just
     contains a different internal layout (sparkline below the number). */
}


/* ── AI INSIGHT CARD — the brand signature element ────────────────────────
   2px LEFT border in --accent-default. This is the visual signature for
   any AI-generated content in the product. Never use the left-border
   accent for non-AI content.
   ────────────────────────────────────────────────────────────────────── */



/* ── TABLE ────────────────────────────────────────────────────────────────
   The most-used surface in Operato. Compact, sticky header, hover states.
   Numeric columns RIGHT-aligned with tabular-nums. Always.
   ────────────────────────────────────────────────────────────────────── */

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-3, 14px);
  font-variant-numeric: tabular-nums;
}

.table thead {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--surface-base);
}

.table th {
  height: 32px;
  padding: 0 var(--space-3);
  text-align: left;
  font-size: var(--fs-1, 11px);
  font-weight: var(--font-weight-medium);
  letter-spacing: var(--letter-spacing-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-bottom: var(--border-width-1) solid var(--border-default);
  white-space: nowrap;
}

.table th[data-align="right"] { text-align: right; }
.table th[data-align="center"] { text-align: center; }

.table td {
  height: 40px;
  padding: 0 var(--space-3);
  color: var(--text-primary);
  border-bottom: var(--border-width-1) solid var(--border-subtle);
  vertical-align: middle;
}

.table td[data-align="right"] { text-align: right; }
.table td[data-align="center"] { text-align: center; }

/* Numeric column gap fix — between consecutive right-aligned columns,
   give 16px breathing room. */
.table td[data-align="right"] + td[data-align="right"] {
  padding-left: var(--space-4);
}
.table th[data-align="right"] + th[data-align="right"] {
  padding-left: var(--space-4);
}

/* Row hover — subtle bg shift. */
.table tbody tr:hover {
  background: rgba(255, 255, 255, 0.02);
}

/* Selected row — 2px left accent border + faint accent bg. */
.table tbody tr[aria-selected="true"] {
  background: var(--accent-trace);
  box-shadow: inset 2px 0 0 0 var(--accent-default);
}

/* Last row removes the bottom border so the table ends clean. */
.table tbody tr:last-child td {
  border-bottom: none;
}


/* ── SIDE PANEL — the B2B SaaS killer feature ──────────────────────────────
   Slides in from the right. 480px on desktop, full-width on mobile.
   ────────────────────────────────────────────────────────────────────── */

.side-panel {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: 480px;
  max-width: 100vw;
  z-index: var(--z-side-panel);
  background: var(--surface-elevated);
  border-left: var(--border-width-1) solid var(--border-default);
  box-shadow: var(--shadow-modal);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--motion-duration-normal) var(--ease-standard);
}

.side-panel[data-open="true"] {
  transform: translateX(0);
}

.side-panel__header {
  flex: 0 0 auto;
  padding: var(--space-5) var(--space-6);
  border-bottom: var(--border-width-1) solid var(--border-subtle);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.side-panel__body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--space-6);
}

.side-panel__footer {
  flex: 0 0 auto;
  padding: var(--space-4) var(--space-6);
  border-top: var(--border-width-1) solid var(--border-subtle);
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}


/* ── NAV ITEM — the sidebar nav entries with the 2px left border ──────────
   Active state uses 2px left accent border + primary text. NO background.
   This is the iteration-2 fix: less screaming, more confident.
   ────────────────────────────────────────────────────────────────────── */

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 32px;
  padding: 0 var(--space-3);
  /* Reserve space for the active border so text doesn't shift on activation. */
  border-left: var(--border-width-2) solid transparent;
  color: var(--text-secondary);
  font-size: var(--fs-3, 14px);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition:
    color var(--motion-duration-fast) var(--ease-standard);
}

.nav-item:hover {
  color: var(--text-primary);
}

.nav-item[aria-current="page"] {
  color: var(--text-primary);
  border-left-color: var(--nav-active-underline);   /* D-26 Step 3: was --accent-default (sulphur #E8FF6B, 1.11:1) → --nav-active-underline #808F00 (3.59:1), the token D-04 authored for exactly this marker and never wired. Selector currently matches no element (see §Z). */
}


/* ── AVATAR ───────────────────────────────────────────────────────────────
   Sizes: sm 20px | md 24px | lg 32px | xl 40px
   ────────────────────────────────────────────────────────────────────── */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--accent-subtle);
  color: var(--text-primary);
  font-size: var(--fs-1, 11px);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0;
  flex-shrink: 0;
  user-select: none;
}

.avatar--sm { width: 20px; height: 20px; font-size: 10px; }
.avatar--md { width: 24px; height: 24px; font-size: var(--fs-1, 11px); }
.avatar--lg { width: 32px; height: 32px; font-size: 13px; }
.avatar--xl { width: 40px; height: 40px; font-size: 15px; }


/* ── STATUS DOT — small colored dot for at-risk indicators ────────────────
   Placed inline with names. 8px circle. Use status-warning for at-risk,
   status-error for critical, status-success rarely (only when explicitly
   confirming health).
   ────────────────────────────────────────────────────────────────────── */

.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

.status-dot--warning { background: var(--status-warning); }
.status-dot--error   { background: var(--status-error); }
.status-dot--success { background: var(--status-success); }
.status-dot--neutral { background: var(--text-tertiary); }


/* ── TOAST NOTIFICATION ───────────────────────────────────────────────────
   Bottom-right. Auto-dismiss. Max 3 stacked.
   ────────────────────────────────────────────────────────────────────── */

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 320px;
  max-width: 400px;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-overlay);
  border: var(--border-width-1) solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-overlay);
  font-size: var(--fs-3, 14px);
  color: var(--text-primary);
}


/* =============================================================================
   LAYOUT PRIMITIVES
   Page-level layout helpers. Use these before reaching for ad-hoc CSS.
   ============================================================================= */

.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

.app-sidebar {
  background: var(--surface-elevated);
  border-right: var(--border-width-1) solid var(--border-subtle);
  padding: var(--space-4) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.app-main {
  padding: var(--space-8);
  max-width: 1440px;
  /* Don't center — left-align in the available column. */
}

/* The editorial hero block at the top of every main page. */
.editorial-hero {
  margin-bottom: var(--section-gap);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
}

.editorial-hero__content {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.editorial-hero__actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}


/* =============================================================================
   RESPONSIVE BREAKPOINTS (REFERENCE — apply per-component as needed)
   ============================================================================= */

/*
  --breakpoint-sm:  640px;   single column, mobile
  --breakpoint-md:  768px;   tablet, 2-column grids
  --breakpoint-lg:  1024px;  small desktop, sidebar appears
  --breakpoint-xl:  1280px;  full desktop layout
  --breakpoint-2xl: 1440px;  max content width
*/


/* =============================================================================
   ICON SYSTEM (Iconoir + Simple Icons + operato wordmark)
   Added 2026-05 by aos-icon-migration
   ============================================================================= */

/* Default icon sizing for Iconoir */
i[class^="iconoir-"], i[class*=" iconoir-"] {
  font-size: 18px;
  line-height: 1;
  vertical-align: -2px;
  display: inline-block;
}

.icon--sm   { font-size: 14px !important; vertical-align: -1px !important; }
.icon--md   { font-size: 18px !important; vertical-align: -2px !important; }
.icon--lg   { font-size: 24px !important; vertical-align: -4px !important; }
.icon--xl   { font-size: 32px !important; vertical-align: -6px !important; }

.icon--primary    { color: var(--text-primary); }
.icon--secondary  { color: var(--text-secondary); }
.icon--tertiary   { color: var(--text-tertiary); }
.icon--accent     { color: var(--accent-default); }
.icon--success    { color: var(--status-success-text); }
.icon--warning    { color: var(--status-warning-text); }
.icon--error      { color: var(--status-error-text); }
.icon--info       { color: var(--status-info-text); }

/* Brand logo from Simple Icons CDN */
.brand-logo {
  width: 24px;
  height: 24px;
  display: inline-block;
  vertical-align: middle;
  border-radius: 4px;
}
.brand-logo--sm { width: 16px; height: 16px; }
.brand-logo--lg { width: 32px; height: 32px; }
.brand-logo--xl { width: 48px; height: 48px; }

/* ============ Operato Triangulation logo ============ */

/* Container — icon + wordmark side-by-side, tight spacing */
.operato-wordmark {
  font-family: 'Inter Variable', Inter, system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  gap: 6px;                /* tight gap — icon close to text */
  font-size: 18px;         /* default size */
  line-height: 1;
}

/* Triangulation icon — inline SVG via ::before */
.operato-wordmark::before {
  content: "";
  display: inline-block;
  width: 1em;
  height: 1em;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='6' r='3' fill='%23E8FF6B'/><circle cx='4' cy='20' r='3' fill='%23F1EFE8'/><circle cx='20' cy='20' r='3' fill='%23F1EFE8'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  flex-shrink: 0;
}

/* Size variants — icon scales with em */
.operato-wordmark--sm { font-size: 14px; gap: 5px; }
.operato-wordmark--lg { font-size: 24px; gap: 8px; }
.operato-wordmark--xl { font-size: 32px; gap: 10px; }

/* Icon-only variants (collapsed sidebar, favicon-style placement) */
.operato-mark {
  display: inline-block;
  width: 24px;
  height: 24px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='6' r='3' fill='%23E8FF6B'/><circle cx='4' cy='20' r='3' fill='%23F1EFE8'/><circle cx='20' cy='20' r='3' fill='%23F1EFE8'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  flex-shrink: 0;
  vertical-align: middle;
}
.operato-mark--sm { width: 16px; height: 16px; }
.operato-mark--lg { width: 32px; height: 32px; }
.operato-mark--xl { width: 48px; height: 48px; }

/* ============ Sidebar nav icon states (Phase 2a) ============ */

/* Mobile/main sidebar nav items */
.nav-item .nav-icon i[class^="iconoir-"],
.nav-item .nav-icon i[class*=" iconoir-"] {
  font-size: 16px;
  vertical-align: -2px;
  color: var(--text-secondary);
  transition: color 0.15s ease;
}
.nav-item:hover .nav-icon i[class^="iconoir-"],
.nav-item:hover .nav-icon i[class*=" iconoir-"] {
  color: var(--text-primary);
}
.nav-item.active .nav-icon i[class^="iconoir-"],
.nav-item.active .nav-icon i[class*=" iconoir-"] {
  color: var(--nav-active-underline);   /* D-26 Step 6b (§Z #157): was var(--accent-default) — sulphur #E8FF6B at 1.11:1 on the light sidebar, a live 1.4.11 failure. Repointed to --nav-active-underline #808F00 (3.59:1), the darkened-ramp member Step 3 used for the nav marker. Legacy sidebar icon goes lime→olive; accepted — legacy is retiring but the principle applies while it ships. */
}

/* Mobile sidebar group headers (collapsible) */
.p5-nav-group-header i[class^="iconoir-"],
.p5-nav-group-header i[class*=" iconoir-"] {
  font-size: 16px;
  vertical-align: -2px;
  margin-right: 4px;
  color: var(--text-secondary);
}

/* Desktop P6 rail icons */
.p6-nav-icon i[class^="iconoir-"],
.p6-nav-icon i[class*=" iconoir-"] {
  font-size: 20px;
  vertical-align: -3px;
  color: inherit;
}

/* P6 flyout sub-items */
.p6-flyout-item-icon i[class^="iconoir-"],
.p6-flyout-item-icon i[class*=" iconoir-"] {
  font-size: 16px;
  vertical-align: -2px;
  color: var(--text-secondary);
  transition: color 0.15s ease;
}
.p6-flyout-item:hover .p6-flyout-item-icon i[class^="iconoir-"],
.p6-flyout-item:hover .p6-flyout-item-icon i[class*=" iconoir-"] {
  color: var(--text-primary);
}
.p6-flyout-item.p6-flyout-active .p6-flyout-item-icon i[class^="iconoir-"],
.p6-flyout-item.p6-flyout-active .p6-flyout-item-icon i[class*=" iconoir-"] {
  color: var(--accent-default);
}

/* ============ Wave 1A — Client Profile sub-tabs ============ */

.wave1-task-row { font-family: inherit; color: var(--text-primary); }
.wave1-task-row:hover { border-color: var(--border-default); }

.wave1-onb-item { font-family: inherit; color: var(--text-primary); }
.wave1-onb-item:hover { background: var(--surface-elevated); }

/* ============ Wave 1C — Intelligence Profile ============ */

.wave1-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
}
.wave1-icon-btn:hover {
  background: var(--surface-elevated);
  border-color: var(--border-default);
  color: var(--text-primary);
}

/* ============ Wave 1E — Documents folder cards + Timeline filter pills ============ */

.wave1-doc-folder {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave1-doc-folder:hover {
  border-color: var(--accent-default);
  background: var(--surface-elevated);
}

/* Override legacy .p4-timeline-filter-btn with Operato sulphur-underline pattern */
.p4-timeline-filter-btn {
  padding: 10px 16px;
  background: transparent;
  border: none;
  border-radius: 0;
  cursor: pointer;
  white-space: nowrap;
  font-family: inherit;
  font-size: 13px;
  color: var(--text-secondary);
  font-weight: 500;
  transition: color 0.15s ease, box-shadow 0.15s ease;
}
.p4-timeline-filter-btn:hover {
  background: transparent;
  color: var(--text-primary);
}
.p4-timeline-filter-btn.active {
  background: transparent;
  color: var(--text-primary);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--accent-default);
  border-color: transparent;
}

/* ============ Wave 2A — Tasks page ============ */

.wave2-task-row { font-family: inherit; color: var(--text-primary); }
.wave2-task-row:hover { border-color: var(--border-default); }

/* ============ Wave 2B — Projects page ============ */

.wave2-project-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave2-project-card:hover {
  border-color: var(--accent-default);
}

/* ============ Wave 2C — CRM kanban + drag-drop ============ */

.wave2-pipeline-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave2-pipeline-stat:hover { border-color: var(--accent-default); }

.wave2-crm-col { transition: background 0.15s ease, border-color 0.15s ease; }
.wave2-crm-col.drag-over {
  background: rgba(232, 255, 107, 0.05);
  border-color: var(--accent-default);
}

.wave2-lead-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  cursor: grab;
  transition: border-color 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave2-lead-card:hover { border-color: var(--border-default); }
.wave2-lead-card:active { cursor: grabbing; }

/* Active drop zone state on Won/Lost .card sections (shared with .drag-over hook) */
.card.drag-over {
  background: rgba(232, 255, 107, 0.05);
  border-color: var(--accent-default);
}

/* ============ Wave 3A — Templates Library ============ */

.wave3-template-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  transition: border-color 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave3-template-card:hover {
  border-color: var(--accent-default);
}

/* ============ Wave 3D — Resources / Capacity ============ */
.wave3-capacity-card {
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-input);
  background: var(--surface-elevated);
  transition: border-color 0.15s ease;
  font-family: inherit;
  color: var(--text-primary);
}
.wave3-capacity-card:hover { border-color: var(--accent-default); }

/* ============ Wave 3E1 — Creative Hub Gallery ============ */
.ch-list-table tbody tr:hover { background: var(--surface-elevated); }
.ch-view-btn.active {
  background: var(--accent-default);
  color: var(--text-on-accent, #000);
  border-color: var(--accent-default);
}

/* ============ Wave 3E2 — Creative Hub Detail ============ */
.ch-modal-preview { display: block; }
.ch-perf-table tbody tr:hover { background: var(--surface-elevated); }

/* ============ Wave 4C — Tags Management ============ */
.wave4-tag-card { font-family: inherit; color: var(--text-primary); }
.wave4-tag-card:hover { border-color: var(--accent-default); }
.p3-color-option {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.p3-color-option:hover { transform: scale(1.1); }
.p3-color-option.selected { border-color: var(--accent-default) !important; }

/* ============ Wave 5A — Archive ============ */
.archive-month-header:hover { background: var(--surface-elevated); }
.archive-month-header > i { transition: transform 0.15s ease; }
.archive-month-header.collapsed > i { transform: rotate(-90deg); }
.archive-task:hover { background: var(--surface-elevated); }

/* =============================================================================
   WAVE 2 / STAGE 1 — COMPONENT CLASSES (additive; consume Layer-3 tokens only)
   Opt-in classes only — no production markup uses these yet (styleguide route
   demonstrates them). No raw hex; every value → a token or brief-specified rgba().
   ============================================================================= */

/* Global focus-visible: keyboard-only ring on native focusables + opt-in roles.
   Scoped to .btn/.link/.input/.op-row/[role="button"] so legacy flag-off focus
   (which uses its own styles and is never given these classes) is unchanged. */
.btn:focus-visible,
.link:focus-visible,
.input:focus-visible,
.op-row:focus-visible,
[role="button"].btn:focus-visible,
a.link:focus-visible {
  outline: none;
  box-shadow: var(--v2-focus-ring);   /* D-26 Step 4a: was sulphur --focus-ring (1.11:1) */
}

/* ── BUTTON ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--button-gap);
  height: var(--button-height-md);
  padding: 0 var(--button-padding-x);
  border: 1px solid transparent;
  border-radius: var(--button-radius);
  font: inherit; font-weight: var(--button-font-weight); line-height: 1;
  cursor: pointer; -webkit-appearance: none; appearance: none;
  transition: background var(--motion-duration-fast) var(--ease-standard),
              box-shadow var(--motion-duration-fast) var(--ease-standard);
}
.btn--sm { height: var(--button-height-sm); }
.btn--lg { height: var(--button-height-lg); }
.btn--primary { background: var(--button-primary-bg); color: var(--button-primary-text); border-color: var(--button-primary-bg); }
.btn--primary:hover { background: var(--button-primary-bg-hover); }
.btn--primary:active { background: var(--button-primary-bg-active); }
.btn--secondary { background: var(--button-secondary-bg); color: var(--button-secondary-text); border-color: var(--button-secondary-border); }
.btn--secondary:hover { background: var(--button-secondary-bg-hover); }
.btn--ghost { background: transparent; color: var(--text-primary); }
.btn--ghost:hover { background: var(--button-ghost-bg-hover); }
.btn--destructive { background: var(--button-destructive-bg); color: var(--button-destructive-text); }
/* selected */
/* selected = subtle lime tint fill (distinct from the focus ring, which stays an outer outline) */
.btn[aria-selected="true"], .btn[data-selected] { background: color-mix(in srgb, var(--accent-default) 16%, var(--button-secondary-bg)); }
/* disabled */
.btn:disabled, .btn[aria-disabled="true"] { cursor: not-allowed; }
.btn--primary:disabled, .btn--primary[aria-disabled="true"] { background: var(--button-primary-disabled-bg); color: var(--button-primary-disabled-text); }
/* loading — spinner sits inline BEFORE the (still-visible) label, 8px gap via --button-gap,
   vertically centered by .btn's align-items. Give a loading-capable button a min-width so the
   label→spinner transition doesn't reflow (demoed in the styleguide). */
.btn[data-loading="true"] { pointer-events: none; }
.btn[data-loading="true"]::before {
  content: ""; display: inline-block; flex: 0 0 auto;
  width: 14px; height: 14px;
  border: 2px solid currentColor; border-top-color: transparent;
  border-radius: var(--radius-pill);
  animation: op-spin var(--motion-duration-slow) linear infinite;
}
@keyframes op-spin { to { transform: rotate(360deg); } }

/* ── LINK (underline-on-hover is the non-color affordance) ───────────────── */
.link { color: var(--link-text); text-decoration: underline; text-underline-offset: var(--link-underline-offset); cursor: pointer; } /* always-underlined: the non-colour link affordance */
.link:hover { color: var(--link-text-hover); text-decoration: underline; }
.link:active { color: var(--link-text-hover); }

/* ── INPUT ───────────────────────────────────────────────────────────────── */
.input {
  display: inline-flex; align-items: center; width: 100%;
  min-height: var(--input-height);
  padding: var(--input-padding-y) var(--input-padding-x);   /* Micha 12px 14px */
  background: var(--input-bg); color: var(--input-text);
  border: 1px solid var(--input-border); border-radius: var(--input-radius);
  font: inherit; -webkit-appearance: none; appearance: none;
  transition: border-color var(--motion-duration-fast) var(--ease-standard),
              box-shadow var(--motion-duration-fast) var(--ease-standard);
}
.input::placeholder { color: var(--input-placeholder); }
.input:hover { border-color: var(--input-border-hover); }
.input:focus, .input:focus-visible { outline: none; box-shadow: var(--v2-focus-ring); }   /* D-26 Step 4a: was sulphur --input-border-focus + --input-focus-ring (1.11:1/1.03:1); the canonical ring */
.input:disabled, .input[aria-disabled="true"] { background: var(--input-disabled-bg); color: var(--text-disabled); cursor: not-allowed; opacity: 0.6; }   /* light & muted */
.input--error, .input[aria-invalid="true"] { border-color: var(--input-border-error); }
.input--success { border-color: var(--input-border-success); }

/* ── TABLE ───────────────────────────────────────────────────────────────── */
.op-table { width: 100%; border-collapse: collapse; }
.op-table thead th, .op-cell--head {
  height: var(--table-header-height);
  background: var(--table-header-bg); color: var(--table-header-text);
  font-weight: var(--table-header-weight); text-align: left;
  padding: 0 var(--table-cell-padding-x);
}
.op-row { height: var(--table-row-height); border-bottom: 1px solid var(--table-row-border); }
.op-row:hover { background: var(--table-row-bg-hover); }
.op-row[aria-selected="true"], .op-row[data-selected] { background: var(--table-row-bg-selected); box-shadow: var(--table-row-selected-marker); }
.op-cell { padding: 0 var(--table-cell-padding-x); color: var(--text-primary); vertical-align: middle; }
.op-cell--num { text-align: right; font-variant-numeric: tabular-nums; }
.op-cell--sticky { position: sticky; left: 0; background: var(--surface-base); box-shadow: var(--table-sticky-col-shadow); }

/* ── TOOLTIP / INFO (health-score explainer et al.) ──────────────────────── */
.op-tooltip { position: relative; display: inline-flex; }
.op-tooltip__bubble {
  position: absolute; bottom: calc(100% + var(--space-2)); left: 50%; transform: translateX(-50%);
  background: var(--tooltip-bg); color: var(--tooltip-text);
  border-radius: var(--tooltip-radius); box-shadow: var(--tooltip-shadow);
  padding: var(--space-2) var(--space-3); white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity var(--motion-duration-fast) var(--ease-standard);
}
.op-tooltip:hover .op-tooltip__bubble,
.op-tooltip:focus-within .op-tooltip__bubble { opacity: 1; }

/* ── AS-OF DATE data-label (feedback synthesis design rule #3) ────────────── */
.op-asof { color: var(--text-tertiary); }

/* ── STYLEGUIDE-SCOPED button + focus recipe ──────────────────────────────
   The pre-existing inline `body.v2-active #v2Page .btn` rules out-specify the
   plain `.btn--*` classes (they set the base `.btn` background/border). Reconciling
   that competing inline set is Wave 4. To let the styleguide actually SHOW the new
   --button-* family, scope the recipe to `#op-styleguide` (the styleguide route only)
   with a 2-ID selector so it wins WITHOUT !important and WITHOUT editing those rules.
   Production screens have no #op-styleguide, so they are untouched. */
#v2Page #op-styleguide .btn--primary { background: var(--button-primary-bg); color: var(--button-primary-text); border-color: transparent; }
#v2Page #op-styleguide .btn--primary:hover { background: var(--button-primary-bg-hover); }
#v2Page #op-styleguide .btn--primary:active { background: var(--button-primary-bg-active); }
#v2Page #op-styleguide .btn--primary:disabled,
#v2Page #op-styleguide .btn--primary[aria-disabled="true"] { background: var(--button-primary-disabled-bg); color: var(--button-primary-disabled-text); }
#v2Page #op-styleguide .btn--secondary { background: var(--button-secondary-bg); color: var(--button-secondary-text); border-color: var(--button-secondary-border); }
#v2Page #op-styleguide .btn--secondary:hover { background: var(--button-secondary-bg-hover); }
#v2Page #op-styleguide .btn--ghost { background: transparent; color: var(--text-primary); border-color: transparent; }
#v2Page #op-styleguide .btn--ghost:hover { background: var(--button-ghost-bg-hover); }
#v2Page #op-styleguide .btn--destructive { background: var(--button-destructive-bg); color: var(--button-destructive-text); border-color: transparent; }
#v2Page #op-styleguide .btn[data-selected],
#v2Page #op-styleguide .btn[aria-selected="true"] { background: color-mix(in srgb, var(--accent-default) 16%, var(--button-secondary-bg)); box-shadow: none; }
/* Focus-ring is the ONE case that needs !important: the app owns a deliberate unified v2
   focus system — `body.v2-active:not(.v2-pointer) #v2Page *:focus-visible { box-shadow:
   var(--v2-focus-ring) !important }` (indigo, keyboard-only). No plain-specificity selector can
   beat an !important, so to show the NEW accent --focus-ring on the styleguide we match it with a
   higher-specificity (2-ID) !important, scoped to #op-styleguide only. The app rule is untouched;
   the rest of v2 keeps its indigo ring. D-26 Step 4b: the two sulphur focus systems are now DELETED and consolidated under the canonical --v2-focus-ring; the ONE exception is the command palette (--cmdp-accent, measured — see §Z). */
/* Inputs hit the same competing #v2Page layer: `body.v2-active #v2Page *` zeroes .input padding
   (beaten cleanly by 2 IDs), and the app's !important focus system overrides the focus ring (needs
   !important, same as the button ring). Scoped to #op-styleguide only; production inputs untouched. */
#v2Page #op-styleguide .input { padding: var(--input-padding-y) var(--input-padding-x); }

/* ═══ STYLEGUIDE PRESENTATION (Wave 2 Category-B) — document polish, scoped to #op-styleguide
   ONLY. Presentation/layout helpers for the shareable deliverable; NO token value changes,
   NO production impact (production screens have no #op-styleguide). ═══ */
#v2Page #op-styleguide { max-width: 1240px; margin-inline: auto; }
#v2Page #op-styleguide .sg-section { margin-top: var(--space-4); }
#v2Page #op-styleguide .sg-desc { color: var(--text-secondary); margin: var(--space-1) 0 var(--space-3); max-width: 72ch; }
#v2Page #op-styleguide .sg-note { color: var(--ink3); }   /* WS-1A PR-4: was var(--text-secondary) #6b6d7b = 4.49:1 on the new shell --layer-00 #EEF0F4 (was AA on the old #f6f7f9 page). --ink3 #5f6570 = 5.14:1 on the shell — the tertiary token this PR added the pair for. */
#v2Page #op-styleguide .sg-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); align-items: start; }
/* fields: label + input + helper/status message */
#v2Page #op-styleguide .sg-field { display: flex; flex-direction: column; }
#v2Page #op-styleguide .sg-label { text-transform: uppercase; font-size: var(--fs-2, 12px); letter-spacing: 0.06em; font-weight: 600; color: var(--text-secondary); margin-bottom: var(--space-1); }
#v2Page #op-styleguide .sg-msg { font-size: 12.5px; color: var(--text-tertiary); margin-top: 5px; display: inline-flex; align-items: center; gap: 5px; }
#v2Page #op-styleguide .sg-msg--error { color: var(--status-error); }
#v2Page #op-styleguide .sg-msg--success { color: var(--status-success); }
#v2Page #op-styleguide .sg-msg .ti { font-size: var(--fs-3, 14px); }
/* colour-token doc rows: swatch · name · value · role/contrast */
#v2Page #op-styleguide .sg-tokrow { display: grid; grid-template-columns: 44px minmax(140px,1.2fr) minmax(96px,0.9fr) 1.7fr; gap: var(--space-3); align-items: center; padding: var(--space-2) 0; border-bottom: 1px solid var(--border-subtle); }
#v2Page #op-styleguide .sg-tokrow:last-child { border-bottom: 0; }
#v2Page #op-styleguide .sg-sw { width: 34px; height: 34px; border-radius: var(--radius-sm); border: 1px solid var(--border-subtle); box-shadow: var(--elevation-border); }
#v2Page #op-styleguide .sg-tokval { font-variant-numeric: tabular-nums; color: var(--text-secondary); text-transform: uppercase; }
/* financial table: constrained width, taller rows */
#v2Page #op-styleguide .sg-tablewrap { max-width: 680px; overflow-x: auto; }
#v2Page #op-styleguide .sg-tablewrap .op-row { height: 46px; }
/* tooltip: always-open + long-content demos */
#v2Page #op-styleguide .op-tooltip__bubble { max-width: 280px; white-space: normal; }
#v2Page #op-styleguide .op-tooltip--open .op-tooltip__bubble { position: static; transform: none; opacity: 1; display: inline-block; margin-top: var(--space-2); pointer-events: auto; }
/* elevation demo tiles */
#v2Page #op-styleguide .sg-elev { padding: var(--space-4); border-radius: var(--radius-card); background: var(--surface-elevated); color: var(--text-secondary); display: flex; flex-direction: column; gap: 3px; }

/* =============================================================================
   END — OPERATO DESIGN SYSTEM v1.0
   ============================================================================= */
