/* ============================================================
   FLUXATH CRM — FLUXDECK theme (user-selectable, additive)

   Gated entirely under [data-theme="fluxdeck"] — the exact scoping
   shape of static/reskin-v2.css (loaded unconditionally, zero effect
   unless <html data-theme="fluxdeck">). Pick it from the account
   menu's Theme selector; persists per-user via POST /api/user/theme.

   Contents = the FLUXDECK design system from rework/p4v2-foundation
   (static/css/tokens.css + static/css/primitives.css), mechanically
   scoped. Two deliberate deltas from the source branch:
     1. The emoji-grayscale rule (fix 9: `filter: grayscale(1)
        brightness(1.5)` on nav/tabbar/account icons) is DROPPED —
        nav emojis stay colored in every theme (Kevin's call).
     2. Selectors reconciled against THIS branch's base.html (the
        prod shell, not the FLUXDECK-rebuilt shell): the
        .fx-atmosphere-canvas underlay div was added to base.html,
        and the shell rules target the live selectors
        (.sidebar/.topbar/.nav-link/.acct-dropdown/...) which the
        two branches share.

   FLUXDECK intentionally ignores data-accent and data-density —
   its token block re-declares --accent/--brand/etc. AFTER style.css's
   [data-accent="…"] blocks at equal specificity, so source order
   wins and the FLUXDECK palette is total. Light/dark keep the full
   accent/density system untouched.

   @font-face stays unscoped (fonts only download when a rule under
   the fluxdeck scope references them). @keyframes names are fx-*
   prefixed — collision-free with style.css.
   ============================================================ */

/* ============================================================
   FLUXDECK — design tokens (v2, P4v2 foundation)
   Source of truth: ~/.claude/state/crm-rework/design-direction.md
   ("FLUXDECK" v2) §2 color · §3 type · §4 depth · §5 motion.
   Every hex in the §2 block below is transcribed verbatim from that doc.
   Derived values (text-safe accent inks, tint alphas, scrim) are marked
   DERIVED and are mechanically gated by tools/contrast_check.py (§8).

   Dark-only: base.html hardcodes <html data-theme="dark">. There is no
   light theme in v2 — the dark IS the identity (§7 anti-goals).

   Cascade contract: this file loads AFTER static/style.css, so every
   token re-declared here WINS by source order. Selector `:root,
   :root[data-theme]` out-specifies style.css's `[data-theme="dark"]`
   blocks (0,2,0 vs 0,1,0) so the bridge below cannot be shadowed.
   ============================================================ */

/* ---------- §3 Typography — self-hosted woff2, strict CSP, no CDN ----------
   Archivo + Schibsted Grotesk ship as variable woff2 (single file spans
   the declared weight range); IBM Plex Mono ships static 500/600.
   All OFL-licensed, downloaded from Google Fonts gstatic (latin subset). */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 600 800;               /* variable wght axis */
  font-stretch: 112.5%;               /* SemiExpanded — industrial confidence */
  font-display: swap;
  src: url("../fonts/archivo-semiexpanded.var.woff2") format("woff2");
}
@font-face {
  font-family: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 400 700;               /* variable wght axis */
  font-display: swap;
  src: url("../fonts/schibsted-grotesk.var.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-500.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono-600.woff2") format("woff2");
}

/* ============================================================
   Theme-independent tokens — type scale, radii, z, motion, depth
   ============================================================ */
[data-theme="fluxdeck"] {
  /* ---------- §3 font stacks (never Inter/Roboto/system-ui as primary) ---------- */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-ui: "Schibsted Grotesk", -apple-system, "Segoe UI", Helvetica, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  /* ---------- §3 scale (dense work tool — 6h/day compact-first) ---------- */
  --fs-body: 13.5px;   --lh-body: 1.5;
  --fs-table: 13px;
  --fs-h1: 24px;       /* Archivo 700 */
  --fs-h2: 18px;
  --fs-h3: 15px;
  --fs-micro: 11px;    /* micro-caps labels */
  --track-micro: 0.08em;

  /* ---------- §4 radius system ---------- */
  --radius-card: 10px;   /* cards, drawers, modals */
  --radius-btn: 8px;     /* buttons, inputs */
  --radius-chip: 6px;    /* chips */
  --radius-pill: 999px;  /* count badges ONLY (§7: no pill buttons) */

  /* ---------- §4 depth: elevation = lighter bg + 1px border + shadow ---------- */
  --shadow-card: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-overlay: 0 12px 40px rgba(0, 0, 0, .55);
  /* Machined edge — inset top highlight on raised surfaces */
  --edge-machined: inset 0 1px 0 rgba(255, 255, 255, .04);
  /* Composites (box-shadow lists) for one-property consumption */
  --elev-card: var(--shadow-card), var(--edge-machined);
  --elev-overlay: var(--shadow-overlay), var(--edge-machined);

  /* Scrim — blue-black, never pure black (DERIVED, §2 spirit) */
  --scrim: rgba(6, 9, 18, .62);

  /* ---------- §5 motion (fast + mechanical; command decks don't bounce) ---------- */
  --dur-press: 120ms;      /* hover/press lower bound */
  --dur-hover: 150ms;      /* hover/press upper bound */
  --dur-overlay: 220ms;    /* drawers/popovers */
  --dur-stagger: 30ms;     /* first-paint row reveal step (first 12 rows) */
  --ease-out: cubic-bezier(0, 0, .2, 1);
  --ease-deck: cubic-bezier(.2, .8, .2, 1);

  /* ---------- z-scale (structure reused from the B1b shell rebuild) ---------- */
  --z-nav: 100;
  --z-sticky: 200;
  --z-dropdown: 500;
  --z-popover: 600;
  --z-panel: 700;
  --z-overlay: 800;
  --z-modal: 850;
  --z-dialer: 900;
  --z-toast: 950;

  /* ---------- §2 glow rules — focus ring (glow = live/armed, nowhere else) ---------- */
  --focus-ring: 0 0 0 1px var(--volt), 0 0 20px rgba(77, 124, 255, .18);
}

/* ============================================================
   §2 Color system — all values final; this file is source of truth
   ============================================================ */
[data-theme="fluxdeck"] {
  /* ---------- base neutrals (blue-cast, never pure black) ---------- */
  --bg-0: #0A0E16;   /* app canvas */
  --bg-1: #101624;   /* panels, rail, columns */
  --bg-2: #161E30;   /* cards, rows-raised, inputs-on-panel */
  --bg-3: #1C2540;   /* popovers, drawers, toasts, modals */
  --line-1: #232E4A; /* hairline borders, dividers, chart grid */
  --line-2: #2E3B60; /* strong borders, focused-adjacent */

  /* ---------- ink (AA table is LAW — see §8 + tools/contrast_check.py) ---------- */
  --ink-0: #F2F5FF;  /* primary text */
  --ink-1: #C3CCE6;  /* secondary text */
  --ink-2: #8A96BD;  /* tertiary, labels, micro-caps (AA ≥4.5 vs bg-0/1/2) */
  --ink-3: #5E6A94;  /* DECORATIVE/DISABLED ONLY — never carries information
                        required to read or act (mechanized: contrast_check.py
                        rejects any body-text pair naming ink-3). */

  /* ---------- the flux accents (vivid, MEANING-BEARING) ---------- */
  --volt:   #4D7CFF; /* electric blue — primary actions, focus, selection, links */
  --pulse:  #9D6BFF; /* violet — AI/automation/workflows surfaces */
  --signal: #3DDC97; /* electric mint — money, success, LIVE/active */
  --ice:    #4DD8FF; /* cyan — info, new/unclaimed */
  --flare:  #FFB84D; /* amber — warnings, callbacks, pending */
  --heat:   #FF5C7A; /* red — danger, losses, failures */

  /* ---------- DERIVED: text-safe accent inks ----------
     Raw volt/pulse/heat fall under 4.5:1 as body-size TEXT on tinted
     surfaces (volt on volt-tint/bg-2 = 4.3:1). §8 AA is LAW, so TEXT in
     an accent family uses --X-ink; fills/borders/rings/icons keep the
     raw accent. signal/ice/flare are bright enough that ink == raw. */
  --volt-ink:   #7D9BFF;
  --pulse-ink:  #AE88FF;
  --signal-ink: #3DDC97;
  --ice-ink:    #4DD8FF;
  --flare-ink:  #FFB84D;
  --heat-ink:   #FF7D93;

  /* Hover-brighten fills (primary CTA hover keeps dark text ≥4.5) */
  --volt-strong:   #6B92FF;
  --pulse-strong:  #AE88FF;
  --signal-strong: #63E5AC;
  --heat-strong:   #FF7D93;

  /* ---------- §2 tinted surface recipe: accent @10–12% over bg
     + accent-ink text + 1px accent @30% border ---------- */
  --volt-tint:   rgba(77, 124, 255, .11);
  --pulse-tint:  rgba(157, 107, 255, .11);
  --signal-tint: rgba(61, 220, 151, .11);
  --ice-tint:    rgba(77, 216, 255, .11);
  --flare-tint:  rgba(255, 184, 77, .11);
  --heat-tint:   rgba(255, 92, 122, .11);

  --volt-border:   rgba(77, 124, 255, .30);
  --pulse-border:  rgba(157, 107, 255, .30);
  --signal-border: rgba(61, 220, 151, .30);
  --ice-border:    rgba(77, 216, 255, .30);
  --flare-border:  rgba(255, 184, 77, .30);
  --heat-border:   rgba(255, 92, 122, .30);

  /* Lower-alpha volt washes (§5/§6 exact specs) */
  --volt-tint-8: rgba(77, 124, 255, .08);   /* ghost hover, selected rows */
  --volt-wash-6: rgba(77, 124, 255, .06);   /* kanban drop-target column */
  --volt-drag-outline: rgba(77, 124, 255, .40); /* dashed drop outline */

  /* Text/UI on accent fills: bg-0 as ink (primary button ≈5:1 on volt) */
  --on-accent: #0A0E16;

  /* Neutral row hover (§6 tables) */
  --row-hover: rgba(255, 255, 255, .03);

  /* ---------- §2 pipeline stage color map (fixed, app-wide) ----------
     chips, kanban, charts. Lost/Dead deliberately maps to ink-2 (a
     TEXT-SAFE neutral), not ink-3. */
  --stage-new: var(--ice);            --stage-new-ink: var(--ice-ink);
  --stage-new-tint: var(--ice-tint);  --stage-new-border: var(--ice-border);
  --stage-contacted: var(--volt);           --stage-contacted-ink: var(--volt-ink);
  --stage-contacted-tint: var(--volt-tint); --stage-contacted-border: var(--volt-border);
  --stage-booked: var(--pulse);           --stage-booked-ink: var(--pulse-ink);
  --stage-booked-tint: var(--pulse-tint); --stage-booked-border: var(--pulse-border);
  --stage-won: var(--signal);           --stage-won-ink: var(--signal-ink);
  --stage-won-tint: var(--signal-tint); --stage-won-border: var(--signal-border);
  --stage-callback: var(--flare);           --stage-callback-ink: var(--flare-ink);
  --stage-callback-tint: var(--flare-tint); --stage-callback-border: var(--flare-border);
  --stage-lost: var(--ink-2);
  /* DERIVED: ink-2 itself reads 4.36:1 on the lost tint over bg-3 —
     chip TEXT for lost/dead uses this slightly-lifted neutral instead
     (fills/indicators keep --stage-lost = ink-2). */
  --stage-lost-ink: #94A0C7;
  --stage-lost-tint: rgba(138, 150, 189, .11);
  --stage-lost-border: rgba(138, 150, 189, .30);

  /* ---------- §6 charts: series order volt→signal→pulse→ice→flare ---------- */
  --chart-1: var(--volt);
  --chart-2: var(--signal);
  --chart-3: var(--pulse);
  --chart-4: var(--ice);
  --chart-5: var(--flare);
  --chart-grid: var(--line-1);
  --chart-fill-alpha: 12%;   /* area fills */
}

/* ============================================================
   Semantic aliases + LEGACY BRIDGE
   base.html's inline CSS/JS and the not-yet-rebuilt templates consume
   the old style.css custom-property names. Re-pointing them here makes
   the staged hybrid coherent (dark, FLUXDECK neutrals + accents)
   without touching ~65 templates before their waves.
   DELETE the bridge once wave 8 lands and style.css retires.
   ============================================================ */
[data-theme="fluxdeck"] {
  /* semantic accents */
  --accent: var(--volt);
  --accent-strong: var(--volt-strong);
  --accent-soft: var(--volt-tint);
  --accent-bright: var(--volt-ink);
  --accent-hover: var(--volt-strong);
  --accent-primary: var(--volt);
  --accent-line: var(--volt-border);
  --accent-muted: var(--volt-ink);
  --brand: var(--volt);
  --brand-deep: #3555C4;          /* DERIVED: fill/gradient use only, never text */
  --brand-bright: var(--volt-ink);
  --brand-soft: var(--volt-tint);

  /* semantic state */
  --danger: var(--heat);
  --danger-soft: var(--heat-tint);
  --ok: var(--signal);
  --ok-soft: var(--signal-tint);
  --success: var(--signal);
  --warn: var(--flare);
  --warn-soft: var(--flare-tint);
  --info: var(--ice);
  --info-soft: var(--ice-tint);

  /* surfaces */
  --bg: var(--bg-0);
  --bg-primary: var(--bg-0);
  --bg-secondary: var(--bg-1);
  --bg-surface: var(--bg-1);
  --panel: var(--bg-1);
  --bg-elev: var(--bg-2);
  --bg-elevated: var(--bg-2);
  --bg-elev-2: var(--bg-3);
  --card-bg: var(--bg-2);
  --bg-hover: var(--row-hover);
  --bg-active: var(--volt-tint);
  --surface-0: var(--bg-0);
  --surface-1: var(--bg-2);
  --surface-2: var(--bg-3);

  /* ink */
  --ink: var(--ink-0);
  --ink-dim: var(--ink-1);
  --ink-faint: var(--ink-2);
  --ink-mute: var(--ink-2);
  --ink-4: var(--ink-3);          /* decorative/disabled contexts only */

  /* lines */
  --border: var(--line-1);
  --border-subtle: var(--line-1);
  --border-default: var(--line-1);
  --border-bright: var(--line-2);
  --border-strong: var(--line-2);

  /* shell */
  --sidebar-w: 232px;             /* §6 rail width */
  --sidebar-bg: var(--bg-1);
  --sidebar-border: var(--line-1);
  --sidebar-label: var(--ink-2);
  --sidebar-sublabel: var(--ink-2);
  --sidebar-link: var(--ink-1);
  --sidebar-link-active-bg: var(--volt-tint);
  --sidebar-link-hover-bg: var(--row-hover);
  --sidebar-badge-bg: var(--bg-3);
  --sidebar-badge-ink: var(--ink-1);
  --sidebar-user-name: var(--ink-0);
  --sidebar-user-org: var(--ink-2);
  --sidebar-brand-sep: var(--line-1);
  --sidebar-nav-sep: var(--line-1);
  --sidebar-foot-sep: var(--line-1);
  --sidebar-foot-who: var(--ink-1);
  --sidebar-foot-ink: var(--ink-2);
  --sidebar-foot-link: var(--ink-2);
  --topbar-bg: var(--bg-1);

  /* dropdowns/overlays */
  --dropdown-bg: var(--bg-3);
  --dropdown-border: var(--line-2);
  --dropdown-divider: var(--line-1);
  --dropdown-item-hover: rgba(255, 255, 255, .04);
  --dropdown-item-ink: var(--ink-0);
  --dropdown-item-sub: var(--ink-2);
  --dropdown-role: var(--ink-2);
  --dropdown-shadow: var(--shadow-overlay);

  /* geometry + depth legacy names */
  --radius: var(--radius-card);
  --radius-sm: var(--radius-chip);
  --shadow: var(--shadow-card);
  --shadow-sm: var(--shadow-card);
  --shadow-lg: var(--shadow-overlay);

  /* legacy font names */
  --font-sans: var(--font-ui);
}

/* ============================================================
   §2 Atmosphere — utility classes
   --bg-0 canvas + fixed (non-scrolling) layered background:
   radial volt@4% top-left + radial pulse@3% bottom-right +
   2.5%-opacity fine grain (embedded data-URI, no external asset).
   Zero animation, zero distraction.
   ============================================================ */

/* Paint the recipe directly on an element (login page, standalone) */
[data-theme="fluxdeck"] .fx-atmosphere {
  background-color: var(--bg-0);
  background-image:
    radial-gradient(1200px 800px at 0% 0%, rgba(77, 124, 255, .04), transparent 62%),
    radial-gradient(1000px 720px at 100% 100%, rgba(157, 107, 255, .03), transparent 62%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.025'/%3E%3C/svg%3E");
  background-attachment: fixed, fixed, fixed;
  background-size: auto, auto, 160px 160px;
}

/* App-shell variant: a fixed, inert underlay div (base.html renders
   <div class="fx-atmosphere-canvas" aria-hidden="true"></div> as the
   first child of <body>). Sits above the body background and below all
   content; survives iOS Safari's background-attachment quirks. */
[data-theme="fluxdeck"] .fx-atmosphere-canvas {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--bg-0);
  background-image:
    radial-gradient(1200px 800px at 0% 0%, rgba(77, 124, 255, .04), transparent 62%),
    radial-gradient(1000px 720px at 100% 100%, rgba(157, 107, 255, .03), transparent 62%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.025'/%3E%3C/svg%3E");
  background-size: auto, auto, 160px 160px;
}

/* ============================================================
   §5 prefers-reduced-motion — transitions collapse to opacity-only.
   Durations survive (opacity fades stay smooth); primitives.css keys
   every transform/slide off these flags.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-theme="fluxdeck"] {
    --dur-stagger: 0ms;
  }
}


/* ============================================================
   FLUXDECK — component primitives + shell (P4v2 foundation)
   Source of truth: design-direction.md §4 depth · §5 motion · §6 specs.
   Loads AFTER style.css and tokens.css — FLUXDECK wins every conflict
   by source order. Zero raw hex outside documented derivations: every
   color reads a token from tokens.css.

   Naming: new primitives are .fx-* (collision-free with legacy classes
   during the staged hybrid). The SHELL section restyles the existing
   base.html selectors (.sidebar/.topbar/.nav-link/…) in place so the
   frame is 100% FLUXDECK while template waves land one by one.
   CSP-safe: consumers need classes only — no inline styles required.
   ============================================================ */

/* ============================================================
   0 · Base
   ============================================================ */
[data-theme="fluxdeck"] body {
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-0);
  background: var(--bg-0);
}

[data-theme="fluxdeck"] h1,
[data-theme="fluxdeck"] .fx-h1 {
  font-family: var(--font-display);
  font-stretch: semi-expanded;
  font-size: var(--fs-h1);
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink-0);
  letter-spacing: -0.01em;
}
[data-theme="fluxdeck"] h2,
[data-theme="fluxdeck"] .fx-h2 {
  font-family: var(--font-display);
  font-stretch: semi-expanded;
  font-size: var(--fs-h2);
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink-0);
}
[data-theme="fluxdeck"] h3,
[data-theme="fluxdeck"] .fx-h3 {
  font-family: var(--font-display);
  font-stretch: semi-expanded;
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink-0);
}

/* ALL data: money, phone numbers, IDs, timestamps, code, API keys (§3) */
[data-theme="fluxdeck"] .fx-mono,
[data-theme="fluxdeck"] code,
[data-theme="fluxdeck"] kbd,
[data-theme="fluxdeck"] samp {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
[data-theme="fluxdeck"] .fx-num { font-variant-numeric: tabular-nums; }

/* Money values: always signal (positive) / heat (negative) in mono (§2) */
[data-theme="fluxdeck"] .fx-money {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--signal-ink);
}
[data-theme="fluxdeck"] .fx-money--neg { color: var(--heat-ink); }

[data-theme="fluxdeck"] a { color: var(--volt-ink); }
[data-theme="fluxdeck"] a:hover { color: var(--volt-strong); }

/* §8: focus visible on EVERY interactive element — volt ring */
[data-theme="fluxdeck"] a:focus-visible,
[data-theme="fluxdeck"] button:focus-visible,
[data-theme="fluxdeck"] input:focus-visible,
[data-theme="fluxdeck"] select:focus-visible,
[data-theme="fluxdeck"] textarea:focus-visible,
[data-theme="fluxdeck"] [tabindex]:focus-visible,
[data-theme="fluxdeck"] summary:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: 4px;
}

[data-theme="fluxdeck"] ::selection { background: var(--volt-border); color: var(--ink-0); }

[data-theme="fluxdeck"] * { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
[data-theme="fluxdeck"] *::-webkit-scrollbar { width: 10px; height: 10px; }
[data-theme="fluxdeck"] *::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 5px;
  border: 2px solid transparent;
  background-clip: content-box;
}
[data-theme="fluxdeck"] *::-webkit-scrollbar-track { background: transparent; }

/* ============================================================
   1 · Micro-caps labels (§3/§6 — rail sections, table headers, forms)
   ============================================================ */
[data-theme="fluxdeck"] .fx-microcaps {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}

/* ============================================================
   2 · Shell — 232px rail · 52px top bar · env chip (§6)
   Restyles the existing base.html selectors in place.
   ============================================================ */
[data-theme="fluxdeck"] .layout { background: transparent; }
[data-theme="fluxdeck"] .main { background: transparent; }

/* ---- rail ---- */
[data-theme="fluxdeck"] .sidebar {
  width: var(--sidebar-w);
  background: var(--bg-1);
  border-right: 1px solid var(--line-1);
}
[data-theme="fluxdeck"] .brand-block { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .user-name { color: var(--ink-0); font-weight: 600; }
[data-theme="fluxdeck"] .user-org {
  color: var(--ink-2);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .04em;
}

[data-theme="fluxdeck"] .nav-label {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .nav-sec-toggle { color: var(--ink-3); }   /* disclosure affordance — decorative */

[data-theme="fluxdeck"] .nav-link {
  color: var(--ink-1);
  border-left: 2px solid transparent;
  transition: background-color var(--dur-press) var(--ease-out),
              color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .nav-link:hover { background: var(--row-hover); color: var(--ink-0); }
[data-theme="fluxdeck"] .nav-link.active {
  border-left-color: var(--volt);       /* 2px volt left bar (§6) */
  background: var(--volt-tint);         /* volt@10% tint */
  color: var(--ink-0);
}
[data-theme="fluxdeck"] .nav-link .icon { color: var(--ink-2); }
[data-theme="fluxdeck"] .nav-link.active .icon { color: var(--volt-ink); }

/* count badges — the ONLY pill shape in the system (§4) */
[data-theme="fluxdeck"] .badge {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  font-weight: 500;
  border-radius: var(--radius-pill);
  background: var(--bg-3);
  color: var(--ink-1);
  border: 1px solid var(--line-1);
}
[data-theme="fluxdeck"] .badge.red {
  background: var(--heat-tint);
  color: var(--heat-ink);
  border-color: var(--heat-border);
}

[data-theme="fluxdeck"] .nav-divider { border-color: var(--line-1); }
[data-theme="fluxdeck"] .sidebar-foot { border-top: 1px solid var(--line-1); color: var(--ink-2); }
[data-theme="fluxdeck"] .signout-link { color: var(--ink-2); }
[data-theme="fluxdeck"] .signout-link:hover { color: var(--heat-ink); }

/* ---- top bar: 52px, panel surface, hairline (§6) ---- */
[data-theme="fluxdeck"] .topbar {
  height: 52px;
  min-height: 52px;
  background: var(--bg-1);
  border-bottom: 1px solid var(--line-1);
}

/* global search — mono placeholder, ⌘K (§6) */
[data-theme="fluxdeck"] .search input {
  background: var(--bg-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-btn);
  color: var(--ink-0);
  transition: border-color var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .search input::placeholder {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .search input:focus {
  outline: none;
  border-color: var(--volt);
  box-shadow: var(--focus-ring);
}

[data-theme="fluxdeck"] .topbar-icon-btn { color: var(--ink-1); border-radius: var(--radius-btn); }
[data-theme="fluxdeck"] .topbar-icon-btn:hover { background: var(--row-hover); color: var(--ink-0); }

/* env chip — PROD = heat-tinted · PREVIEW = flare-tinted (§6) */
[data-theme="fluxdeck"] .env-chip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--radius-chip);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  user-select: none;
  flex-shrink: 0;
}
[data-theme="fluxdeck"] .env-chip--prod {
  background: var(--heat-tint);
  color: var(--heat-ink);
  border: 1px solid var(--heat-border);
}
[data-theme="fluxdeck"] .env-chip--preview {
  background: var(--flare-tint);
  color: var(--flare-ink);
  border: 1px solid var(--flare-border);
}

/* session tracker pills — data = mono */
[data-theme="fluxdeck"] .st-pill { background: var(--bg-2); border: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .st-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-0);
}
[data-theme="fluxdeck"] .st-label { color: var(--ink-2); }
[data-theme="fluxdeck"] .st-bump { color: var(--volt-ink); }

/* account / notification overlays ride the legacy --dropdown-* bridge;
   machined edge on the raised panels */
[data-theme="fluxdeck"] .acct-dropdown,
[data-theme="fluxdeck"] .notif-panel,
[data-theme="fluxdeck"] .recent-leads-panel {
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-overlay);
}

/* preview-mode banner (read-only demo sessions) — flare = pending/warning */
[data-theme="fluxdeck"] .preview-banner {
  background: var(--flare-tint);
  color: var(--flare-ink);
  border-bottom: 1px solid var(--flare-border);
}

/* mobile tab bar */
[data-theme="fluxdeck"] .mobile-tabbar { background: var(--bg-1); border-top: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .mtb-tab { color: var(--ink-2); }
[data-theme="fluxdeck"] .mtb-tab.active { color: var(--volt-ink); }
[data-theme="fluxdeck"] .mtb-badge {
  font-family: var(--font-mono);
  background: var(--heat-tint);
  color: var(--heat-ink);
  border: 1px solid var(--heat-border);
  border-radius: var(--radius-pill);
}

/* flash messages → §6 toast recipe (3px left accent bar on bg-3) */
[data-theme="fluxdeck"] .flash {
  background: var(--bg-3);
  color: var(--ink-0);
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--ice);
  border-radius: var(--radius-btn);
  box-shadow: var(--elev-card);
}
[data-theme="fluxdeck"] .flash-ok,
[data-theme="fluxdeck"] .flash-success { border-left-color: var(--signal); }
[data-theme="fluxdeck"] .flash-err,
[data-theme="fluxdeck"] .flash-error,
[data-theme="fluxdeck"] .flash-danger { border-left-color: var(--heat); }
[data-theme="fluxdeck"] .flash-warn,
[data-theme="fluxdeck"] .flash-warning { border-left-color: var(--flare); }

/* ============================================================
   3 · Buttons (§6) — heights 32px dense / 38px forms
   ============================================================ */
[data-theme="fluxdeck"] .fx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border-radius: var(--radius-btn);
  border: 1px solid transparent;
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  user-select: none;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur-press) var(--ease-out),
              border-color var(--dur-press) var(--ease-out),
              color var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .fx-btn--form { height: 38px; padding: 0 18px; }
[data-theme="fluxdeck"] .fx-btn:disabled,
[data-theme="fluxdeck"] .fx-btn[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
}

/* primary — volt fill, bg-0 ink (≈5:1), hover brighten+glow (§2 glow rule 3) */
[data-theme="fluxdeck"] .fx-btn--primary {
  background: var(--volt);
  color: var(--on-accent);
}
[data-theme="fluxdeck"] .fx-btn--primary:hover:not(:disabled) {
  background: var(--volt-strong);
  box-shadow: 0 0 24px rgba(77, 124, 255, .35);
}
[data-theme="fluxdeck"] .fx-btn--primary:active:not(:disabled) { background: var(--volt); }

/* secondary — bg-2 + line-2 + ink-0 */
[data-theme="fluxdeck"] .fx-btn--secondary {
  background: var(--bg-2);
  border-color: var(--line-2);
  color: var(--ink-0);
}
[data-theme="fluxdeck"] .fx-btn--secondary:hover:not(:disabled) { background: var(--bg-3); }

/* ghost — ink-1, hover volt@8% tint */
[data-theme="fluxdeck"] .fx-btn--ghost {
  background: transparent;
  color: var(--ink-1);
}
[data-theme="fluxdeck"] .fx-btn--ghost:hover:not(:disabled) {
  background: var(--volt-tint-8);
  color: var(--ink-0);
}

/* danger — heat outline at rest → heat fill ONLY when confirm-armed */
[data-theme="fluxdeck"] .fx-btn--danger {
  background: transparent;
  border-color: var(--heat-border);
  color: var(--heat-ink);
}
[data-theme="fluxdeck"] .fx-btn--danger:hover:not(:disabled) {
  background: var(--heat-tint);
  border-color: var(--heat);
}
[data-theme="fluxdeck"] .fx-btn--danger.is-armed,
[data-theme="fluxdeck"] .fx-btn--danger[data-armed="1"] {
  background: var(--heat);
  border-color: var(--heat);
  color: var(--on-accent);      /* 6.5:1 — gated by contrast_check */
}
[data-theme="fluxdeck"] .fx-btn--danger.is-armed:hover:not(:disabled) { background: var(--heat-strong); }

/* ============================================================
   4 · Inputs (§6) — bg-0 inset on panels, focus = volt glow ring
   ============================================================ */
[data-theme="fluxdeck"] .fx-input,
[data-theme="fluxdeck"] .fx-select,
[data-theme="fluxdeck"] .fx-textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  height: 32px;
  padding: 0 10px;
  background: var(--bg-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-btn);
  color: var(--ink-0);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  transition: border-color var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .fx-textarea { height: auto; min-height: 72px; padding: 8px 10px; }
[data-theme="fluxdeck"] .fx-input--form,
[data-theme="fluxdeck"] .fx-select--form { height: 38px; }
[data-theme="fluxdeck"] .fx-input::placeholder,
[data-theme="fluxdeck"] .fx-textarea::placeholder { color: var(--ink-2); }
[data-theme="fluxdeck"] .fx-input:focus,
[data-theme="fluxdeck"] .fx-select:focus,
[data-theme="fluxdeck"] .fx-textarea:focus {
  outline: none;
  border-color: var(--volt);
  box-shadow: var(--focus-ring);
}
[data-theme="fluxdeck"] .fx-input:disabled,
[data-theme="fluxdeck"] .fx-select:disabled,
[data-theme="fluxdeck"] .fx-textarea:disabled {
  color: var(--ink-3);          /* decorative/disabled — sanctioned ink-3 use */
  background: var(--bg-1);
  cursor: not-allowed;
}

/* labels = micro-caps (§6) */
[data-theme="fluxdeck"] .fx-label {
  display: block;
  margin-bottom: 5px;
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}

/* errors: heat border + 12.5px heat text below */
[data-theme="fluxdeck"] .fx-input.is-invalid,
[data-theme="fluxdeck"] .fx-select.is-invalid,
[data-theme="fluxdeck"] .fx-textarea.is-invalid {
  border-color: var(--heat);
}
[data-theme="fluxdeck"] .fx-field-error {
  margin-top: 4px;
  font-size: 12.5px;
  color: var(--heat-ink);
}

/* ============================================================
   5 · Tables (§6) — sticky micro-caps header, 40px rows
   ============================================================ */
[data-theme="fluxdeck"] .fx-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-table);
  color: var(--ink-1);
}
[data-theme="fluxdeck"] .fx-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-1);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
  text-align: left;
  padding: 0 12px;
  height: 34px;
  border-bottom: 1px solid var(--line-1);
}
[data-theme="fluxdeck"] .fx-table tbody td {
  height: 40px;
  padding: 0 12px;
  border-bottom: 1px solid var(--line-1);
  color: var(--ink-1);
}
[data-theme="fluxdeck"] .fx-table tbody td:first-child { color: var(--ink-0); }
[data-theme="fluxdeck"] .fx-table tbody tr {
  transition: background-color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .fx-table tbody tr:hover { background: var(--row-hover); }
[data-theme="fluxdeck"] .fx-table tbody tr.is-selected {
  background: var(--volt-tint-8);
  box-shadow: inset 2px 0 0 var(--volt);   /* 2px volt left bar */
}
[data-theme="fluxdeck"] .fx-table td.fx-cell-money {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--signal-ink);
}
[data-theme="fluxdeck"] .fx-table td.fx-cell-money.fx-money--neg { color: var(--heat-ink); }
[data-theme="fluxdeck"] .fx-table td.fx-cell-mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   6 · Chips (§6) — tinted recipe, 6px radius, 11px/500
   Fixed pipeline stage map (§2): New=ice · Contacted=volt ·
   Booked=pulse · Won/Paid=signal · Callback=flare · Lost=ink-2
   ============================================================ */
[data-theme="fluxdeck"] .fx-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--radius-chip);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  /* neutral default */
  background: var(--bg-3);
  color: var(--ink-1);
  border: 1px solid var(--line-2);
}
[data-theme="fluxdeck"] .fx-chip--new {
  background: var(--stage-new-tint);
  color: var(--stage-new-ink);
  border-color: var(--stage-new-border);
}
[data-theme="fluxdeck"] .fx-chip--contacted {
  background: var(--stage-contacted-tint);
  color: var(--stage-contacted-ink);
  border-color: var(--stage-contacted-border);
}
[data-theme="fluxdeck"] .fx-chip--booked {
  background: var(--stage-booked-tint);
  color: var(--stage-booked-ink);
  border-color: var(--stage-booked-border);
}
[data-theme="fluxdeck"] .fx-chip--won {
  background: var(--stage-won-tint);
  color: var(--stage-won-ink);
  border-color: var(--stage-won-border);
}
[data-theme="fluxdeck"] .fx-chip--callback {
  background: var(--stage-callback-tint);
  color: var(--stage-callback-ink);
  border-color: var(--stage-callback-border);
}
[data-theme="fluxdeck"] .fx-chip--lost {
  background: var(--stage-lost-tint);
  color: var(--stage-lost-ink);
  border-color: var(--stage-lost-border);
}
/* §2 stage map, FULL vocabulary (extended 2026-07-17): six INTENT
   families, never per-stage invention. Any new stage a future wave meets
   is classified into one of these families — never mint a color.
   ice = untouched · volt = in-conversation · pulse = committed-motion ·
   signal = money-real · flare = needs-another-push · ink-2 = inert. */

/* volt — in-conversation: Contacted, Interested */
[data-theme="fluxdeck"] .fx-chip--interested {
  background: var(--stage-contacted-tint);
  color: var(--stage-contacted-ink);
  border-color: var(--stage-contacted-border);
}
/* pulse — committed-motion: Proposal Sent, Booked Meeting */
[data-theme="fluxdeck"] .fx-chip--proposal {
  background: var(--stage-booked-tint);
  color: var(--stage-booked-ink);
  border-color: var(--stage-booked-border);
}
/* signal — money-real: Won, Paid, Active Client, Closed-won */
[data-theme="fluxdeck"] .fx-chip--paid,
[data-theme="fluxdeck"] .fx-chip--active-client,
[data-theme="fluxdeck"] .fx-chip--closed-won {
  background: var(--stage-won-tint);
  color: var(--stage-won-ink);
  border-color: var(--stage-won-border);
}
/* flare — needs-another-push: Callback, Follow-up, No Pick Up */
[data-theme="fluxdeck"] .fx-chip--follow-up,
[data-theme="fluxdeck"] .fx-chip--no-pickup {
  background: var(--stage-callback-tint);
  color: var(--stage-callback-ink);
  border-color: var(--stage-callback-border);
}
/* ink-2 — inert: Ghosted, Lost, Dead, Bad Data, Disqualified */
[data-theme="fluxdeck"] .fx-chip--ghosted,
[data-theme="fluxdeck"] .fx-chip--dead,
[data-theme="fluxdeck"] .fx-chip--bad-data,
[data-theme="fluxdeck"] .fx-chip--disqualified {
  background: var(--stage-lost-tint);
  color: var(--stage-lost-ink);
  border-color: var(--stage-lost-border);
}

/* LIVE badge — §2 glow rule 2 (calls in progress, campaign running) */
[data-theme="fluxdeck"] .fx-chip--live {
  background: var(--signal-tint);
  color: var(--signal-ink);
  border-color: var(--signal-border);
  animation: fx-live-pulse 2s var(--ease-out) infinite;
}
@keyframes fx-live-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(61, 220, 151, 0); }
  50% { box-shadow: 0 0 12px 0 rgba(61, 220, 151, .35); }
}

/* ============================================================
   7 · Toasts (§6) — bottom-right, bg-3, 3px left accent bar + faint glow
   ============================================================ */
[data-theme="fluxdeck"] .fx-toasts {
  position: fixed;
  right: 16px;
  bottom: calc(16px + max(env(safe-area-inset-bottom, 0px), var(--sab-fallback, 0px)));
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
[data-theme="fluxdeck"] .fx-toast {
  pointer-events: auto;
  min-width: 240px;
  max-width: 380px;
  padding: 10px 14px;
  background: var(--bg-3);
  color: var(--ink-0);
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--ice);
  border-radius: var(--radius-btn);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(77, 216, 255, .08);
  font-size: var(--fs-body);
  animation: fx-slide-in var(--dur-overlay) var(--ease-deck) both;
}
[data-theme="fluxdeck"] .fx-toast--ok {
  border-left-color: var(--signal);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(61, 220, 151, .08);
}
[data-theme="fluxdeck"] .fx-toast--err {
  border-left-color: var(--heat);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(255, 92, 122, .08);
}
[data-theme="fluxdeck"] .fx-toast--warn {
  border-left-color: var(--flare);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(255, 184, 77, .08);
}
[data-theme="fluxdeck"] .fx-toast .fx-toast-id {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-1);
}

/* ============================================================
   8 · Drawer / popover shells (§4 overlays + §5 motion)
   bg-3 + line-2 + overlay shadow + machined edge; 220ms slide 8px + fade
   ============================================================ */
[data-theme="fluxdeck"] .fx-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--scrim);
}

[data-theme="fluxdeck"] .fx-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-panel);
  width: min(480px, 94vw);
  display: flex;
  flex-direction: column;
  background: var(--bg-3);
  border-left: 1px solid var(--line-2);
  box-shadow: var(--elev-overlay);
  animation: fx-slide-in var(--dur-overlay) var(--ease-deck) both;
}
[data-theme="fluxdeck"] .fx-drawer__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-1);
}
[data-theme="fluxdeck"] .fx-drawer__title {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-stretch: semi-expanded;
  font-size: var(--fs-h2);
  font-weight: 600;
  color: var(--ink-0);
}
[data-theme="fluxdeck"] .fx-drawer__body { flex: 1; overflow-y: auto; padding: 16px 18px; }

[data-theme="fluxdeck"] .fx-popover {
  position: absolute;
  z-index: var(--z-popover);
  min-width: 200px;
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-overlay);
  animation: fx-slide-in var(--dur-overlay) var(--ease-deck) both;
}

@keyframes fx-slide-in {
  from { opacity: 0; transform: translateX(8px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes fx-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ============================================================
   9 · Skeleton shimmer (§5 — no spinners where skeletons fit)
   ============================================================ */
[data-theme="fluxdeck"] .fx-skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-chip);
  background: var(--bg-2);
  color: transparent;
  user-select: none;
  pointer-events: none;
}
[data-theme="fluxdeck"] .fx-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, var(--bg-3) 50%, transparent 80%);
  background-size: 200% 100%;
  animation: fx-shimmer 1.4s linear infinite;
}
@keyframes fx-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -100% 0; }
}
[data-theme="fluxdeck"] .fx-skeleton--line { height: 12px; }
[data-theme="fluxdeck"] .fx-skeleton--row { height: 40px; border-radius: 0; }

/* ============================================================
   10 · Empty state (§6) — one mono glyph + one ink-1 line + one action
   ============================================================ */
[data-theme="fluxdeck"] .fx-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 48px 24px;
  text-align: center;
}
[data-theme="fluxdeck"] .fx-empty__glyph {
  font-family: var(--font-mono);
  font-size: 28px;
  line-height: 1;
  color: var(--ink-3);       /* decorative — sanctioned ink-3 use */
}
[data-theme="fluxdeck"] .fx-empty__line { margin: 0; color: var(--ink-1); font-size: var(--fs-body); }

/* ============================================================
   11 · Kanban drag states (§5) — consumed by the board wave
   ============================================================ */
[data-theme="fluxdeck"] .fx-drag-card {
  transform: scale(1.02);
  box-shadow: var(--shadow-overlay), 0 0 0 1px var(--volt);
}
[data-theme="fluxdeck"] .fx-drop-target {
  background: var(--volt-wash-6);
  outline: 1px dashed var(--volt-drag-outline);
  outline-offset: -1px;
}

/* aging leads: flare left-edge tick after 48h idle (§6 — meaning, not décor) */
[data-theme="fluxdeck"] .fx-card--aging { box-shadow: inset 2px 0 0 var(--flare), var(--elev-card); }

/* ============================================================
   12 · Card primitive (§4 recipe: bg-2 + line-1 + shadow + machined edge)
   ============================================================ */
[data-theme="fluxdeck"] .fx-card {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
}

/* ============================================================
   13 · First-paint reveal (§5) — 30ms stagger, first 12 rows, once/load
   ============================================================ */
[data-theme="fluxdeck"] .fx-stagger > * {
  animation: fx-reveal 240ms var(--ease-out) both;
}
[data-theme="fluxdeck"] .fx-stagger > :nth-child(1) { animation-delay: calc(var(--dur-stagger) * 0); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(2) { animation-delay: calc(var(--dur-stagger) * 1); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(3) { animation-delay: calc(var(--dur-stagger) * 2); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(4) { animation-delay: calc(var(--dur-stagger) * 3); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(5) { animation-delay: calc(var(--dur-stagger) * 4); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(6) { animation-delay: calc(var(--dur-stagger) * 5); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(7) { animation-delay: calc(var(--dur-stagger) * 6); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(8) { animation-delay: calc(var(--dur-stagger) * 7); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(9) { animation-delay: calc(var(--dur-stagger) * 8); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(10) { animation-delay: calc(var(--dur-stagger) * 9); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(11) { animation-delay: calc(var(--dur-stagger) * 10); }
[data-theme="fluxdeck"] .fx-stagger > :nth-child(12) { animation-delay: calc(var(--dur-stagger) * 11); }
/* rows 13+ appear instantly — stagger is a reveal, not a slideshow */
[data-theme="fluxdeck"] .fx-stagger > :nth-child(n+13) { animation: none; }
@keyframes fx-reveal {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   13.5 · Foundation-critique bridge fixes (2026-07-17)
   CSS-level overrides of legacy style.css / UA defaults so the frame
   + login + hybrid pages hold FLUXDECK law before their content waves.
   Each block names the critique fix it lands.
   ============================================================ */

/* -- fix 1+8: legacy .btn.primary = §6 primary (volt fill, bg-0 ink ≈5:1,
   hover brighten + sanctioned CTA glow). Kills white-on-volt 3.7:1. -- */
[data-theme="fluxdeck"] .btn.primary {
  background: var(--volt);
  border-color: var(--volt);
  color: var(--on-accent);
  font-weight: 600;
}
[data-theme="fluxdeck"] .btn.primary:hover {
  background: var(--volt-strong);
  border-color: var(--volt-strong);
  color: var(--on-accent);
  box-shadow: 0 0 24px rgba(77, 124, 255, .35);
}

/* -- fix 6: button/input radii → 8px (§4). Checkbox/radio/range excluded. -- */
[data-theme="fluxdeck"] .btn { border-radius: var(--radius-btn); }
[data-theme="fluxdeck"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
[data-theme="fluxdeck"] select,
[data-theme="fluxdeck"] textarea {
  border-radius: var(--radius-btn);
}

/* -- fix 4: shell avatars off Stripe-era #7C3AED → pulse, dark initials
   (on-accent on pulse = 5.5:1, gated). -- */
[data-theme="fluxdeck"] .user-avatar,
[data-theme="fluxdeck"] .topbar-avatar,
[data-theme="fluxdeck"] .acct-header-avatar {
  background: var(--pulse);
  color: var(--on-accent);
}

/* -- fix 4: rail badge red off #EF4444 → heat tint recipe (out-specifies
   style.css's .nav-link .badge.red). -- */
[data-theme="fluxdeck"] .nav-link .badge.red {
  background: var(--heat-tint);
  color: var(--heat-ink);
  border: 1px solid var(--heat-border);
}

/* -- fix 3: inbox island filter chips. The island's <button class="chip">
   elements had NO rule anywhere — they rendered UA default button chrome
   (near-white rgb(239,239,239) pills). FLUXDECK recipe at island scope;
   frontend/* and static/dist/* untouched (W15 owns those). -- */
[data-theme="fluxdeck"] #inbox-root .chip {
  appearance: none;
  -webkit-appearance: none;
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-chip);
  color: var(--ink-1);
  font: inherit;
  font-size: 11px;
  font-weight: 500;
  padding: 3px 9px;
  cursor: pointer;
  transition: background-color var(--dur-press) var(--ease-out),
              border-color var(--dur-press) var(--ease-out),
              color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] #inbox-root .chip:hover { border-color: var(--line-2); color: var(--ink-0); }
[data-theme="fluxdeck"] #inbox-root .chip.on,
[data-theme="fluxdeck"] #inbox-root .chip[aria-pressed="true"],
[data-theme="fluxdeck"] #inbox-root .chip.active {
  background: var(--volt-tint);
  border-color: var(--volt-border);
  color: var(--volt-ink);
}

/* -- fix 11: legacy window.toast() → §6 recipe: bg-3 + 3px left accent
   bar by type + faint matching glow (mono IDs come with template waves). -- */
[data-theme="fluxdeck"] .toast {
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--ice);
  border-radius: var(--radius-btn);
  color: var(--ink-0);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(77, 216, 255, .08);
}
[data-theme="fluxdeck"] .toast.ok {
  background: var(--bg-3);
  border-color: var(--line-2);
  border-left: 3px solid var(--signal);
  color: var(--ink-0);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(61, 220, 151, .08);
}
[data-theme="fluxdeck"] .toast.err,
[data-theme="fluxdeck"] .toast.error {
  background: var(--bg-3);
  border-color: var(--line-2);
  border-left: 3px solid var(--heat);
  color: var(--ink-0);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(255, 92, 122, .08);
}
[data-theme="fluxdeck"] .toast.warn {
  background: var(--bg-3);
  border-color: var(--line-2);
  border-left: 3px solid var(--flare);
  color: var(--ink-0);
  box-shadow: var(--elev-overlay), 0 0 16px rgba(255, 184, 77, .08);
}

/* -- fix 10: page titles hold the §3 scale (legacy pages set 22px at
   higher specificity than the base h1 rule). -- */
[data-theme="fluxdeck"] .page-head h1,
[data-theme="fluxdeck"] .lead-head-card h1,
[data-theme="fluxdeck"] .rec-head h1,
[data-theme="fluxdeck"] .forum-head h1 {
  font-size: var(--fs-h1);
}

/* -- fix 2: login wordmark = Archivo SemiExpanded 800 (§6: the one
   theatrical moment; Archivo otherwise never loads on /login). -- */
[data-theme="fluxdeck"] .login-card .brand {
  font-family: var(--font-display);
  font-stretch: 112.5%;
  font-weight: 800;
  color: var(--ink-0);
}

/* -- fix 12: login card wears the §4 machined edge (inset top highlight
   + overlay shadow — it sits on the atmosphere canvas). -- */
[data-theme="fluxdeck"] .login-card {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-overlay), var(--edge-machined);
}

/* -- fix 7: login labels = micro-caps. Inputs live INSIDE the labels, so
   re-neutralize every inherited label property on the input itself. -- */
[data-theme="fluxdeck"] .login-card label {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .login-card label input {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--fs-body);
  font-weight: 400;
  color: var(--ink-0);
}

@media (prefers-reduced-motion: reduce) {
  [data-theme="fluxdeck"] .toast { transition-property: opacity; transform: none; }
  [data-theme="fluxdeck"] #inbox-root .chip { transition-property: opacity, background-color, border-color, color; }
}

/* ============================================================
   14 · Reduced motion (§5) — every transition collapses to opacity-only
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-theme="fluxdeck"] .fx-btn,
[data-theme="fluxdeck"] .fx-input,
[data-theme="fluxdeck"] .fx-select,
[data-theme="fluxdeck"] .fx-textarea,
[data-theme="fluxdeck"] .nav-link,
[data-theme="fluxdeck"] .fx-table tbody tr,
[data-theme="fluxdeck"] .search input,
[data-theme="fluxdeck"] .topbar-icon-btn {
    transition-property: opacity, background-color, border-color, color, box-shadow;
  }
  [data-theme="fluxdeck"] .fx-drawer,
[data-theme="fluxdeck"] .fx-popover,
[data-theme="fluxdeck"] .fx-toast {
    animation: fx-fade-in var(--dur-overlay) var(--ease-out) both;
  }
  [data-theme="fluxdeck"] .fx-stagger > * { animation: fx-fade-in 180ms var(--ease-out) both; }
  [data-theme="fluxdeck"] .fx-skeleton::after { animation: none; }
  [data-theme="fluxdeck"] .fx-chip--live { animation: none; box-shadow: 0 0 8px 0 rgba(61, 220, 151, .25); }
  [data-theme="fluxdeck"] .fx-drag-card { transform: none; }
  @keyframes fx-slide-in {
    from { opacity: 0; transform: none; }
    to   { opacity: 1; transform: none; }
  }
  @keyframes fx-reveal {
    from { opacity: 0; transform: none; }
    to   { opacity: 1; transform: none; }
  }
}

/* ============================================================
   ============================================================
   WAVE 2 (2026-07-17) — dashboard · pipeline kanban · inbox island
   Everything below extends the foundation primitives for the three
   highest-traffic screens. Zero raw hex: every color reads tokens.css.
   ============================================================
   ============================================================ */

/* ============================================================
   15 · Stage-family utility vars + app-wide status chips (§2 map)
   Six INTENT families — never per-stage invention. Full 16-status
   vocabulary classified (wave-2 call; rationale in the commit):
     ice    = untouched        : New
     volt   = in-conversation  : Contacted · Interested · Called
     pulse  = committed-motion : Proposal Sent · Booked Meeting
     signal = money-real       : Closed · Active Client · Built Website
              (Closed pairs with Active Client in every app.py terminal-
               good query — it is closed-WON in this pipeline)
     flare  = needs-another-push: No Show · No Pick Up · Left Voicemail
     inert  = ink-2            : Ghosted · Disqualified · Bad Data ·
                                 Do Not Contact
   .fx-fam-* sets --fam/--fam-ink/--fam-tint/--fam-border for any
   surface (kanban columns, stage tiles, chips) to consume.
   ============================================================ */
[data-theme="fluxdeck"] .fx-fam-ice { --fam: var(--ice);        --fam-ink: var(--ice-ink);        --fam-tint: var(--ice-tint);        --fam-border: var(--ice-border); }
[data-theme="fluxdeck"] .fx-fam-volt { --fam: var(--volt);       --fam-ink: var(--volt-ink);       --fam-tint: var(--volt-tint);       --fam-border: var(--volt-border); }
[data-theme="fluxdeck"] .fx-fam-pulse { --fam: var(--pulse);      --fam-ink: var(--pulse-ink);      --fam-tint: var(--pulse-tint);      --fam-border: var(--pulse-border); }
[data-theme="fluxdeck"] .fx-fam-signal { --fam: var(--signal);     --fam-ink: var(--signal-ink);     --fam-tint: var(--signal-tint);     --fam-border: var(--signal-border); }
[data-theme="fluxdeck"] .fx-fam-flare { --fam: var(--flare);      --fam-ink: var(--flare-ink);      --fam-tint: var(--flare-tint);      --fam-border: var(--flare-border); }
[data-theme="fluxdeck"] .fx-fam-inert { --fam: var(--stage-lost); --fam-ink: var(--stage-lost-ink); --fam-tint: var(--stage-lost-tint); --fam-border: var(--stage-lost-border); }

/* Legacy `.status status-<slug>` pills (inbox island rows + detail,
   dashboard mini-lists, leads table) → §6 chip recipe on the fixed map.
   Overrides style.css's Tailwind-era per-status hexes by source order. */
[data-theme="fluxdeck"] .status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: var(--radius-chip);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  background: var(--bg-3);
  color: var(--ink-1);
  border: 1px solid var(--line-2);
}
/* ice — untouched */
[data-theme="fluxdeck"] .status-new {
  background: var(--stage-new-tint); color: var(--stage-new-ink);
  border-color: var(--stage-new-border);
}
/* volt — in-conversation */
[data-theme="fluxdeck"] .status-contacted,
[data-theme="fluxdeck"] .status-interested,
[data-theme="fluxdeck"] .status-called {
  background: var(--stage-contacted-tint); color: var(--stage-contacted-ink);
  border-color: var(--stage-contacted-border);
}
/* pulse — committed-motion */
[data-theme="fluxdeck"] .status-proposal-sent,
[data-theme="fluxdeck"] .status-booked-meeting {
  background: var(--stage-booked-tint); color: var(--stage-booked-ink);
  border-color: var(--stage-booked-border);
}
/* signal — money-real */
[data-theme="fluxdeck"] .status-closed,
[data-theme="fluxdeck"] .status-active-client,
[data-theme="fluxdeck"] .status-built-website {
  background: var(--stage-won-tint); color: var(--stage-won-ink);
  border-color: var(--stage-won-border);
}
/* flare — needs-another-push */
[data-theme="fluxdeck"] .status-no-show,
[data-theme="fluxdeck"] .status-no-pick-up,
[data-theme="fluxdeck"] .status-left-voicemail {
  background: var(--stage-callback-tint); color: var(--stage-callback-ink);
  border-color: var(--stage-callback-border);
}
/* ink-2 — inert */
[data-theme="fluxdeck"] .status-ghosted,
[data-theme="fluxdeck"] .status-disqualified,
[data-theme="fluxdeck"] .status-bad-data,
[data-theme="fluxdeck"] .status-do-not-contact {
  background: var(--stage-lost-tint); color: var(--stage-lost-ink);
  border-color: var(--stage-lost-border);
}

/* ---- Opportunity markers (wave-2 semantic recode) ----
   "NO SITE" and a weak website SCORE mark an OPPORTUNITY (prime target),
   not an error. Legacy wore heat (reads as failure). Recoded to the ICE
   family — info / new-unclaimed target — per the §2 intent vocabulary. */
[data-theme="fluxdeck"] .no-site {
  background: var(--ice-tint);
  color: var(--ice-ink);
  border: 1px solid var(--ice-border);
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: var(--radius-chip);
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
}
[data-theme="fluxdeck"] .score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-chip);
  border: 1px solid var(--line-2);
  background: var(--bg-3);
  color: var(--ink-1);
}
[data-theme="fluxdeck"] .score-low { background: var(--ice-tint);  color: var(--ice-ink);  border-color: var(--ice-border); }
[data-theme="fluxdeck"] .score-mid { background: var(--bg-3);      color: var(--ink-1);    border-color: var(--line-2); }
[data-theme="fluxdeck"] .score-high { background: var(--bg-3);      color: var(--ink-1);    border-color: var(--line-2); }

/* ---- open/closed liveness pill (inbox rows + kanban cards) ----
   "Open" = the business can pick up RIGHT NOW → signal (LIVE family).
   "Closed" is not an error → inert neutral, never heat. */
[data-theme="fluxdeck"] .open-mini { border-radius: var(--radius-chip); }
[data-theme="fluxdeck"] .open-mini.open-now { color: var(--signal-ink); background: var(--signal-tint); }
[data-theme="fluxdeck"] .open-mini.open-now::before { box-shadow: 0 0 5px var(--signal); }
[data-theme="fluxdeck"] .open-mini.open-closed { color: var(--stage-lost-ink); background: var(--stage-lost-tint); }

/* ---- service .tag chips: volt-ink text (raw volt is sub-AA at 11px) ---- */
[data-theme="fluxdeck"] .tag {
  background: var(--volt-tint);
  color: var(--volt-ink);
  border: 1px solid var(--volt-border);
  border-radius: var(--radius-chip);
}

/* ---- legacy .btn = §6 secondary · .btn.subtle = ghost · .btn.danger =
   heat outline (style.css's bridged values were close; these pin the
   exact §6 recipe) ---- */
[data-theme="fluxdeck"] .btn {
  background: var(--bg-2);
  border-color: var(--line-2);
  color: var(--ink-0);
  font-weight: 600;
  border-radius: var(--radius-btn);
}
[data-theme="fluxdeck"] .btn:hover { background: var(--bg-3); border-color: var(--line-2); color: var(--ink-0); }
[data-theme="fluxdeck"] .btn.subtle { background: transparent; border-color: transparent; color: var(--ink-1); }
[data-theme="fluxdeck"] .btn.subtle:hover { background: var(--volt-tint-8); color: var(--ink-0); }
[data-theme="fluxdeck"] .btn.danger { background: transparent; border-color: var(--heat-border); color: var(--heat-ink); }
[data-theme="fluxdeck"] .btn.danger:hover { background: var(--heat-tint); border-color: var(--heat); color: var(--heat-ink); }

/* ---- shared empty-state (server-rendered + JS-recreated markup on the
   kanban board uses .empty-state; §6: one mono glyph + one ink-1 line +
   one action) ---- */
[data-theme="fluxdeck"] .empty-state { color: var(--ink-1); }
[data-theme="fluxdeck"] .empty-state .icon {
  font-family: var(--font-mono);
  font-size: 22px;
  line-height: 1;
  display: block;
  margin-bottom: 8px;
  color: var(--ink-3);            /* decorative — sanctioned ink-3 use */
  opacity: 1;
}
[data-theme="fluxdeck"] .empty-state h3 { color: var(--ink-0); }
[data-theme="fluxdeck"] .empty-state p { color: var(--ink-1); }

/* ============================================================
   16 · Kanban board (§5 drag · §6 kanban) — templates/pipeline.html
   Columns bg-1 · cards bg-2 machined · stage-family header accents ·
   flare aging tick ≥48h idle · volt drag/drop states.
   ============================================================ */
[data-theme="fluxdeck"] .main-wide { background: transparent; }   /* canvas + atmosphere show through */
[data-theme="fluxdeck"] .kanban { background: transparent; }

[data-theme="fluxdeck"] .kanban-col {
  background: var(--bg-1);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  /* stage-family stripe as an INSET shadow so it stays inside the
     radius (a border-top wraps the corner arc — un-machined) */
  box-shadow: inset 0 2px 0 var(--fam, var(--line-2));
}
[data-theme="fluxdeck"] .kanban-col-head { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .kanban-col-head .title {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--fam-ink, var(--ink-2));
}
/* count = the ONLY pill; mono data */
[data-theme="fluxdeck"] .kanban-col-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}
[data-theme="fluxdeck"] .kanban-col-meta .count,
[data-theme="fluxdeck"] .kanban-col-head .count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  font-weight: 500;
  color: var(--ink-1);
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  padding: 1px 7px;
  border-radius: var(--radius-pill);
}
/* column $ total = money = signal mono (§2) */
[data-theme="fluxdeck"] .kanban-col-meta .value,
[data-theme="fluxdeck"] .kanban-col-head .value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 500;
  color: var(--signal-ink);
}
[data-theme="fluxdeck"] .kanban-add-btn {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-chip);
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-2);
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
  transition: background-color var(--dur-press) var(--ease-out),
              border-color var(--dur-press) var(--ease-out),
              color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .kanban-add-btn:hover {
  background: var(--volt-tint-8);
  border-color: var(--volt-border);
  color: var(--volt-ink);
}

/* cards: §4 machined recipe */
[data-theme="fluxdeck"] .kanban-card {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
  color: var(--ink-1);
  cursor: grab;
  transition: border-color var(--dur-press) var(--ease-out),
              box-shadow var(--dur-press) var(--ease-out),
              background-color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .kanban-card:hover {
  background: var(--bg-2);
  border-color: var(--line-2);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .45), var(--edge-machined);
  transform: none;
}
[data-theme="fluxdeck"] .kanban-card .biz { color: var(--ink-0); }
[data-theme="fluxdeck"] .kanban-card .meta { color: var(--ink-2); }

/* §5 drag: source card lifts w/ 1px volt ring; drop column = volt@6%
   wash + dashed volt@40% outline. Classes are the ones pipeline.html's
   W16-contract JS already toggles (.dragging / .dropping). */
[data-theme="fluxdeck"] .kanban-card.dragging {
  opacity: .55;
  transform: scale(1.02);
  box-shadow: var(--shadow-overlay), 0 0 0 1px var(--volt);
}
[data-theme="fluxdeck"] .kanban-col.dropping {
  background: var(--volt-wash-6);
  border-color: var(--line-1);
  outline: 1px dashed var(--volt-drag-outline);
  outline-offset: -1px;
}

/* aging tick: flare left edge after 48h idle (JS adds .fx-card--aging
   from the same days computation that feeds the mono days-badge) */
[data-theme="fluxdeck"] .kanban-card.fx-card--aging { box-shadow: inset 2px 0 0 var(--flare), var(--elev-card); }
[data-theme="fluxdeck"] .kanban-card.fx-card--aging.dragging {
  box-shadow: inset 2px 0 0 var(--flare), var(--shadow-overlay), 0 0 0 1px var(--volt);
}

/* days-in-stage: TIME IS DATA → neutral mono chip. The old green/amber/
   red trio was three accent families of decoration; the flare tick above
   is the only aging color. (.fresh/.warn/.stale still arrive from JS —
   all three now resolve neutral.) */
[data-theme="fluxdeck"] .kanban-card .days-badge,
[data-theme="fluxdeck"] .kanban-card .days-badge.fresh,
[data-theme="fluxdeck"] .kanban-card .days-badge.warn,
[data-theme="fluxdeck"] .kanban-card .days-badge.stale {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  font-weight: 500;
  background: var(--bg-1);
  color: var(--ink-2);
  border-radius: var(--radius-chip);
}

/* follow-up chips: flare = needs-another-push (today AND overdue — a
   missed follow-up is a push, not a failure; text carries the which) */
[data-theme="fluxdeck"] .due-badge,
[data-theme="fluxdeck"] .due-badge.today,
[data-theme="fluxdeck"] .due-badge.overdue {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  border-radius: var(--radius-chip);
  background: var(--flare-tint);
  color: var(--flare-ink);
  border: 1px solid var(--flare-border);
}

/* card money = signal mono (§2) */
[data-theme="fluxdeck"] .deal-val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--signal-ink);
  font-weight: 500;
}

/* owner stamp = attribution data, not state → neutral mono */
[data-theme="fluxdeck"] .kanban-card .lead-owner {
  font-family: var(--font-mono);
  background: var(--bg-1);
  color: var(--ink-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-chip);
  font-weight: 500;
}

[data-theme="fluxdeck"] .kanban-empty { color: var(--ink-1); }

/* ============================================================
   17 · Dashboard (§2 KPI corollary · §6 charts) — templates/dashboard.html
   KPI tiles neutral ink; the ONLY accent in the row is flare on a
   follow-ups count that demands action. Panels/cards get the §4 recipe.
   ============================================================ */
[data-theme="fluxdeck"] .kpi {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .kpi:hover { border-color: var(--line-2); text-decoration: none; }
[data-theme="fluxdeck"] .kpi .label {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
/* big numbers pair w/ mono (§3); neutral ink is the rule */
[data-theme="fluxdeck"] .kpi .value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink-0);
  letter-spacing: -0.01em;
}
/* neutralize the legacy 5-color value classes for any straggler page */
[data-theme="fluxdeck"] .kpi .value.warn,
[data-theme="fluxdeck"] .kpi .value.ok,
[data-theme="fluxdeck"] .kpi .value.danger,
[data-theme="fluxdeck"] .kpi .value.info,
[data-theme="fluxdeck"] .kpi .value.accent { color: var(--ink-0); }
/* the one sanctioned KPI accent: work is DUE now → flare */
[data-theme="fluxdeck"] .kpi .value.is-flare { color: var(--flare-ink); }
[data-theme="fluxdeck"] .kpi .meta { color: var(--ink-2); }
[data-theme="fluxdeck"] .kpi .cta { color: var(--volt-ink); }

/* stage strip tiles: family top edge + family micro-caps, mono count */
[data-theme="fluxdeck"] .pipe-cell {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  /* family stripe inset (radius-clean) + the §4 card recipe */
  box-shadow: inset 0 2px 0 var(--fam, var(--line-2)), var(--shadow-card);
  transition: border-color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] .pipe-cell:hover {
  background: var(--bg-2);
  border-color: var(--line-2);
  transform: none;
}
[data-theme="fluxdeck"] .pipe-cell .stage { color: var(--fam-ink, var(--ink-2)); letter-spacing: var(--track-micro); }
[data-theme="fluxdeck"] .pipe-cell .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink-0);
}

/* §4 card recipe for the shared panel/chart surfaces */
[data-theme="fluxdeck"] .panel,
[data-theme="fluxdeck"] .chart-card {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
}
[data-theme="fluxdeck"] .chart-card h3 {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .chart-card .chart-meta { color: var(--ink-2); }
[data-theme="fluxdeck"] .section-head h2 {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .section-head .link { color: var(--volt-ink); }
[data-theme="fluxdeck"] .section-head--panel { margin-bottom: 10px; }
[data-theme="fluxdeck"] .chart-card #spark-meta { margin-top: 8px; margin-bottom: 0; }

/* single-series bars (funnel + tag breakdown): chart-1 volt, 12%-alpha
   fill + 30% border per the §6 area recipe, machined 2px volt cap */
[data-theme="fluxdeck"] .funnel-row .bar-wrap {
  background: var(--bg-0);
  border: 1px solid var(--line-1);
  border-radius: 4px;
}
[data-theme="fluxdeck"] .funnel-row .bar {
  background: var(--volt-tint);
  box-shadow: inset -2px 0 0 var(--volt);
  border-radius: 0;
}
[data-theme="fluxdeck"] .funnel-row .label { color: var(--ink-2); }
[data-theme="fluxdeck"] .funnel-row .count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-0);
}
[data-theme="fluxdeck"] .breakdown-row .bar-wrap { background: var(--bg-0); border: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .breakdown-row .bar {
  background: var(--volt-tint);
  box-shadow: inset -2px 0 0 var(--volt);
  opacity: 1;
}
[data-theme="fluxdeck"] .breakdown-row .name { color: var(--ink-2); }
[data-theme="fluxdeck"] .breakdown-row .count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-1);
}

/* activity feed: the label names the action — colored icons were
   decoration. Neutral machined glyph wells; timestamps mono. */
[data-theme="fluxdeck"] .activity-item { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .activity-item .icon,
[data-theme="fluxdeck"] .activity-item .icon.scrape,
[data-theme="fluxdeck"] .activity-item .icon.scraped,
[data-theme="fluxdeck"] .activity-item .icon.call_logged,
[data-theme="fluxdeck"] .activity-item .icon.email_sent,
[data-theme="fluxdeck"] .activity-item .icon.sms_sent,
[data-theme="fluxdeck"] .activity-item .icon.voicemail,
[data-theme="fluxdeck"] .activity-item .icon.note_added,
[data-theme="fluxdeck"] .activity-item .icon.status_change,
[data-theme="fluxdeck"] .activity-item .icon.tag_change,
[data-theme="fluxdeck"] .activity-item .icon.proposal_sent,
[data-theme="fluxdeck"] .activity-item .icon.followup_set,
[data-theme="fluxdeck"] .activity-item .icon.manual_add {
  background: var(--bg-1);
  border: 1px solid var(--line-1);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .activity-item .body .by { color: var(--ink-2); }
[data-theme="fluxdeck"] .activity-item .body .biz { color: var(--ink-0); }
[data-theme="fluxdeck"] .activity-item .body .biz:hover { color: var(--volt-ink); }
[data-theme="fluxdeck"] .activity-item .body .desc { color: var(--ink-2); }
[data-theme="fluxdeck"] .activity-item .ts {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}

/* dashboard mini-lists (follow-ups / hotlist) */
[data-theme="fluxdeck"] .mini-row { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] .mini-row .name { color: var(--ink-0); }
[data-theme="fluxdeck"] .mini-row .name:hover { color: var(--volt-ink); }
[data-theme="fluxdeck"] .mini-row .meta { color: var(--ink-2); }
[data-theme="fluxdeck"] .mini-row .due {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
[data-theme="fluxdeck"] .mini-row .due.overdue,
[data-theme="fluxdeck"] .mini-row .due.today { color: var(--flare-ink); font-weight: 600; }

/* ============================================================
   18 · Inbox island (full surface) — extends the foundation's
   #inbox-root .chip work to list, toolbar, detail pane, drawers.
   CSS-only: frontend/inbox/src untouched (W15 owns the JSX).
   #inbox-root scope out-specifies dist/inbox.css, which loads AFTER
   primitives.css in the template body. !important appears ONLY where
   the JSX sets inline styles (stale-banner) — still CSS-level.
   ============================================================ */
[data-theme="fluxdeck"] .inbox { border-top: 1px solid var(--line-1); background: transparent; }

/* left rail: panel surface */
[data-theme="fluxdeck"] #inbox-root .inbox-list { background: var(--bg-1); border-right: 1px solid var(--line-1); }
[data-theme="fluxdeck"] #inbox-root .inbox-toolbar {
  background: var(--bg-1);
  border-bottom: 1px solid var(--line-1);
}
[data-theme="fluxdeck"] #inbox-root .inbox-toolbar input[type="search"],
[data-theme="fluxdeck"] #inbox-root .inbox-toolbar select {
  background: var(--bg-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-btn);
  color: var(--ink-0);
}
[data-theme="fluxdeck"] #inbox-root .inbox-toolbar input[type="search"]::placeholder { color: var(--ink-2); }

/* rows: §6 table law — hover wash, selected = volt@8% + 2px volt bar */
[data-theme="fluxdeck"] #inbox-root .lead-item {
  background: var(--bg-1);
  color: var(--ink-1);
  border-bottom: 1px solid var(--line-1);
  transition: background-color var(--dur-press) var(--ease-out);
}
[data-theme="fluxdeck"] #inbox-root .lead-item:hover { background: var(--bg-2); }
[data-theme="fluxdeck"] #inbox-root .lead-item.selected {
  background: var(--volt-tint-8);   /* §6 selected-row law: volt@8% + 2px volt bar */
  box-shadow: inset 2px 0 0 var(--volt);
  border-left: none;
  padding-left: 14px;
}
[data-theme="fluxdeck"] #inbox-root .lead-item .biz { color: var(--ink-0); }
[data-theme="fluxdeck"] #inbox-root .lead-item .meta { color: var(--ink-2); }
[data-theme="fluxdeck"] #inbox-root .lead-item .right .due {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}
[data-theme="fluxdeck"] #inbox-root .lead-item .right .due.overdue,
[data-theme="fluxdeck"] #inbox-root .lead-item .right .due.today { color: var(--flare-ink); font-weight: 600; }
[data-theme="fluxdeck"] #inbox-root .lead-item .time-since {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: var(--ink-2);
  background: var(--bg-2);
  border-radius: var(--radius-chip);
}
[data-theme="fluxdeck"] #inbox-root .rep-pill {
  font-family: var(--font-mono);
  background: var(--bg-2);
  color: var(--ink-1);
  border: 1px solid var(--line-2);
}

/* swipe-to-take action bar: signal fill + DARK ink (white-on-signal was
   ~1.9:1; on-accent is 10.9:1 — gated) */
[data-theme="fluxdeck"] #inbox-root .lead-item::after {
  background: var(--signal);
  color: var(--on-accent);
}
[data-theme="fluxdeck"] #inbox-root .lead-item.will-trigger::after {
  background: var(--signal-strong);
  filter: none;
  box-shadow: inset 0 0 0 2px rgba(10, 14, 22, 0.35);
}

/* stale banner (inline-styled in the bundle → sanctioned !important):
   past-SLA leads need another push = flare, not heat */
[data-theme="fluxdeck"] #inbox-root .stale-banner {
  background: var(--flare-tint) !important;
  border: 1px solid var(--flare-border) !important;
  color: var(--ink-0) !important;
  border-radius: var(--radius-btn) !important;
}

/* bulk bar: overlay surface */
[data-theme="fluxdeck"] #inbox-root .bulk-bar {
  background: var(--bg-3);
  border: 1px solid var(--line-2);
  box-shadow: var(--elev-overlay);
}
[data-theme="fluxdeck"] #inbox-root .bulk-bar-left { color: var(--ink-1); }
[data-theme="fluxdeck"] #inbox-root .bulk-bar-left strong {
  font-family: var(--font-mono);
  color: var(--volt-ink);
}
[data-theme="fluxdeck"] #inbox-root .lead-item:has(.bulk-check:checked) { background: var(--volt-tint-8); }

/* detail pane: content sits on the canvas; the side card is elevated */
[data-theme="fluxdeck"] #inbox-root .inbox-detail { background: transparent; }
[data-theme="fluxdeck"] #inbox-root .inbox-detail .placeholder { color: var(--ink-1); }
[data-theme="fluxdeck"] #inbox-root .detail-head { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] #inbox-root .detail-head h2 {
  font-family: var(--font-display);
  font-stretch: semi-expanded;
  font-size: 20px;
  font-weight: 700;
  color: var(--ink-0);
}
[data-theme="fluxdeck"] #inbox-root .detail-head .sub { color: var(--ink-2); }
[data-theme="fluxdeck"] #inbox-root .detail-head .sub a { color: var(--volt-ink); }
[data-theme="fluxdeck"] #inbox-root .detail-head .sub a:hover { color: var(--volt-strong); }
[data-theme="fluxdeck"] #inbox-root .detail-side {
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-card);
  box-shadow: var(--elev-card);
}
[data-theme="fluxdeck"] #inbox-root .detail-side h3,
[data-theme="fluxdeck"] #inbox-root .detail-side .field .lbl {
  font-family: var(--font-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--track-micro);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] #inbox-root .detail-side .field .val { color: var(--ink-0); }
[data-theme="fluxdeck"] #inbox-root .detail-side select,
[data-theme="fluxdeck"] #inbox-root .detail-side input[type="date"],
[data-theme="fluxdeck"] #inbox-root .detail-side input[type="text"],
[data-theme="fluxdeck"] #inbox-root .note-composer textarea {
  background: var(--bg-0);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-btn);
  color: var(--ink-0);
}

/* tabs: volt marks the active surface (§6 nav law) */
[data-theme="fluxdeck"] #inbox-root .tabs { border-bottom: 1px solid var(--line-1); }
[data-theme="fluxdeck"] #inbox-root .tab { color: var(--ink-2); }
[data-theme="fluxdeck"] #inbox-root .tab:hover { color: var(--ink-0); }
[data-theme="fluxdeck"] #inbox-root .tab.active { color: var(--volt-ink); border-bottom-color: var(--volt); }
[data-theme="fluxdeck"] #inbox-root .tab .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  color: var(--ink-2);
  border-radius: var(--radius-pill);
}
[data-theme="fluxdeck"] #inbox-root .tab.active .num {
  background: var(--volt);
  border-color: var(--volt);
  color: var(--on-accent);
}

/* next-step chip: a pinned follow-up = flare family; 6px radius (§7:
   pills are for count badges only) */
[data-theme="fluxdeck"] #inbox-root .next-step-chip {
  background: var(--flare-tint);
  color: var(--flare-ink);
  border: 1px solid var(--flare-border);
  border-radius: var(--radius-chip);
}
[data-theme="fluxdeck"] #inbox-root .next-step-chip:hover { filter: none; background: var(--flare-tint); border-color: var(--flare); }
[data-theme="fluxdeck"] #inbox-root .next-step-chip.empty {
  background: transparent;
  border: 1px dashed var(--line-2);
  color: var(--ink-2);
}
[data-theme="fluxdeck"] #inbox-root .next-step-chip.empty:hover {
  color: var(--flare-ink);
  border-color: var(--flare-border);
  background: var(--flare-tint);
}

/* wave-2 reduced-motion additions */
@media (prefers-reduced-motion: reduce) {
  [data-theme="fluxdeck"] .kanban-card,
[data-theme="fluxdeck"] .kanban-add-btn,
[data-theme="fluxdeck"] .kpi,
[data-theme="fluxdeck"] .pipe-cell,
[data-theme="fluxdeck"] #inbox-root .lead-item {
    transition-property: opacity, background-color, border-color, color, box-shadow;
  }
  [data-theme="fluxdeck"] .kanban-card.dragging { transform: none; }
  [data-theme="fluxdeck"] .open-mini.open-now::before { animation: none; }
}

